• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1cmake_minimum_required(VERSION 3.13.4)
2
3# RPATH settings on macOS do not affect INSTALL_NAME.
4if (POLICY CMP0068)
5  cmake_policy(SET CMP0068 NEW)
6  set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON)
7endif()
8
9# Include file check macros honor CMAKE_REQUIRED_LIBRARIES.
10if(POLICY CMP0075)
11  cmake_policy(SET CMP0075 NEW)
12endif()
13
14# option() honors normal variables.
15if (POLICY CMP0077)
16  cmake_policy(SET CMP0077 NEW)
17endif()
18
19option(LINK_WITH_FIR "Link driver with FIR and LLVM" ON)
20option(FLANG_BUILD_NEW_DRIVER "Build the flang compiler driver" OFF)
21
22# Flang requires C++17.
23set(CMAKE_CXX_STANDARD 17)
24set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
25set(CMAKE_CXX_EXTENSIONS OFF)
26
27set(FLANG_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
28
29if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE)
30  message(FATAL_ERROR "In-source builds are not allowed. \
31          Please create a directory and run cmake from there,\
32          passing the path to this source directory as the last argument.\
33          This process created the file `CMakeCache.txt' and the directory\
34          `CMakeFiles'. Please delete them.")
35endif()
36
37# Add Flang-centric modules to cmake path.
38list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
39include(AddFlang)
40
41option(FLANG_ENABLE_WERROR "Fail and stop building flang if a warning is triggered." OFF)
42
43# Check for a standalone build and configure as appropriate from
44# there.
45if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
46  message("Building Flang as a standalone project.")
47  project(Flang)
48  set(FLANG_STANDALONE_BUILD ON)
49
50  set(FLANG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
51  if (NOT MSVC_IDE)
52    set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS}
53      CACHE BOOL "Enable assertions")
54    # Assertions follow llvm's configuration.
55    mark_as_advanced(LLVM_ENABLE_ASSERTIONS)
56  endif()
57
58  # We need a pre-built/installed version of LLVM.
59  find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_PATH}")
60  # If the user specifies a relative path to LLVM_DIR, the calls to include
61  # LLVM modules fail. Append the absolute path to LLVM_DIR instead.
62  get_filename_component(LLVM_DIR_ABSOLUTE ${LLVM_DIR} REALPATH)
63  list(APPEND CMAKE_MODULE_PATH ${LLVM_DIR_ABSOLUTE})
64
65  if(FLANG_BUILD_NEW_DRIVER)
66    # TODO: Remove when libclangDriver is lifted out of Clang
67    list(APPEND CMAKE_MODULE_PATH ${CLANG_DIR})
68    find_package(Clang REQUIRED HINTS "${CLANG_DIR}")
69  endif()
70
71  # If LLVM links to zlib we need the imported targets so we can too.
72  if(LLVM_ENABLE_ZLIB)
73    find_package(ZLIB REQUIRED)
74  endif()
75  option(LLVM_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
76  if(CMAKE_COMPILER_IS_GNUCXX)
77    set(USE_NO_MAYBE_UNINITIALIZED 1)
78  endif()
79
80  include(CMakeParseArguments)
81  include(AddLLVM)
82  include(HandleLLVMOptions)
83  include(VersionFromVCS)
84
85  if(FLANG_BUILD_NEW_DRIVER)
86    include(AddClang)
87  endif()
88
89  if(LINK_WITH_FIR)
90    include(TableGen)
91    find_package(MLIR REQUIRED CONFIG)
92    # Use SYSTEM for the same reasons as for LLVM includes
93    include_directories(SYSTEM ${MLIR_INCLUDE_DIRS})
94    # If the user specifies a relative path to MLIR_DIR, the calls to include
95    # MLIR modules fail. Append the absolute path to MLIR_DIR instead.
96    get_filename_component(MLIR_DIR_ABSOLUTE ${MLIR_DIR} REALPATH)
97    list(APPEND CMAKE_MODULE_PATH ${MLIR_DIR_ABSOLUTE})
98    include(AddMLIR)
99    find_program(MLIR_TABLEGEN_EXE "mlir-tblgen" ${LLVM_TOOLS_BINARY_DIR}
100      NO_DEFAULT_PATH)
101  endif()
102
103  option(LLVM_INSTALL_TOOLCHAIN_ONLY
104    "Only include toolchain files in the 'install' target." OFF)
105  option(LLVM_FORCE_USE_OLD_HOST_TOOLCHAIN
106    "Set to ON to force using an old, unsupported host toolchain." OFF)
107
108
109  # Add LLVM include files as if they were SYSTEM because there are complex unused
110  # parameter issues that may or may not appear depending on the environments and
111  # compilers (ifdefs are involved). This allows warnings from LLVM headers to be
112  # ignored while keeping -Wunused-parameter a fatal error inside f18 code base.
113  # This may have to be fine-tuned if flang headers are consider part of this
114  # LLVM_INCLUDE_DIRS when merging in the monorepo (Warning from flang headers
115  # should not be suppressed).
116  include_directories(SYSTEM ${LLVM_INCLUDE_DIRS})
117  add_definitions(${LLVM_DEFINITIONS})
118
119  # LLVM's cmake configuration files currently sneak in a c++11 flag.
120  # We look for it here and remove it from Flang's compile flags to
121  # avoid some mixed compilation flangs (e.g. -std=c++11 ... -std=c++17).
122  if (DEFINED LLVM_CXX_STD)
123    message("LLVM configuration set a C++ standard: ${LLVM_CXX_STD}")
124    if (NOT LLVM_CXX_STD EQUAL "c++17")
125      message("Flang: Overriding LLVM's 'cxx_std' setting...")
126      message("    removing '-std=${LLVM_CXX_STD}'")
127      message("    CMAKE_CXX_FLAGS='${CMAKE_CXX_FLAGS}'")
128      string(REPLACE " -std=${LLVM_CXX_STD}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
129      message("    [NEW] CMAKE_CXX_FLAGS='${CMAKE_CXX_FLAGS}'")
130    endif()
131  endif()
132
133  link_directories("${LLVM_LIBRARY_DIR}")
134
135  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
136  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
137    ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX})
138  set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
139    ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX})
140
141  set(BACKEND_PACKAGE_STRING "LLVM ${LLVM_PACKAGE_VERSION}")
142  set(LLVM_EXTERNAL_LIT "${LLVM_TOOLS_BINARY_DIR}/llvm-lit" CACHE STRING "Command used to spawn lit")
143
144  option(FLANG_INCLUDE_TESTS
145         "Generate build targets for the Flang unit tests."
146         ON)
147
148#Handle unittests when out-of-tree
149#LLVM_BUILD_MAIN_SRC_DIR - Path to llvm source when out-of-tree.
150  set(FLANG_GTEST_AVAIL 0)
151  if (FLANG_INCLUDE_TESTS)
152    set(UNITTEST_DIR ${LLVM_BUILD_MAIN_SRC_DIR}/utils/unittest)
153    if(EXISTS ${UNITTEST_DIR}/googletest/include/gtest/gtest.h)
154      if (NOT TARGET gtest)
155        add_library(gtest
156          ${UNITTEST_DIR}/googletest/src/gtest-all.cc
157          ${UNITTEST_DIR}/googlemock/src/gmock-all.cc
158          )
159        target_include_directories(gtest
160          PUBLIC
161          "${UNITTEST_DIR}/googletest/include"
162          "${UNITTEST_DIR}/googlemock/include"
163
164          PRIVATE
165          "${UNITTEST_DIR}/googletest"
166          "${UNITTEST_DIR}/googlemock"
167          )
168         find_package(Threads)
169         target_link_libraries(gtest PUBLIC Threads::Threads)
170        add_library(gtest_main ${UNITTEST_DIR}/UnitTestMain/TestMain.cpp)
171        target_link_libraries(gtest_main PUBLIC gtest)
172      endif()
173      set(FLANG_GTEST_AVAIL 1)
174    else()
175      message(WARNING
176      "Unit-tests will be skipped as LLVM install does not include google-test related headers and libraries.")
177      set(FLANG_GTEST_AVAIL 0)
178    endif()
179  endif()
180  if (FLANG_GTEST_AVAIL)
181    add_custom_target(check-all DEPENDS check-flang FlangUnitTests)
182  else()
183    add_custom_target(check-all DEPENDS check-flang )
184  endif()
185  if (LLVM_BUILD_DOCS)
186    add_custom_target(doxygen ALL)
187  endif()
188
189else()
190  set(FLANG_STANDALONE_BUILD OFF)
191  option(FLANG_INCLUDE_TESTS
192         "Generate build targets for the Flang unit tests."
193         ${LLVM_INCLUDE_TESTS})
194  set(FLANG_GTEST_AVAIL 1)
195
196  if(FLANG_STANDALONE_BUILD)
197    set(FLANG_BINARY_DIR ${CMAKE_BINARY_DIR}/tools/flang)
198  else()
199    set(FLANG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
200  endif()
201
202  set(BACKEND_PACKAGE_STRING "${PACKAGE_STRING}")
203  if (LINK_WITH_FIR)
204    set(MLIR_MAIN_SRC_DIR ${LLVM_MAIN_SRC_DIR}/../mlir/include ) # --src-root
205    set(MLIR_INCLUDE_DIR ${LLVM_MAIN_SRC_DIR}/../mlir/include ) # --includedir
206    set(MLIR_TABLEGEN_OUTPUT_DIR ${CMAKE_BINARY_DIR}/tools/mlir/include)
207    set(MLIR_TABLEGEN_EXE $<TARGET_FILE:mlir-tblgen>)
208    include_directories(SYSTEM ${MLIR_INCLUDE_DIR})
209    include_directories(SYSTEM ${MLIR_TABLEGEN_OUTPUT_DIR})
210  endif()
211endif()
212
213if(FLANG_BUILD_NEW_DRIVER)
214    # TODO: Remove when libclangDriver is lifted out of Clang
215    if(FLANG_STANDALONE_BUILD)
216      set(CLANG_INCLUDE_DIR ${CLANG_INCLUDE_DIRS} )
217      # No need to specify TableGen output dir as that's embedded in CLANG_DIR
218    else()
219      set(CLANG_INCLUDE_DIR ${LLVM_MAIN_SRC_DIR}/../clang/include )
220      # Specify TableGen output dir for things like DiagnosticCommonKinds.inc,
221      # DiagnosticDriverKinds.inc (required for reporting diagnostics)
222      set(CLANG_TABLEGEN_OUTPUT_DIR ${CMAKE_BINARY_DIR}/tools/clang/include)
223      include_directories(SYSTEM ${CLANG_TABLEGEN_OUTPUT_DIR})
224    endif()
225    include_directories(SYSTEM ${CLANG_INCLUDE_DIR})
226endif()
227
228if(LINK_WITH_FIR)
229  # tco tool and FIR lib output directories
230  if(FLANG_STANDALONE_BUILD)
231    set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/bin)
232    set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/lib)
233  endif()
234  # Always build tco tool
235  set(LLVM_BUILD_TOOLS ON)
236  set(LLVM_COMMON_COMPONENTS Support)
237  message(STATUS "Linking driver with FIR and LLVM, using LLVM components: ${LLVM_COMMON_COMPONENTS}")
238endif()
239
240# Add Flang-centric modules to cmake path.
241include_directories(BEFORE
242  ${FLANG_BINARY_DIR}/include
243  ${FLANG_SOURCE_DIR}/include)
244
245list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
246
247if (NOT DEFAULT_SYSROOT)
248  set(DEFAULT_SYSROOT "" CACHE PATH
249    "The <path> to use for the system root for all compiler invocations (--sysroot=<path>).")
250endif()
251
252if (NOT ENABLE_LINKER_BUILD_ID)
253  set(ENABLE_LINKER_BUILD_ID OFF CACHE BOOL "pass --build-id to ld")
254endif()
255
256set(FLANG_DEFAULT_LINKER "" CACHE STRING
257  "Default linker to use (linker name or absolute path, empty for platform default)")
258
259set(FLANG_DEFAULT_RTLIB "" CACHE STRING
260   "Default Fortran runtime library to use (\"libFortranRuntime\"), leave empty for platform default.")
261
262if (NOT(FLANG_DEFAULT_RTLIB STREQUAL ""))
263  message(WARNING "Resetting Flang's default runtime library to use platform default.")
264  set(FLANG_DEFAULT_RTLIB "" CACHE STRING
265      "Default runtime library to use (empty for platform default)" FORCE)
266endif()
267
268
269
270set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
271# Override LLVM versioning for now...
272set(FLANG_VERSION_MAJOR      "0")
273set(FLANG_VERSION_MINOR      "1")
274set(FLANG_VERSION_PATCHLEVEL "0")
275
276
277if (NOT DEFINED FLANG_VERSION_MAJOR)
278  set(FLANG_VERSION_MAJOR ${LLVM_VERSION_MAJOR})
279endif()
280
281if (NOT DEFINED FLANG_VERSION_MINOR)
282  set(FLANG_VERSION_MINOR ${LLVM_VERSION_MINOR})
283endif()
284
285if (NOT DEFINED FLANG_VERSION_PATCHLEVEL)
286  set(FLANG_VERSION_PATCHLEVEL ${LLVM_VERSION_PATCH})
287endif()
288
289# Unlike PACKAGE_VERSION, FLANG_VERSION does not include LLVM_VERSION_SUFFIX.
290set(FLANG_VERSION "${FLANG_VERSION_MAJOR}.${FLANG_VERSION_MINOR}.${FLANG_VERSION_PATCHLEVEL}")
291message(STATUS "Flang version: ${FLANG_VERSION}")
292# Flang executable version information
293set(FLANG_EXECUTABLE_VERSION
294    "${FLANG_VERSION_MAJOR}" CACHE STRING
295    "Major version number to appended to the flang executable name.")
296set(LIBFLANG_LIBRARY_VERSION
297    "${FLANG_VERSION_MAJOR}" CACHE STRING
298    "Major version number to appended to the libflang library.")
299
300mark_as_advanced(FLANG_EXECUTABLE_VERSION LIBFLANG_LIBRARY_VERSION)
301
302set(FLANG_VENDOR ${PACKAGE_VENDOR} CACHE STRING
303  "Vendor-specific Flang version information.")
304set(FLANG_VENDOR_UTI "org.llvm.flang" CACHE STRING
305  "Vendor-specific uti.")
306
307if (FLANG_VENDOR)
308  add_definitions(-DFLANG_VENDOR="${FLANG_VENDOR} ")
309endif()
310
311set(FLANG_REPOSITORY_STRING "" CACHE STRING
312  "Vendor-specific text for showing the repository the source is taken from.")
313if (FLANG_REPOSITORY_STRING)
314  add_definitions(-DFLANG_REPOSITORY_STRING="${FLANG_REPOSITORY_STRING}")
315endif()
316
317# Configure Flang's Version.inc file.
318configure_file(
319  ${CMAKE_CURRENT_SOURCE_DIR}/include/flang/Version.inc.in
320  ${CMAKE_CURRENT_BINARY_DIR}/include/flang/Version.inc)
321# Configure Flang's version info header file.
322configure_file(
323  ${FLANG_SOURCE_DIR}/include/flang/Config/config.h.cmake
324  ${FLANG_BINARY_DIR}/include/flang/Config/config.h)
325
326if (FLANG_ENABLE_WERROR)
327  # The following is taken from llvm/cmake/modules/HandleLLVMOptions.cmake
328  # Keep this up-to-date with that file
329  if( MSVC )
330    append("/WX" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
331  endif()
332  if ( LLVM_COMPILER_IS_GCC_COMPATIBLE )
333    append("-Werror" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
334    append("-Wno-error" CMAKE_REQUIRED_FLAGS)
335  endif( LLVM_COMPILER_IS_GCC_COMPATIBLE )
336endif()
337
338# Builtin check_cxx_compiler_flag doesn't seem to work correctly
339macro(check_compiler_flag flag resultVar)
340  unset(${resultVar} CACHE)
341  check_cxx_compiler_flag("${flag}" ${resultVar})
342endmacro()
343
344check_compiler_flag("-Werror -Wno-deprecated-copy" CXX_SUPPORTS_NO_DEPRECATED_COPY_FLAG)
345if (CXX_SUPPORTS_NO_DEPRECATED_COPY_FLAG)
346  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-copy")
347endif()
348check_compiler_flag("-Wstring-conversion" CXX_SUPPORTS_NO_STRING_CONVERSION_FLAG)
349if (CXX_SUPPORTS_NO_STRING_CONVERSION_FLAG)
350  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-string-conversion")
351endif()
352
353# Add appropriate flags for GCC
354if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
355
356  if (NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
357    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing -fno-semantic-interposition")
358  else()
359    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-command-line-argument -Wstring-conversion \
360          -Wcovered-switch-default")
361  endif()  # Clang.
362
363  check_cxx_compiler_flag("-Werror -Wnested-anon-types" CXX_SUPPORTS_NO_NESTED_ANON_TYPES_FLAG)
364  if (CXX_SUPPORTS_NO_NESTED_ANON_TYPES_FLAG)
365    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-nested-anon-types")
366  endif()
367
368  # Add to build type flags.
369  set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUGF18")
370  set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -DCHECK=\"(void)\"")
371
372  # Building shared libraries is bad for performance with GCC by default
373  # due to the need to preserve the right to override external entry points
374  if (BUILD_SHARED_LIBS AND NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
375   set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-semantic-interposition")
376  endif()
377
378endif()
379
380list(REMOVE_DUPLICATES CMAKE_CXX_FLAGS)
381
382# Determine HOST_LINK_VERSION on Darwin.
383set(HOST_LINK_VERSION)
384if (APPLE)
385  set(LD_V_OUTPUT)
386  execute_process(
387    COMMAND sh -c "${CMAKE_LINKER} -v 2>&1 | head -1"
388    RESULT_VARIABLE HAD_ERROR
389    OUTPUT_VARIABLE LD_V_OUTPUT)
390  if (NOT HAD_ERROR)
391    if ("${LD_V_OUTPUT}" MATCHES ".*ld64-([0-9.]+).*")
392      string(REGEX REPLACE ".*ld64-([0-9.]+).*" "\\1" HOST_LINK_VERSION ${LD_V_OUTPUT})
393    elseif ("${LD_V_OUTPUT}" MATCHES "[^0-9]*([0-9.]+).*")
394      string(REGEX REPLACE "[^0-9]*([0-9.]+).*" "\\1" HOST_LINK_VERSION ${LD_V_OUTPUT})
395    endif()
396  else()
397    message(FATAL_ERROR "${CMAKE_LINKER} failed with status ${HAD_ERROR}")
398  endif()
399endif()
400
401include(CMakeParseArguments)
402include(AddFlang)
403
404
405add_subdirectory(include)
406add_subdirectory(lib)
407add_subdirectory(cmake/modules)
408
409option(FLANG_BUILD_TOOLS
410  "Build the Flang tools. If OFF, just generate build targets." ON)
411if (FLANG_BUILD_TOOLS)
412  add_subdirectory(tools)
413endif()
414add_subdirectory(runtime)
415
416if (FLANG_INCLUDE_TESTS)
417  add_subdirectory(test)
418  if (FLANG_GTEST_AVAIL)
419    add_subdirectory(unittests)
420  endif ()
421endif()
422
423option(FLANG_INCLUDE_DOCS "Generate build targets for the Flang docs."
424       ${LLVM_INCLUDE_DOCS})
425if (FLANG_INCLUDE_DOCS)
426  add_subdirectory(docs)
427endif()
428
429# Custom target to install Flang libraries.
430add_custom_target(flang-libraries)
431set_target_properties(flang-libraries PROPERTIES FOLDER "Misc")
432
433if (NOT LLVM_ENABLE_IDE)
434  add_llvm_install_targets(install-flang-libraries
435   DEPENDS flang-libraries
436   COMPONENT flang-libraries)
437endif()
438
439get_property(FLANG_LIBS GLOBAL PROPERTY FLANG_LIBS)
440if (FLANG_LIBS)
441  list(REMOVE_DUPLICATES FLANG_LIBS)
442  foreach(lib ${FLANG_LIBS})
443    add_dependencies(flang-libraries ${lib})
444    if (NOT LLVM_ENABLE_IDE)
445      add_dependencies(install-flang-libraries install-${lib})
446    endif()
447  endforeach()
448endif()
449
450if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
451  install(DIRECTORY include/flang
452    DESTINATION include
453    COMPONENT flang-headers
454    FILES_MATCHING
455    PATTERN "*.def"
456    PATTERN "*.h"
457    PATTERN "*.inc"
458    PATTERN "*.td"
459    PATTERN "config.h" EXCLUDE
460    PATTERN ".git"     EXCLUDE
461    PATTERN "CMakeFiles" EXCLUDE)
462endif()
463