From 5a32aa5919bd9dab272748c0e0ea12fbcd36436b Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 22 Mar 2007 09:45:25 -0400 Subject: 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. --- Modules/Platform/Windows-bcc32.cmake | 20 ++++++++++++++------ Modules/Platform/Windows-wcl386.cmake | 11 ++++++++--- Source/cmLocalGenerator.cxx | 16 +++++++++++++--- Source/cmMakefile.cxx | 7 +++++-- Source/cmMakefileExecutableTargetGenerator.cxx | 13 +++++++++++++ Source/cmTarget.cxx | 17 +++++++++++++++++ 6 files changed, 70 insertions(+), 14 deletions(-) diff --git a/Modules/Platform/Windows-bcc32.cmake b/Modules/Platform/Windows-bcc32.cmake index 82fa064..382bf2d 100644 --- a/Modules/Platform/Windows-bcc32.cmake +++ b/Modules/Platform/Windows-bcc32.cmake @@ -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 " + ) + # Create a C++ module library. SET(CMAKE_CXX_CREATE_SHARED_MODULE " ${CMAKE_START_TEMP_FILE}-e -tWD -tWR ${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 " - ) +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 " - ) +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 /a ${CMAKE_END_TEMP_FILE}") diff --git a/Modules/Platform/Windows-wcl386.cmake b/Modules/Platform/Windows-wcl386.cmake index f56e148..acec459 100644 --- a/Modules/Platform/Windows-wcl386.cmake +++ b/Modules/Platform/Windows-wcl386.cmake @@ -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 +") +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 option caseexact file {} ${CMAKE_END_TEMP_FILE}") @@ -39,9 +43,10 @@ SET(CMAKE_C_COMPILE_OBJECT " ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -dWIN32 -fo -c -cc ${CMAKE_END_TEMP_FILE}") SET(CMAKE_CXX_CREATE_SHARED_MODULE - "wlink ${CMAKE_START_TEMP_FILE} system nt_dll ${CMAKE_WLINK_QUIET} name option caseexact file {} ") -SET(CMAKE_CXX_CREATE_SHARED_LIBRARY ${CMAKE_CXX_CREATE_SHARED_MODULE} - "wlib -q -n -b + ${CMAKE_END_TEMP_FILE}") + "wlink ${CMAKE_START_TEMP_FILE} system nt_dll ${CMAKE_WLINK_QUIET} name option caseexact file {} ${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}) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 71d3c51..c7f50f6 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -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 diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 78b44a4..e5dc29b 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -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(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 ) { diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 2414458..48aa284 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -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(), diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index ef4a07e..441269c 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -259,6 +259,23 @@ void cmTarget::DefineProperties(cmake *cm) "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 " "target.", -- cgit v0.12