ENH: Added target property ENABLE_EXPORTS for executable targets. It enables the executables for linking by loadable modules that import symbols from the executable. This finishes the executable import library support mentioned in bug #4210.
This commit is contained in:
parent
187816c937
commit
5a32aa5919
|
@ -26,6 +26,11 @@ SET(CMAKE_FIND_LIBRARY_SUFFIXES "-bcc.lib" ".lib")
|
|||
# Borland cannot handle + in the file name, so mangle object file name
|
||||
SET (CMAKE_MANGLE_OBJECT_FILE_NAMES "ON")
|
||||
|
||||
# Create an import library for another target.
|
||||
SET(CMAKE_CXX_CREATE_IMPORT_LIBRARY
|
||||
"implib -c -w <TARGET_IMPLIB> <TARGET>"
|
||||
)
|
||||
|
||||
# Create a C++ module library.
|
||||
SET(CMAKE_CXX_CREATE_SHARED_MODULE
|
||||
"<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE}-e<TARGET> -tWD <LINK_FLAGS> -tWR <LINK_LIBRARIES> <OBJECTS>${CMAKE_END_TEMP_FILE}"
|
||||
|
@ -33,9 +38,12 @@ SET(CMAKE_CXX_CREATE_SHARED_MODULE
|
|||
|
||||
# Create a C++ shared library.
|
||||
# First create a module and then its import library.
|
||||
SET(CMAKE_CXX_CREATE_SHARED_LIBRARY ${CMAKE_CXX_CREATE_SHARED_MODULE}
|
||||
"implib -c -w <TARGET_IMPLIB> <TARGET>"
|
||||
)
|
||||
SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
|
||||
${CMAKE_CXX_CREATE_SHARED_MODULE}
|
||||
${CMAKE_CXX_CREATE_IMPORT_LIBRARY})
|
||||
|
||||
# Create an import library for another target.
|
||||
SET(CMAKE_C_CREATE_IMPORT_LIBRARY ${CMAKE_CXX_CREATE_IMPORT_LIBRARY})
|
||||
|
||||
# Create a C module library.
|
||||
SET(CMAKE_C_CREATE_SHARED_MODULE
|
||||
|
@ -44,9 +52,9 @@ SET(CMAKE_C_CREATE_SHARED_MODULE
|
|||
|
||||
# Create a C shared library.
|
||||
# First create a module and then its import library.
|
||||
SET(CMAKE_C_CREATE_SHARED_LIBRARY ${CMAKE_C_CREATE_SHARED_MODULE}
|
||||
"implib -c -w <TARGET_IMPLIB> <TARGET>"
|
||||
)
|
||||
SET(CMAKE_C_CREATE_SHARED_LIBRARY
|
||||
${CMAKE_C_CREATE_SHARED_MODULE}
|
||||
${CMAKE_C_CREATE_IMPORT_LIBRARY})
|
||||
|
||||
# create a C++ static library
|
||||
SET(CMAKE_CXX_CREATE_STATIC_LIBRARY "tlib ${CMAKE_START_TEMP_FILE}/p512 <LINK_FLAGS> /a <TARGET_QUOTED> <OBJECTS_QUOTED>${CMAKE_END_TEMP_FILE}")
|
||||
|
|
|
@ -25,6 +25,10 @@ SET (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-br -bm -ot -dNDEBUG")
|
|||
SET (CMAKE_C_STANDARD_LIBRARIES_INIT "library clbrdll.lib library plbrdll.lib library kernel32.lib library user32.lib library gdi32.lib library winspool.lib library comdlg32.lib library advapi32.lib library shell32.lib library ole32.lib library oleaut32.lib library uuid.lib library odbc32.lib library odbccp32.lib")
|
||||
SET (CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}")
|
||||
|
||||
SET(CMAKE_C_CREATE_IMPORT_LIBRARY
|
||||
"wlib -q -n -b <TARGET_IMPLIB> +<TARGET>")
|
||||
SET(CMAKE_CXX_CREATE_IMPORT_LIBRARY ${CMAKE_C_CREATE_IMPORT_LIBRARY})
|
||||
|
||||
SET(CMAKE_C_LINK_EXECUTABLE
|
||||
"wlink ${CMAKE_START_TEMP_FILE} ${CMAKE_WLINK_QUIET} name <TARGET> option caseexact file {<OBJECTS>} <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
|
||||
|
||||
|
@ -39,9 +43,10 @@ SET(CMAKE_C_COMPILE_OBJECT
|
|||
"<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} <FLAGS> -dWIN32 -fo<OBJECT> -c -cc <SOURCE>${CMAKE_END_TEMP_FILE}")
|
||||
|
||||
SET(CMAKE_CXX_CREATE_SHARED_MODULE
|
||||
"wlink ${CMAKE_START_TEMP_FILE} system nt_dll ${CMAKE_WLINK_QUIET} name <TARGET> option caseexact file {<OBJECTS>} <LINK_LIBRARIES>")
|
||||
SET(CMAKE_CXX_CREATE_SHARED_LIBRARY ${CMAKE_CXX_CREATE_SHARED_MODULE}
|
||||
"wlib -q -n -b <TARGET_IMPLIB> +<TARGET> ${CMAKE_END_TEMP_FILE}")
|
||||
"wlink ${CMAKE_START_TEMP_FILE} system nt_dll ${CMAKE_WLINK_QUIET} name <TARGET> option caseexact file {<OBJECTS>} <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
|
||||
SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
|
||||
${CMAKE_CXX_CREATE_SHARED_MODULE}
|
||||
${CMAKE_CXX_CREATE_IMPORT_LIBRARY})
|
||||
|
||||
# create a C shared library
|
||||
SET(CMAKE_C_CREATE_SHARED_LIBRARY ${CMAKE_CXX_CREATE_SHARED_LIBRARY})
|
||||
|
|
|
@ -1659,9 +1659,19 @@ void cmLocalGenerator
|
|||
{
|
||||
// Compute the proper name to use to link this library.
|
||||
cmTarget* tgt = this->GlobalGenerator->FindTarget(0, lib.c_str());
|
||||
if(tgt && (tgt->GetType() == cmTarget::STATIC_LIBRARY ||
|
||||
bool impexe = (tgt &&
|
||||
tgt->GetType() == cmTarget::EXECUTABLE &&
|
||||
tgt->GetPropertyAsBool("ENABLE_EXPORTS"));
|
||||
if(impexe && !implib)
|
||||
{
|
||||
// Skip linking to executables on platforms with no import
|
||||
// libraries.
|
||||
continue;
|
||||
}
|
||||
else if(tgt && (tgt->GetType() == cmTarget::STATIC_LIBRARY ||
|
||||
tgt->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||
tgt->GetType() == cmTarget::MODULE_LIBRARY))
|
||||
tgt->GetType() == cmTarget::MODULE_LIBRARY ||
|
||||
impexe))
|
||||
{
|
||||
// This is a CMake target. Ask the target for its real name.
|
||||
// Pass the full path to the target file but purposely leave
|
||||
|
|
|
@ -944,13 +944,16 @@ void cmMakefile::AddLinkLibraryForTarget(const char *target,
|
|||
}
|
||||
// if it is not a static or shared library then you can not link to it
|
||||
if(!((tgt->GetType() == cmTarget::STATIC_LIBRARY) ||
|
||||
(tgt->GetType() == cmTarget::SHARED_LIBRARY)))
|
||||
(tgt->GetType() == cmTarget::SHARED_LIBRARY) ||
|
||||
(tgt->GetType() == cmTarget::EXECUTABLE &&
|
||||
tgt->GetPropertyAsBool("ENABLE_EXPORTS"))))
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Attempt to add link target " << lib << " of type: "
|
||||
<< cmTarget::TargetTypeNames[static_cast<int>(tgt->GetType())]
|
||||
<< "\nto target " << target
|
||||
<< ". You can only link to STATIC or SHARED libraries.";
|
||||
<< ". One can only link to STATIC or SHARED libraries, or "
|
||||
<< "to executables with the ENABLE_EXPORTS property set.";
|
||||
// in older versions of cmake linking to modules was allowed
|
||||
if( tgt->GetType() == cmTarget::MODULE_LIBRARY )
|
||||
{
|
||||
|
|
|
@ -347,6 +347,19 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
|||
std::string linkRule =
|
||||
this->Makefile->GetRequiredDefinition(linkRuleVar.c_str());
|
||||
cmSystemTools::ExpandListArgument(linkRule, commands1);
|
||||
if(this->Target->GetPropertyAsBool("ENABLE_EXPORTS"))
|
||||
{
|
||||
// If a separate rule for creating an import library is specified
|
||||
// add it now.
|
||||
std::string implibRuleVar = "CMAKE_";
|
||||
implibRuleVar += linkLanguage;
|
||||
implibRuleVar += "_CREATE_IMPORT_LIBRARY";
|
||||
if(const char* rule =
|
||||
this->Makefile->GetDefinition(implibRuleVar.c_str()))
|
||||
{
|
||||
cmSystemTools::ExpandListArgument(rule, commands1);
|
||||
}
|
||||
}
|
||||
this->LocalGenerator->CreateCDCommand
|
||||
(commands1,
|
||||
this->Makefile->GetStartOutputDirectory(),
|
||||
|
|
|
@ -258,6 +258,23 @@ void cmTarget::DefineProperties(cmake *cm)
|
|||
"in contrast to a console application for example. This changes "
|
||||
"how the executable will be linked.");
|
||||
|
||||
cm->DefineProperty
|
||||
("ENABLE_EXPORTS", cmProperty::TARGET,
|
||||
"Specify whether an executable exports symbols for loadable modules.",
|
||||
"Normally an executable does not export any symbols because it is "
|
||||
"the final program. It is possible for an executable to export "
|
||||
"symbols to be used by loadable modules. When this property is "
|
||||
"set to true CMake will allow other targets to \"link\" to the "
|
||||
"executable with the TARGET_LINK_LIBRARIES command. "
|
||||
"On all platforms a target-level dependency on the executable is "
|
||||
"created for targets that link to it. "
|
||||
"For non-DLL platforms the link rule is simply ignored since "
|
||||
"the dynamic loader will automatically bind symbols when the "
|
||||
"module is loaded. "
|
||||
"For DLL platforms an import library will be created for the "
|
||||
"exported symbols and then used for linking. "
|
||||
"All Windows-based systems including Cygwin are DLL platforms.");
|
||||
|
||||
cm->DefineProperty
|
||||
("OBJECT_FILES", cmProperty::TARGET,
|
||||
"Used to get the resulting list of object files that make up a "
|
||||
|
|
Loading…
Reference in New Issue