Commit fc7c4334 authored by Brad King's avatar Brad King
Browse files

ENH: Added support for import libraries created by executable and module...

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.
parent 43589ec7
......@@ -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>")
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
"<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.
SET(CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION 1)
......
......@@ -64,11 +64,15 @@ SET(CMAKE_C_COMPILE_OBJECT
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
"<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
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel.")
......
......@@ -15,8 +15,7 @@ ENDIF(CMAKE_VERBOSE_MAKEFILE)
# create a shared C++ 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}")
SET(CMAKE_CXX_CREATE_SHARED_MODULE
"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}")
SET(CMAKE_CXX_CREATE_SHARED_MODULE ${CMAKE_CXX_CREATE_SHARED_LIBRARY})
# create a C 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
"<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
"<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
"<CMAKE_C_COMPILER> > <PREPROCESSED_SOURCE> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} <FLAGS> -E <SOURCE>${CMAKE_END_TEMP_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>")
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
"<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
# building a shared library, shared module, or executable that links
......
......@@ -532,6 +532,20 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
this->SetError(e.str().c_str());
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;
default:
......
......@@ -208,11 +208,21 @@ cmInstallTargetGenerator
{
std::string targetName;
std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB;
target->GetExecutableNames(targetName, targetNameReal,
targetNamePDB, i->c_str());
// Use the canonical name.
fname += targetName;
targetNameImport, targetNamePDB,
i->c_str());
if(this->ImportLibrary)
{
// Use the import library name.
fname += targetNameImport;
}
else
{
// Use the canonical name.
fname += targetName;
}
}
else
{
......@@ -259,11 +269,21 @@ std::string cmInstallTargetGenerator::GetScriptReference(cmTarget* target,
{
std::string targetName;
std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB;
target->GetExecutableNames(targetName, targetNameReal,
targetNamePDB, this->ConfigurationName);
// Use the canonical name.
return targetName;
targetNameImport, targetNamePDB,
this->ConfigurationName);
if(this->ImportLibrary)
{
// Use the import library name.
return targetNameImport;
}
else
{
// Use the canonical name.
return targetName;
}
}
else
{
......
......@@ -1645,8 +1645,9 @@ cmLocalUnixMakefileGenerator3
objectName = cmSystemTools::GetFilenameName(objectName.c_str());
std::string targetName;
std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB;
target.GetExecutableNames(targetName, targetNameReal,
target.GetExecutableNames(targetName, targetNameReal, targetNameImport,
targetNamePDB, this->ConfigurationName.c_str());
std::string obj;
if ( target.GetPropertyAsBool("MACOSX_BUNDLE") )
......
......@@ -1221,7 +1221,9 @@ void cmLocalVisualStudio6Generator
std::string targetImplibFlagRelease;
std::string targetImplibFlagMinSizeRel;
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 fullPathImpRelease = target.GetDirectory("Release", true);
......
......@@ -733,17 +733,6 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
target.GetLibraryNames(targetName, targetNameSO, targetNameFull,
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.
std::vector<cmStdString> linkLibs;
std::vector<cmStdString> linkDirs;
......@@ -816,9 +805,10 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
{
std::string targetName;
std::string targetNameFull;
std::string targetNameImport;
std::string targetNamePDB;
target.GetExecutableNames(targetName, targetNameFull,
targetNamePDB, configName);
targetNameImport, targetNamePDB, configName);
// Compute the link library and directory information.
std::vector<cmStdString> linkLibs;
......@@ -886,7 +876,11 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
{
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;
}
case cmTarget::UTILITY:
......
......@@ -110,9 +110,10 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Get the name of the executable to generate.
std::string targetName;
std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB;
this->Target->GetExecutableNames
(targetName, targetNameReal, targetNamePDB,
(targetName, targetNameReal, targetNameImport, targetNamePDB,
this->LocalGenerator->ConfigurationName.c_str());
// Construct the full path version of the names.
......@@ -167,6 +168,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
false, false, false);
}
#endif
std::string outpathImp;
if(relink)
{
outpath = this->Makefile->GetStartOutputDirectory();
......@@ -174,10 +176,23 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
outpath += "/CMakeRelink.dir";
cmSystemTools::MakeDirectory(outpath.c_str());
outpath += "/";
if(!targetNameImport.empty())
{
outpathImp = outpath;
}
}
else
{
if(!targetNameImport.empty())
{
outpathImp = this->Target->GetDirectory(0, true);
outpathImp += "/";
}
}
std::string targetFullPath = outpath + targetName;
std::string targetFullPathReal = outpath + targetNameReal;
std::string targetFullPathPDB = outpath + targetNamePDB;
std::string targetFullPathImport = outpathImp + targetNameImport;
std::string targetOutPathPDB =
this->Convert(targetFullPathPDB.c_str(),
cmLocalGenerator::FULL,
......@@ -191,7 +206,11 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->Convert(targetFullPathReal.c_str(),
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
std::string targetOutPathImport =
this->Convert(targetFullPathImport.c_str(),
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
// Get the language to use for linking this executable.
const char* linkLanguage =
this->Target->GetLinkerLanguage(this->GlobalGenerator);
......@@ -258,14 +277,16 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
{
std::string cleanName;
std::string cleanRealName;
std::string cleanImportName;
std::string cleanPDBName;
this->Target->GetExecutableCleanNames
(cleanName, cleanRealName, cleanPDBName,
(cleanName, cleanRealName, cleanImportName, cleanPDBName,
this->LocalGenerator->ConfigurationName.c_str());
std::string cleanFullName = outpath + cleanName;
std::string cleanFullRealName = outpath + cleanRealName;
std::string cleanFullPDBName = outpath + cleanPDBName;
std::string cleanFullImportName = outpathImp + cleanImportName;
exeCleanFiles.push_back(this->Convert(cleanFullName.c_str(),
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
......@@ -282,6 +303,12 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
cmLocalGenerator::START_OUTPUT,
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
// 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.LinkFlags = linkFlags.c_str();
// Expand placeholders in the commands.
this->LocalGenerator->TargetImplib = targetOutPathImport;
for(std::vector<std::string>::iterator i = commands.begin();
i != commands.end(); ++i)
{
this->LocalGenerator->ExpandRuleVariables(*i, vars);
}
this->LocalGenerator->TargetImplib = "";
// Write the build rule.
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream,
......
......@@ -341,10 +341,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
}
if(!targetNameImport.empty() &&
targetNameImport != targetName &&
targetNameImport != targetNameReal &&
targetNameImport != targetNameSO)
if(!targetNameImport.empty())
{
libCleanFiles.push_back(this->Convert(targetFullPathImport.c_str(),
cmLocalGenerator::START_OUTPUT,
......@@ -401,11 +398,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
}
if(!cleanImportName.empty() &&
cleanImportName != cleanStaticName &&
cleanImportName != cleanSharedSOName &&
cleanImportName != cleanSharedRealName &&
cleanImportName != cleanSharedName)
if(!cleanImportName.empty())
{
libCleanFiles.push_back(this->Convert(cleanFullImportName.c_str(),
cmLocalGenerator::START_OUTPUT,
......
......@@ -37,6 +37,7 @@ cmTarget::cmTarget()
this->LinkLibrariesAnalyzed = false;
this->LinkDirectoriesComputed = false;
this->HaveInstallRule = false;
this->DLLPlatform = false;
}
......@@ -335,6 +336,11 @@ void cmTarget::SetMakefile(cmMakefile* mf)
// set the cmake instance of the properties
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.
this->SetPropertyDefault("INSTALL_NAME_DIR", "");
this->SetPropertyDefault("INSTALL_RPATH", "");
......@@ -1427,9 +1433,13 @@ const char* cmTarget::GetSuffixVariableInternal(TargetType type,
? "CMAKE_IMPORT_LIBRARY_SUFFIX"
: "CMAKE_SHARED_LIBRARY_SUFFIX");
case cmTarget::MODULE_LIBRARY:
return "CMAKE_SHARED_MODULE_SUFFIX";
return (implib
? "CMAKE_IMPORT_LIBRARY_SUFFIX"
: "CMAKE_SHARED_MODULE_SUFFIX");
case cmTarget::EXECUTABLE:
return "CMAKE_EXECUTABLE_SUFFIX";
return (implib
? "CMAKE_IMPORT_LIBRARY_SUFFIX"
: "CMAKE_EXECUTABLE_SUFFIX");
case cmTarget::UTILITY:
case cmTarget::GLOBAL_TARGET:
case cmTarget::INSTALL_FILES:
......@@ -1453,8 +1463,11 @@ const char* cmTarget::GetPrefixVariableInternal(TargetType type,
? "CMAKE_IMPORT_LIBRARY_PREFIX"
: "CMAKE_SHARED_LIBRARY_PREFIX");
case cmTarget::MODULE_LIBRARY:
return "CMAKE_SHARED_MODULE_PREFIX";
return (implib
? "CMAKE_IMPORT_LIBRARY_PREFIX"
: "CMAKE_SHARED_MODULE_PREFIX");
case cmTarget::EXECUTABLE:
return (implib? "CMAKE_IMPORT_LIBRARY_PREFIX" : "");
case cmTarget::UTILITY:
case cmTarget::GLOBAL_TARGET:
case cmTarget::INSTALL_FILES:
......@@ -1545,8 +1558,11 @@ void cmTarget::GetFullNameInternal(TargetType type,
return;
}
// The implib option is only allowed for shared libraries.
if(type != cmTarget::SHARED_LIBRARY)
// The implib option is only allowed for shared libraries, module
// libraries, and executables.
if(type != cmTarget::SHARED_LIBRARY &&
type != cmTarget::MODULE_LIBRARY &&
type != cmTarget::EXECUTABLE)
{
implib = false;
}
......@@ -1769,7 +1785,8 @@ void cmTarget::GetLibraryNamesInternal(std::string& name,
#endif
// The import library name.
if(type == cmTarget::SHARED_LIBRARY)
if(type == cmTarget::SHARED_LIBRARY ||
type == cmTarget::MODULE_LIBRARY)
{
impName = this->GetFullNameInternal(type, config, true);
}
......@@ -1784,26 +1801,29 @@ void cmTarget::GetLibraryNamesInternal(std::string& name,
void cmTarget::GetExecutableNames(std::string& name,
std::string& realName,
std::string& impName,
std::string& pdbName,
const char* config)
{
// 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);
}
void cmTarget::GetExecutableCleanNames(std::string& name,
std::string& realName,
std::string& impName,
std::string& pdbName,
const char* config)
{
// Get the name and versioned name of this executable.
this->GetExecutableNamesInternal(name, realName, pdbName,
this->GetExecutableNamesInternal(name, realName, impName, pdbName,
cmTarget::EXECUTABLE, config);
}
void cmTarget::GetExecutableNamesInternal(std::string& name,
std::string& realName,
std::string& impName,
std::string& pdbName,
TargetType type,
const char* config)
......@@ -1845,6 +1865,9 @@ void cmTarget::GetExecutableNamesInternal(std::string& name,
realName += suffix;
#endif
// The import library name.
impName = this->GetFullNameInternal(type, config, true);
// The program database file name.
pdbName = prefix+base+".pdb";
}
......@@ -1986,8 +2009,11 @@ std::string cmTarget::GetInstallNameDirForInstallTree(const char*)
//----------------------------------------------------------------------------
const char* cmTarget::GetOutputDir(bool implib)
{
// The implib option is only allowed for shared libraries.
if(this->GetType() != cmTarget::SHARED_LIBRARY)
// The implib option is only allowed for shared libraries, module
// libraries, and executables.
if(this->GetType() != cmTarget::SHARED_LIBRARY &&
this->GetType() != cmTarget::MODULE_LIBRARY &&
this->GetType() != cmTarget::EXECUTABLE)
{
implib = false;
}
......@@ -2000,6 +2026,10 @@ const char* cmTarget::GetOutputDir(bool implib)
{
abort();
}
if(implib && !this->DLLPlatform)
{
abort();
}
// Select whether we are constructing the directory for the main
// 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
// corresponding import library is treated as an archive
// target.
// 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(this->DLLPlatform)
{
if(implib)
{
......@@ -2048,12 +2073,28 @@ const char* cmTarget::GetOutputDir(bool implib)
case cmTarget::MODULE_LIBRARY:
{
// 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;
case cmTarget::EXECUTABLE:
{
// 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;
default: break;
}
......
......@@ -228,6 +228,7 @@ public:
that takes into account executable version numbers. This should
be called only on an executable target. */
void GetExecutableNames(std::string& name, std::string& realName,
std::string& impName,
std::string& pdbName, const char* config);
/** 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
executable target. */
void GetExecutableCleanNames(std::string& name, std::string& realName,
std::string& impName,
std::string& pdbName, const char* config);
/**
......@@ -323,6 +325,7 @@ private:
const char* config);
void GetExecutableNamesInternal(std::string& name,
std::string& realName,
std::string& impName,
std::string& pdbName,
TargetType type,
const char* config);
......@@ -360,6 +363,7 @@ private:
bool RecordDependencies;
cmPropertyMap Properties;
LinkLibraryVectorType OriginalLinkLibraries;
bool DLLPlatform;
// The cmMakefile instance that owns this target. This should
// always be set.
......
......@@ -69,7 +69,7 @@ BSC32=bscmake.exe
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089
# 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
CMAKE_CUSTOM_RULE_CODE
......@@ -101,7 +101,7 @@ BSC32=bscmake.exe
LINK32=link.exe
# 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 /out:"OUTPUT_DIRECTORY\Debug\OUTPUT_NAME_DEBUG"
# ADD LINK32 /out:"OUTPUT_DIRECTORY\Debug\OUTPUT_NAME_DEBUG" TARGET_IMPLIB_FLAG_DEBUG
CM_MULTILINE_OPTIONS_DEBUG
CMAKE_CUSTOM_RULE_CODE
......@@ -130,7 +130,7 @@ BSC32=bscmake.exe
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089
# 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
CMAKE_CUSTOM_RULE_CODE
......@@ -160,7 +160,7 @@ BSC32=bscmake.exe
LINK32=link.exe
# 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 /out:"OUTPUT_DIRECTORY\RelWithDebInfo\OUTPUT_NAME_RELWITHDEBINFO"
# ADD LINK32 /out:"OUTPUT_DIRECTORY\RelWithDebInfo\OUTPUT_NAME_RELWITHDEBINFO" TARGET_IMPLIB_FLAG_RELWITHDEBINFO
CM_MULTILINE_OPTIONS_RELWITHDEBINFO
CMAKE_CUSTOM_RULE_CODE
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment