xref: /llvm-project/flang/tools/f18/CMakeLists.txt (revision c701c18bed0c6c1bfd4a1dcfa9f207ddbb74cdfc)
1set(LLVM_LINK_COMPONENTS
2  FrontendOpenACC
3  FrontendOpenMP
4  Support
5  )
6
7# Define the list of Fortran module files that need to be compiled
8# to produce an object file for inclusion into the FortranRuntime
9# library.
10set(MODULES_WITH_IMPLEMENTATION
11  "iso_fortran_env_impl"
12)
13
14# Define the list of Fortran module files for which it is
15# sufficient to generate the module file via -fsyntax-only.
16set(MODULES_WITHOUT_IMPLEMENTATION
17  "__fortran_builtins"
18  "__fortran_ieee_exceptions"
19  "__fortran_type_info"
20  "__ppc_types"
21  "__ppc_intrinsics"
22  "mma"
23  "__cuda_builtins"
24  "__cuda_device"
25  "cudadevice"
26  "ieee_arithmetic"
27  "ieee_exceptions"
28  "ieee_features"
29  "iso_c_binding"
30  "iso_fortran_env"
31)
32
33set(MODULES ${MODULES_WITH_IMPLEMENTATION} ${MODULES_WITHOUT_IMPLEMENTATION})
34
35# Check if 128-bit float computations can be done via long double.
36check_cxx_source_compiles(
37  "#include <cfloat>
38   #if LDBL_MANT_DIG != 113
39   #error LDBL_MANT_DIG != 113
40   #endif
41   int main() { return 0; }
42  "
43  HAVE_LDBL_MANT_DIG_113)
44
45# Figure out whether we can support REAL(KIND=16)
46if (FLANG_RUNTIME_F128_MATH_LIB)
47  set(FLANG_SUPPORT_R16 "1")
48elseif (HAVE_LDBL_MANT_DIG_113)
49  set(FLANG_SUPPORT_R16 "1")
50else()
51  set(FLANG_SUPPORT_R16 "0")
52endif()
53
54# Init variable to hold extra object files coming from the Fortran modules;
55# these module files will be contributed from the CMakeLists in flang/tools/f18.
56set(module_objects "")
57
58# Create module files directly from the top-level module source directory.
59# If CMAKE_CROSSCOMPILING, then the newly built flang executable was
60# cross compiled, and thus can't be executed on the build system and thus
61# can't be used for generating module files.
62if (NOT CMAKE_CROSSCOMPILING)
63  foreach(filename ${MODULES})
64    set(depends "")
65    set(opts "")
66    if(${filename} STREQUAL "__fortran_builtins" OR
67       ${filename} STREQUAL "__ppc_types")
68    elseif(${filename} STREQUAL "__ppc_intrinsics" OR
69           ${filename} STREQUAL "mma")
70      set(depends ${FLANG_INTRINSIC_MODULES_DIR}/__ppc_types.mod)
71    elseif(${filename} STREQUAL "__cuda_device")
72      set(opts -fc1 -xcuda)
73      set(depends ${FLANG_INTRINSIC_MODULES_DIR}/__cuda_builtins.mod)
74    elseif(${filename} STREQUAL "cudadevice")
75      set(opts -fc1 -xcuda)
76      set(depends ${FLANG_INTRINSIC_MODULES_DIR}/__cuda_device.mod)
77    else()
78      set(depends ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_builtins.mod)
79      if(${filename} STREQUAL "iso_fortran_env")
80        set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/iso_fortran_env_impl.mod)
81      endif()
82      if(${filename} STREQUAL "ieee_arithmetic" OR
83         ${filename} STREQUAL "ieee_exceptions")
84        set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_ieee_exceptions.mod)
85      endif()
86    endif()
87    if(NOT ${filename} STREQUAL "__fortran_type_info" AND NOT ${filename} STREQUAL "__fortran_builtins")
88      set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_type_info.mod)
89    endif()
90
91    # The module contains PPC vector types that needs the PPC target.
92    if(${filename} STREQUAL "__ppc_intrinsics" OR
93       ${filename} STREQUAL "mma")
94      if (PowerPC IN_LIST LLVM_TARGETS_TO_BUILD)
95        set(opts "--target=ppc64le")
96      else()
97        # Do not compile PPC module if the target is not available.
98        continue()
99      endif()
100    endif()
101
102    set(decls "")
103    if (FLANG_SUPPORT_R16)
104      set(decls "-DFLANG_SUPPORT_R16")
105    endif()
106
107    # Some modules have an implementation part that needs to be added to the
108    # FortranRuntime library.
109    set(compile_with "-fsyntax-only")
110    set(object_output "")
111    set(include_in_link FALSE)
112    if(${filename} IN_LIST MODULES_WITH_IMPLEMENTATION)
113      set(object_output "${CMAKE_CURRENT_BINARY_DIR}/${filename}${CMAKE_CXX_OUTPUT_EXTENSION}")
114      set(compile_with -c -o ${object_output})
115      set(include_in_link TRUE)
116    endif()
117
118    set(base ${FLANG_INTRINSIC_MODULES_DIR}/${filename})
119    # TODO: We may need to flag this with conditional, in case Flang is built w/o OpenMP support
120    add_custom_command(OUTPUT ${base}.mod ${object_output}
121      COMMAND ${CMAKE_COMMAND} -E make_directory ${FLANG_INTRINSIC_MODULES_DIR}
122      COMMAND flang ${opts} ${decls} -cpp ${compile_with} -module-dir ${FLANG_INTRINSIC_MODULES_DIR}
123        ${FLANG_SOURCE_DIR}/module/${filename}.f90
124      DEPENDS flang ${FLANG_SOURCE_DIR}/module/${filename}.f90 ${FLANG_SOURCE_DIR}/module/__fortran_builtins.f90 ${depends}
125    )
126    list(APPEND MODULE_FILES ${base}.mod)
127    install(FILES ${base}.mod DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/flang")
128
129    # If a module has been compiled into an object file, add the file to
130    # the link line for the FortranRuntime library.
131    if(include_in_link)
132      list(APPEND module_objects ${object_output})
133    endif()
134  endforeach()
135
136  # Set a CACHE variable that is visible to the CMakeLists.txt in runtime/, so that
137  # the compiled Fortran modules can be added to the link line of the FortranRuntime
138  # library.
139  set(FORTRAN_MODULE_OBJECTS ${module_objects} CACHE INTERNAL "" FORCE)
140
141  # Special case for omp_lib.mod, because its source comes from openmp/runtime/src/include.
142  # It also produces two module files: omp_lib.mod and omp_lib_kinds.mod.  Compile these
143  # files only if OpenMP support has been configured.
144  if (LLVM_TOOL_OPENMP_BUILD)
145    message(STATUS "OpenMP runtime support enabled via LLVM_ENABLED_PROJECTS, building omp_lib.mod")
146    set(base ${FLANG_INTRINSIC_MODULES_DIR}/omp_lib)
147    add_custom_command(OUTPUT ${base}.mod ${base}_kinds.mod
148      COMMAND ${CMAKE_COMMAND} -E make_directory ${FLANG_INTRINSIC_MODULES_DIR}
149      COMMAND flang -cpp -fsyntax-only ${opts} -module-dir ${FLANG_INTRINSIC_MODULES_DIR}
150        ${CMAKE_BINARY_DIR}/projects/openmp/runtime/src/omp_lib.F90
151      DEPENDS flang ${FLANG_INTRINSIC_MODULES_DIR}/iso_c_binding.mod ${CMAKE_BINARY_DIR}/projects/openmp/runtime/src/omp_lib.F90 ${depends}
152    )
153    add_custom_command(OUTPUT ${base}.f18.mod
154      DEPENDS ${base}.mod
155      COMMAND ${CMAKE_COMMAND} -E copy ${base}.mod ${base}.f18.mod)
156      add_custom_command(OUTPUT ${base}_kinds.f18.mod
157        DEPENDS ${base}.mod
158        COMMAND ${CMAKE_COMMAND} -E copy ${base}_kinds.mod ${base}_kinds.f18.mod)
159    list(APPEND MODULE_FILES ${base}.mod ${base}.f18.mod ${base}_kinds.mod ${base}_kinds.f18.mod)
160    install(FILES ${base}.mod ${base}.f18.mod ${base}_kinds.mod ${base}_kinds.f18.mod DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/flang")
161  else()
162    message(STATUS "Not building omp_lib.mod, no OpenMP runtime in LLVM_ENABLED_PROJECTS")
163  endif()
164endif()
165
166add_custom_target(module_files ALL DEPENDS ${MODULE_FILES})
167set_target_properties(module_files PROPERTIES FOLDER "Flang/Resources")
168
169# TODO Move this to a more suitable location
170# Copy the generated omp_lib.h header file, if OpenMP support has been configured.
171if (LLVM_TOOL_OPENMP_BUILD)
172  message(STATUS "OpenMP runtime support enabled via LLVM_ENABLED_PROJECTS, building omp_lib.h")
173  file(COPY ${CMAKE_BINARY_DIR}/projects/openmp/runtime/src/omp_lib.h DESTINATION "${CMAKE_BINARY_DIR}/include/flang/OpenMP/" FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
174  install(FILES ${CMAKE_BINARY_DIR}/include/flang/OpenMP/omp_lib.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/flang/OpenMP")
175else()
176  message(STATUS "Not copying omp_lib.h, no OpenMP runtime in LLVM_ENABLED_PROJECTS")
177endif()
178