ENH: Added support for import libraries created by executable and module targets. The module import libraries should never be used but some windows compilers always create them for .dll files since there is no distinction from shared libraries on that platform. The executable import libraries may be used to create modules that when loaded bind to symbols from the executables. This is an enhancement related to bug#4210 though not requested by it explicitly.

This commit is contained in:
Brad King 2007-03-19 10:00:36 -04:00
parent 43589ec702
commit fc7c433463
14 changed files with 166 additions and 65 deletions

View File

@ -32,9 +32,9 @@ SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
"<CMAKE_CXX_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>") "<CMAKE_CXX_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
SET(CMAKE_C_LINK_EXECUTABLE SET(CMAKE_C_LINK_EXECUTABLE
"<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>") "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
SET(CMAKE_CXX_LINK_EXECUTABLE SET(CMAKE_CXX_LINK_EXECUTABLE
"<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>") "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
# Shared libraries on cygwin can be named with their version number. # Shared libraries on cygwin can be named with their version number.
SET(CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION 1) SET(CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION 1)

View File

@ -64,11 +64,15 @@ SET(CMAKE_C_COMPILE_OBJECT
SET(CMAKE_C_LINK_EXECUTABLE SET(CMAKE_C_LINK_EXECUTABLE
"<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE}-e<TARGET> <LINK_FLAGS> <FLAGS> <LINK_LIBRARIES> <OBJECTS> ${CMAKE_END_TEMP_FILE}") "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE}-e<TARGET> <LINK_FLAGS> <FLAGS> <LINK_LIBRARIES> <OBJECTS> ${CMAKE_END_TEMP_FILE}"
"implib -c -w <TARGET_IMPLIB> <TARGET>"
)
SET(CMAKE_CXX_LINK_EXECUTABLE SET(CMAKE_CXX_LINK_EXECUTABLE
"<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> -e<TARGET> <FLAGS> <LINK_LIBRARIES> <OBJECTS> ${CMAKE_END_TEMP_FILE}") "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> -e<TARGET> <FLAGS> <LINK_LIBRARIES> <OBJECTS> ${CMAKE_END_TEMP_FILE}"
"implib -c -w <TARGET_IMPLIB> <TARGET>"
)
SET (CMAKE_BUILD_TYPE Debug CACHE STRING SET (CMAKE_BUILD_TYPE Debug CACHE STRING
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel.") "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel.")

View File

@ -15,8 +15,7 @@ ENDIF(CMAKE_VERBOSE_MAKEFILE)
# create a shared C++ library # create a shared C++ library
SET(CMAKE_CXX_CREATE_SHARED_LIBRARY SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
"link ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}") "link ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
SET(CMAKE_CXX_CREATE_SHARED_MODULE SET(CMAKE_CXX_CREATE_SHARED_MODULE ${CMAKE_CXX_CREATE_SHARED_LIBRARY})
"link ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out:<TARGET> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
# create a C shared library # create a C shared library
SET(CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY}") SET(CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY}")
@ -40,10 +39,10 @@ SET(CMAKE_C_COMPILE_OBJECT
SET(CMAKE_C_LINK_EXECUTABLE SET(CMAKE_C_LINK_EXECUTABLE
"<CMAKE_C_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> <OBJECTS> /Fe<TARGET> /Fd<TARGET_PDB> -link /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}") "<CMAKE_C_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> <OBJECTS> /Fe<TARGET> /Fd<TARGET_PDB> -link /implib:<TARGET_IMPLIB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
SET(CMAKE_CXX_LINK_EXECUTABLE SET(CMAKE_CXX_LINK_EXECUTABLE
"<CMAKE_CXX_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> <OBJECTS> /Fe<TARGET> /Fd<TARGET_PDB> -link /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}") "<CMAKE_CXX_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> <OBJECTS> /Fe<TARGET> /Fd<TARGET_PDB> -link /implib:<TARGET_IMPLIB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
SET(CMAKE_C_CREATE_PREPROCESSED_SOURCE SET(CMAKE_C_CREATE_PREPROCESSED_SOURCE
"<CMAKE_C_COMPILER> > <PREPROCESSED_SOURCE> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} <FLAGS> -E <SOURCE>${CMAKE_END_TEMP_FILE}") "<CMAKE_C_COMPILER> > <PREPROCESSED_SOURCE> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} <FLAGS> -E <SOURCE>${CMAKE_END_TEMP_FILE}")

View File

@ -39,9 +39,9 @@ SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
"<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>") "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
SET(CMAKE_C_LINK_EXECUTABLE SET(CMAKE_C_LINK_EXECUTABLE
"<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>") "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
SET(CMAKE_CXX_LINK_EXECUTABLE SET(CMAKE_CXX_LINK_EXECUTABLE
"<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>") "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
# Initialize C link type selection flags. These flags are used when # Initialize C link type selection flags. These flags are used when
# building a shared library, shared module, or executable that links # building a shared library, shared module, or executable that links

View File

@ -532,6 +532,20 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
this->SetError(e.str().c_str()); this->SetError(e.str().c_str());
return false; return false;
} }
// On DLL platforms an executable may also have an import
// library. Install it to the archive destination if it
// exists.
if(dll_platform && archive_destination)
{
// The import library uses the ARCHIVE properties.
this->Makefile->AddInstallGenerator(
new cmInstallTargetGenerator(target, archive_dest.c_str(), true,
archive_permissions.c_str(),
archive_configurations,
archive_component.c_str(),
true));
}
} }
break; break;
default: default:

View File

@ -208,11 +208,21 @@ cmInstallTargetGenerator
{ {
std::string targetName; std::string targetName;
std::string targetNameReal; std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB; std::string targetNamePDB;
target->GetExecutableNames(targetName, targetNameReal, target->GetExecutableNames(targetName, targetNameReal,
targetNamePDB, i->c_str()); targetNameImport, targetNamePDB,
// Use the canonical name. i->c_str());
fname += targetName; if(this->ImportLibrary)
{
// Use the import library name.
fname += targetNameImport;
}
else
{
// Use the canonical name.
fname += targetName;
}
} }
else else
{ {
@ -259,11 +269,21 @@ std::string cmInstallTargetGenerator::GetScriptReference(cmTarget* target,
{ {
std::string targetName; std::string targetName;
std::string targetNameReal; std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB; std::string targetNamePDB;
target->GetExecutableNames(targetName, targetNameReal, target->GetExecutableNames(targetName, targetNameReal,
targetNamePDB, this->ConfigurationName); targetNameImport, targetNamePDB,
// Use the canonical name. this->ConfigurationName);
return targetName; if(this->ImportLibrary)
{
// Use the import library name.
return targetNameImport;
}
else
{
// Use the canonical name.
return targetName;
}
} }
else else
{ {

View File

@ -1645,8 +1645,9 @@ cmLocalUnixMakefileGenerator3
objectName = cmSystemTools::GetFilenameName(objectName.c_str()); objectName = cmSystemTools::GetFilenameName(objectName.c_str());
std::string targetName; std::string targetName;
std::string targetNameReal; std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB; std::string targetNamePDB;
target.GetExecutableNames(targetName, targetNameReal, target.GetExecutableNames(targetName, targetNameReal, targetNameImport,
targetNamePDB, this->ConfigurationName.c_str()); targetNamePDB, this->ConfigurationName.c_str());
std::string obj; std::string obj;
if ( target.GetPropertyAsBool("MACOSX_BUNDLE") ) if ( target.GetPropertyAsBool("MACOSX_BUNDLE") )

View File

@ -1221,7 +1221,9 @@ void cmLocalVisualStudio6Generator
std::string targetImplibFlagRelease; std::string targetImplibFlagRelease;
std::string targetImplibFlagMinSizeRel; std::string targetImplibFlagMinSizeRel;
std::string targetImplibFlagRelWithDebInfo; std::string targetImplibFlagRelWithDebInfo;
if(target.GetType() == cmTarget::SHARED_LIBRARY) if(target.GetType() == cmTarget::SHARED_LIBRARY ||
target.GetType() == cmTarget::MODULE_LIBRARY ||
target.GetType() == cmTarget::EXECUTABLE)
{ {
std::string fullPathImpDebug = target.GetDirectory("Debug", true); std::string fullPathImpDebug = target.GetDirectory("Debug", true);
std::string fullPathImpRelease = target.GetDirectory("Release", true); std::string fullPathImpRelease = target.GetDirectory("Release", true);

View File

@ -733,17 +733,6 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
target.GetLibraryNames(targetName, targetNameSO, targetNameFull, target.GetLibraryNames(targetName, targetNameSO, targetNameFull,
targetNameImport, targetNamePDB, configName); targetNameImport, targetNamePDB, configName);
// VS does not distinguish between shared libraries and module
// libraries so it still wants to be given the name of an import
// library for modules.
if(targetNameImport.empty() &&
target.GetType() == cmTarget::MODULE_LIBRARY)
{
targetNameImport =
cmSystemTools::GetFilenameWithoutLastExtension(targetNameFull);
targetNameImport += ".lib";
}
// Compute the link library and directory information. // Compute the link library and directory information.
std::vector<cmStdString> linkLibs; std::vector<cmStdString> linkLibs;
std::vector<cmStdString> linkDirs; std::vector<cmStdString> linkDirs;
@ -816,9 +805,10 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
{ {
std::string targetName; std::string targetName;
std::string targetNameFull; std::string targetNameFull;
std::string targetNameImport;
std::string targetNamePDB; std::string targetNamePDB;
target.GetExecutableNames(targetName, targetNameFull, target.GetExecutableNames(targetName, targetNameFull,
targetNamePDB, configName); targetNameImport, targetNamePDB, configName);
// Compute the link library and directory information. // Compute the link library and directory information.
std::vector<cmStdString> linkLibs; std::vector<cmStdString> linkLibs;
@ -886,7 +876,11 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
{ {
fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\""; fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"";
} }
fout << "/>\n"; temp = target.GetDirectory(configName, true);
temp += "/";
temp += targetNameImport;
fout << "\t\t\t\tImportLibrary=\""
<< this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n";
break; break;
} }
case cmTarget::UTILITY: case cmTarget::UTILITY:

View File

@ -110,9 +110,10 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Get the name of the executable to generate. // Get the name of the executable to generate.
std::string targetName; std::string targetName;
std::string targetNameReal; std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB; std::string targetNamePDB;
this->Target->GetExecutableNames this->Target->GetExecutableNames
(targetName, targetNameReal, targetNamePDB, (targetName, targetNameReal, targetNameImport, targetNamePDB,
this->LocalGenerator->ConfigurationName.c_str()); this->LocalGenerator->ConfigurationName.c_str());
// Construct the full path version of the names. // Construct the full path version of the names.
@ -167,6 +168,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
false, false, false); false, false, false);
} }
#endif #endif
std::string outpathImp;
if(relink) if(relink)
{ {
outpath = this->Makefile->GetStartOutputDirectory(); outpath = this->Makefile->GetStartOutputDirectory();
@ -174,10 +176,23 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
outpath += "/CMakeRelink.dir"; outpath += "/CMakeRelink.dir";
cmSystemTools::MakeDirectory(outpath.c_str()); cmSystemTools::MakeDirectory(outpath.c_str());
outpath += "/"; outpath += "/";
if(!targetNameImport.empty())
{
outpathImp = outpath;
}
}
else
{
if(!targetNameImport.empty())
{
outpathImp = this->Target->GetDirectory(0, true);
outpathImp += "/";
}
} }
std::string targetFullPath = outpath + targetName; std::string targetFullPath = outpath + targetName;
std::string targetFullPathReal = outpath + targetNameReal; std::string targetFullPathReal = outpath + targetNameReal;
std::string targetFullPathPDB = outpath + targetNamePDB; std::string targetFullPathPDB = outpath + targetNamePDB;
std::string targetFullPathImport = outpathImp + targetNameImport;
std::string targetOutPathPDB = std::string targetOutPathPDB =
this->Convert(targetFullPathPDB.c_str(), this->Convert(targetFullPathPDB.c_str(),
cmLocalGenerator::FULL, cmLocalGenerator::FULL,
@ -191,7 +206,11 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->Convert(targetFullPathReal.c_str(), this->Convert(targetFullPathReal.c_str(),
cmLocalGenerator::START_OUTPUT, cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL); cmLocalGenerator::SHELL);
std::string targetOutPathImport =
this->Convert(targetFullPathImport.c_str(),
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
// Get the language to use for linking this executable. // Get the language to use for linking this executable.
const char* linkLanguage = const char* linkLanguage =
this->Target->GetLinkerLanguage(this->GlobalGenerator); this->Target->GetLinkerLanguage(this->GlobalGenerator);
@ -258,14 +277,16 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
{ {
std::string cleanName; std::string cleanName;
std::string cleanRealName; std::string cleanRealName;
std::string cleanImportName;
std::string cleanPDBName; std::string cleanPDBName;
this->Target->GetExecutableCleanNames this->Target->GetExecutableCleanNames
(cleanName, cleanRealName, cleanPDBName, (cleanName, cleanRealName, cleanImportName, cleanPDBName,
this->LocalGenerator->ConfigurationName.c_str()); this->LocalGenerator->ConfigurationName.c_str());
std::string cleanFullName = outpath + cleanName; std::string cleanFullName = outpath + cleanName;
std::string cleanFullRealName = outpath + cleanRealName; std::string cleanFullRealName = outpath + cleanRealName;
std::string cleanFullPDBName = outpath + cleanPDBName; std::string cleanFullPDBName = outpath + cleanPDBName;
std::string cleanFullImportName = outpathImp + cleanImportName;
exeCleanFiles.push_back(this->Convert(cleanFullName.c_str(), exeCleanFiles.push_back(this->Convert(cleanFullName.c_str(),
cmLocalGenerator::START_OUTPUT, cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED)); cmLocalGenerator::UNCHANGED));
@ -282,6 +303,12 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
cmLocalGenerator::START_OUTPUT, cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED)); cmLocalGenerator::UNCHANGED));
} }
if(!cleanImportName.empty())
{
exeCleanFiles.push_back(this->Convert(cleanFullImportName.c_str(),
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
}
// List the PDB for cleaning only when the whole target is // List the PDB for cleaning only when the whole target is
// cleaned. We do not want to delete the .pdb file just before // cleaned. We do not want to delete the .pdb file just before
@ -394,11 +421,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
vars.Flags = flags.c_str(); vars.Flags = flags.c_str();
vars.LinkFlags = linkFlags.c_str(); vars.LinkFlags = linkFlags.c_str();
// Expand placeholders in the commands. // Expand placeholders in the commands.
this->LocalGenerator->TargetImplib = targetOutPathImport;
for(std::vector<std::string>::iterator i = commands.begin(); for(std::vector<std::string>::iterator i = commands.begin();
i != commands.end(); ++i) i != commands.end(); ++i)
{ {
this->LocalGenerator->ExpandRuleVariables(*i, vars); this->LocalGenerator->ExpandRuleVariables(*i, vars);
} }
this->LocalGenerator->TargetImplib = "";
// Write the build rule. // Write the build rule.
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, this->LocalGenerator->WriteMakeRule(*this->BuildFileStream,

View File

@ -341,10 +341,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
cmLocalGenerator::START_OUTPUT, cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED)); cmLocalGenerator::UNCHANGED));
} }
if(!targetNameImport.empty() && if(!targetNameImport.empty())
targetNameImport != targetName &&
targetNameImport != targetNameReal &&
targetNameImport != targetNameSO)
{ {
libCleanFiles.push_back(this->Convert(targetFullPathImport.c_str(), libCleanFiles.push_back(this->Convert(targetFullPathImport.c_str(),
cmLocalGenerator::START_OUTPUT, cmLocalGenerator::START_OUTPUT,
@ -401,11 +398,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
cmLocalGenerator::START_OUTPUT, cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED)); cmLocalGenerator::UNCHANGED));
} }
if(!cleanImportName.empty() && if(!cleanImportName.empty())
cleanImportName != cleanStaticName &&
cleanImportName != cleanSharedSOName &&
cleanImportName != cleanSharedRealName &&
cleanImportName != cleanSharedName)
{ {
libCleanFiles.push_back(this->Convert(cleanFullImportName.c_str(), libCleanFiles.push_back(this->Convert(cleanFullImportName.c_str(),
cmLocalGenerator::START_OUTPUT, cmLocalGenerator::START_OUTPUT,

View File

@ -37,6 +37,7 @@ cmTarget::cmTarget()
this->LinkLibrariesAnalyzed = false; this->LinkLibrariesAnalyzed = false;
this->LinkDirectoriesComputed = false; this->LinkDirectoriesComputed = false;
this->HaveInstallRule = false; this->HaveInstallRule = false;
this->DLLPlatform = false;
} }
@ -335,6 +336,11 @@ void cmTarget::SetMakefile(cmMakefile* mf)
// set the cmake instance of the properties // set the cmake instance of the properties
this->Properties.SetCMakeInstance(mf->GetCMakeInstance()); this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
// Check whether this is a DLL platform.
this->DLLPlatform = (this->Makefile->IsOn("WIN32") ||
this->Makefile->IsOn("CYGWIN") ||
this->Makefile->IsOn("MINGW"));
// Setup default property values. // Setup default property values.
this->SetPropertyDefault("INSTALL_NAME_DIR", ""); this->SetPropertyDefault("INSTALL_NAME_DIR", "");
this->SetPropertyDefault("INSTALL_RPATH", ""); this->SetPropertyDefault("INSTALL_RPATH", "");
@ -1427,9 +1433,13 @@ const char* cmTarget::GetSuffixVariableInternal(TargetType type,
? "CMAKE_IMPORT_LIBRARY_SUFFIX" ? "CMAKE_IMPORT_LIBRARY_SUFFIX"
: "CMAKE_SHARED_LIBRARY_SUFFIX"); : "CMAKE_SHARED_LIBRARY_SUFFIX");
case cmTarget::MODULE_LIBRARY: case cmTarget::MODULE_LIBRARY:
return "CMAKE_SHARED_MODULE_SUFFIX"; return (implib
? "CMAKE_IMPORT_LIBRARY_SUFFIX"
: "CMAKE_SHARED_MODULE_SUFFIX");
case cmTarget::EXECUTABLE: case cmTarget::EXECUTABLE:
return "CMAKE_EXECUTABLE_SUFFIX"; return (implib
? "CMAKE_IMPORT_LIBRARY_SUFFIX"
: "CMAKE_EXECUTABLE_SUFFIX");
case cmTarget::UTILITY: case cmTarget::UTILITY:
case cmTarget::GLOBAL_TARGET: case cmTarget::GLOBAL_TARGET:
case cmTarget::INSTALL_FILES: case cmTarget::INSTALL_FILES:
@ -1453,8 +1463,11 @@ const char* cmTarget::GetPrefixVariableInternal(TargetType type,
? "CMAKE_IMPORT_LIBRARY_PREFIX" ? "CMAKE_IMPORT_LIBRARY_PREFIX"
: "CMAKE_SHARED_LIBRARY_PREFIX"); : "CMAKE_SHARED_LIBRARY_PREFIX");
case cmTarget::MODULE_LIBRARY: case cmTarget::MODULE_LIBRARY:
return "CMAKE_SHARED_MODULE_PREFIX"; return (implib
? "CMAKE_IMPORT_LIBRARY_PREFIX"
: "CMAKE_SHARED_MODULE_PREFIX");
case cmTarget::EXECUTABLE: case cmTarget::EXECUTABLE:
return (implib? "CMAKE_IMPORT_LIBRARY_PREFIX" : "");
case cmTarget::UTILITY: case cmTarget::UTILITY:
case cmTarget::GLOBAL_TARGET: case cmTarget::GLOBAL_TARGET:
case cmTarget::INSTALL_FILES: case cmTarget::INSTALL_FILES:
@ -1545,8 +1558,11 @@ void cmTarget::GetFullNameInternal(TargetType type,
return; return;
} }
// The implib option is only allowed for shared libraries. // The implib option is only allowed for shared libraries, module
if(type != cmTarget::SHARED_LIBRARY) // libraries, and executables.
if(type != cmTarget::SHARED_LIBRARY &&
type != cmTarget::MODULE_LIBRARY &&
type != cmTarget::EXECUTABLE)
{ {
implib = false; implib = false;
} }
@ -1769,7 +1785,8 @@ void cmTarget::GetLibraryNamesInternal(std::string& name,
#endif #endif
// The import library name. // The import library name.
if(type == cmTarget::SHARED_LIBRARY) if(type == cmTarget::SHARED_LIBRARY ||
type == cmTarget::MODULE_LIBRARY)
{ {
impName = this->GetFullNameInternal(type, config, true); impName = this->GetFullNameInternal(type, config, true);
} }
@ -1784,26 +1801,29 @@ void cmTarget::GetLibraryNamesInternal(std::string& name,
void cmTarget::GetExecutableNames(std::string& name, void cmTarget::GetExecutableNames(std::string& name,
std::string& realName, std::string& realName,
std::string& impName,
std::string& pdbName, std::string& pdbName,
const char* config) const char* config)
{ {
// Get the names based on the real type of the executable. // Get the names based on the real type of the executable.
this->GetExecutableNamesInternal(name, realName, pdbName, this->GetExecutableNamesInternal(name, realName, impName, pdbName,
this->GetType(), config); this->GetType(), config);
} }
void cmTarget::GetExecutableCleanNames(std::string& name, void cmTarget::GetExecutableCleanNames(std::string& name,
std::string& realName, std::string& realName,
std::string& impName,
std::string& pdbName, std::string& pdbName,
const char* config) const char* config)
{ {
// Get the name and versioned name of this executable. // Get the name and versioned name of this executable.
this->GetExecutableNamesInternal(name, realName, pdbName, this->GetExecutableNamesInternal(name, realName, impName, pdbName,
cmTarget::EXECUTABLE, config); cmTarget::EXECUTABLE, config);
} }
void cmTarget::GetExecutableNamesInternal(std::string& name, void cmTarget::GetExecutableNamesInternal(std::string& name,
std::string& realName, std::string& realName,
std::string& impName,
std::string& pdbName, std::string& pdbName,
TargetType type, TargetType type,
const char* config) const char* config)
@ -1845,6 +1865,9 @@ void cmTarget::GetExecutableNamesInternal(std::string& name,
realName += suffix; realName += suffix;
#endif #endif
// The import library name.
impName = this->GetFullNameInternal(type, config, true);
// The program database file name. // The program database file name.
pdbName = prefix+base+".pdb"; pdbName = prefix+base+".pdb";
} }
@ -1986,8 +2009,11 @@ std::string cmTarget::GetInstallNameDirForInstallTree(const char*)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
const char* cmTarget::GetOutputDir(bool implib) const char* cmTarget::GetOutputDir(bool implib)
{ {
// The implib option is only allowed for shared libraries. // The implib option is only allowed for shared libraries, module
if(this->GetType() != cmTarget::SHARED_LIBRARY) // libraries, and executables.
if(this->GetType() != cmTarget::SHARED_LIBRARY &&
this->GetType() != cmTarget::MODULE_LIBRARY &&
this->GetType() != cmTarget::EXECUTABLE)
{ {
implib = false; implib = false;
} }
@ -2000,6 +2026,10 @@ const char* cmTarget::GetOutputDir(bool implib)
{ {
abort(); abort();
} }
if(implib && !this->DLLPlatform)
{
abort();
}
// Select whether we are constructing the directory for the main // Select whether we are constructing the directory for the main
// target or the import library. // target or the import library.
@ -2019,12 +2049,7 @@ const char* cmTarget::GetOutputDir(bool implib)
// shared library is treated as a runtime target and the // shared library is treated as a runtime target and the
// corresponding import library is treated as an archive // corresponding import library is treated as an archive
// target. // target.
if(this->DLLPlatform)
// Check whether this is a DLL platform.
bool dll_platform = (this->Makefile->IsOn("WIN32") ||
this->Makefile->IsOn("CYGWIN") ||
this->Makefile->IsOn("MINGW"));
if(dll_platform)
{ {
if(implib) if(implib)
{ {
@ -2048,12 +2073,28 @@ const char* cmTarget::GetOutputDir(bool implib)
case cmTarget::MODULE_LIBRARY: case cmTarget::MODULE_LIBRARY:
{ {
// Module libraries are always treated as library targets. // Module libraries are always treated as library targets.
propertyName = "LIBRARY_OUTPUT_DIRECTORY"; // Module import libraries are treated as archive targets.
if(implib)
{
propertyName = "ARCHIVE_OUTPUT_DIRECTORY";
}
else
{
propertyName = "LIBRARY_OUTPUT_DIRECTORY";
}
} break; } break;
case cmTarget::EXECUTABLE: case cmTarget::EXECUTABLE:
{ {
// Executables are always treated as runtime targets. // Executables are always treated as runtime targets.
propertyName = "RUNTIME_OUTPUT_DIRECTORY"; // Executable import libraries are treated as archive targets.
if(implib)
{
propertyName = "ARCHIVE_OUTPUT_DIRECTORY";
}
else
{
propertyName = "RUNTIME_OUTPUT_DIRECTORY";
}
} break; } break;
default: break; default: break;
} }

View File

@ -228,6 +228,7 @@ public:
that takes into account executable version numbers. This should that takes into account executable version numbers. This should
be called only on an executable target. */ be called only on an executable target. */
void GetExecutableNames(std::string& name, std::string& realName, void GetExecutableNames(std::string& name, std::string& realName,
std::string& impName,
std::string& pdbName, const char* config); std::string& pdbName, const char* config);
/** Get the names of the executable used to remove existing copies /** Get the names of the executable used to remove existing copies
@ -235,6 +236,7 @@ public:
during a clean step. This should be called only on an during a clean step. This should be called only on an
executable target. */ executable target. */
void GetExecutableCleanNames(std::string& name, std::string& realName, void GetExecutableCleanNames(std::string& name, std::string& realName,
std::string& impName,
std::string& pdbName, const char* config); std::string& pdbName, const char* config);
/** /**
@ -323,6 +325,7 @@ private:
const char* config); const char* config);
void GetExecutableNamesInternal(std::string& name, void GetExecutableNamesInternal(std::string& name,
std::string& realName, std::string& realName,
std::string& impName,
std::string& pdbName, std::string& pdbName,
TargetType type, TargetType type,
const char* config); const char* config);
@ -360,6 +363,7 @@ private:
bool RecordDependencies; bool RecordDependencies;
cmPropertyMap Properties; cmPropertyMap Properties;
LinkLibraryVectorType OriginalLinkLibraries; LinkLibraryVectorType OriginalLinkLibraries;
bool DLLPlatform;
// The cmMakefile instance that owns this target. This should // The cmMakefile instance that owns this target. This should
// always be set. // always be set.

View File

@ -69,7 +69,7 @@ BSC32=bscmake.exe
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089 # ADD BASE LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089
# ADD LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG # ADD LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG
# ADD LINK32 /out:"OUTPUT_DIRECTORY\Release\OUTPUT_NAME_RELEASE" # ADD LINK32 /out:"OUTPUT_DIRECTORY\Release\OUTPUT_NAME_RELEASE" TARGET_IMPLIB_FLAG_RELEASE
CM_MULTILINE_OPTIONS_RELEASE CM_MULTILINE_OPTIONS_RELEASE
CMAKE_CUSTOM_RULE_CODE CMAKE_CUSTOM_RULE_CODE
@ -101,7 +101,7 @@ BSC32=bscmake.exe
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /IGNORE:4089 # ADD BASE LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /IGNORE:4089
# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /IGNORE:4089 TARGET_VERSION_FLAG # ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /IGNORE:4089 TARGET_VERSION_FLAG
# ADD LINK32 /out:"OUTPUT_DIRECTORY\Debug\OUTPUT_NAME_DEBUG" # ADD LINK32 /out:"OUTPUT_DIRECTORY\Debug\OUTPUT_NAME_DEBUG" TARGET_IMPLIB_FLAG_DEBUG
CM_MULTILINE_OPTIONS_DEBUG CM_MULTILINE_OPTIONS_DEBUG
CMAKE_CUSTOM_RULE_CODE CMAKE_CUSTOM_RULE_CODE
@ -130,7 +130,7 @@ BSC32=bscmake.exe
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089 # ADD BASE LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089
# ADD LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG # ADD LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG
# ADD LINK32 /out:"OUTPUT_DIRECTORY\MinSizeRel\OUTPUT_NAME_MINSIZEREL" # ADD LINK32 /out:"OUTPUT_DIRECTORY\MinSizeRel\OUTPUT_NAME_MINSIZEREL" TARGET_IMPLIB_FLAG_MINSIZEREL
CM_MULTILINE_OPTIONS_MINSIZEREL CM_MULTILINE_OPTIONS_MINSIZEREL
CMAKE_CUSTOM_RULE_CODE CMAKE_CUSTOM_RULE_CODE
@ -160,7 +160,7 @@ BSC32=bscmake.exe
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:console /debug /machine:I386 /IGNORE:4089 # ADD BASE LINK32 /nologo /subsystem:console /debug /machine:I386 /IGNORE:4089
# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG # ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG
# ADD LINK32 /out:"OUTPUT_DIRECTORY\RelWithDebInfo\OUTPUT_NAME_RELWITHDEBINFO" # ADD LINK32 /out:"OUTPUT_DIRECTORY\RelWithDebInfo\OUTPUT_NAME_RELWITHDEBINFO" TARGET_IMPLIB_FLAG_RELWITHDEBINFO
CM_MULTILINE_OPTIONS_RELWITHDEBINFO CM_MULTILINE_OPTIONS_RELWITHDEBINFO
CMAKE_CUSTOM_RULE_CODE CMAKE_CUSTOM_RULE_CODE