try_{compile,run}: add LINKER_LANGUAGE option

Fixes: #25326
stage/master/nightly/2023/10/17
scivision 2023-10-12 13:49:15 -04:00 committed by Brad King
parent dc0dbffb0f
commit 0f37000304
10 changed files with 89 additions and 1 deletions

View File

@ -77,6 +77,7 @@ Try Compiling Source Files
[COMPILE_DEFINITIONS <defs>...]
[LINK_OPTIONS <options>...]
[LINK_LIBRARIES <libs>...]
[LINKER_LANGUAGE <lang>]
[OUTPUT_VARIABLE <var>]
[COPY_FILE <fileName> [COPY_FILE_ERROR <var>]]
[<LANG>_STANDARD <std>]
@ -184,6 +185,14 @@ The options for the above signatures are:
set the :prop_tgt:`STATIC_LIBRARY_OPTIONS` target property in the generated
project, depending on the :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` variable.
``LINKER_LANGUAGE <lang>```
.. versionadded:: 3.29
Specify the :prop_tgt:`LINKER_LANGUAGE` target property of the generated
project. When using multiple source files with different languages, set
this to the language of the source file containing the program entry point,
e.g., ``main``.
``LOG_DESCRIPTION <text>``
.. versionadded:: 3.26

View File

@ -67,6 +67,7 @@ The signature above is recommended for clarity.
[COMPILE_DEFINITIONS <defs>...]
[LINK_OPTIONS <options>...]
[LINK_LIBRARIES <libs>...]
[LINKER_LANGUAGE <lang>]
[COMPILE_OUTPUT_VARIABLE <var>]
[COPY_FILE <fileName> [COPY_FILE_ERROR <var>]]
[<LANG>_STANDARD <std>]

View File

@ -0,0 +1,6 @@
try_compile-linker-language
---------------------------
* The :command:`try_compile` and :command:`try_run` commands gained a
``LINKER_LANGUAGE`` option to specify the :prop_tgt:`LINKER_LANGUAGE`
target property in the generated test project.

View File

@ -176,6 +176,7 @@ auto const TryCompileBaseSourcesArgParser =
ArgumentParser::ExpectAtLeast{ 0 })
.Bind("LINK_LIBRARIES"_s, &Arguments::LinkLibraries)
.Bind("LINK_OPTIONS"_s, &Arguments::LinkOptions)
.Bind("LINKER_LANGUAGE"_s, &Arguments::LinkerLanguage)
.Bind("COPY_FILE"_s, &Arguments::CopyFileTo)
.Bind("COPY_FILE_ERROR"_s, &Arguments::CopyFileError)
.BIND_LANG_PROPS(C)
@ -1043,6 +1044,19 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
}
}
if (arguments.LinkerLanguage) {
std::string LinkerLanguage = *arguments.LinkerLanguage;
if (testLangs.find(LinkerLanguage) == testLangs.end()) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"Linker language '" + LinkerLanguage +
"' must be enabled in project(LANGUAGES).");
}
fprintf(fout, "set_property(TARGET %s PROPERTY LINKER_LANGUAGE %s)\n",
targetName.c_str(), LinkerLanguage.c_str());
}
if (arguments.LinkLibraries) {
std::string libsToLink = " ";
for (std::string const& i : *arguments.LinkLibraries) {

View File

@ -91,6 +91,7 @@ public:
cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>>
LinkLibraries;
ArgumentParser::MaybeEmpty<std::vector<std::string>> LinkOptions;
cm::optional<std::string> LinkerLanguage;
std::map<std::string, std::string> LangProps;
std::string CMakeInternal;
cm::optional<std::string> OutputVariable;

View File

@ -583,7 +583,9 @@ endfunction()
add_RunCMake_test_try_compile()
add_RunCMake_test(try_run -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
-DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
-DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
-DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}
-DCMAKE_Fortran_COMPILER_ID=${CMAKE_Fortran_COMPILER_ID})
add_RunCMake_test(set)
add_RunCMake_test(variable_watch)
add_RunCMake_test(while)

View File

@ -0,0 +1,29 @@
enable_language(CXX)
enable_language(Fortran)
set (lib_name "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}lib${CMAKE_STATIC_LIBRARY_SUFFIX}")
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
set (undef_flag -u _func)
else()
set (undef_flag -u func)
endif()
elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set (undef_flag -u _func)
else()
set (undef_flag -u func)
endif()
set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE)
try_run(run_result compile_result
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/lib.cxx ${CMAKE_CURRENT_SOURCE_DIR}/main.f90
COMPILE_OUTPUT_VARIABLE compile_out
RUN_OUTPUT_VARIABLE run_out
LINKER_LANGUAGE Fortran)
if(NOT compile_result)
message(FATAL_ERROR "try_run(... LINKER_LANGUAGE Fortran) compilation failed:\n${compile_out}")
endif()
if(run_result STREQUAL "FAILED_TO_RUN")
message(FATAL_ERROR "try_run(... LINKER_LANGUAGE Fortran) execution failed:\n${run_out}")
endif()

View File

@ -19,3 +19,13 @@ if (CMAKE_SYSTEM_NAME MATCHES "^(Linux|Darwin|Windows)$" AND
run_cmake(LinkOptions)
unset (RunCMake_TEST_OPTIONS)
endif()
if (CMAKE_SYSTEM_NAME MATCHES "^(Linux|Darwin|Windows)$" AND
CMAKE_CXX_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang)$" AND
CMAKE_Fortran_COMPILER_ID MATCHES "^(GNU)$")
set (RunCMake_TEST_OPTIONS
-DRunCMake_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}
-DRunCMake_Fortran_COMPILER_ID=${CMAKE_Fortran_COMPILER_ID})
run_cmake(LinkerLanguage)
unset (RunCMake_TEST_OPTIONS)
endif()

View File

@ -0,0 +1,4 @@
extern "C" void func()
{
}

View File

@ -0,0 +1,12 @@
program main
implicit none
interface
subroutine func() bind(C)
end subroutine
end interface
call func()
end program