diff options
author | Brad King <brad.king@kitware.com> | 2024-08-02 18:59:23 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2024-08-02 19:15:02 (GMT) |
commit | 509e8be7848f9c1123b26f7c0ad89f22dec8c0ea (patch) | |
tree | 5fb4da0b126eed1ceb8b2d707a4561ebaf3214e2 | |
parent | cb6e8698ffd35197d1662f6fe5ecd0944eb92681 (diff) | |
download | CMake-509e8be7848f9c1123b26f7c0ad89f22dec8c0ea.zip CMake-509e8be7848f9c1123b26f7c0ad89f22dec8c0ea.tar.gz CMake-509e8be7848f9c1123b26f7c0ad89f22dec8c0ea.tar.bz2 |
LFortran: Add support for mixed-language linking with Fortran
Parse implicit link information for this compiler to support
mixed-language linking. This was missed by commit 98d0f918ba (LFortran:
Add support for this compiler, 2024-01-25). Also activate mixed-language
test cases that would have caught this.
Fixes: #26145
8 files changed, 73 insertions, 4 deletions
diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake index c90a421..87c9e8a 100644 --- a/Modules/CMakeParseImplicitLinkInfo.cmake +++ b/Modules/CMakeParseImplicitLinkInfo.cmake @@ -49,15 +49,22 @@ function(cmake_parse_implicit_link_info2 text log_var obj_regex) set(multiValueArgs ) cmake_parse_arguments(EXTRA_PARSE "${keywordArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + set(is_lfortran 0) set(is_msvc 0) if(EXTRA_PARSE_LANGUAGE) if("x${CMAKE_${EXTRA_PARSE_LANGUAGE}_COMPILER_ID}" STREQUAL "xMSVC" OR "x${CMAKE_${EXTRA_PARSE_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC") set(is_msvc 1) + elseif("x${CMAKE_${EXTRA_PARSE_LANGUAGE}_COMPILER_ID}" STREQUAL "xLFortran") + set(is_lfortran 1) endif() endif() # Parse implicit linker arguments. set(linker "ld[0-9]*(\\.[a-z]+)?") + if(is_lfortran) + # FIXME(lfortran): No way to pass -v to clang/gcc driver. + string(APPEND linker "|clang|gcc") + endif() if(is_msvc) string(APPEND linker "|link\\.exe|lld-link(\\.exe)?") endif() @@ -78,6 +85,10 @@ function(cmake_parse_implicit_link_info2 text log_var obj_regex) set(linker_exclude_regex "collect2 version |^[A-Za-z0-9_]+=|/ldfe ") set(linker_tool_regex "^[ \t]*(->|\")?[ \t]*(([^\"]*[/\\])?(${linker}))(\"|,| |$)") set(linker_tool_exclude_regex "cuda-fake-ld|-fuse-ld=|^ExecuteExternalTool ") + if(is_lfortran) + # FIXME(lfortran): No way to pass -v to clang/gcc driver. + string(APPEND linker_tool_exclude_regex "|^clang |^gcc ") + endif() set(linker_tool "NOTFOUND") set(linker_tool_fallback "") set(link_line_parsed 0) diff --git a/Tests/Fortran/CMakeLists.txt b/Tests/Fortran/CMakeLists.txt index 71f9413..6e2fa0b 100644 --- a/Tests/Fortran/CMakeLists.txt +++ b/Tests/Fortran/CMakeLists.txt @@ -38,7 +38,7 @@ if(WIN32 AND NOT CYGWIN) endif() if(CMAKE_Fortran_COMPILER_ID STREQUAL "LFortran") - add_compile_options(--implicit-interface) + add_compile_options("$<$<COMPILE_LANGUAGE:Fortran>:--implicit-interface>") endif() add_library(hello STATIC hello.f) @@ -53,7 +53,7 @@ function(test_fortran_c_interface_module) FortranCInterface_VERIFY() FortranCInterface_VERIFY(CXX) if(CMAKE_Fortran_COMPILER_SUPPORTS_F90) - if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "SunPro|PathScale|Absoft|Fujitsu|LCC") + if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "SunPro|PathScale|Absoft|Fujitsu|LCC|LFortran") set(module_expected 1) endif() if(FortranCInterface_MODULE_FOUND OR module_expected) @@ -127,7 +127,7 @@ endfunction() # if the id's match or the compilers are compatible, then # call the test_fortran_c_interface_module function if("${CMAKE_Fortran_COMPILER_ID}:${CMAKE_C_COMPILER_ID}" MATCHES - "(Intel(LLVM)?:MSVC|Absoft:GNU|LLVMFlang:(GNU|Clang))" + "(Intel(LLVM)?:MSVC|Absoft:GNU|(LLVMFlang|LFortran):(GNU|Clang))" OR ("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "${CMAKE_C_COMPILER_ID}" )) test_fortran_c_interface_module() else() diff --git a/Tests/FortranC/CMakeLists.txt b/Tests/FortranC/CMakeLists.txt index f5e056b..b98d826 100644 --- a/Tests/FortranC/CMakeLists.txt +++ b/Tests/FortranC/CMakeLists.txt @@ -3,7 +3,7 @@ project(FortranC C Fortran) # Skip this test for compilers not known to be compatible. if(NOT (CMAKE_C_COMPILER_ID STREQUAL CMAKE_Fortran_COMPILER_ID OR - "${CMAKE_C_COMPILER_ID}-${CMAKE_Fortran_COMPILER_ID}" MATCHES "^(MSVC-Intel|(GNU|Clang)-LLVMFlang)$")) + "${CMAKE_C_COMPILER_ID}-${CMAKE_Fortran_COMPILER_ID}" MATCHES "^(MSVC-Intel|(GNU|Clang)-(LLVMFlang|LFortran))$")) message(STATUS "${CMAKE_C_COMPILER_ID} C and ${CMAKE_Fortran_COMPILER_ID} Fortran not known to be compatible!") return() endif() diff --git a/Tests/RunCMake/ParseImplicitData/linux-Fortran-LFortran-0.35.0-clang.input b/Tests/RunCMake/ParseImplicitData/linux-Fortran-LFortran-0.35.0-clang.input new file mode 100644 index 0000000..f314608 --- /dev/null +++ b/Tests/RunCMake/ParseImplicitData/linux-Fortran-LFortran-0.35.0-clang.input @@ -0,0 +1,25 @@ +CMAKE_LANG=Fortran +CMAKE_LINKER=/usr/bin/ld +CMAKE_Fortran_COMPILER_ABI=ELF +CMAKE_Fortran_COMPILER_AR= +CMAKE_Fortran_COMPILER_ARCHITECTURE_ID= +CMAKE_Fortran_COMPILER_EXTERNAL_TOOLCHAIN= +CMAKE_Fortran_COMPILER_ID=LFortran +CMAKE_Fortran_COMPILER_LAUNCHER= +CMAKE_Fortran_COMPILER_LOADED=1 +CMAKE_Fortran_COMPILER_RANLIB= +CMAKE_Fortran_COMPILER_TARGET= +CMAKE_Fortran_COMPILER_VERSION=0.35.0 +CMAKE_Fortran_COMPILER_VERSION_INTERAL= +Change Dir: '/tmp/ii/CMakeFiles/CMakeTmp' + +Run Build Command(s): /tmp/CMake/bin/cmake -E env VERBOSE=1 /usr/bin/gmake -f Makefile cmTC_48bf9/fast +/usr/bin/gmake -f CMakeFiles/cmTC_48bf9.dir/build.make CMakeFiles/cmTC_48bf9.dir/build +gmake[1]: Entering directory '/tmp/ii/CMakeFiles/CMakeTmp' +Building Fortran object CMakeFiles/cmTC_48bf9.dir/CMakeFortranCompilerABI.F.o +/usr/bin/lfortran --cpp-infer -v --generate-object-code -c /tmp/CMake/Modules/CMakeFortranCompilerABI.F -o CMakeFiles/cmTC_48bf9.dir/CMakeFortranCompilerABI.F.o +Linking Fortran executable cmTC_48bf9 +/tmp/CMake/bin/cmake -E cmake_link_script CMakeFiles/cmTC_48bf9.dir/link.txt --verbose=1 +/usr/bin/lfortran -v -Wl,-export-dynamic CMakeFiles/cmTC_48bf9.dir/CMakeFortranCompilerABI.F.o -o cmTC_48bf9 +clang -o cmTC_48bf9 CMakeFiles/cmTC_48bf9.dir/CMakeFortranCompilerABI.F.o -L"/usr/bin/../lib64" -Wl,-rpath,"/usr/bin/../lib64" -Wl,-export-dynamic -llfortran_runtime -lm +gmake[1]: Leaving directory '/tmp/ii/CMakeFiles/CMakeTmp' diff --git a/Tests/RunCMake/ParseImplicitData/linux-Fortran-LFortran-0.35.0-gcc.input b/Tests/RunCMake/ParseImplicitData/linux-Fortran-LFortran-0.35.0-gcc.input new file mode 100644 index 0000000..7879a3a --- /dev/null +++ b/Tests/RunCMake/ParseImplicitData/linux-Fortran-LFortran-0.35.0-gcc.input @@ -0,0 +1,25 @@ +CMAKE_LANG=Fortran +CMAKE_LINKER=/usr/bin/ld +CMAKE_Fortran_COMPILER_ABI=ELF +CMAKE_Fortran_COMPILER_AR= +CMAKE_Fortran_COMPILER_ARCHITECTURE_ID= +CMAKE_Fortran_COMPILER_EXTERNAL_TOOLCHAIN= +CMAKE_Fortran_COMPILER_ID=LFortran +CMAKE_Fortran_COMPILER_LAUNCHER= +CMAKE_Fortran_COMPILER_LOADED=1 +CMAKE_Fortran_COMPILER_RANLIB= +CMAKE_Fortran_COMPILER_TARGET= +CMAKE_Fortran_COMPILER_VERSION=0.35.0 +CMAKE_Fortran_COMPILER_VERSION_INTERAL= +Change Dir: '/tmp/ii/CMakeFiles/CMakeTmp' + +Run Build Command(s): /tmp/CMake/bin/cmake -E env VERBOSE=1 /usr/bin/gmake -f Makefile cmTC_48bf9/fast +/usr/bin/gmake -f CMakeFiles/cmTC_48bf9.dir/build.make CMakeFiles/cmTC_48bf9.dir/build +gmake[1]: Entering directory '/tmp/ii/CMakeFiles/CMakeTmp' +Building Fortran object CMakeFiles/cmTC_48bf9.dir/CMakeFortranCompilerABI.F.o +/usr/bin/lfortran --cpp-infer --link-with-gcc -v --generate-object-code -c /tmp/CMake/Modules/CMakeFortranCompilerABI.F -o CMakeFiles/cmTC_48bf9.dir/CMakeFortranCompilerABI.F.o +Linking Fortran executable cmTC_48bf9 +/tmp/CMake/bin/cmake -E cmake_link_script CMakeFiles/cmTC_48bf9.dir/link.txt --verbose=1 +/usr/bin/lfortran -v -Wl,-export-dynamic --link-with-gcc CMakeFiles/cmTC_48bf9.dir/CMakeFortranCompilerABI.F.o -o cmTC_48bf9 +gcc -o cmTC_48bf9 CMakeFiles/cmTC_48bf9.dir/CMakeFortranCompilerABI.F.o -L"/usr/bin/../lib64" -Wl,-rpath,"/usr/bin/../lib64" -Wl,-export-dynamic -llfortran_runtime -lm +gmake[1]: Leaving directory '/tmp/ii/CMakeFiles/CMakeTmp' diff --git a/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake b/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake index c988536..121a1d2 100644 --- a/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake +++ b/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake @@ -41,6 +41,8 @@ set(targets linux-CUDA-NVIDIA-10.1.168-CLANG linux-CUDA-NVIDIA-10.1.168-XLClang-v linux-CUDA-NVIDIA-9.2.148-GCC linux-Fortran-LLVMFlang-15.0.0 + linux-Fortran-LFortran-0.35.0-clang + linux-Fortran-LFortran-0.35.0-gcc linux-custom_clang-C-Clang-13.0.0 linux-custom_clang-CXX-Clang-13.0.0 mingw.org-C-GNU-4.9.3 mingw.org-CXX-GNU-4.9.3 netbsd-C-GNU-4.8.5 netbsd-CXX-GNU-4.8.5 diff --git a/Tests/RunCMake/ParseImplicitLinkInfo/results/linux-Fortran-LFortran-0.35.0-clang.output b/Tests/RunCMake/ParseImplicitLinkInfo/results/linux-Fortran-LFortran-0.35.0-clang.output new file mode 100644 index 0000000..859e330 --- /dev/null +++ b/Tests/RunCMake/ParseImplicitLinkInfo/results/linux-Fortran-LFortran-0.35.0-clang.output @@ -0,0 +1,3 @@ +libs=lfortran_runtime;m +dirs=/usr/lib64 +linker_tool= diff --git a/Tests/RunCMake/ParseImplicitLinkInfo/results/linux-Fortran-LFortran-0.35.0-gcc.output b/Tests/RunCMake/ParseImplicitLinkInfo/results/linux-Fortran-LFortran-0.35.0-gcc.output new file mode 100644 index 0000000..859e330 --- /dev/null +++ b/Tests/RunCMake/ParseImplicitLinkInfo/results/linux-Fortran-LFortran-0.35.0-gcc.output @@ -0,0 +1,3 @@ +libs=lfortran_runtime;m +dirs=/usr/lib64 +linker_tool= |