diff options
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/CMakeDetermineCompilerId.cmake | 26 | ||||
-rw-r--r-- | Modules/CMakeDetermineFortranCompiler.cmake | 50 | ||||
-rw-r--r-- | Modules/CMakeFindBinUtils.cmake | 2 | ||||
-rw-r--r-- | Modules/Compiler/LLVMFlang-Fortran.cmake | 12 | ||||
-rw-r--r-- | Modules/Platform/Windows-LLVMFlang-Fortran.cmake | 61 |
5 files changed, 142 insertions, 9 deletions
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 9d3b60f..4f1eaba 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -174,6 +174,32 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) endif() endif() + # FIXME(LLVMFlang): It does not provide predefines identifying the MSVC ABI or architecture. + # It should be taught to define _MSC_VER and its _M_* architecture flags. + if("x${lang}" STREQUAL "xFortran" AND "x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xLLVMFlang") + # Parse the target triple to detect information we should later be able + # to get during preprocessing above, once LLVMFlang provides it. + if(COMPILER_${lang}_PRODUCED_OUTPUT MATCHES "-triple ([0-9a-z_]*)-.*windows-msvc([0-9]+)\\.([0-9]+)") + set(CMAKE_${lang}_SIMULATE_ID "MSVC") + set(CMAKE_${lang}_SIMULATE_VERSION "${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") + set(arch ${CMAKE_MATCH_1}) + if(arch STREQUAL "x86_64") + set(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID "x64") + elseif(arch STREQUAL "aarch64") + set(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID "ARM64") + elseif(arch STREQUAL "arm64ec") + set(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID "ARM64EC") + elseif(arch MATCHES "^i[3-9]86$") + set(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID "X86") + else() + message(FATAL_ERROR "LLVMFlang target architecture unrecognized: ${arch}") + endif() + set(MSVC_${lang}_ARCHITECTURE_ID "${CMAKE_${lang}_COMPILER_ARCHITECTURE_ID}") + elseif(COMPILER_${lang}_PRODUCED_OUTPUT MATCHES "-triple ([0-9a-z_]*)-.*windows-gnu") + set(CMAKE_${lang}_SIMULATE_ID "GNU") + endif() + endif() + if (COMPILER_QNXNTO AND (CMAKE_${lang}_COMPILER_ID STREQUAL "GNU" OR CMAKE_${lang}_COMPILER_ID STREQUAL "LCC")) execute_process( COMMAND "${CMAKE_${lang}_COMPILER}" diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake index 8cbaf70..392f0f1 100644 --- a/Modules/CMakeDetermineFortranCompiler.cmake +++ b/Modules/CMakeDetermineFortranCompiler.cmake @@ -98,6 +98,9 @@ else() set(CMAKE_Fortran_COMPILER_ID_TEST_FLAGS_FIRST # Get verbose output to help distinguish compilers. "-v" + + # Try compiling to an object file only, with verbose output. + "-v -c" ) set(CMAKE_Fortran_COMPILER_ID_TEST_FLAGS # Try compiling to an object file only. @@ -108,6 +111,10 @@ else() ) endif() +if(CMAKE_Fortran_COMPILER_TARGET) + set(CMAKE_Fortran_COMPILER_ID_TEST_FLAGS_FIRST "-v -c --target=${CMAKE_Fortran_COMPILER_TARGET}") +endif() + # Build a small source file to identify the compiler. if(NOT CMAKE_Fortran_COMPILER_ID_RUN) set(CMAKE_Fortran_COMPILER_ID_RUN 1) @@ -227,6 +234,49 @@ if(NOT CMAKE_Fortran_COMPILER_ID_RUN) endif() endif() +if("${CMAKE_Fortran_COMPILER_ID};${CMAKE_Fortran_SIMULATE_ID}" STREQUAL "LLVMFlang;MSVC") + # With LLVMFlang targeting the MSVC ABI we link using lld-link. + # Detect the implicit link information from the compiler driver + # so we can explicitly pass it to the linker. + include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake) + set(_LLVMFlang_COMMAND "${CMAKE_Fortran_COMPILER}" "-###" ${CMAKE_CURRENT_LIST_DIR}/CMakeFortranCompilerABI.F) + if(CMAKE_Fortran_COMPILER_TARGET) + list(APPEND _LLVMFlang_COMMAND --target=${CMAKE_Fortran_COMPILER_TARGET}) + endif() + execute_process(COMMAND ${_LLVMFlang_COMMAND} + OUTPUT_VARIABLE _LLVMFlang_OUTPUT + ERROR_VARIABLE _LLVMFlang_OUTPUT + RESULT_VARIABLE _LLVMFlang_RESULT) + string(JOIN "\" \"" _LLVMFlang_COMMAND ${_LLVMFlang_COMMAND}) + message(CONFIGURE_LOG + "Running the Fortran compiler: \"${_LLVMFlang_COMMAND}\"\n" + "${_LLVMFlang_OUTPUT}" + ) + if(_LLVMFlang_RESULT EQUAL 0) + cmake_parse_implicit_link_info("${_LLVMFlang_OUTPUT}" + CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES + CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES + CMAKE_Fortran_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES + log + "${CMAKE_Fortran_IMPLICIT_OBJECT_REGEX}" + LANGUAGE Fortran) + message(CONFIGURE_LOG + "Parsed Fortran implicit link information:\n" + "${log}\n" + ) + set(_CMAKE_Fortran_IMPLICIT_LINK_INFORMATION_DETERMINED_EARLY 1) + if("x${CMAKE_Fortran_COMPILER_ARCHITECTURE_ID}" STREQUAL "xARM64") + # FIXME(LLVMFlang): It does not add `-defaultlib:` fields to object + # files to specify link dependencies on its runtime libraries. + # For now, we add them ourselves. + list(APPEND CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES "clang_rt.builtins-aarch64.lib") + endif() + endif() + unset(_LLVMFlang_COMMAND) + unset(_LLVMFlang_OUTPUT) + unset(_LLVMFlang_RESULT) +endif() + if (NOT _CMAKE_TOOLCHAIN_LOCATION) get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_Fortran_COMPILER}" PATH) endif () diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake index 431d00b..e12b175 100644 --- a/Modules/CMakeFindBinUtils.cmake +++ b/Modules/CMakeFindBinUtils.cmake @@ -79,7 +79,7 @@ if(("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC" AND set(_CMAKE_MT_NAMES "mt") # Prepend toolchain-specific names. - if("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xClang") + if("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" MATCHES "^x(Clang|LLVMFlang)$") set(_CMAKE_NM_NAMES "llvm-nm" "nm") list(PREPEND _CMAKE_AR_NAMES "llvm-lib") # llvm-mt is not ready to be used as a replacement for mt.exe diff --git a/Modules/Compiler/LLVMFlang-Fortran.cmake b/Modules/Compiler/LLVMFlang-Fortran.cmake index 6b0c0fc..d27f094 100644 --- a/Modules/Compiler/LLVMFlang-Fortran.cmake +++ b/Modules/Compiler/LLVMFlang-Fortran.cmake @@ -1,5 +1,3 @@ -set(CMAKE_Fortran_VERBOSE_FLAG "-v") - set(CMAKE_Fortran_SUBMODULE_SEP "-") set(CMAKE_Fortran_SUBMODULE_EXT ".mod") @@ -17,6 +15,10 @@ set(CMAKE_Fortran_POSTPROCESS_FLAG "-ffixed-line-length-72") set(CMAKE_Fortran_COMPILE_OPTIONS_TARGET "--target=") -string(APPEND CMAKE_Fortran_FLAGS_DEBUG_INIT " -O0 -g") -string(APPEND CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT " -O2 -g") -string(APPEND CMAKE_Fortran_FLAGS_RELEASE_INIT " -O3") +if(NOT "x${CMAKE_Fortran_SIMULATE_ID}" STREQUAL "xMSVC") + set(CMAKE_Fortran_VERBOSE_FLAG "-v") + + string(APPEND CMAKE_Fortran_FLAGS_DEBUG_INIT " -O0 -g") + string(APPEND CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT " -O2 -g") + string(APPEND CMAKE_Fortran_FLAGS_RELEASE_INIT " -O3") +endif() diff --git a/Modules/Platform/Windows-LLVMFlang-Fortran.cmake b/Modules/Platform/Windows-LLVMFlang-Fortran.cmake index 64dc0da..3e22a6e 100644 --- a/Modules/Platform/Windows-LLVMFlang-Fortran.cmake +++ b/Modules/Platform/Windows-LLVMFlang-Fortran.cmake @@ -1,3 +1,58 @@ -include(Platform/Windows-GNU) -__windows_compiler_gnu(Fortran) -# TODO: MSVC ABI Support +if("x${CMAKE_Fortran_SIMULATE_ID}" STREQUAL "xGNU") + include(Platform/Windows-GNU) + __windows_compiler_gnu(Fortran) +elseif("x${CMAKE_Fortran_SIMULATE_ID}" STREQUAL "xMSVC") + include(Platform/Windows-MSVC) + __windows_compiler_msvc(Fortran) + + # FIXME(LLVMFlang): It does not provides MSVC runtime library selection flags. + # It should be given a flag like classic Flang's `-Xclang --dependent-lib=`, or a + # dedicated flag to select among multiple `Fortran*.lib` runtime library variants + # that each depend on a different MSVC runtime library. For now, LLVMFlang's + # `Fortran*.lib` runtime libraries hard-code use of msvcrt (MultiThreadedDLL), + # so we link to it ourselves. + set(_LLVMFlang_LINK_RUNTIME "-defaultlib:msvcrt") + set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "") + set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "") + set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "") + set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "") + + # FIXME(LLVMFlang): It does not provide all debug information format flags or predefines. + # It should be given a flag to enable Embedded debug information like MSVC -Z7. + #set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_Embedded) # not supported by LLVMFlang + #set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_EditAndContinue) # not supported by LLVMFlang + set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_ProgramDatabase "-g") + + set(CMAKE_Fortran_COMPILE_OBJECT "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>") + + if(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT_DEFAULT) + set(_g "") + else() + set(_g " -g") + endif() + string(APPEND CMAKE_Fortran_FLAGS_DEBUG_INIT "${_g}") + string(APPEND CMAKE_Fortran_FLAGS_RELEASE_INIT "") + string(APPEND CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "${_g}") + string(APPEND CMAKE_Fortran_FLAGS_MINSIZEREL_INIT "") + unset(_g) + + # We link with lld-link.exe instead of the compiler driver, so explicitly + # pass implicit link information previously detected from the compiler. + set(_LLVMFlang_LINK_DIRS "${CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES}") + list(TRANSFORM _LLVMFlang_LINK_DIRS PREPEND "-libpath:\"") + list(TRANSFORM _LLVMFlang_LINK_DIRS APPEND "\"") + string(JOIN " " _LLVMFlang_LINK_DIRS ${_LLVMFlang_LINK_DIRS}) + string(JOIN " " _LLVMFlang_LINK_LIBS ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES}) + foreach(v IN ITEMS + CMAKE_Fortran_LINK_EXECUTABLE + CMAKE_Fortran_CREATE_SHARED_LIBRARY + CMAKE_Fortran_CREATE_SHARED_MODULE + ) + string(APPEND "${v}" " ${_LLVMFlang_LINK_DIRS} ${_LLVMFlang_LINK_LIBS} ${_LLVMFlang_LINK_RUNTIME}") + endforeach() + unset(_LLVMFlang_LINK_DIRS) + unset(_LLVMFlang_LINK_LIBS) + unset(_LLVMFlang_LINK_RUNTIME) +else() + message(FATAL_ERROR "LLVMFlang target ABI unrecognized: ${CMAKE_Fortran_SIMULATE_ID}") +endif() |