mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-11 16:32:14 -06:00
Linker: Generate per-language module -DEF: flags on Windows
With IntelLLVM on Windows, we link using the compiler driver. With MSVC on Windows, we invoke the linker directly. If we use both in a single build tree, for separate languages, the value of `CMAKE_LINK_DEF_FILE_FLAG` conflicts. Add a per-language `CMAKE_<LANG>_LINK_DEF_FILE_FLAG` variable to avoid the conflict. Preserve the language-agnostic variable for compatibility with projects that reference it. Fixes: #26005
This commit is contained in:
@@ -493,6 +493,7 @@ Variables that Control the Build
|
||||
/variable/CMAKE_LANG_COMPILER_LAUNCHER
|
||||
/variable/CMAKE_LANG_CPPCHECK
|
||||
/variable/CMAKE_LANG_CPPLINT
|
||||
/variable/CMAKE_LANG_LINK_DEF_FILE_FLAG
|
||||
/variable/CMAKE_LANG_ICSTAT
|
||||
/variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE
|
||||
/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE
|
||||
|
||||
14
Help/variable/CMAKE_LANG_LINK_DEF_FILE_FLAG.rst
Normal file
14
Help/variable/CMAKE_LANG_LINK_DEF_FILE_FLAG.rst
Normal file
@@ -0,0 +1,14 @@
|
||||
CMAKE_<LANG>_LINK_DEF_FILE_FLAG
|
||||
-------------------------------
|
||||
|
||||
.. versionadded:: 4.1
|
||||
|
||||
Linker flag to be used to specify a ``.def`` file for dll creation
|
||||
with the toolchain for language ``<LANG>``.
|
||||
|
||||
CMake sets this variable automatically during toolchain inspection by
|
||||
calls to the :command:`project` or :command:`enable_language` commands.
|
||||
|
||||
If the :variable:`!CMAKE_<LANG>_LINK_DEF_FILE_FLAG` variable
|
||||
is defined, it takes precedence over the language-agnostic
|
||||
:variable:`CMAKE_LINK_DEF_FILE_FLAG` variable.
|
||||
@@ -5,3 +5,9 @@ Linker flag to be used to specify a ``.def`` file for dll creation.
|
||||
|
||||
The flag will be used to add a ``.def`` file when creating a dll on
|
||||
Windows; this is only defined on Windows.
|
||||
|
||||
CMake sets this variable automatically during toolchain inspection by
|
||||
calls to the :command:`project` or :command:`enable_language` commands.
|
||||
|
||||
If the per-language :variable:`CMAKE_<LANG>_LINK_DEF_FILE_FLAG` variable
|
||||
is defined, it takes precedence over :variable:`!CMAKE_LINK_DEF_FILE_FLAG`.
|
||||
|
||||
@@ -33,7 +33,8 @@ macro(__windows_compiler_clang_gnu lang)
|
||||
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a" ".a" ".lib")
|
||||
set(CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 1)
|
||||
set (CMAKE_LINK_DEF_FILE_FLAG "-Xlinker /DEF:")
|
||||
set(CMAKE_${lang}_LINK_DEF_FILE_FLAG "-Xlinker /DEF:")
|
||||
set(CMAKE_LINK_DEF_FILE_FLAG "${CMAKE_${lang}_LINK_DEF_FILE_FLAG}")
|
||||
|
||||
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Xlinker" " ")
|
||||
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP)
|
||||
|
||||
@@ -127,6 +127,8 @@ macro(__windows_compiler_gnu lang)
|
||||
set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "@")
|
||||
endif()
|
||||
|
||||
set(CMAKE_${lang}_LINK_DEF_FILE_FLAG "") # Empty string: passing the file is enough
|
||||
|
||||
# Binary link rules.
|
||||
set(CMAKE_${lang}_CREATE_SHARED_MODULE
|
||||
"<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_MODULE_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
|
||||
|
||||
@@ -35,7 +35,8 @@ macro(__windows_compiler_intel lang)
|
||||
|
||||
set(CMAKE_${lang}_CREATE_WIN32_EXE "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/subsystem:windows")
|
||||
set(CMAKE_${lang}_CREATE_CONSOLE_EXE "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/subsystem:console")
|
||||
set(CMAKE_LINK_DEF_FILE_FLAG "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/DEF:")
|
||||
set(CMAKE_${lang}_LINK_DEF_FILE_FLAG "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/DEF:")
|
||||
set(CMAKE_LINK_DEF_FILE_FLAG "${CMAKE_${lang}_LINK_DEF_FILE_FLAG}")
|
||||
set(CMAKE_LIBRARY_PATH_FLAG "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/LIBPATH:")
|
||||
|
||||
set(CMAKE_${lang}_LINK_EXECUTABLE
|
||||
|
||||
@@ -396,6 +396,7 @@ macro(__windows_compiler_msvc lang)
|
||||
set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE
|
||||
"<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <DEFINES> <INCLUDES> <FLAGS> /FoNUL /FAs /Fa<ASSEMBLY_SOURCE> /c <SOURCE>${CMAKE_END_TEMP_FILE}")
|
||||
|
||||
set(CMAKE_${lang}_LINK_DEF_FILE_FLAG "/DEF:")
|
||||
set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
set(CMAKE_${lang}_LINK_EXECUTABLE
|
||||
"${_CMAKE_VS_LINK_EXE}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
|
||||
|
||||
@@ -37,6 +37,8 @@ else()
|
||||
endif()
|
||||
|
||||
macro(__windows_compiler_pgi lang)
|
||||
set(CMAKE_${lang}_LINK_DEF_FILE_FLAG "-def:")
|
||||
|
||||
# Shared library compile and link rules.
|
||||
set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "lib ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
|
||||
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY "<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} -Mmakedll -implib:<TARGET_IMPLIB> -Xlinker -pdb:<TARGET_PDB> -Xlinker -version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <LINK_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
|
||||
|
||||
@@ -1673,7 +1673,7 @@ void cmLocalGenerator::GetTargetFlags(
|
||||
this->AppendWarningAsErrorLinkerFlags(extraLinkFlags, target, linkLanguage);
|
||||
this->AppendIPOLinkerFlags(extraLinkFlags, target, config, linkLanguage);
|
||||
this->AppendModuleDefinitionFlag(extraLinkFlags, target, linkLineComputer,
|
||||
config);
|
||||
config, linkLanguage);
|
||||
|
||||
if (!extraLinkFlags.empty()) {
|
||||
this->GetGlobalGenerator()->EncodeLiteral(extraLinkFlags);
|
||||
@@ -3615,7 +3615,8 @@ std::string cmLocalGenerator::GetLinkDependencyFile(
|
||||
|
||||
void cmLocalGenerator::AppendModuleDefinitionFlag(
|
||||
std::string& flags, cmGeneratorTarget const* target,
|
||||
cmLinkLineComputer* linkLineComputer, std::string const& config)
|
||||
cmLinkLineComputer* linkLineComputer, std::string const& config,
|
||||
std::string const& lang)
|
||||
{
|
||||
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
|
||||
target->GetModuleDefinitionInfo(config);
|
||||
@@ -3623,8 +3624,11 @@ void cmLocalGenerator::AppendModuleDefinitionFlag(
|
||||
return;
|
||||
}
|
||||
|
||||
cmValue defFileFlag =
|
||||
this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
|
||||
cmValue defFileFlag = this->Makefile->GetDefinition(
|
||||
cmStrCat("CMAKE_", lang, "_LINK_DEF_FILE_FLAG"));
|
||||
if (!defFileFlag) {
|
||||
defFileFlag = this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
|
||||
}
|
||||
if (!defFileFlag) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -192,7 +192,8 @@ public:
|
||||
void AppendModuleDefinitionFlag(std::string& flags,
|
||||
cmGeneratorTarget const* target,
|
||||
cmLinkLineComputer* linkLineComputer,
|
||||
std::string const& config);
|
||||
std::string const& config,
|
||||
std::string const& lang);
|
||||
bool AppendLWYUFlags(std::string& flags, cmGeneratorTarget const* target,
|
||||
std::string const& lang);
|
||||
|
||||
|
||||
@@ -421,7 +421,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||
|
||||
this->LocalGenerator->AppendModuleDefinitionFlag(
|
||||
linkFlags, this->GeneratorTarget, linkLineComputer.get(),
|
||||
this->GetConfigName());
|
||||
this->GetConfigName(), linkLanguage);
|
||||
}
|
||||
|
||||
this->LocalGenerator->AppendIPOLinkerFlags(
|
||||
|
||||
@@ -188,7 +188,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
|
||||
|
||||
this->LocalGenerator->AppendModuleDefinitionFlag(
|
||||
extraFlags, this->GeneratorTarget, linkLineComputer.get(),
|
||||
this->GetConfigName());
|
||||
this->GetConfigName(), linkLanguage);
|
||||
|
||||
this->UseLWYU = this->LocalGenerator->AppendLWYUFlags(
|
||||
extraFlags, this->GeneratorTarget, linkLanguage);
|
||||
@@ -224,7 +224,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
|
||||
|
||||
this->LocalGenerator->AppendModuleDefinitionFlag(
|
||||
extraFlags, this->GeneratorTarget, linkLineComputer.get(),
|
||||
this->GetConfigName());
|
||||
this->GetConfigName(), linkLanguage);
|
||||
|
||||
this->UseLWYU = this->LocalGenerator->AppendLWYUFlags(
|
||||
extraFlags, this->GeneratorTarget, linkLanguage);
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(ModuleDefinition C)
|
||||
|
||||
# Simulate another language overriding the -DEF: flag.
|
||||
# The generators now prefer CMAKE_<LANG>_LINK_DEF_FILE_FLAG.
|
||||
set(CMAKE_LINK_DEF_FILE_FLAG "bad-def-flag:")
|
||||
|
||||
# Test .def file source recognition for DLLs.
|
||||
add_library(example_dll SHARED example_dll.c example_dll.def)
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ target_link_libraries(UseABstatic ABstatic)
|
||||
# Test module definition file to export object library symbols in the test
|
||||
# below if the platform needs and supports it.
|
||||
set(ABshared_SRCS $<TARGET_OBJECTS:A>)
|
||||
if(CMAKE_LINK_DEF_FILE_FLAG OR NOT WIN32)
|
||||
if(CMAKE_C_LINK_DEF_FILE_FLAG OR NOT WIN32)
|
||||
list(APPEND ABshared_SRCS $<TARGET_OBJECTS:B> AB.def)
|
||||
else()
|
||||
set(NO_A NO_A)
|
||||
|
||||
Reference in New Issue
Block a user