From fc7c43346318744d05829579e6312aecddc66207 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 19 Mar 2007 10:00:36 -0400 Subject: [PATCH] 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. --- Modules/Platform/CYGWIN.cmake | 4 +- Modules/Platform/Windows-bcc32.cmake | 8 +- Modules/Platform/Windows-cl.cmake | 7 +- Modules/Platform/Windows-gcc.cmake | 4 +- Source/cmInstallCommand.cxx | 14 ++++ Source/cmInstallTargetGenerator.cxx | 32 ++++++-- Source/cmLocalUnixMakefileGenerator3.cxx | 3 +- Source/cmLocalVisualStudio6Generator.cxx | 4 +- Source/cmLocalVisualStudio7Generator.cxx | 20 ++--- .../cmMakefileExecutableTargetGenerator.cxx | 35 ++++++++- Source/cmMakefileLibraryTargetGenerator.cxx | 11 +-- Source/cmTarget.cxx | 77 ++++++++++++++----- Source/cmTarget.h | 4 + Templates/EXEHeader.dsptemplate | 8 +- 14 files changed, 166 insertions(+), 65 deletions(-) diff --git a/Modules/Platform/CYGWIN.cmake b/Modules/Platform/CYGWIN.cmake index 386acf2f5..89c345324 100644 --- a/Modules/Platform/CYGWIN.cmake +++ b/Modules/Platform/CYGWIN.cmake @@ -32,9 +32,9 @@ SET(CMAKE_CXX_CREATE_SHARED_LIBRARY " -o -Wl,--out-implib, ${CMAKE_GNULD_IMAGE_VERSION} ") SET(CMAKE_C_LINK_EXECUTABLE - " -o ${CMAKE_GNULD_IMAGE_VERSION} ") + " -o -Wl,--out-implib, ${CMAKE_GNULD_IMAGE_VERSION} ") SET(CMAKE_CXX_LINK_EXECUTABLE - " -o ${CMAKE_GNULD_IMAGE_VERSION} ") + " -o -Wl,--out-implib, ${CMAKE_GNULD_IMAGE_VERSION} ") # Shared libraries on cygwin can be named with their version number. SET(CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION 1) diff --git a/Modules/Platform/Windows-bcc32.cmake b/Modules/Platform/Windows-bcc32.cmake index d921cb43e..784047318 100644 --- a/Modules/Platform/Windows-bcc32.cmake +++ b/Modules/Platform/Windows-bcc32.cmake @@ -64,11 +64,15 @@ SET(CMAKE_C_COMPILE_OBJECT SET(CMAKE_C_LINK_EXECUTABLE - " ${CMAKE_START_TEMP_FILE}-e ${CMAKE_END_TEMP_FILE}") + " ${CMAKE_START_TEMP_FILE}-e ${CMAKE_END_TEMP_FILE}" + "implib -c -w " + ) SET(CMAKE_CXX_LINK_EXECUTABLE - " ${CMAKE_START_TEMP_FILE} -e ${CMAKE_END_TEMP_FILE}") + " ${CMAKE_START_TEMP_FILE} -e ${CMAKE_END_TEMP_FILE}" + "implib -c -w " + ) SET (CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel.") diff --git a/Modules/Platform/Windows-cl.cmake b/Modules/Platform/Windows-cl.cmake index 94cb64da6..6c6cac207 100644 --- a/Modules/Platform/Windows-cl.cmake +++ b/Modules/Platform/Windows-cl.cmake @@ -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: /implib: /pdb: /dll /version:. ${CMAKE_END_TEMP_FILE}") -SET(CMAKE_CXX_CREATE_SHARED_MODULE - "link ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out: /pdb: /dll /version:. ${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_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /Fe /Fd -link /version:. ${CMAKE_END_TEMP_FILE}") + " ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /Fe /Fd -link /implib: /version:. ${CMAKE_END_TEMP_FILE}") SET(CMAKE_CXX_LINK_EXECUTABLE - " ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /Fe /Fd -link /version:. ${CMAKE_END_TEMP_FILE}") + " ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /Fe /Fd -link /implib: /version:. ${CMAKE_END_TEMP_FILE}") SET(CMAKE_C_CREATE_PREPROCESSED_SOURCE " > ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} -E ${CMAKE_END_TEMP_FILE}") diff --git a/Modules/Platform/Windows-gcc.cmake b/Modules/Platform/Windows-gcc.cmake index 8a2cf9859..805b45126 100644 --- a/Modules/Platform/Windows-gcc.cmake +++ b/Modules/Platform/Windows-gcc.cmake @@ -39,9 +39,9 @@ SET(CMAKE_CXX_CREATE_SHARED_LIBRARY " -o -Wl,--out-implib, ${CMAKE_GNULD_IMAGE_VERSION} ") SET(CMAKE_C_LINK_EXECUTABLE - " -o ${CMAKE_GNULD_IMAGE_VERSION} ") + " -o -Wl,--out-implib, ${CMAKE_GNULD_IMAGE_VERSION} ") SET(CMAKE_CXX_LINK_EXECUTABLE - " -o ${CMAKE_GNULD_IMAGE_VERSION} ") + " -o -Wl,--out-implib, ${CMAKE_GNULD_IMAGE_VERSION} ") # Initialize C link type selection flags. These flags are used when # building a shared library, shared module, or executable that links diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index d270c77d3..5244b9f9c 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -532,6 +532,20 @@ bool cmInstallCommand::HandleTargetsMode(std::vector 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: diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 3acabec40..fd92eab22 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -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 { diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 008061a34..2b8f3466f 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -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") ) diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 3a72de699..40ba47390 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -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); diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index e627f0d6a..71a1e0d7d 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -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 linkLibs; std::vector 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 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: diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 06b054a7d..241445800 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -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::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, diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index d1398a182..717b0ddc4 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -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, diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 45e71d04f..ef4a07ee0 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -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; } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 6e446e057..028231a75 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -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. diff --git a/Templates/EXEHeader.dsptemplate b/Templates/EXEHeader.dsptemplate index bd743d6b1..90faf7784 100644 --- a/Templates/EXEHeader.dsptemplate +++ b/Templates/EXEHeader.dsptemplate @@ -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