summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Modules')
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake26
-rw-r--r--Modules/CMakeDetermineFortranCompiler.cmake50
-rw-r--r--Modules/CMakeFindBinUtils.cmake2
-rw-r--r--Modules/Compiler/LLVMFlang-Fortran.cmake12
-rw-r--r--Modules/Platform/Windows-LLVMFlang-Fortran.cmake61
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()