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