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:
Brad King 2007-03-22 09:45:25 -04:00
parent 187816c937
commit 5a32aa5919
6 changed files with 70 additions and 14 deletions

View File

@ -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}")

View 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})

View File

@ -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 ||
tgt->GetType() == cmTarget::SHARED_LIBRARY ||
tgt->GetType() == cmTarget::MODULE_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 ||
impexe))
{
// This is a CMake target. Ask the target for its real name.
// Pass the full path to the target file but purposely leave

View File

@ -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 )
{

View File

@ -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(),

View File

@ -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 "