View Issue Details [ Jump to Notes ] | [ Print ] | ||||||||
ID | Project | Category | View Status | Date Submitted | Last Update | ||||
0010830 | CMake | CMake | public | 2010-06-14 17:35 | 2013-04-05 07:58 | ||||
Reporter | Andreas Johansen | ||||||||
Assigned To | Brad King | ||||||||
Priority | normal | Severity | feature | Reproducibility | always | ||||
Status | closed | Resolution | fixed | ||||||
Platform | OS | OS Version | |||||||
Product Version | CMake-2-8 | ||||||||
Target Version | CMake 2.8.10 | Fixed in Version | CMake 2.8.10 | ||||||
Summary | 0010830: Add option to specify output of Visual Studio .pdb files (Debug symbols) | ||||||||
Description | I need to be able to either a: specify the output name of the debug symbols file, or b: specify the output directory for the debug symbols file. Currently CMake just grabs the output name of the target, and changes the file ending to .pdb leaving the debug symbols to always end up with the binary file. In most cases this if fine, but I'm currently working with a project where there's two targets with the same output name (one is .exe and the other is .dll). The current system in CMake makes those two projects write out the exact same .pdb file (one overwriting the other) when both binaries are set to output in the same directory (won't overwrite each other). | ||||||||
Tags | No tags attached. | ||||||||
Attached Files | set_debug_symbols_name.patch [^] (1,782 bytes) 2010-06-17 09:52 [Show Content] [Hide Content]From 312d53ad3d3440d0400e41813b6ff79159a90d67 Mon Sep 17 00:00:00 2001 From: Andreas Johansen <aj@andreasjohansen.com> Date: Thu, 17 Jun 2010 15:43:21 +0200 Subject: [PATCH] Added "DEBUG_SYMBOLS_NAME" property for target. When set, the property is used for the debug symbol filename in VS generator (.pdb file) --- Source/cmTarget.cxx | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 45ba358..8778653 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -608,6 +608,13 @@ void cmTarget::DefineProperties(cmake *cm) "Use OUTPUT_NAME_<CONFIG> instead."); cm->DefineProperty + ("DEBUG_SYMBOLS_NAME", cmProperty::TARGET, + "Output name for debug symbols files.", + "This sets the base name for debug symbols files created for an executable or " + "library target. " + "If not set, the logical target name is used by default."); + + cm->DefineProperty ("PRE_INSTALL_SCRIPT", cmProperty::TARGET, "Deprecated install support.", "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the " @@ -2792,6 +2799,11 @@ std::string cmTarget::GetPDBName(const char* config) std::string base; std::string suffix; this->GetFullNameInternal(config, false, prefix, base, suffix); + + const char* dbgName = this->GetProperty( "DEBUG_SYMBOLS_NAME" ); + if ( dbgName ) + base = dbgName; + return prefix+base+".pdb"; } @@ -3214,7 +3226,7 @@ void cmTarget::GetLibraryNames(std::string& name, } // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName( config ); //prefix+base+".pdb"; } //---------------------------------------------------------------------------- -- 1.7.0.2.msysgit.0 0001-Add-target-property-PDB_NAME-to-set-MS-.pdb-names.patch [^] (1,971 bytes) 2010-12-15 10:19 [Show Content] [Hide Content] From 3a6b89fa001cb01a175b7b9c04866483af6d2aa5 Mon Sep 17 00:00:00 2001 From: Andreas Johansen <aj@andreasjohansen.com> Date: Thu, 17 Jun 2010 15:43:21 +0200 Subject: [PATCH] Add target property PDB_NAME to set MS .pdb names --- Source/cmTarget.cxx | 15 +++++++++++++-- 1 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index ef274b4..25c637c 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -638,6 +638,13 @@ void cmTarget::DefineProperties(cmake *cm) "Use OUTPUT_NAME_<CONFIG> instead."); cm->DefineProperty + ("PDB_NAME", cmProperty::TARGET, + "Output name for MS debug symbols .pdb file.", + "Set the base name for debug symbols file created for an " + "executable or library target. " + "If not set, the logical target name is used by default."); + + cm->DefineProperty ("PRE_INSTALL_SCRIPT", cmProperty::TARGET, "Deprecated install support.", "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the " @@ -2840,6 +2847,10 @@ std::string cmTarget::GetPDBName(const char* config) std::string base; std::string suffix; this->GetFullNameInternal(config, false, prefix, base, suffix); + if(const char* pdbBase = this->GetProperty("PDB_NAME")) + { + base = pdbBase; + } return prefix+base+".pdb"; } @@ -3271,7 +3282,7 @@ void cmTarget::GetLibraryNames(std::string& name, } // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3333,7 +3344,7 @@ void cmTarget::GetExecutableNames(std::string& name, impName = this->GetFullNameInternal(config, true); // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- -- 1.7.2.3 0001-PDB_NAME-target-property-to-set-full-PDB-file-path.patch [^] (4,251 bytes) 2011-01-25 03:34 [Show Content] [Hide Content] From 19cdd91d517fb75867314abd65133284f1c4d6a5 Mon Sep 17 00:00:00 2001 From: be <be@ipetronik.com> Date: Tue, 25 Jan 2011 09:31:53 +0100 Subject: [PATCH] PDB_NAME target property to set full PDB file path --- Source/cmLocalVisualStudio7Generator.cxx | 7 +++---- Source/cmMakefileTargetGenerator.cxx | 6 ++---- Source/cmTarget.cxx | 25 ++++++++++++++++++------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 34756d8..e94ae88 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -763,10 +763,9 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, // We need to specify a program database file name even for // non-debug configurations because VS still creates .idb files. fout << "\t\t\t\tProgramDataBaseFileName=\"" - << this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()) - << "/" - << target.GetPDBName(configName) << "\"\n"; + << this->ConvertToXMLOutputPathSingle( + target.GetPDBName(configName).c_str() + ) << "\"\n"; } fout << "/>\n"; // end of <Tool Name=VCCLCompilerTool tool = "VCCustomBuildTool"; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 9dcd8f1..ccfdeb2 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -607,10 +607,8 @@ cmMakefileTargetGenerator this->Target->GetType() == cmTarget::STATIC_LIBRARY || this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) - { - targetFullPathPDB = this->Target->GetDirectory(this->ConfigName); - targetFullPathPDB += "/"; - targetFullPathPDB += this->Target->GetPDBName(this->ConfigName); + { + targetFullPathPDB = this->Target->GetPDBName(this->ConfigName); } targetOutPathPDB = this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::NONE, diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 72efce3..f361364 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -644,6 +644,12 @@ void cmTarget::DefineProperties(cmake *cm) "Old per-configuration target file base name.", "This is a configuration-specific version of OUTPUT_NAME. " "Use OUTPUT_NAME_<CONFIG> instead."); + cm->DefineProperty + ("PDB_NAME", cmProperty::TARGET, + "Output name for MS debug symbols .pdb file.", + "Set the base name for debug symbols file created for an " + "executable or library target. " + "If not set, the logical target name is used by default."); cm->DefineProperty ("PRE_INSTALL_SCRIPT", cmProperty::TARGET, @@ -2860,11 +2866,16 @@ const char* cmTarget::GetPrefixVariableInternal(bool implib) //---------------------------------------------------------------------------- std::string cmTarget::GetPDBName(const char* config) { - std::string prefix; - std::string base; - std::string suffix; - this->GetFullNameInternal(config, false, prefix, base, suffix); - return prefix+base+".pdb"; + const char *target_pdb=this->GetProperty("PDB_NAME"); + if(target_pdb) + return target_pdb; + + std::string prefix; + std::string base; + std::string suffix; + + this->GetFullNameInternal(config, false, prefix, base, suffix); + return GetDirectory(config)+"/"+prefix+base+".pdb"; } //---------------------------------------------------------------------------- @@ -3295,7 +3306,7 @@ void cmTarget::GetLibraryNames(std::string& name, } // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3357,7 +3368,7 @@ void cmTarget::GetExecutableNames(std::string& name, impName = this->GetFullNameInternal(config, true); // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- -- 1.7.3.1.msysgit.0 0001-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch [^] (19,343 bytes) 2011-01-28 08:43 [Show Content] [Hide Content] From ee8ba55590930cd514d45600c11b0ab2e4654d7a Mon Sep 17 00:00:00 2001 From: be <be@ipetronik.com> Date: Fri, 28 Jan 2011 13:49:12 +0100 Subject: [PATCH] Added PDB_OUTPUT_DIRECTORY and PDB_NAME as target properties. This enables changing the name and output folder of the debug symbol files produced by MS compilers. --- Source/cmDocumentVariables.cxx | 9 ++ Source/cmLocalVisualStudio7Generator.cxx | 6 +- Source/cmMakefileExecutableTargetGenerator.cxx | 6 +- Source/cmMakefileLibraryTargetGenerator.cxx | 5 +- Source/cmMakefileTargetGenerator.cxx | 2 +- Source/cmTarget.cxx | 141 ++++++++++++++++++++++-- Source/cmTarget.h | 7 + Source/cmVisualStudio10TargetGenerator.cxx | 5 +- Tests/CMakeLists.txt | 1 + Tests/PDBDirectoryAndName/CMakeLists.txt | 31 +++++ Tests/PDBDirectoryAndName/myexe.c | 3 + Tests/PDBDirectoryAndName/mylibA.c | 1 + Tests/PDBDirectoryAndName/mylibB.c | 1 + 13 files changed, 202 insertions(+), 16 deletions(-) create mode 100644 Tests/PDBDirectoryAndName/CMakeLists.txt create mode 100644 Tests/PDBDirectoryAndName/myexe.c create mode 100644 Tests/PDBDirectoryAndName/mylibA.c create mode 100644 Tests/PDBDirectoryAndName/mylibB.c diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index e9b54d8..d2cf643 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1013,6 +1013,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables that Control the Build"); cm->DefineProperty + ("CMAKE_PDB_OUTPUT_DIRECTORY", cmProperty::VARIABLE, + "Where to put all the MS debug symbol files.", + "This variable is used to initialize the " + "PDB_OUTPUT_DIRECTORY property on all the targets. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); + + cm->DefineProperty ("CMAKE_DEBUG_POSTFIX", cmProperty::VARIABLE, "See variable CMAKE_<CONFIG>_POSTFIX.", "This variable is a special case of the more-general " diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 34756d8..7165e9c 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -764,7 +764,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, // non-debug configurations because VS still creates .idb files. fout << "\t\t\t\tProgramDataBaseFileName=\"" << this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()) + target.GetPDBDirectory(configName).c_str()) << "/" << target.GetPDBName(configName) << "\"\n"; } @@ -1006,7 +1006,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, fout << "\t\t\t\tAdditionalLibraryDirectories=\""; this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; - temp = target.GetDirectory(configName); + temp = target.GetPDBDirectory(configName); temp += "/"; temp += targetNamePDB; fout << "\t\t\t\tProgramDatabaseFile=\"" << @@ -1088,7 +1088,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; std::string path = this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()); + target.GetPDBDirectory(configName).c_str()); fout << "\t\t\t\tProgramDatabaseFile=\"" << path << "/" << targetNamePDB << "\"\n"; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 4426241..bafa483 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -125,9 +125,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) outpathImp += "/"; } } + + std::string pdbOutputPath = this->Target->GetPDBDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + std::string targetFullPath = outpath + targetName; std::string targetFullPathReal = outpath + targetNameReal; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + targetNamePDB; std::string targetFullPathImport = outpathImp + targetNameImport; std::string targetOutPathPDB = this->Convert(targetFullPathPDB.c_str(), diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 049a338..007dcfd 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -379,8 +379,11 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules } } + std::string pdbOutputPath = this->Target->GetPDBDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + std::string targetFullPath = outpath + targetName; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + targetNamePDB; std::string targetFullPathSO = outpath + targetNameSO; std::string targetFullPathReal = outpath + targetNameReal; std::string targetFullPathImport = outpathImp + targetNameImport; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 9dcd8f1..d8a49c0 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -608,7 +608,7 @@ cmMakefileTargetGenerator this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - targetFullPathPDB = this->Target->GetDirectory(this->ConfigName); + targetFullPathPDB = this->Target->GetPDBDirectory(this->ConfigName); targetFullPathPDB += "/"; targetFullPathPDB += this->Target->GetPDBName(this->ConfigName); } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 72efce3..b251106 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -37,6 +37,7 @@ struct cmTarget::OutputInfo { std::string OutDir; std::string ImpDir; + std::string PdbDir; }; //---------------------------------------------------------------------------- @@ -646,6 +647,19 @@ void cmTarget::DefineProperties(cmake *cm) "Use OUTPUT_NAME_<CONFIG> instead."); cm->DefineProperty + ("PDB_NAME", cmProperty::TARGET, + "Output name for MS debug symbols .pdb file.", + "Set the base name for debug symbols file created for an " + "executable or library target. " + "If not set, the logical target name is used by default."); + + cm->DefineProperty + ("PDB_NAME_<CONFIG>", cmProperty::TARGET, + "Per-configuration name for MS debug symbols .pdb file.", + "This is the configuration-specific version of PDB_NAME." + ); + + cm->DefineProperty ("PRE_INSTALL_SCRIPT", cmProperty::TARGET, "Deprecated install support.", "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the " @@ -997,6 +1011,23 @@ void cmTarget::DefineProperties(cmake *cm) CM_TARGET_OUTDIR_CONFIG_DOC(RUNTIME)); cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY", cmProperty::TARGET, + "Output directory for MS debug symbols .pdb files.", + "This property specifies the directory into which the MS debug symbols" + "will be placed. " + "This property is initialized by the value of the variable " + "CMAKE_<TAFGET_TYPE>_OUTPUT_DIRECTORY if it is set when a target is created."); + cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY_<CONFIG>", cmProperty::TARGET, + "Per-configuration output directory for MS debug symbols .pdb files.", + "This is a per-configuration version of PDB_OUTPUT_DIRECTORY, " + "but multi-configuration generators (VS, Xcode) do NOT append " + "a per-configuration subdirectory to the specified directory. " + "This property is initialized by the value of the variable " + "CMAKE_<TARGET_TYPE>_OUTPUT_DIRECTORY_<CONFIG> " + "if it is set when a target is created."); + + cm->DefineProperty ("ARCHIVE_OUTPUT_NAME", cmProperty::TARGET, "Output name for ARCHIVE target files.", "This property specifies the base name for archive target files. " @@ -1077,6 +1108,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); + this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); this->SetPropertyDefault("OSX_ARCHITECTURES", 0); @@ -1089,6 +1121,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) "ARCHIVE_OUTPUT_DIRECTORY_", "LIBRARY_OUTPUT_DIRECTORY_", "RUNTIME_OUTPUT_DIRECTORY_", + "PDB_OUTPUT_DIRECTORY_", 0}; for(std::vector<std::string>::iterator ci = configNames.begin(); ci != configNames.end(); ++ci) @@ -2283,6 +2316,7 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config) OutputInfo info; this->ComputeOutputDir(config, false, info.OutDir); this->ComputeOutputDir(config, true, info.ImpDir); + this->ComputePdbOutputDir(config,info.PdbDir); OutputInfoMapType::value_type entry(config_upper, info); i = this->Internal->OutputInfoMap.insert(entry).first; } @@ -2308,6 +2342,17 @@ std::string cmTarget::GetDirectory(const char* config, bool implib) } //---------------------------------------------------------------------------- +std::string cmTarget::GetPDBDirectory(const char* config) +{ + if(OutputInfo const* info = this->GetOutputInfo(config)) + { + // Return the directory in which the target will be built. + return info->PdbDir; + } + return ""; +} + +//---------------------------------------------------------------------------- const char* cmTarget::GetLocation(const char* config) { if (this->IsImported()) @@ -2860,11 +2905,32 @@ const char* cmTarget::GetPrefixVariableInternal(bool implib) //---------------------------------------------------------------------------- std::string cmTarget::GetPDBName(const char* config) { - std::string prefix; - std::string base; - std::string suffix; - this->GetFullNameInternal(config, false, prefix, base, suffix); - return prefix+base+".pdb"; + std::string prefix; + std::string base; + std::string suffix; + this->GetFullNameInternal(config, false, prefix, base, suffix); + + std::vector<std::string> props; + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + if(!configUpper.empty()) + { + // PDB_NAME_<CONFIG> + props.push_back("PDB_NAME_" + configUpper); + } + + // PDB_NAME + props.push_back("PDB_NAME"); + + for(std::vector<std::string>::const_iterator i = props.begin(); + i != props.end(); ++i) + { + if(const char* outName = this->GetProperty(i->c_str())) + { + base = outName; + break; + } + } + return prefix+base+".pdb"; } //---------------------------------------------------------------------------- @@ -3295,7 +3361,7 @@ void cmTarget::GetLibraryNames(std::string& name, } // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3357,7 +3423,7 @@ void cmTarget::GetExecutableNames(std::string& name, impName = this->GetFullNameInternal(config, true); // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3416,7 +3482,7 @@ void cmTarget::GenerateTargetManifest(const char* config) } if(!pdbName.empty()) { - f = dir; + f = this->GetPDBDirectory(config); f += "/"; f += pdbName; gg->AddToManifest(config? config:"", f); @@ -3593,6 +3659,65 @@ std::string cmTarget::GetInstallNameDirForInstallTree(const char* config, } //---------------------------------------------------------------------------- +void cmTarget::ComputePdbOutputDir(const char* config, std::string& out) +{ + // Look for a target property defining the target output directory + // based on the target type. + std::string targetTypeName = "PDB"; + const char* propertyName = 0; + std::string propertyNameStr = targetTypeName; + if(!propertyNameStr.empty()) + { + propertyNameStr += "_OUTPUT_DIRECTORY"; + propertyName = propertyNameStr.c_str(); + } + + // Check for a per-configuration output directory target property. + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + const char* configProp = 0; + std::string configPropStr = targetTypeName; + if(!configPropStr.empty()) + { + configPropStr += "_OUTPUT_DIRECTORY_"; + configPropStr += configUpper; + configProp = configPropStr.c_str(); + } + + // Select an output directory. + if(const char* config_outdir = this->GetProperty(configProp)) + { + // Use the user-specified per-configuration output directory. + out = config_outdir; + + // Skip per-configuration subdirectory. + config = 0; + } + else if(const char* outdir = this->GetProperty(propertyName)) + { + // Use the user-specified output directory. + out = outdir; + } + if(out.empty()) + { + // Default to the current output directory. + out = "."; + } + + // Convert the output path to a full path in case it is + // specified as a relative path. Treat a relative path as + // relative to the current output directory for this makefile. + out = (cmSystemTools::CollapseFullPath + (out.c_str(), this->Makefile->GetStartOutputDirectory())); + + // The generator may add the configuration's subdirectory. + if(config && *config) + { + this->Makefile->GetLocalGenerator()->GetGlobalGenerator()-> + AppendDirectoryForConfig("/", config, "", out); + } +} + +//---------------------------------------------------------------------------- const char* cmTarget::GetOutputTargetType(bool implib) { switch(this->GetType()) diff --git a/Source/cmTarget.h b/Source/cmTarget.h index f2b7d61..566d795 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -300,6 +300,12 @@ public: output directory is given. */ std::string GetDirectory(const char* config = 0, bool implib = false); + /** Get the directory in which this targets .pdb files will be placed. If the + configuration name is given then the generator will add its + subdirectory for that configuration. Otherwise just the canonical + pdb output directory is given. */ + std::string GetPDBDirectory(const char* config = 0); + /** Get the location of the target in the build tree for the given configuration. This location is suitable for use as the LOCATION target property. */ @@ -556,6 +562,7 @@ private: struct OutputInfo; OutputInfo const* GetOutputInfo(const char* config); void ComputeOutputDir(const char* config, bool implib, std::string& out); + void ComputePdbOutputDir(const char* config, std::string& out); // Cache import information from properties for each configuration. struct ImportInfo; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index ab282b0..e38c298 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1121,7 +1121,7 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( << "</AssemblerListingLocation>\n"; this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3); this->WriteString("<ProgramDataBaseFileName>", 3); - *this->BuildFileStream << this->Target->GetDirectory(configName.c_str()) + *this->BuildFileStream << this->Target->GetPDBDirectory(configName.c_str()) << "/" << this->Target->GetPDBName(configName.c_str()) << "</ProgramDataBaseFileName>\n"; @@ -1347,7 +1347,8 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& std::string dir = this->Target->GetDirectory(config.c_str()); dir += "/"; - std::string pdb = dir; + std::string pdb = this->Target->GetPDBDirectory(config.c_str()); + pdb += "/"; pdb += targetNamePDB; std::string imLib = this->Target->GetDirectory(config.c_str(), true); imLib += "/"; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index adef084..8716a4f 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1060,6 +1060,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ADD_TEST_MACRO(ForceInclude foo) ADD_TEST_MACRO(PrecompiledHeader foo) ADD_TEST_MACRO(ModuleDefinition example_exe) + ADD_TEST_MACRO(PDBDirectoryAndName myexe) ENDIF(CMAKE_TEST_MSVC) ADD_TEST_MACRO(CheckCompilerRelatedVariables CheckCompilerRelatedVariables) diff --git a/Tests/PDBDirectoryAndName/CMakeLists.txt b/Tests/PDBDirectoryAndName/CMakeLists.txt new file mode 100644 index 0000000..ba3f26d --- /dev/null +++ b/Tests/PDBDirectoryAndName/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 2.8) +project(PDBDirectoryAndName C) + +# Make sure the proper compiler is in use. +IF(NOT MSVC) + MESSAGE(FATAL_ERROR "The PDB file test works only with MSVC") +ENDIF() + + +# Put the subproject source tree in our build tree so it can refer to +# link directories relative to its source. +if(NOT "${LinkDirectory_SOURCE_DIR}" STREQUAL "${LinkDirectory_BINARY_DIR}") + file(COPY External/ DESTINATION External PATTERN CVS EXCLUDE) +endif() + +# Build a library into the subproject source tree. +add_library(mylibA STATIC mylibA.c) +set_property(TARGET mylibA PROPERTY + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pdb") +get_property(mylibA TARGET mylibA PROPERTY LOCATION) + +# Build a library into our build tree relative to the subproject build tree. +add_library(mylibB STATIC mylibB.c) +set_property(TARGET mylibB PROPERTY + PDB_NAME "specialpdb") +get_property(mylibB TARGET mylibB PROPERTY LOCATION) + +add_executable(myexe myexe.c) +target_link_libraries(myexe mylibA mylibB) + + diff --git a/Tests/PDBDirectoryAndName/myexe.c b/Tests/PDBDirectoryAndName/myexe.c new file mode 100644 index 0000000..6ef1ebe --- /dev/null +++ b/Tests/PDBDirectoryAndName/myexe.c @@ -0,0 +1,3 @@ +extern int mylibA(void); +extern int mylibB(void); +int main(void) { return mylibA() + mylibB(); } diff --git a/Tests/PDBDirectoryAndName/mylibA.c b/Tests/PDBDirectoryAndName/mylibA.c new file mode 100644 index 0000000..890a089 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibA.c @@ -0,0 +1 @@ +int mylibA(void) { return 0; } diff --git a/Tests/PDBDirectoryAndName/mylibB.c b/Tests/PDBDirectoryAndName/mylibB.c new file mode 100644 index 0000000..090cc6c --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibB.c @@ -0,0 +1 @@ +int mylibB(void) { return 0; } -- 1.7.3.1.msysgit.0 Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch [^] (19,057 bytes) 2012-09-22 04:48 [Show Content] [Hide Content] From f2ed6c57e085c8b48209af71d63bcb60115830b1 Mon Sep 17 00:00:00 2001 From: Yuchen Deng <loaden@gmail.com> Date: Sat, 22 Sep 2012 16:46:45 +0800 Subject: [PATCH] Added PDB_OUTPUT_DIRECTORY and PDB_NAME as target properties This enables changing the name and output folder of the debug symbol files produced by MS compilers. Original Patch by: be <be@ipetronik.com> See: http://public.kitware.com/Bug/view.php?id=10830 --- Source/cmDocumentVariables.cxx | 9 ++ Source/cmLocalVisualStudio7Generator.cxx | 6 +- Source/cmMakefileExecutableTargetGenerator.cxx | 6 +- Source/cmMakefileLibraryTargetGenerator.cxx | 5 +- Source/cmMakefileTargetGenerator.cxx | 2 +- Source/cmTarget.cxx | 129 +++++++++++++++++++++++- Source/cmTarget.h | 7 ++ Source/cmVisualStudio10TargetGenerator.cxx | 6 +- Tests/CMakeLists.txt | 1 + Tests/PDBDirectoryAndName/CMakeLists.txt | 32 ++++++ Tests/PDBDirectoryAndName/myexe.c | 4 + Tests/PDBDirectoryAndName/mylibA.c | 2 + Tests/PDBDirectoryAndName/mylibB.c | 2 + 13 files changed, 199 insertions(+), 12 deletions(-) create mode 100644 Tests/PDBDirectoryAndName/CMakeLists.txt create mode 100644 Tests/PDBDirectoryAndName/myexe.c create mode 100644 Tests/PDBDirectoryAndName/mylibA.c create mode 100644 Tests/PDBDirectoryAndName/mylibB.c diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 5e7e081..db3d055 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1211,6 +1211,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables that Control the Build"); cm->DefineProperty + ("CMAKE_PDB_OUTPUT_DIRECTORY", cmProperty::VARIABLE, + "Where to put all the MS debug symbol files.", + "This variable is used to initialize the " + "PDB_OUTPUT_DIRECTORY property on all the targets. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); + + cm->DefineProperty ("CMAKE_AUTOMOC", cmProperty::VARIABLE, "Whether to handle moc automatically for Qt targets.", "This variable is used to initialize the " diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 2dfca02..ed17786 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -847,7 +847,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, // non-debug configurations because VS still creates .idb files. fout << "\t\t\t\tProgramDataBaseFileName=\"" << this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()) + target.GetPDBDirectory(configName).c_str()) << "/" << target.GetPDBName(configName) << "\"\n"; } @@ -1125,7 +1125,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, fout << "\t\t\t\tAdditionalLibraryDirectories=\""; this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; - temp = target.GetDirectory(configName); + temp = target.GetPDBDirectory(configName); temp += "/"; temp += targetNamePDB; fout << "\t\t\t\tProgramDatabaseFile=\"" << @@ -1211,7 +1211,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; std::string path = this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()); + target.GetPDBDirectory(configName).c_str()); fout << "\t\t\t\tProgramDatabaseFile=\"" << path << "/" << targetNamePDB << "\"\n"; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index ab5150a..c515574 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -131,9 +131,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) outpathImp += "/"; } } + + std::string pdbOutputPath = this->Target->GetPdbDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + std::string targetFullPath = outpath + targetName; std::string targetFullPathReal = outpath + targetNameReal; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + targetNamePDB; std::string targetFullPathImport = outpathImp + targetNameImport; std::string targetOutPathPDB = this->Convert(targetFullPathPDB.c_str(), diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 577e5fd..42f6895 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -328,8 +328,11 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules } } + std::string pdbOutputPath = this->Target->GetPdbDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + std::string targetFullPath = outpath + targetName; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + targetNamePDB; std::string targetFullPathSO = outpath + targetNameSO; std::string targetFullPathReal = outpath + targetNameReal; std::string targetFullPathImport = outpathImp + targetNameImport; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 95738c4..23d670c 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -652,7 +652,7 @@ cmMakefileTargetGenerator this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - targetFullPathPDB = this->Target->GetDirectory(this->ConfigName); + targetFullPathPDB = this->Target->GetPdbDirectory(this->ConfigName); targetFullPathPDB += "/"; targetFullPathPDB += this->Target->GetPDBName(this->ConfigName); } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 9a3812c..a3666d0 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -57,6 +57,7 @@ struct cmTarget::OutputInfo { std::string OutDir; std::string ImpDir; + std::string PdbDir; }; //---------------------------------------------------------------------------- @@ -741,6 +742,18 @@ void cmTarget::DefineProperties(cmake *cm) "Use OUTPUT_NAME_<CONFIG> instead."); cm->DefineProperty + ("PDB_NAME", cmProperty::TARGET, + "Output name for MS debug symbols .pdb file.", + "Set the base name for debug symbols file created for an " + "executable or library target." + "If not set, the logical target name is used by default."); + + cm->DefineProperty + ("PDB_NAME_<CONFIG>", cmProperty::TARGET, + "Per-configuration name for MS debug symbols .pdb file.", + "This is the configuration-specific version of PDB_NAME."); + + cm->DefineProperty ("PRE_INSTALL_SCRIPT", cmProperty::TARGET, "Deprecated install support.", "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the " @@ -1190,6 +1203,23 @@ void cmTarget::DefineProperties(cmake *cm) CM_TARGET_OUTDIR_CONFIG_DOC(RUNTIME)); cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY", cmProperty::TARGET, + "Output directory for MS debug symbols .pdb files.", + "This property specifies the directory into which the MS debug symbols" + "will be placed." + "This property is initialized by the value of the variable " + "CMAKE_<TAFGET_TYPE>_OUTPUT_DIRECTORY if it is set when a target is created."); + cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY_<CONFIG>", cmProperty::TARGET, + "Per-configuration output directory for MS debug symbols .pdb files.", + "This is a per-configuration version of PDB_OUTPUT_DIRECTORY, " + "but multi-configuration generators (VS, Xcode) do NOT append " + "a per-configuration subdirectory to the specified directory. " + "This property is initialized by the value of the variable " + "CMAKE_<TARGET_TYPE>_OUTPUT_DIRECTORY_<CONFIG> " + "if it is set when a target is created."); + + cm->DefineProperty ("ARCHIVE_OUTPUT_NAME", cmProperty::TARGET, "Output name for ARCHIVE target files.", "This property specifies the base name for archive target files. " @@ -1263,6 +1293,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); + this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("Fortran_FORMAT", 0); this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); this->SetPropertyDefault("GNUtoMS", 0); @@ -1282,6 +1313,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) "ARCHIVE_OUTPUT_DIRECTORY_", "LIBRARY_OUTPUT_DIRECTORY_", "RUNTIME_OUTPUT_DIRECTORY_", + "PDB_OUTPUT_DIRECTORY_", 0}; for(std::vector<std::string>::iterator ci = configNames.begin(); ci != configNames.end(); ++ci) @@ -2539,6 +2571,7 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config) OutputInfo info; this->ComputeOutputDir(config, false, info.OutDir); this->ComputeOutputDir(config, true, info.ImpDir); + this->ComputePdbOutputDir(config, info.PdbDir); OutputInfoMapType::value_type entry(config_upper, info); i = this->Internal->OutputInfoMap.insert(entry).first; } @@ -2564,6 +2597,17 @@ std::string cmTarget::GetDirectory(const char* config, bool implib) } //---------------------------------------------------------------------------- +std::string cmTarget::GetPdbDirectory(const char* config) +{ + if(OutputInfo const* info = this->GetOutputInfo(config)) + { + // Return the directory in which the target will be built. + return info->PdbDir; + } + return ""; +} + +//---------------------------------------------------------------------------- const char* cmTarget::GetLocation(const char* config) { if (this->IsImported()) @@ -3028,6 +3072,26 @@ std::string cmTarget::GetPDBName(const char* config) std::string base; std::string suffix; this->GetFullNameInternal(config, false, prefix, base, suffix); + + std::vector<std::string> props; + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + if(!configUpper.empty()) + { + // PDB_NAME_<CONFIG> + props.push_back("PDB_NAME_" + configUpper); + } + + // PDB_NAME + props.push_back("PDB_NAME"); + + for(std::vector<std::string>::const_iterator i = props.begin(); i != props.end(); ++i) + { + if(const char* outName = this->GetProperty(i->c_str())) + { + base = outName; + break; + } + } return prefix+base+".pdb"; } @@ -3412,7 +3476,7 @@ void cmTarget::GetLibraryNames(std::string& name, } // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3491,7 +3555,7 @@ void cmTarget::GetExecutableNames(std::string& name, impName = this->GetFullNameInternal(config, true); // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3570,7 +3634,7 @@ void cmTarget::GenerateTargetManifest(const char* config) } if(!pdbName.empty()) { - f = dir; + f = this->GetPdbDirectory(config); f += "/"; f += pdbName; gg->AddToManifest(config? config:"", f); @@ -3880,6 +3944,65 @@ bool cmTarget::ComputeOutputDir(const char* config, } //---------------------------------------------------------------------------- +void cmTarget::ComputePdbOutputDir(const char* config, std::string& out) +{ + // Look for a target property defining the target output directory + // based on the target type. + std::string targetTypeName = "PDB"; + const char* propertyName = 0; + std::string propertyNameStr = targetTypeName; + if(!propertyNameStr.empty()) + { + propertyNameStr += "_OUTPUT_DIRECTORY"; + propertyName = propertyNameStr.c_str(); + } + + // Check for a per-configuration output directory target property. + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + const char* configProp = 0; + std::string configPropStr = targetTypeName; + if(!configPropStr.empty()) + { + configPropStr += "_OUTPUT_DIRECTORY_"; + configPropStr += configUpper; + configProp = configPropStr.c_str(); + } + + // Select an output directory. + if(const char* config_outdir = this->GetProperty(configProp)) + { + // Use the user-specified per-configuration output directory. + out = config_outdir; + + // Skip per-configuration subdirectory. + config = 0; + } + else if(const char* outdir = this->GetProperty(propertyName)) + { + // Use the user-specified output directory. + out = outdir; + } + if(out.empty()) + { + // Default to the current output directory. + out = "."; + } + + // Convert the output path to a full path in case it is + // specified as a relative path. Treat a relative path as + // relative to the current output directory for this makefile. + out = (cmSystemTools::CollapseFullPath + (out.c_str(), this->Makefile->GetStartOutputDirectory())); + + // The generator may add the configuration's subdirectory. + if(config && *config) + { + this->Makefile->GetLocalGenerator()->GetGlobalGenerator()-> + AppendDirectoryForConfig("/", config, "", out); + } +} + +//---------------------------------------------------------------------------- bool cmTarget::UsesDefaultOutputDir(const char* config, bool implib) { std::string dir; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 98eaeec..a08a8c6 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -301,6 +301,12 @@ public: output directory is given. */ std::string GetDirectory(const char* config = 0, bool implib = false); + /** Get the directory in which this targets .pdb files will be placed. If the + configuration name is given then the generator will add its + subdirectory for that configuration. Otherwise just the canonical + pdb output directory is given. */ + std::string GetPdbDirectory(const char* config = 0); + /** Get the location of the target in the build tree for the given configuration. This location is suitable for use as the LOCATION target property. */ @@ -593,6 +599,7 @@ private: struct OutputInfo; OutputInfo const* GetOutputInfo(const char* config); bool ComputeOutputDir(const char* config, bool implib, std::string& out); + void ComputePdbOutputDir(const char* config, std::string& out); // Cache import information from properties for each configuration. struct ImportInfo; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 3d2828d..7426079 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1284,9 +1284,8 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3); if(this->Target->GetType() != cmTarget::OBJECT_LIBRARY) { - // TODO: PDB for object library? this->WriteString("<ProgramDataBaseFileName>", 3); - *this->BuildFileStream << this->Target->GetDirectory(configName.c_str()) + *this->BuildFileStream << this->Target->GetPDBDirectory(configName.c_str()) << "/" << this->Target->GetPDBName(configName.c_str()) << "</ProgramDataBaseFileName>\n"; @@ -1513,7 +1512,8 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& std::string dir = this->Target->GetDirectory(config.c_str()); dir += "/"; - std::string pdb = dir; + std::string pdb = this->Target->GetPDBDirectory(config.c_str()); + pdb += "/"; pdb += targetNamePDB; std::string imLib = this->Target->GetDirectory(config.c_str(), true); imLib += "/"; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index e03b926..4d071cb 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1259,6 +1259,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ if(CMAKE_TEST_MSVC OR "${CMAKE_TEST_GENERATOR}" MATCHES "(MSYS|MinGW) Makefiles") ADD_TEST_MACRO(ModuleDefinition example_exe) + ADD_TEST_MACRO(PDBDirectoryAndName myexe) endif() ADD_TEST_MACRO(CheckCompilerRelatedVariables CheckCompilerRelatedVariables) diff --git a/Tests/PDBDirectoryAndName/CMakeLists.txt b/Tests/PDBDirectoryAndName/CMakeLists.txt new file mode 100644 index 0000000..aa6b94b --- /dev/null +++ b/Tests/PDBDirectoryAndName/CMakeLists.txt @@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 2.8.9) +project(PDBDirectoryAndName C) + +# Make sure the proper compiler is in use. +if(NOT MSVC) + MESSAGE(FATAL_ERROR "The PDB file test works only with MSVC") +endif() + + +# Put the subproject source tree in our build tree so it can refer to +# link directories relative to its source. +if(NOT "${LinkDirectory_SOURCE_DIR}" STREQUAL "${LinkDirectory_BINARY_DIR}") + file(COPY External/ DESTINATION External PATTERN CVS EXCLUDE) +endif() + +# Build a library into the subproject source tree. +add_library(mylibA SHARED mylibA.c) +set_property(TARGET mylibA PROPERTY + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pdb" +) +get_property(mylibA TARGET mylibA PROPERTY LOCATION) + +# Build a library into our build tree relative to the subproject build tree. +add_library(mylibB SHARED mylibB.c) +set_property(TARGET mylibB PROPERTY + PDB_NAME "specialpdb" +) +get_property(mylibB TARGET mylibB PROPERTY LOCATION) + +add_executable(myexe myexe.c) +target_link_libraries(myexe mylibA mylibB) + diff --git a/Tests/PDBDirectoryAndName/myexe.c b/Tests/PDBDirectoryAndName/myexe.c new file mode 100644 index 0000000..db5a4f0 --- /dev/null +++ b/Tests/PDBDirectoryAndName/myexe.c @@ -0,0 +1,4 @@ +extern int mylibA(void); +extern int mylibB(void); +int main() { return mylibA() + mylibB(); } + diff --git a/Tests/PDBDirectoryAndName/mylibA.c b/Tests/PDBDirectoryAndName/mylibA.c new file mode 100644 index 0000000..8a0d0be --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibA.c @@ -0,0 +1,2 @@ +int mylibA() { return 1; } + diff --git a/Tests/PDBDirectoryAndName/mylibB.c b/Tests/PDBDirectoryAndName/mylibB.c new file mode 100644 index 0000000..d203bd6 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibB.c @@ -0,0 +1,2 @@ +int mylibB() { return -1; } + -- 1.7.9.5 2-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch [^] (19,686 bytes) 2012-09-22 08:30 [Show Content] [Hide Content] From 45a1f3735238ea6dfdccc1b41f23ebfe65fe312c Mon Sep 17 00:00:00 2001 From: Yuchen Deng <loaden@gmail.com> Date: Sat, 22 Sep 2012 16:46:45 +0800 Subject: [PATCH] Added PDB_OUTPUT_DIRECTORY and PDB_NAME as target properties This enables changing the name and output folder of the debug symbol files produced by MS compilers. Original Patch by: be <be@ipetronik.com> See: http://public.kitware.com/Bug/view.php?id=10830 --- Source/cmDocumentVariables.cxx | 9 ++ Source/cmLocalVisualStudio7Generator.cxx | 6 +- Source/cmMakefileExecutableTargetGenerator.cxx | 6 +- Source/cmMakefileLibraryTargetGenerator.cxx | 5 +- Source/cmMakefileTargetGenerator.cxx | 2 +- Source/cmNinjaTargetGenerator.cxx | 2 +- Source/cmTarget.cxx | 129 ++++++++++++++++++++++++- Source/cmTarget.h | 7 ++ Source/cmVisualStudio10TargetGenerator.cxx | 6 +- Tests/CMakeLists.txt | 1 + Tests/PDBDirectoryAndName/CMakeLists.txt | 29 ++++++ Tests/PDBDirectoryAndName/myexe.c | 4 + Tests/PDBDirectoryAndName/mylibA.c | 2 + Tests/PDBDirectoryAndName/mylibB.c | 2 + 14 files changed, 197 insertions(+), 13 deletions(-) create mode 100644 Tests/PDBDirectoryAndName/CMakeLists.txt create mode 100644 Tests/PDBDirectoryAndName/myexe.c create mode 100644 Tests/PDBDirectoryAndName/mylibA.c create mode 100644 Tests/PDBDirectoryAndName/mylibB.c diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 77aaffc..1bb419f 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1169,6 +1169,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables that Control the Build"); cm->DefineProperty + ("CMAKE_PDB_OUTPUT_DIRECTORY", cmProperty::VARIABLE, + "Where to put all the MS debug symbol files.", + "This variable is used to initialize the " + "PDB_OUTPUT_DIRECTORY property on all the targets. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); + + cm->DefineProperty ("CMAKE_AUTOMOC", cmProperty::VARIABLE, "Whether to handle moc automatically for Qt targets.", "This variable is used to initialize the " diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index f2ab79d..d2a5e3a 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -847,7 +847,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, // non-debug configurations because VS still creates .idb files. fout << "\t\t\t\tProgramDataBaseFileName=\"" << this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()) + target.GetPdbDirectory(configName).c_str()) << "/" << target.GetPDBName(configName) << "\"\n"; } @@ -1125,7 +1125,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, fout << "\t\t\t\tAdditionalLibraryDirectories=\""; this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; - temp = target.GetDirectory(configName); + temp = target.GetPdbDirectory(configName); temp += "/"; temp += targetNamePDB; fout << "\t\t\t\tProgramDatabaseFile=\"" << @@ -1211,7 +1211,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; std::string path = this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()); + target.GetPdbDirectory(configName).c_str()); fout << "\t\t\t\tProgramDatabaseFile=\"" << path << "/" << targetNamePDB << "\"\n"; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index ab5150a..d435ff9 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -131,9 +131,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) outpathImp += "/"; } } + + std::string pdbOutputPath = this->Target->GetPdbDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + std::string targetFullPath = outpath + targetName; std::string targetFullPathReal = outpath + targetNameReal; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + "/" + targetNamePDB; std::string targetFullPathImport = outpathImp + targetNameImport; std::string targetOutPathPDB = this->Convert(targetFullPathPDB.c_str(), diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 577e5fd..9850fcf 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -328,8 +328,11 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules } } + std::string pdbOutputPath = this->Target->GetPdbDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + std::string targetFullPath = outpath + targetName; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + "/" + targetNamePDB; std::string targetFullPathSO = outpath + targetNameSO; std::string targetFullPathReal = outpath + targetNameReal; std::string targetFullPathImport = outpathImp + targetNameImport; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 0de182e..910e1cb 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -651,7 +651,7 @@ cmMakefileTargetGenerator this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - targetFullPathPDB = this->Target->GetDirectory(this->ConfigName); + targetFullPathPDB = this->Target->GetPdbDirectory(this->ConfigName); targetFullPathPDB += "/"; targetFullPathPDB += this->Target->GetPDBName(this->ConfigName); } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 3532c8b..009cc3e 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -303,7 +303,7 @@ std::string cmNinjaTargetGenerator::GetTargetPDB() const this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - targetFullPathPDB = this->Target->GetDirectory(this->GetConfigName()); + targetFullPathPDB = this->Target->GetPdbDirectory(this->GetConfigName()); targetFullPathPDB += "/"; targetFullPathPDB += this->Target->GetPDBName(this->GetConfigName()); } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 775662c..ac7c9ee 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -57,6 +57,7 @@ struct cmTarget::OutputInfo { std::string OutDir; std::string ImpDir; + std::string PdbDir; }; //---------------------------------------------------------------------------- @@ -741,6 +742,18 @@ void cmTarget::DefineProperties(cmake *cm) "Use OUTPUT_NAME_<CONFIG> instead."); cm->DefineProperty + ("PDB_NAME", cmProperty::TARGET, + "Output name for MS debug symbols .pdb file.", + "Set the base name for debug symbols file created for an " + "executable or library target." + "If not set, the logical target name is used by default."); + + cm->DefineProperty + ("PDB_NAME_<CONFIG>", cmProperty::TARGET, + "Per-configuration name for MS debug symbols .pdb file.", + "This is the configuration-specific version of PDB_NAME."); + + cm->DefineProperty ("PRE_INSTALL_SCRIPT", cmProperty::TARGET, "Deprecated install support.", "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the " @@ -1187,6 +1200,23 @@ void cmTarget::DefineProperties(cmake *cm) CM_TARGET_OUTDIR_CONFIG_DOC(RUNTIME)); cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY", cmProperty::TARGET, + "Output directory for MS debug symbols .pdb files.", + "This property specifies the directory into which the MS debug symbols" + "will be placed." + "This property is initialized by the value of the variable " + "CMAKE_<TAFGET_TYPE>_OUTPUT_DIRECTORY if it is set when a target is created."); + cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY_<CONFIG>", cmProperty::TARGET, + "Per-configuration output directory for MS debug symbols .pdb files.", + "This is a per-configuration version of PDB_OUTPUT_DIRECTORY, " + "but multi-configuration generators (VS, Xcode) do NOT append " + "a per-configuration subdirectory to the specified directory. " + "This property is initialized by the value of the variable " + "CMAKE_<TARGET_TYPE>_OUTPUT_DIRECTORY_<CONFIG> " + "if it is set when a target is created."); + + cm->DefineProperty ("ARCHIVE_OUTPUT_NAME", cmProperty::TARGET, "Output name for ARCHIVE target files.", "This property specifies the base name for archive target files. " @@ -1260,6 +1290,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); + this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("Fortran_FORMAT", 0); this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); this->SetPropertyDefault("GNUtoMS", 0); @@ -1279,6 +1310,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) "ARCHIVE_OUTPUT_DIRECTORY_", "LIBRARY_OUTPUT_DIRECTORY_", "RUNTIME_OUTPUT_DIRECTORY_", + "PDB_OUTPUT_DIRECTORY_", 0}; for(std::vector<std::string>::iterator ci = configNames.begin(); ci != configNames.end(); ++ci) @@ -2527,6 +2559,7 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config) OutputInfo info; this->ComputeOutputDir(config, false, info.OutDir); this->ComputeOutputDir(config, true, info.ImpDir); + this->ComputePdbOutputDir(config, info.PdbDir); OutputInfoMapType::value_type entry(config_upper, info); i = this->Internal->OutputInfoMap.insert(entry).first; } @@ -2552,6 +2585,17 @@ std::string cmTarget::GetDirectory(const char* config, bool implib) } //---------------------------------------------------------------------------- +std::string cmTarget::GetPdbDirectory(const char* config) +{ + if(OutputInfo const* info = this->GetOutputInfo(config)) + { + // Return the directory in which the target will be built. + return info->PdbDir; + } + return ""; +} + +//---------------------------------------------------------------------------- const char* cmTarget::GetLocation(const char* config) { if (this->IsImported()) @@ -3016,6 +3060,26 @@ std::string cmTarget::GetPDBName(const char* config) std::string base; std::string suffix; this->GetFullNameInternal(config, false, prefix, base, suffix); + + std::vector<std::string> props; + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + if(!configUpper.empty()) + { + // PDB_NAME_<CONFIG> + props.push_back("PDB_NAME_" + configUpper); + } + + // PDB_NAME + props.push_back("PDB_NAME"); + + for(std::vector<std::string>::const_iterator i = props.begin(); i != props.end(); ++i) + { + if(const char* outName = this->GetProperty(i->c_str())) + { + base = outName; + break; + } + } return prefix+base+".pdb"; } @@ -3400,7 +3464,7 @@ void cmTarget::GetLibraryNames(std::string& name, } // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3479,7 +3543,7 @@ void cmTarget::GetExecutableNames(std::string& name, impName = this->GetFullNameInternal(config, true); // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3558,7 +3622,7 @@ void cmTarget::GenerateTargetManifest(const char* config) } if(!pdbName.empty()) { - f = dir; + f = this->GetPdbDirectory(config); f += "/"; f += pdbName; gg->AddToManifest(config? config:"", f); @@ -3868,6 +3932,65 @@ bool cmTarget::ComputeOutputDir(const char* config, } //---------------------------------------------------------------------------- +void cmTarget::ComputePdbOutputDir(const char* config, std::string& out) +{ + // Look for a target property defining the target output directory + // based on the target type. + std::string targetTypeName = "PDB"; + const char* propertyName = 0; + std::string propertyNameStr = targetTypeName; + if(!propertyNameStr.empty()) + { + propertyNameStr += "_OUTPUT_DIRECTORY"; + propertyName = propertyNameStr.c_str(); + } + + // Check for a per-configuration output directory target property. + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + const char* configProp = 0; + std::string configPropStr = targetTypeName; + if(!configPropStr.empty()) + { + configPropStr += "_OUTPUT_DIRECTORY_"; + configPropStr += configUpper; + configProp = configPropStr.c_str(); + } + + // Select an output directory. + if(const char* config_outdir = this->GetProperty(configProp)) + { + // Use the user-specified per-configuration output directory. + out = config_outdir; + + // Skip per-configuration subdirectory. + config = 0; + } + else if(const char* outdir = this->GetProperty(propertyName)) + { + // Use the user-specified output directory. + out = outdir; + } + if(out.empty()) + { + // Default to the current output directory. + out = "."; + } + + // Convert the output path to a full path in case it is + // specified as a relative path. Treat a relative path as + // relative to the current output directory for this makefile. + out = (cmSystemTools::CollapseFullPath + (out.c_str(), this->Makefile->GetStartOutputDirectory())); + + // The generator may add the configuration's subdirectory. + if(config && *config) + { + this->Makefile->GetLocalGenerator()->GetGlobalGenerator()-> + AppendDirectoryForConfig("/", config, "", out); + } +} + +//---------------------------------------------------------------------------- bool cmTarget::UsesDefaultOutputDir(const char* config, bool implib) { std::string dir; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index a89c5d9..5b1c89f 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -304,6 +304,12 @@ public: output directory is given. */ std::string GetDirectory(const char* config = 0, bool implib = false); + /** Get the directory in which this targets .pdb files will be placed. If the + configuration name is given then the generator will add its + subdirectory for that configuration. Otherwise just the canonical + pdb output directory is given. */ + std::string GetPdbDirectory(const char* config = 0); + /** Get the location of the target in the build tree for the given configuration. This location is suitable for use as the LOCATION target property. */ @@ -596,6 +602,7 @@ private: struct OutputInfo; OutputInfo const* GetOutputInfo(const char* config); bool ComputeOutputDir(const char* config, bool implib, std::string& out); + void ComputePdbOutputDir(const char* config, std::string& out); // Cache import information from properties for each configuration. struct ImportInfo; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 9a97ab0..ab1edd2 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1255,9 +1255,8 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3); if(this->Target->GetType() != cmTarget::OBJECT_LIBRARY) { - // TODO: PDB for object library? this->WriteString("<ProgramDataBaseFileName>", 3); - *this->BuildFileStream << this->Target->GetDirectory(configName.c_str()) + *this->BuildFileStream << this->Target->GetPdbDirectory(configName.c_str()) << "/" << this->Target->GetPDBName(configName.c_str()) << "</ProgramDataBaseFileName>\n"; @@ -1484,7 +1483,8 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& std::string dir = this->Target->GetDirectory(config.c_str()); dir += "/"; - std::string pdb = dir; + std::string pdb = this->Target->GetPdbDirectory(config.c_str()); + pdb += "/"; pdb += targetNamePDB; std::string imLib = this->Target->GetDirectory(config.c_str(), true); imLib += "/"; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 27ae3a0..f769d2a 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1257,6 +1257,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ IF(CMAKE_TEST_MSVC OR "${CMAKE_TEST_GENERATOR}" MATCHES "(MSYS|MinGW) Makefiles") ADD_TEST_MACRO(ModuleDefinition example_exe) + ADD_TEST_MACRO(PDBDirectoryAndName myexe) ENDIF() ADD_TEST_MACRO(CheckCompilerRelatedVariables CheckCompilerRelatedVariables) diff --git a/Tests/PDBDirectoryAndName/CMakeLists.txt b/Tests/PDBDirectoryAndName/CMakeLists.txt new file mode 100644 index 0000000..c8813ce --- /dev/null +++ b/Tests/PDBDirectoryAndName/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 2.8.9) +project(PDBDirectoryAndName C) + +# Make sure the proper compiler is in use. +if(NOT MSVC) + MESSAGE(FATAL_ERROR "The PDB file test works only with MSVC") +endif() + + +# Put the subproject source tree in our build tree so it can refer to +# link directories relative to its source. +if(NOT "${LinkDirectory_SOURCE_DIR}" STREQUAL "${LinkDirectory_BINARY_DIR}") + file(COPY External/ DESTINATION External PATTERN CVS EXCLUDE) +endif() + +# Build a library into the subproject source tree. +add_library(mylibA STATIC mylibA.c) +set_target_properties(mylibA PROPERTIES + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pdb" +) + +# Build a library into our build tree relative to the subproject build tree. +add_library(mylibB STATIC mylibB.c) +set_target_properties(mylibB PROPERTIES + PDB_NAME "specialpdb" +) + +add_executable(myexe myexe.c) +target_link_libraries(myexe mylibA mylibB) diff --git a/Tests/PDBDirectoryAndName/myexe.c b/Tests/PDBDirectoryAndName/myexe.c new file mode 100644 index 0000000..db5a4f0 --- /dev/null +++ b/Tests/PDBDirectoryAndName/myexe.c @@ -0,0 +1,4 @@ +extern int mylibA(void); +extern int mylibB(void); +int main() { return mylibA() + mylibB(); } + diff --git a/Tests/PDBDirectoryAndName/mylibA.c b/Tests/PDBDirectoryAndName/mylibA.c new file mode 100644 index 0000000..8a0d0be --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibA.c @@ -0,0 +1,2 @@ +int mylibA() { return 1; } + diff --git a/Tests/PDBDirectoryAndName/mylibB.c b/Tests/PDBDirectoryAndName/mylibB.c new file mode 100644 index 0000000..d203bd6 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibB.c @@ -0,0 +1,2 @@ +int mylibB() { return -1; } + -- 1.7.11.msysgit.1 loaden-v3-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch [^] (21,091 bytes) 2012-09-22 10:24 [Show Content] [Hide Content] From fae08fc219d6920092d871352c273fef10099421 Mon Sep 17 00:00:00 2001 From: Yuchen Deng <loaden@gmail.com> Date: Sat, 22 Sep 2012 22:21:05 +0800 Subject: [PATCH] Added PDB_OUTPUT_DIRECTORY and PDB_NAME as target properties This enables changing the name and output folder of the debug symbol files produced by MS compilers. Original Patch by: be <be@ipetronik.com> See: http://public.kitware.com/Bug/view.php?id=10830 --- Source/cmDocumentVariables.cxx | 9 ++ Source/cmLocalVisualStudio7Generator.cxx | 6 +- Source/cmMakefileExecutableTargetGenerator.cxx | 6 +- Source/cmMakefileLibraryTargetGenerator.cxx | 5 +- Source/cmMakefileTargetGenerator.cxx | 2 +- Source/cmNinjaTargetGenerator.cxx | 2 +- Source/cmTarget.cxx | 129 +++++++++++++++++++++++- Source/cmTarget.h | 7 ++ Source/cmVisualStudio10TargetGenerator.cxx | 6 +- Tests/CMakeLists.txt | 1 + Tests/PDBDirectoryAndName/CMakeLists.txt | 45 +++++++++ Tests/PDBDirectoryAndName/myexe.c | 6 ++ Tests/PDBDirectoryAndName/myexe2.c | 4 + Tests/PDBDirectoryAndName/mylibA.c | 2 + Tests/PDBDirectoryAndName/mylibB.c | 2 + Tests/PDBDirectoryAndName/mylibC.c | 2 + Tests/PDBDirectoryAndName/mylibD.c | 2 + 17 files changed, 223 insertions(+), 13 deletions(-) create mode 100644 Tests/PDBDirectoryAndName/CMakeLists.txt create mode 100644 Tests/PDBDirectoryAndName/myexe.c create mode 100644 Tests/PDBDirectoryAndName/myexe2.c create mode 100644 Tests/PDBDirectoryAndName/mylibA.c create mode 100644 Tests/PDBDirectoryAndName/mylibB.c create mode 100644 Tests/PDBDirectoryAndName/mylibC.c create mode 100644 Tests/PDBDirectoryAndName/mylibD.c diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 77aaffc..1bb419f 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1169,6 +1169,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables that Control the Build"); cm->DefineProperty + ("CMAKE_PDB_OUTPUT_DIRECTORY", cmProperty::VARIABLE, + "Where to put all the MS debug symbol files.", + "This variable is used to initialize the " + "PDB_OUTPUT_DIRECTORY property on all the targets. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); + + cm->DefineProperty ("CMAKE_AUTOMOC", cmProperty::VARIABLE, "Whether to handle moc automatically for Qt targets.", "This variable is used to initialize the " diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index f2ab79d..d2a5e3a 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -847,7 +847,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, // non-debug configurations because VS still creates .idb files. fout << "\t\t\t\tProgramDataBaseFileName=\"" << this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()) + target.GetPdbDirectory(configName).c_str()) << "/" << target.GetPDBName(configName) << "\"\n"; } @@ -1125,7 +1125,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, fout << "\t\t\t\tAdditionalLibraryDirectories=\""; this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; - temp = target.GetDirectory(configName); + temp = target.GetPdbDirectory(configName); temp += "/"; temp += targetNamePDB; fout << "\t\t\t\tProgramDatabaseFile=\"" << @@ -1211,7 +1211,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; std::string path = this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()); + target.GetPdbDirectory(configName).c_str()); fout << "\t\t\t\tProgramDatabaseFile=\"" << path << "/" << targetNamePDB << "\"\n"; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index ab5150a..d435ff9 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -131,9 +131,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) outpathImp += "/"; } } + + std::string pdbOutputPath = this->Target->GetPdbDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + std::string targetFullPath = outpath + targetName; std::string targetFullPathReal = outpath + targetNameReal; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + "/" + targetNamePDB; std::string targetFullPathImport = outpathImp + targetNameImport; std::string targetOutPathPDB = this->Convert(targetFullPathPDB.c_str(), diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 577e5fd..9850fcf 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -328,8 +328,11 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules } } + std::string pdbOutputPath = this->Target->GetPdbDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + std::string targetFullPath = outpath + targetName; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + "/" + targetNamePDB; std::string targetFullPathSO = outpath + targetNameSO; std::string targetFullPathReal = outpath + targetNameReal; std::string targetFullPathImport = outpathImp + targetNameImport; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 0de182e..910e1cb 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -651,7 +651,7 @@ cmMakefileTargetGenerator this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - targetFullPathPDB = this->Target->GetDirectory(this->ConfigName); + targetFullPathPDB = this->Target->GetPdbDirectory(this->ConfigName); targetFullPathPDB += "/"; targetFullPathPDB += this->Target->GetPDBName(this->ConfigName); } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 3532c8b..009cc3e 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -303,7 +303,7 @@ std::string cmNinjaTargetGenerator::GetTargetPDB() const this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - targetFullPathPDB = this->Target->GetDirectory(this->GetConfigName()); + targetFullPathPDB = this->Target->GetPdbDirectory(this->GetConfigName()); targetFullPathPDB += "/"; targetFullPathPDB += this->Target->GetPDBName(this->GetConfigName()); } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 775662c..ac7c9ee 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -57,6 +57,7 @@ struct cmTarget::OutputInfo { std::string OutDir; std::string ImpDir; + std::string PdbDir; }; //---------------------------------------------------------------------------- @@ -741,6 +742,18 @@ void cmTarget::DefineProperties(cmake *cm) "Use OUTPUT_NAME_<CONFIG> instead."); cm->DefineProperty + ("PDB_NAME", cmProperty::TARGET, + "Output name for MS debug symbols .pdb file.", + "Set the base name for debug symbols file created for an " + "executable or library target." + "If not set, the logical target name is used by default."); + + cm->DefineProperty + ("PDB_NAME_<CONFIG>", cmProperty::TARGET, + "Per-configuration name for MS debug symbols .pdb file.", + "This is the configuration-specific version of PDB_NAME."); + + cm->DefineProperty ("PRE_INSTALL_SCRIPT", cmProperty::TARGET, "Deprecated install support.", "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the " @@ -1187,6 +1200,23 @@ void cmTarget::DefineProperties(cmake *cm) CM_TARGET_OUTDIR_CONFIG_DOC(RUNTIME)); cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY", cmProperty::TARGET, + "Output directory for MS debug symbols .pdb files.", + "This property specifies the directory into which the MS debug symbols" + "will be placed." + "This property is initialized by the value of the variable " + "CMAKE_<TAFGET_TYPE>_OUTPUT_DIRECTORY if it is set when a target is created."); + cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY_<CONFIG>", cmProperty::TARGET, + "Per-configuration output directory for MS debug symbols .pdb files.", + "This is a per-configuration version of PDB_OUTPUT_DIRECTORY, " + "but multi-configuration generators (VS, Xcode) do NOT append " + "a per-configuration subdirectory to the specified directory. " + "This property is initialized by the value of the variable " + "CMAKE_<TARGET_TYPE>_OUTPUT_DIRECTORY_<CONFIG> " + "if it is set when a target is created."); + + cm->DefineProperty ("ARCHIVE_OUTPUT_NAME", cmProperty::TARGET, "Output name for ARCHIVE target files.", "This property specifies the base name for archive target files. " @@ -1260,6 +1290,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); + this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("Fortran_FORMAT", 0); this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); this->SetPropertyDefault("GNUtoMS", 0); @@ -1279,6 +1310,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) "ARCHIVE_OUTPUT_DIRECTORY_", "LIBRARY_OUTPUT_DIRECTORY_", "RUNTIME_OUTPUT_DIRECTORY_", + "PDB_OUTPUT_DIRECTORY_", 0}; for(std::vector<std::string>::iterator ci = configNames.begin(); ci != configNames.end(); ++ci) @@ -2527,6 +2559,7 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config) OutputInfo info; this->ComputeOutputDir(config, false, info.OutDir); this->ComputeOutputDir(config, true, info.ImpDir); + this->ComputePdbOutputDir(config, info.PdbDir); OutputInfoMapType::value_type entry(config_upper, info); i = this->Internal->OutputInfoMap.insert(entry).first; } @@ -2552,6 +2585,17 @@ std::string cmTarget::GetDirectory(const char* config, bool implib) } //---------------------------------------------------------------------------- +std::string cmTarget::GetPdbDirectory(const char* config) +{ + if(OutputInfo const* info = this->GetOutputInfo(config)) + { + // Return the directory in which the target will be built. + return info->PdbDir; + } + return ""; +} + +//---------------------------------------------------------------------------- const char* cmTarget::GetLocation(const char* config) { if (this->IsImported()) @@ -3016,6 +3060,26 @@ std::string cmTarget::GetPDBName(const char* config) std::string base; std::string suffix; this->GetFullNameInternal(config, false, prefix, base, suffix); + + std::vector<std::string> props; + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + if(!configUpper.empty()) + { + // PDB_NAME_<CONFIG> + props.push_back("PDB_NAME_" + configUpper); + } + + // PDB_NAME + props.push_back("PDB_NAME"); + + for(std::vector<std::string>::const_iterator i = props.begin(); i != props.end(); ++i) + { + if(const char* outName = this->GetProperty(i->c_str())) + { + base = outName; + break; + } + } return prefix+base+".pdb"; } @@ -3400,7 +3464,7 @@ void cmTarget::GetLibraryNames(std::string& name, } // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3479,7 +3543,7 @@ void cmTarget::GetExecutableNames(std::string& name, impName = this->GetFullNameInternal(config, true); // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3558,7 +3622,7 @@ void cmTarget::GenerateTargetManifest(const char* config) } if(!pdbName.empty()) { - f = dir; + f = this->GetPdbDirectory(config); f += "/"; f += pdbName; gg->AddToManifest(config? config:"", f); @@ -3868,6 +3932,65 @@ bool cmTarget::ComputeOutputDir(const char* config, } //---------------------------------------------------------------------------- +void cmTarget::ComputePdbOutputDir(const char* config, std::string& out) +{ + // Look for a target property defining the target output directory + // based on the target type. + std::string targetTypeName = "PDB"; + const char* propertyName = 0; + std::string propertyNameStr = targetTypeName; + if(!propertyNameStr.empty()) + { + propertyNameStr += "_OUTPUT_DIRECTORY"; + propertyName = propertyNameStr.c_str(); + } + + // Check for a per-configuration output directory target property. + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + const char* configProp = 0; + std::string configPropStr = targetTypeName; + if(!configPropStr.empty()) + { + configPropStr += "_OUTPUT_DIRECTORY_"; + configPropStr += configUpper; + configProp = configPropStr.c_str(); + } + + // Select an output directory. + if(const char* config_outdir = this->GetProperty(configProp)) + { + // Use the user-specified per-configuration output directory. + out = config_outdir; + + // Skip per-configuration subdirectory. + config = 0; + } + else if(const char* outdir = this->GetProperty(propertyName)) + { + // Use the user-specified output directory. + out = outdir; + } + if(out.empty()) + { + // Default to the current output directory. + out = "."; + } + + // Convert the output path to a full path in case it is + // specified as a relative path. Treat a relative path as + // relative to the current output directory for this makefile. + out = (cmSystemTools::CollapseFullPath + (out.c_str(), this->Makefile->GetStartOutputDirectory())); + + // The generator may add the configuration's subdirectory. + if(config && *config) + { + this->Makefile->GetLocalGenerator()->GetGlobalGenerator()-> + AppendDirectoryForConfig("/", config, "", out); + } +} + +//---------------------------------------------------------------------------- bool cmTarget::UsesDefaultOutputDir(const char* config, bool implib) { std::string dir; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index a89c5d9..5b1c89f 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -304,6 +304,12 @@ public: output directory is given. */ std::string GetDirectory(const char* config = 0, bool implib = false); + /** Get the directory in which this targets .pdb files will be placed. If the + configuration name is given then the generator will add its + subdirectory for that configuration. Otherwise just the canonical + pdb output directory is given. */ + std::string GetPdbDirectory(const char* config = 0); + /** Get the location of the target in the build tree for the given configuration. This location is suitable for use as the LOCATION target property. */ @@ -596,6 +602,7 @@ private: struct OutputInfo; OutputInfo const* GetOutputInfo(const char* config); bool ComputeOutputDir(const char* config, bool implib, std::string& out); + void ComputePdbOutputDir(const char* config, std::string& out); // Cache import information from properties for each configuration. struct ImportInfo; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 9a97ab0..ab1edd2 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1255,9 +1255,8 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3); if(this->Target->GetType() != cmTarget::OBJECT_LIBRARY) { - // TODO: PDB for object library? this->WriteString("<ProgramDataBaseFileName>", 3); - *this->BuildFileStream << this->Target->GetDirectory(configName.c_str()) + *this->BuildFileStream << this->Target->GetPdbDirectory(configName.c_str()) << "/" << this->Target->GetPDBName(configName.c_str()) << "</ProgramDataBaseFileName>\n"; @@ -1484,7 +1483,8 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& std::string dir = this->Target->GetDirectory(config.c_str()); dir += "/"; - std::string pdb = dir; + std::string pdb = this->Target->GetPdbDirectory(config.c_str()); + pdb += "/"; pdb += targetNamePDB; std::string imLib = this->Target->GetDirectory(config.c_str(), true); imLib += "/"; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 27ae3a0..f769d2a 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1257,6 +1257,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ IF(CMAKE_TEST_MSVC OR "${CMAKE_TEST_GENERATOR}" MATCHES "(MSYS|MinGW) Makefiles") ADD_TEST_MACRO(ModuleDefinition example_exe) + ADD_TEST_MACRO(PDBDirectoryAndName myexe) ENDIF() ADD_TEST_MACRO(CheckCompilerRelatedVariables CheckCompilerRelatedVariables) diff --git a/Tests/PDBDirectoryAndName/CMakeLists.txt b/Tests/PDBDirectoryAndName/CMakeLists.txt new file mode 100644 index 0000000..926b7be --- /dev/null +++ b/Tests/PDBDirectoryAndName/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 2.8.9) +project(PDBDirectoryAndName C) + +if(NOT MSVC) + MESSAGE(FATAL_ERROR "The PDB file test works only with MSVC") +endif() + +add_library(mylibA SHARED mylibA.c) +set_target_properties(mylibA PROPERTIES + PDB_NAME "mylibA_Special" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mylibA_PDB" +) + +add_library(mylibB STATIC mylibB.c) +set_target_properties(mylibB PROPERTIES + PDB_NAME "mylibB_Special" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mylibB_PDB" +) + +add_library(mylibC SHARED mylibC.c) +set_target_properties(mylibC PROPERTIES + PDB_NAME "mylibC_Special" +) + +add_library(mylibD STATIC mylibD.c) +set_target_properties(mylibD PROPERTIES + PDB_NAME "mylibD_Special" +) + +add_executable(myexe myexe.c) +set_target_properties(myexe PROPERTIES + PDB_NAME "myexe_Special" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/myexe_PDB" +) + +target_link_libraries(myexe mylibA mylibB mylibC mylibD) + +add_executable(myexe2 myexe2.c) +set_target_properties(myexe2 PROPERTIES + PDB_NAME "myexe2_Special" +) + +target_link_libraries(myexe2 mylibA mylibD) + + diff --git a/Tests/PDBDirectoryAndName/myexe.c b/Tests/PDBDirectoryAndName/myexe.c new file mode 100644 index 0000000..f6230b1 --- /dev/null +++ b/Tests/PDBDirectoryAndName/myexe.c @@ -0,0 +1,6 @@ +extern int mylibA(); +extern int mylibB(); +extern int mylibC(); +extern int mylibD(); +int main() { return mylibA() + mylibB() + mylibC() + mylibD(); } + diff --git a/Tests/PDBDirectoryAndName/myexe2.c b/Tests/PDBDirectoryAndName/myexe2.c new file mode 100644 index 0000000..5373bbd --- /dev/null +++ b/Tests/PDBDirectoryAndName/myexe2.c @@ -0,0 +1,4 @@ +extern int mylibA(); +extern int mylibD(); +int main() { return mylibA() + mylibD(); } + diff --git a/Tests/PDBDirectoryAndName/mylibA.c b/Tests/PDBDirectoryAndName/mylibA.c new file mode 100644 index 0000000..cb54437 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibA.c @@ -0,0 +1,2 @@ +__declspec(dllexport) int mylibA() { return 1; } + diff --git a/Tests/PDBDirectoryAndName/mylibB.c b/Tests/PDBDirectoryAndName/mylibB.c new file mode 100644 index 0000000..d203bd6 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibB.c @@ -0,0 +1,2 @@ +int mylibB() { return -1; } + diff --git a/Tests/PDBDirectoryAndName/mylibC.c b/Tests/PDBDirectoryAndName/mylibC.c new file mode 100644 index 0000000..fd1cc29 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibC.c @@ -0,0 +1,2 @@ +__declspec(dllexport) int mylibC() { return 1; } + diff --git a/Tests/PDBDirectoryAndName/mylibD.c b/Tests/PDBDirectoryAndName/mylibD.c new file mode 100644 index 0000000..1945360 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibD.c @@ -0,0 +1,2 @@ +int mylibD() { return -1; } + -- 1.7.9.5 loaden-V4-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch [^] (21,090 bytes) 2012-09-22 10:52 [Show Content] [Hide Content] From fd87b59cd057b00b939d769400fa32fcba3e656f Mon Sep 17 00:00:00 2001 From: Yuchen Deng <loaden@gmail.com> Date: Sat, 22 Sep 2012 22:21:05 +0800 Subject: [PATCH] Added PDB_OUTPUT_DIRECTORY and PDB_NAME as target properties This enables changing the name and output folder of the debug symbol files produced by MS compilers. Original Patch by: be <be@ipetronik.com> See: http://public.kitware.com/Bug/view.php?id=10830 --- Source/cmDocumentVariables.cxx | 9 ++ Source/cmLocalVisualStudio7Generator.cxx | 6 +- Source/cmMakefileExecutableTargetGenerator.cxx | 6 +- Source/cmMakefileLibraryTargetGenerator.cxx | 5 +- Source/cmMakefileTargetGenerator.cxx | 2 +- Source/cmNinjaTargetGenerator.cxx | 2 +- Source/cmTarget.cxx | 129 +++++++++++++++++++++++- Source/cmTarget.h | 7 ++ Source/cmVisualStudio10TargetGenerator.cxx | 6 +- Tests/CMakeLists.txt | 1 + Tests/PDBDirectoryAndName/CMakeLists.txt | 45 +++++++++ Tests/PDBDirectoryAndName/myexe.c | 6 ++ Tests/PDBDirectoryAndName/myexe2.c | 4 + Tests/PDBDirectoryAndName/mylibA.c | 2 + Tests/PDBDirectoryAndName/mylibB.c | 2 + Tests/PDBDirectoryAndName/mylibC.c | 2 + Tests/PDBDirectoryAndName/mylibD.c | 2 + 17 files changed, 223 insertions(+), 13 deletions(-) create mode 100644 Tests/PDBDirectoryAndName/CMakeLists.txt create mode 100644 Tests/PDBDirectoryAndName/myexe.c create mode 100644 Tests/PDBDirectoryAndName/myexe2.c create mode 100644 Tests/PDBDirectoryAndName/mylibA.c create mode 100644 Tests/PDBDirectoryAndName/mylibB.c create mode 100644 Tests/PDBDirectoryAndName/mylibC.c create mode 100644 Tests/PDBDirectoryAndName/mylibD.c diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 77aaffc..1bb419f 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1169,6 +1169,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables that Control the Build"); cm->DefineProperty + ("CMAKE_PDB_OUTPUT_DIRECTORY", cmProperty::VARIABLE, + "Where to put all the MS debug symbol files.", + "This variable is used to initialize the " + "PDB_OUTPUT_DIRECTORY property on all the targets. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); + + cm->DefineProperty ("CMAKE_AUTOMOC", cmProperty::VARIABLE, "Whether to handle moc automatically for Qt targets.", "This variable is used to initialize the " diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index f2ab79d..d2a5e3a 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -847,7 +847,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, // non-debug configurations because VS still creates .idb files. fout << "\t\t\t\tProgramDataBaseFileName=\"" << this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()) + target.GetPdbDirectory(configName).c_str()) << "/" << target.GetPDBName(configName) << "\"\n"; } @@ -1125,7 +1125,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, fout << "\t\t\t\tAdditionalLibraryDirectories=\""; this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; - temp = target.GetDirectory(configName); + temp = target.GetPdbDirectory(configName); temp += "/"; temp += targetNamePDB; fout << "\t\t\t\tProgramDatabaseFile=\"" << @@ -1211,7 +1211,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; std::string path = this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()); + target.GetPdbDirectory(configName).c_str()); fout << "\t\t\t\tProgramDatabaseFile=\"" << path << "/" << targetNamePDB << "\"\n"; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index ab5150a..36e7736 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -131,9 +131,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) outpathImp += "/"; } } + + std::string pdbOutputPath = this->Target->GetPDBDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + std::string targetFullPath = outpath + targetName; std::string targetFullPathReal = outpath + targetNameReal; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + "/" + targetNamePDB; std::string targetFullPathImport = outpathImp + targetNameImport; std::string targetOutPathPDB = this->Convert(targetFullPathPDB.c_str(), diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 577e5fd..cde959a 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -328,8 +328,11 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules } } + std::string pdbOutputPath = this->Target->GetPDBDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + std::string targetFullPath = outpath + targetName; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + "/" + targetNamePDB; std::string targetFullPathSO = outpath + targetNameSO; std::string targetFullPathReal = outpath + targetNameReal; std::string targetFullPathImport = outpathImp + targetNameImport; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 0de182e..85a357b 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -651,7 +651,7 @@ cmMakefileTargetGenerator this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - targetFullPathPDB = this->Target->GetDirectory(this->ConfigName); + targetFullPathPDB = this->Target->GetPDBDirectory(this->ConfigName); targetFullPathPDB += "/"; targetFullPathPDB += this->Target->GetPDBName(this->ConfigName); } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 3532c8b..b406aab 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -303,7 +303,7 @@ std::string cmNinjaTargetGenerator::GetTargetPDB() const this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - targetFullPathPDB = this->Target->GetDirectory(this->GetConfigName()); + targetFullPathPDB = this->Target->GetPDBDirectory(this->GetConfigName()); targetFullPathPDB += "/"; targetFullPathPDB += this->Target->GetPDBName(this->GetConfigName()); } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 775662c..efb6759 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -57,6 +57,7 @@ struct cmTarget::OutputInfo { std::string OutDir; std::string ImpDir; + std::string PdbDir; }; //---------------------------------------------------------------------------- @@ -741,6 +742,18 @@ void cmTarget::DefineProperties(cmake *cm) "Use OUTPUT_NAME_<CONFIG> instead."); cm->DefineProperty + ("PDB_NAME", cmProperty::TARGET, + "Output name for MS debug symbols .pdb file.", + "Set the base name for debug symbols file created for an " + "executable or library target." + "If not set, the logical target name is used by default."); + + cm->DefineProperty + ("PDB_NAME_<CONFIG>", cmProperty::TARGET, + "Per-configuration name for MS debug symbols .pdb file.", + "This is the configuration-specific version of PDB_NAME."); + + cm->DefineProperty ("PRE_INSTALL_SCRIPT", cmProperty::TARGET, "Deprecated install support.", "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the " @@ -1187,6 +1200,23 @@ void cmTarget::DefineProperties(cmake *cm) CM_TARGET_OUTDIR_CONFIG_DOC(RUNTIME)); cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY", cmProperty::TARGET, + "Output directory for MS debug symbols .pdb files.", + "This property specifies the directory into which the MS debug symbols" + "will be placed." + "This property is initialized by the value of the variable " + "CMAKE_<TAFGET_TYPE>_OUTPUT_DIRECTORY if it is set when a target is created."); + cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY_<CONFIG>", cmProperty::TARGET, + "Per-configuration output directory for MS debug symbols .pdb files.", + "This is a per-configuration version of PDB_OUTPUT_DIRECTORY, " + "but multi-configuration generators (VS, Xcode) do NOT append " + "a per-configuration subdirectory to the specified directory. " + "This property is initialized by the value of the variable " + "CMAKE_<TARGET_TYPE>_OUTPUT_DIRECTORY_<CONFIG> " + "if it is set when a target is created."); + + cm->DefineProperty ("ARCHIVE_OUTPUT_NAME", cmProperty::TARGET, "Output name for ARCHIVE target files.", "This property specifies the base name for archive target files. " @@ -1260,6 +1290,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); + this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("Fortran_FORMAT", 0); this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); this->SetPropertyDefault("GNUtoMS", 0); @@ -1279,6 +1310,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) "ARCHIVE_OUTPUT_DIRECTORY_", "LIBRARY_OUTPUT_DIRECTORY_", "RUNTIME_OUTPUT_DIRECTORY_", + "PDB_OUTPUT_DIRECTORY_", 0}; for(std::vector<std::string>::iterator ci = configNames.begin(); ci != configNames.end(); ++ci) @@ -2527,6 +2559,7 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config) OutputInfo info; this->ComputeOutputDir(config, false, info.OutDir); this->ComputeOutputDir(config, true, info.ImpDir); + this->ComputePDBOutputDir(config, info.PdbDir); OutputInfoMapType::value_type entry(config_upper, info); i = this->Internal->OutputInfoMap.insert(entry).first; } @@ -2552,6 +2585,17 @@ std::string cmTarget::GetDirectory(const char* config, bool implib) } //---------------------------------------------------------------------------- +std::string cmTarget::GetPDBDirectory(const char* config) +{ + if(OutputInfo const* info = this->GetOutputInfo(config)) + { + // Return the directory in which the target will be built. + return info->PdbDir; + } + return ""; +} + +//---------------------------------------------------------------------------- const char* cmTarget::GetLocation(const char* config) { if (this->IsImported()) @@ -3016,6 +3060,26 @@ std::string cmTarget::GetPDBName(const char* config) std::string base; std::string suffix; this->GetFullNameInternal(config, false, prefix, base, suffix); + + std::vector<std::string> props; + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + if(!configUpper.empty()) + { + // PDB_NAME_<CONFIG> + props.push_back("PDB_NAME_" + configUpper); + } + + // PDB_NAME + props.push_back("PDB_NAME"); + + for(std::vector<std::string>::const_iterator i = props.begin(); i != props.end(); ++i) + { + if(const char* outName = this->GetProperty(i->c_str())) + { + base = outName; + break; + } + } return prefix+base+".pdb"; } @@ -3400,7 +3464,7 @@ void cmTarget::GetLibraryNames(std::string& name, } // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3479,7 +3543,7 @@ void cmTarget::GetExecutableNames(std::string& name, impName = this->GetFullNameInternal(config, true); // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3558,7 +3622,7 @@ void cmTarget::GenerateTargetManifest(const char* config) } if(!pdbName.empty()) { - f = dir; + f = this->GetPDBDirectory(config); f += "/"; f += pdbName; gg->AddToManifest(config? config:"", f); @@ -3868,6 +3932,65 @@ bool cmTarget::ComputeOutputDir(const char* config, } //---------------------------------------------------------------------------- +void cmTarget::ComputePDBOutputDir(const char* config, std::string& out) +{ + // Look for a target property defining the target output directory + // based on the target type. + std::string targetTypeName = "PDB"; + const char* propertyName = 0; + std::string propertyNameStr = targetTypeName; + if(!propertyNameStr.empty()) + { + propertyNameStr += "_OUTPUT_DIRECTORY"; + propertyName = propertyNameStr.c_str(); + } + + // Check for a per-configuration output directory target property. + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + const char* configProp = 0; + std::string configPropStr = targetTypeName; + if(!configPropStr.empty()) + { + configPropStr += "_OUTPUT_DIRECTORY_"; + configPropStr += configUpper; + configProp = configPropStr.c_str(); + } + + // Select an output directory. + if(const char* config_outdir = this->GetProperty(configProp)) + { + // Use the user-specified per-configuration output directory. + out = config_outdir; + + // Skip per-configuration subdirectory. + config = 0; + } + else if(const char* outdir = this->GetProperty(propertyName)) + { + // Use the user-specified output directory. + out = outdir; + } + if(out.empty()) + { + // Default to the current output directory. + out = "."; + } + + // Convert the output path to a full path in case it is + // specified as a relative path. Treat a relative path as + // relative to the current output directory for this makefile. + out = (cmSystemTools::CollapseFullPath + (out.c_str(), this->Makefile->GetStartOutputDirectory())); + + // The generator may add the configuration's subdirectory. + if(config && *config) + { + this->Makefile->GetLocalGenerator()->GetGlobalGenerator()-> + AppendDirectoryForConfig("/", config, "", out); + } +} + +//---------------------------------------------------------------------------- bool cmTarget::UsesDefaultOutputDir(const char* config, bool implib) { std::string dir; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index a89c5d9..8eba47d 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -304,6 +304,12 @@ public: output directory is given. */ std::string GetDirectory(const char* config = 0, bool implib = false); + /** Get the directory in which this targets .pdb files will be placed. If the + configuration name is given then the generator will add its + subdirectory for that configuration. Otherwise just the canonical + pdb output directory is given. */ + std::string GetPDBDirectory(const char* config = 0); + /** Get the location of the target in the build tree for the given configuration. This location is suitable for use as the LOCATION target property. */ @@ -596,6 +602,7 @@ private: struct OutputInfo; OutputInfo const* GetOutputInfo(const char* config); bool ComputeOutputDir(const char* config, bool implib, std::string& out); + void ComputePDBOutputDir(const char* config, std::string& out); // Cache import information from properties for each configuration. struct ImportInfo; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 9a97ab0..ab1edd2 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1255,9 +1255,8 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3); if(this->Target->GetType() != cmTarget::OBJECT_LIBRARY) { - // TODO: PDB for object library? this->WriteString("<ProgramDataBaseFileName>", 3); - *this->BuildFileStream << this->Target->GetDirectory(configName.c_str()) + *this->BuildFileStream << this->Target->GetPdbDirectory(configName.c_str()) << "/" << this->Target->GetPDBName(configName.c_str()) << "</ProgramDataBaseFileName>\n"; @@ -1484,7 +1483,8 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& std::string dir = this->Target->GetDirectory(config.c_str()); dir += "/"; - std::string pdb = dir; + std::string pdb = this->Target->GetPdbDirectory(config.c_str()); + pdb += "/"; pdb += targetNamePDB; std::string imLib = this->Target->GetDirectory(config.c_str(), true); imLib += "/"; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 27ae3a0..f769d2a 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1257,6 +1257,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ IF(CMAKE_TEST_MSVC OR "${CMAKE_TEST_GENERATOR}" MATCHES "(MSYS|MinGW) Makefiles") ADD_TEST_MACRO(ModuleDefinition example_exe) + ADD_TEST_MACRO(PDBDirectoryAndName myexe) ENDIF() ADD_TEST_MACRO(CheckCompilerRelatedVariables CheckCompilerRelatedVariables) diff --git a/Tests/PDBDirectoryAndName/CMakeLists.txt b/Tests/PDBDirectoryAndName/CMakeLists.txt new file mode 100644 index 0000000..926b7be --- /dev/null +++ b/Tests/PDBDirectoryAndName/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 2.8.9) +project(PDBDirectoryAndName C) + +if(NOT MSVC) + MESSAGE(FATAL_ERROR "The PDB file test works only with MSVC") +endif() + +add_library(mylibA SHARED mylibA.c) +set_target_properties(mylibA PROPERTIES + PDB_NAME "mylibA_Special" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mylibA_PDB" +) + +add_library(mylibB STATIC mylibB.c) +set_target_properties(mylibB PROPERTIES + PDB_NAME "mylibB_Special" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mylibB_PDB" +) + +add_library(mylibC SHARED mylibC.c) +set_target_properties(mylibC PROPERTIES + PDB_NAME "mylibC_Special" +) + +add_library(mylibD STATIC mylibD.c) +set_target_properties(mylibD PROPERTIES + PDB_NAME "mylibD_Special" +) + +add_executable(myexe myexe.c) +set_target_properties(myexe PROPERTIES + PDB_NAME "myexe_Special" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/myexe_PDB" +) + +target_link_libraries(myexe mylibA mylibB mylibC mylibD) + +add_executable(myexe2 myexe2.c) +set_target_properties(myexe2 PROPERTIES + PDB_NAME "myexe2_Special" +) + +target_link_libraries(myexe2 mylibA mylibD) + + diff --git a/Tests/PDBDirectoryAndName/myexe.c b/Tests/PDBDirectoryAndName/myexe.c new file mode 100644 index 0000000..f6230b1 --- /dev/null +++ b/Tests/PDBDirectoryAndName/myexe.c @@ -0,0 +1,6 @@ +extern int mylibA(); +extern int mylibB(); +extern int mylibC(); +extern int mylibD(); +int main() { return mylibA() + mylibB() + mylibC() + mylibD(); } + diff --git a/Tests/PDBDirectoryAndName/myexe2.c b/Tests/PDBDirectoryAndName/myexe2.c new file mode 100644 index 0000000..5373bbd --- /dev/null +++ b/Tests/PDBDirectoryAndName/myexe2.c @@ -0,0 +1,4 @@ +extern int mylibA(); +extern int mylibD(); +int main() { return mylibA() + mylibD(); } + diff --git a/Tests/PDBDirectoryAndName/mylibA.c b/Tests/PDBDirectoryAndName/mylibA.c new file mode 100644 index 0000000..cb54437 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibA.c @@ -0,0 +1,2 @@ +__declspec(dllexport) int mylibA() { return 1; } + diff --git a/Tests/PDBDirectoryAndName/mylibB.c b/Tests/PDBDirectoryAndName/mylibB.c new file mode 100644 index 0000000..d203bd6 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibB.c @@ -0,0 +1,2 @@ +int mylibB() { return -1; } + diff --git a/Tests/PDBDirectoryAndName/mylibC.c b/Tests/PDBDirectoryAndName/mylibC.c new file mode 100644 index 0000000..fd1cc29 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibC.c @@ -0,0 +1,2 @@ +__declspec(dllexport) int mylibC() { return 1; } + diff --git a/Tests/PDBDirectoryAndName/mylibD.c b/Tests/PDBDirectoryAndName/mylibD.c new file mode 100644 index 0000000..1945360 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibD.c @@ -0,0 +1,2 @@ +int mylibD() { return -1; } + -- 1.7.9.5 loaden-V5-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch [^] (21,180 bytes) 2012-09-22 21:15 [Show Content] [Hide Content] From abc192af751d5569ac5bd101c47bf5124d0522c6 Mon Sep 17 00:00:00 2001 From: Yuchen Deng <loaden@gmail.com> Date: Sat, 22 Sep 2012 22:21:05 +0800 Subject: [PATCH] Added PDB_OUTPUT_DIRECTORY and PDB_NAME as target properties This enables changing the name and output folder of the debug symbol files produced by MS compilers. Original Patch by: be <be@ipetronik.com> See: http://public.kitware.com/Bug/view.php?id=10830 --- Source/cmDocumentVariables.cxx | 9 ++ Source/cmLocalVisualStudio7Generator.cxx | 6 +- Source/cmMakefileExecutableTargetGenerator.cxx | 7 +- Source/cmMakefileLibraryTargetGenerator.cxx | 6 +- Source/cmMakefileTargetGenerator.cxx | 2 +- Source/cmNinjaTargetGenerator.cxx | 2 +- Source/cmTarget.cxx | 129 +++++++++++++++++++++++- Source/cmTarget.h | 7 ++ Source/cmVisualStudio10TargetGenerator.cxx | 8 +- Tests/CMakeLists.txt | 1 + Tests/PDBDirectoryAndName/CMakeLists.txt | 43 ++++++++ Tests/PDBDirectoryAndName/myexe.c | 6 ++ Tests/PDBDirectoryAndName/myexe2.c | 4 + Tests/PDBDirectoryAndName/mylibA.c | 2 + Tests/PDBDirectoryAndName/mylibB.c | 2 + Tests/PDBDirectoryAndName/mylibC.c | 2 + Tests/PDBDirectoryAndName/mylibD.c | 2 + 17 files changed, 223 insertions(+), 15 deletions(-) create mode 100644 Tests/PDBDirectoryAndName/CMakeLists.txt create mode 100644 Tests/PDBDirectoryAndName/myexe.c create mode 100644 Tests/PDBDirectoryAndName/myexe2.c create mode 100644 Tests/PDBDirectoryAndName/mylibA.c create mode 100644 Tests/PDBDirectoryAndName/mylibB.c create mode 100644 Tests/PDBDirectoryAndName/mylibC.c create mode 100644 Tests/PDBDirectoryAndName/mylibD.c diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 77aaffc..1bb419f 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1169,6 +1169,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables that Control the Build"); cm->DefineProperty + ("CMAKE_PDB_OUTPUT_DIRECTORY", cmProperty::VARIABLE, + "Where to put all the MS debug symbol files.", + "This variable is used to initialize the " + "PDB_OUTPUT_DIRECTORY property on all the targets. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); + + cm->DefineProperty ("CMAKE_AUTOMOC", cmProperty::VARIABLE, "Whether to handle moc automatically for Qt targets.", "This variable is used to initialize the " diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index f2ab79d..c97f314 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -847,7 +847,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, // non-debug configurations because VS still creates .idb files. fout << "\t\t\t\tProgramDataBaseFileName=\"" << this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()) + target.GetPDBDirectory(configName).c_str()) << "/" << target.GetPDBName(configName) << "\"\n"; } @@ -1125,7 +1125,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, fout << "\t\t\t\tAdditionalLibraryDirectories=\""; this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; - temp = target.GetDirectory(configName); + temp = target.GetPDBDirectory(configName); temp += "/"; temp += targetNamePDB; fout << "\t\t\t\tProgramDatabaseFile=\"" << @@ -1211,7 +1211,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; std::string path = this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()); + target.GetPDBDirectory(configName).c_str()); fout << "\t\t\t\tProgramDatabaseFile=\"" << path << "/" << targetNamePDB << "\"\n"; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index ab5150a..d06dfc0 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -131,9 +131,14 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) outpathImp += "/"; } } + + std::string pdbOutputPath = this->Target->GetPDBDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + pdbOutputPath += "/"; + std::string targetFullPath = outpath + targetName; std::string targetFullPathReal = outpath + targetNameReal; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + targetNamePDB; std::string targetFullPathImport = outpathImp + targetNameImport; std::string targetOutPathPDB = this->Convert(targetFullPathPDB.c_str(), diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 577e5fd..95b71f2 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -328,8 +328,12 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules } } + std::string pdbOutputPath = this->Target->GetPDBDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + pdbOutputPath += "/"; + std::string targetFullPath = outpath + targetName; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + targetNamePDB; std::string targetFullPathSO = outpath + targetNameSO; std::string targetFullPathReal = outpath + targetNameReal; std::string targetFullPathImport = outpathImp + targetNameImport; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 0de182e..85a357b 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -651,7 +651,7 @@ cmMakefileTargetGenerator this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - targetFullPathPDB = this->Target->GetDirectory(this->ConfigName); + targetFullPathPDB = this->Target->GetPDBDirectory(this->ConfigName); targetFullPathPDB += "/"; targetFullPathPDB += this->Target->GetPDBName(this->ConfigName); } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 3532c8b..b406aab 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -303,7 +303,7 @@ std::string cmNinjaTargetGenerator::GetTargetPDB() const this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - targetFullPathPDB = this->Target->GetDirectory(this->GetConfigName()); + targetFullPathPDB = this->Target->GetPDBDirectory(this->GetConfigName()); targetFullPathPDB += "/"; targetFullPathPDB += this->Target->GetPDBName(this->GetConfigName()); } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 775662c..efb6759 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -57,6 +57,7 @@ struct cmTarget::OutputInfo { std::string OutDir; std::string ImpDir; + std::string PdbDir; }; //---------------------------------------------------------------------------- @@ -741,6 +742,18 @@ void cmTarget::DefineProperties(cmake *cm) "Use OUTPUT_NAME_<CONFIG> instead."); cm->DefineProperty + ("PDB_NAME", cmProperty::TARGET, + "Output name for MS debug symbols .pdb file.", + "Set the base name for debug symbols file created for an " + "executable or library target." + "If not set, the logical target name is used by default."); + + cm->DefineProperty + ("PDB_NAME_<CONFIG>", cmProperty::TARGET, + "Per-configuration name for MS debug symbols .pdb file.", + "This is the configuration-specific version of PDB_NAME."); + + cm->DefineProperty ("PRE_INSTALL_SCRIPT", cmProperty::TARGET, "Deprecated install support.", "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the " @@ -1187,6 +1200,23 @@ void cmTarget::DefineProperties(cmake *cm) CM_TARGET_OUTDIR_CONFIG_DOC(RUNTIME)); cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY", cmProperty::TARGET, + "Output directory for MS debug symbols .pdb files.", + "This property specifies the directory into which the MS debug symbols" + "will be placed." + "This property is initialized by the value of the variable " + "CMAKE_<TAFGET_TYPE>_OUTPUT_DIRECTORY if it is set when a target is created."); + cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY_<CONFIG>", cmProperty::TARGET, + "Per-configuration output directory for MS debug symbols .pdb files.", + "This is a per-configuration version of PDB_OUTPUT_DIRECTORY, " + "but multi-configuration generators (VS, Xcode) do NOT append " + "a per-configuration subdirectory to the specified directory. " + "This property is initialized by the value of the variable " + "CMAKE_<TARGET_TYPE>_OUTPUT_DIRECTORY_<CONFIG> " + "if it is set when a target is created."); + + cm->DefineProperty ("ARCHIVE_OUTPUT_NAME", cmProperty::TARGET, "Output name for ARCHIVE target files.", "This property specifies the base name for archive target files. " @@ -1260,6 +1290,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); + this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("Fortran_FORMAT", 0); this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); this->SetPropertyDefault("GNUtoMS", 0); @@ -1279,6 +1310,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) "ARCHIVE_OUTPUT_DIRECTORY_", "LIBRARY_OUTPUT_DIRECTORY_", "RUNTIME_OUTPUT_DIRECTORY_", + "PDB_OUTPUT_DIRECTORY_", 0}; for(std::vector<std::string>::iterator ci = configNames.begin(); ci != configNames.end(); ++ci) @@ -2527,6 +2559,7 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config) OutputInfo info; this->ComputeOutputDir(config, false, info.OutDir); this->ComputeOutputDir(config, true, info.ImpDir); + this->ComputePDBOutputDir(config, info.PdbDir); OutputInfoMapType::value_type entry(config_upper, info); i = this->Internal->OutputInfoMap.insert(entry).first; } @@ -2552,6 +2585,17 @@ std::string cmTarget::GetDirectory(const char* config, bool implib) } //---------------------------------------------------------------------------- +std::string cmTarget::GetPDBDirectory(const char* config) +{ + if(OutputInfo const* info = this->GetOutputInfo(config)) + { + // Return the directory in which the target will be built. + return info->PdbDir; + } + return ""; +} + +//---------------------------------------------------------------------------- const char* cmTarget::GetLocation(const char* config) { if (this->IsImported()) @@ -3016,6 +3060,26 @@ std::string cmTarget::GetPDBName(const char* config) std::string base; std::string suffix; this->GetFullNameInternal(config, false, prefix, base, suffix); + + std::vector<std::string> props; + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + if(!configUpper.empty()) + { + // PDB_NAME_<CONFIG> + props.push_back("PDB_NAME_" + configUpper); + } + + // PDB_NAME + props.push_back("PDB_NAME"); + + for(std::vector<std::string>::const_iterator i = props.begin(); i != props.end(); ++i) + { + if(const char* outName = this->GetProperty(i->c_str())) + { + base = outName; + break; + } + } return prefix+base+".pdb"; } @@ -3400,7 +3464,7 @@ void cmTarget::GetLibraryNames(std::string& name, } // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3479,7 +3543,7 @@ void cmTarget::GetExecutableNames(std::string& name, impName = this->GetFullNameInternal(config, true); // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3558,7 +3622,7 @@ void cmTarget::GenerateTargetManifest(const char* config) } if(!pdbName.empty()) { - f = dir; + f = this->GetPDBDirectory(config); f += "/"; f += pdbName; gg->AddToManifest(config? config:"", f); @@ -3868,6 +3932,65 @@ bool cmTarget::ComputeOutputDir(const char* config, } //---------------------------------------------------------------------------- +void cmTarget::ComputePDBOutputDir(const char* config, std::string& out) +{ + // Look for a target property defining the target output directory + // based on the target type. + std::string targetTypeName = "PDB"; + const char* propertyName = 0; + std::string propertyNameStr = targetTypeName; + if(!propertyNameStr.empty()) + { + propertyNameStr += "_OUTPUT_DIRECTORY"; + propertyName = propertyNameStr.c_str(); + } + + // Check for a per-configuration output directory target property. + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + const char* configProp = 0; + std::string configPropStr = targetTypeName; + if(!configPropStr.empty()) + { + configPropStr += "_OUTPUT_DIRECTORY_"; + configPropStr += configUpper; + configProp = configPropStr.c_str(); + } + + // Select an output directory. + if(const char* config_outdir = this->GetProperty(configProp)) + { + // Use the user-specified per-configuration output directory. + out = config_outdir; + + // Skip per-configuration subdirectory. + config = 0; + } + else if(const char* outdir = this->GetProperty(propertyName)) + { + // Use the user-specified output directory. + out = outdir; + } + if(out.empty()) + { + // Default to the current output directory. + out = "."; + } + + // Convert the output path to a full path in case it is + // specified as a relative path. Treat a relative path as + // relative to the current output directory for this makefile. + out = (cmSystemTools::CollapseFullPath + (out.c_str(), this->Makefile->GetStartOutputDirectory())); + + // The generator may add the configuration's subdirectory. + if(config && *config) + { + this->Makefile->GetLocalGenerator()->GetGlobalGenerator()-> + AppendDirectoryForConfig("/", config, "", out); + } +} + +//---------------------------------------------------------------------------- bool cmTarget::UsesDefaultOutputDir(const char* config, bool implib) { std::string dir; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index a89c5d9..8eba47d 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -304,6 +304,12 @@ public: output directory is given. */ std::string GetDirectory(const char* config = 0, bool implib = false); + /** Get the directory in which this targets .pdb files will be placed. If the + configuration name is given then the generator will add its + subdirectory for that configuration. Otherwise just the canonical + pdb output directory is given. */ + std::string GetPDBDirectory(const char* config = 0); + /** Get the location of the target in the build tree for the given configuration. This location is suitable for use as the LOCATION target property. */ @@ -596,6 +602,7 @@ private: struct OutputInfo; OutputInfo const* GetOutputInfo(const char* config); bool ComputeOutputDir(const char* config, bool implib, std::string& out); + void ComputePDBOutputDir(const char* config, std::string& out); // Cache import information from properties for each configuration. struct ImportInfo; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 9a97ab0..47a6f5e 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1255,9 +1255,8 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3); if(this->Target->GetType() != cmTarget::OBJECT_LIBRARY) { - // TODO: PDB for object library? this->WriteString("<ProgramDataBaseFileName>", 3); - *this->BuildFileStream << this->Target->GetDirectory(configName.c_str()) + *this->BuildFileStream << this->Target->GetPDBDirectory(configName.c_str()) << "/" << this->Target->GetPDBName(configName.c_str()) << "</ProgramDataBaseFileName>\n"; @@ -1482,9 +1481,8 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& config.c_str()); } - std::string dir = this->Target->GetDirectory(config.c_str()); - dir += "/"; - std::string pdb = dir; + std::string pdb = this->Target->GetPDBDirectory(config.c_str()); + pdb += "/"; pdb += targetNamePDB; std::string imLib = this->Target->GetDirectory(config.c_str(), true); imLib += "/"; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 27ae3a0..f769d2a 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1257,6 +1257,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ IF(CMAKE_TEST_MSVC OR "${CMAKE_TEST_GENERATOR}" MATCHES "(MSYS|MinGW) Makefiles") ADD_TEST_MACRO(ModuleDefinition example_exe) + ADD_TEST_MACRO(PDBDirectoryAndName myexe) ENDIF() ADD_TEST_MACRO(CheckCompilerRelatedVariables CheckCompilerRelatedVariables) diff --git a/Tests/PDBDirectoryAndName/CMakeLists.txt b/Tests/PDBDirectoryAndName/CMakeLists.txt new file mode 100644 index 0000000..ef1cae1 --- /dev/null +++ b/Tests/PDBDirectoryAndName/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 2.8) +project(PDBDirectoryAndName C) + +if(NOT MSVC) + MESSAGE(FATAL_ERROR "The PDB file test works only with MSVC") +endif() + +add_library(mylibA SHARED mylibA.c) +set_target_properties(mylibA PROPERTIES + PDB_NAME "mylibA_Special" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mylibA_PDB" +) + +add_library(mylibB STATIC mylibB.c) +set_target_properties(mylibB PROPERTIES + PDB_NAME "mylibB_Special" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mylibB_PDB" +) + +add_library(mylibC SHARED mylibC.c) +set_target_properties(mylibC PROPERTIES + PDB_NAME "mylibC_Special" +) + +add_library(mylibD STATIC mylibD.c) +set_target_properties(mylibD PROPERTIES + PDB_NAME "mylibD_Special" +) + +add_executable(myexe myexe.c) +set_target_properties(myexe PROPERTIES + PDB_NAME "myexe_Special" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/myexe_PDB" +) + +target_link_libraries(myexe mylibA mylibB mylibC mylibD) + +add_executable(myexe2 myexe2.c) +set_target_properties(myexe2 PROPERTIES + PDB_NAME "myexe2_Special" +) + +target_link_libraries(myexe2 mylibA mylibD) diff --git a/Tests/PDBDirectoryAndName/myexe.c b/Tests/PDBDirectoryAndName/myexe.c new file mode 100644 index 0000000..f6230b1 --- /dev/null +++ b/Tests/PDBDirectoryAndName/myexe.c @@ -0,0 +1,6 @@ +extern int mylibA(); +extern int mylibB(); +extern int mylibC(); +extern int mylibD(); +int main() { return mylibA() + mylibB() + mylibC() + mylibD(); } + diff --git a/Tests/PDBDirectoryAndName/myexe2.c b/Tests/PDBDirectoryAndName/myexe2.c new file mode 100644 index 0000000..5373bbd --- /dev/null +++ b/Tests/PDBDirectoryAndName/myexe2.c @@ -0,0 +1,4 @@ +extern int mylibA(); +extern int mylibD(); +int main() { return mylibA() + mylibD(); } + diff --git a/Tests/PDBDirectoryAndName/mylibA.c b/Tests/PDBDirectoryAndName/mylibA.c new file mode 100644 index 0000000..cb54437 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibA.c @@ -0,0 +1,2 @@ +__declspec(dllexport) int mylibA() { return 1; } + diff --git a/Tests/PDBDirectoryAndName/mylibB.c b/Tests/PDBDirectoryAndName/mylibB.c new file mode 100644 index 0000000..d203bd6 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibB.c @@ -0,0 +1,2 @@ +int mylibB() { return -1; } + diff --git a/Tests/PDBDirectoryAndName/mylibC.c b/Tests/PDBDirectoryAndName/mylibC.c new file mode 100644 index 0000000..fd1cc29 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibC.c @@ -0,0 +1,2 @@ +__declspec(dllexport) int mylibC() { return 1; } + diff --git a/Tests/PDBDirectoryAndName/mylibD.c b/Tests/PDBDirectoryAndName/mylibD.c new file mode 100644 index 0000000..1945360 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibD.c @@ -0,0 +1,2 @@ +int mylibD() { return -1; } + -- 1.7.9.5 loaden-V6-based-master-d550801a-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch [^] (21,331 bytes) 2012-09-24 21:32 [Show Content] [Hide Content] From 62d0717f56a60589bd04d28fff40ea9fa473232d Mon Sep 17 00:00:00 2001 From: Yuchen Deng <loaden@gmail.com> Date: Tue, 25 Sep 2012 09:30:42 +0800 Subject: [PATCH] Added PDB_OUTPUT_DIRECTORY and PDB_NAME as target properties This enables changing the name and output folder of the debug symbol files produced by MS compilers. Original Patch by: be <be@ipetronik.com> See: http://public.kitware.com/Bug/view.php?id=10830 --- Source/cmDocumentVariables.cxx | 9 ++ Source/cmLocalVisualStudio7Generator.cxx | 6 +- Source/cmMakefileExecutableTargetGenerator.cxx | 7 +- Source/cmMakefileLibraryTargetGenerator.cxx | 6 +- Source/cmMakefileTargetGenerator.cxx | 2 +- Source/cmNinjaTargetGenerator.cxx | 4 +- Source/cmTarget.cxx | 129 ++++++++++++++++++++++++- Source/cmTarget.h | 7 ++ Source/cmVisualStudio10TargetGenerator.cxx | 8 +- Tests/CMakeLists.txt | 1 + Tests/PDBDirectoryAndName/CMakeLists.txt | 43 +++++++++ Tests/PDBDirectoryAndName/myexe.c | 6 ++ Tests/PDBDirectoryAndName/myexe2.c | 4 + Tests/PDBDirectoryAndName/mylibA.c | 2 + Tests/PDBDirectoryAndName/mylibB.c | 2 + Tests/PDBDirectoryAndName/mylibC.c | 2 + Tests/PDBDirectoryAndName/mylibD.c | 2 + 17 files changed, 224 insertions(+), 16 deletions(-) create mode 100644 Tests/PDBDirectoryAndName/CMakeLists.txt create mode 100644 Tests/PDBDirectoryAndName/myexe.c create mode 100644 Tests/PDBDirectoryAndName/myexe2.c create mode 100644 Tests/PDBDirectoryAndName/mylibA.c create mode 100644 Tests/PDBDirectoryAndName/mylibB.c create mode 100644 Tests/PDBDirectoryAndName/mylibC.c create mode 100644 Tests/PDBDirectoryAndName/mylibD.c diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 5e7e081..db3d055 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1211,6 +1211,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables that Control the Build"); cm->DefineProperty + ("CMAKE_PDB_OUTPUT_DIRECTORY", cmProperty::VARIABLE, + "Where to put all the MS debug symbol files.", + "This variable is used to initialize the " + "PDB_OUTPUT_DIRECTORY property on all the targets. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); + + cm->DefineProperty ("CMAKE_AUTOMOC", cmProperty::VARIABLE, "Whether to handle moc automatically for Qt targets.", "This variable is used to initialize the " diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 2dfca02..ed17786 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -847,7 +847,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, // non-debug configurations because VS still creates .idb files. fout << "\t\t\t\tProgramDataBaseFileName=\"" << this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()) + target.GetPDBDirectory(configName).c_str()) << "/" << target.GetPDBName(configName) << "\"\n"; } @@ -1125,7 +1125,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, fout << "\t\t\t\tAdditionalLibraryDirectories=\""; this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; - temp = target.GetDirectory(configName); + temp = target.GetPDBDirectory(configName); temp += "/"; temp += targetNamePDB; fout << "\t\t\t\tProgramDatabaseFile=\"" << @@ -1211,7 +1211,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; std::string path = this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()); + target.GetPDBDirectory(configName).c_str()); fout << "\t\t\t\tProgramDatabaseFile=\"" << path << "/" << targetNamePDB << "\"\n"; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index ab5150a..d06dfc0 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -131,9 +131,14 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) outpathImp += "/"; } } + + std::string pdbOutputPath = this->Target->GetPDBDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + pdbOutputPath += "/"; + std::string targetFullPath = outpath + targetName; std::string targetFullPathReal = outpath + targetNameReal; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + targetNamePDB; std::string targetFullPathImport = outpathImp + targetNameImport; std::string targetOutPathPDB = this->Convert(targetFullPathPDB.c_str(), diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 577e5fd..95b71f2 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -328,8 +328,12 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules } } + std::string pdbOutputPath = this->Target->GetPDBDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + pdbOutputPath += "/"; + std::string targetFullPath = outpath + targetName; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + targetNamePDB; std::string targetFullPathSO = outpath + targetNameSO; std::string targetFullPathReal = outpath + targetNameReal; std::string targetFullPathImport = outpathImp + targetNameImport; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 95738c4..ab25907 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -652,7 +652,7 @@ cmMakefileTargetGenerator this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - targetFullPathPDB = this->Target->GetDirectory(this->ConfigName); + targetFullPathPDB = this->Target->GetPDBDirectory(this->ConfigName); targetFullPathPDB += "/"; targetFullPathPDB += this->Target->GetPDBName(this->ConfigName); } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 385b4a0..2456bfc 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -335,10 +335,10 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - pdbPath = this->Target->GetDirectory(this->GetConfigName()); + pdbPath = this->Target->GetPDBDirectory(this->GetConfigName()); pdbPath += "/"; pdbPath += this->Target->GetPDBName(this->GetConfigName()); - } + } vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat( ConvertToNinjaPath(pdbPath.c_str()).c_str(), diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 9a3812c..f4a6818 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -57,6 +57,7 @@ struct cmTarget::OutputInfo { std::string OutDir; std::string ImpDir; + std::string PdbDir; }; //---------------------------------------------------------------------------- @@ -741,6 +742,18 @@ void cmTarget::DefineProperties(cmake *cm) "Use OUTPUT_NAME_<CONFIG> instead."); cm->DefineProperty + ("PDB_NAME", cmProperty::TARGET, + "Output name for MS debug symbols .pdb file.", + "Set the base name for debug symbols file created for an " + "executable or library target." + "If not set, the logical target name is used by default."); + + cm->DefineProperty + ("PDB_NAME_<CONFIG>", cmProperty::TARGET, + "Per-configuration name for MS debug symbols .pdb file.", + "This is the configuration-specific version of PDB_NAME."); + + cm->DefineProperty ("PRE_INSTALL_SCRIPT", cmProperty::TARGET, "Deprecated install support.", "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the " @@ -1190,6 +1203,23 @@ void cmTarget::DefineProperties(cmake *cm) CM_TARGET_OUTDIR_CONFIG_DOC(RUNTIME)); cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY", cmProperty::TARGET, + "Output directory for MS debug symbols .pdb files.", + "This property specifies the directory into which the MS debug symbols" + "will be placed." + "This property is initialized by the value of the variable " + "CMAKE_<TAFGET_TYPE>_OUTPUT_DIRECTORY if it is set when a target is created."); + cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY_<CONFIG>", cmProperty::TARGET, + "Per-configuration output directory for MS debug symbols .pdb files.", + "This is a per-configuration version of PDB_OUTPUT_DIRECTORY, " + "but multi-configuration generators (VS, Xcode) do NOT append " + "a per-configuration subdirectory to the specified directory. " + "This property is initialized by the value of the variable " + "CMAKE_<TARGET_TYPE>_OUTPUT_DIRECTORY_<CONFIG> " + "if it is set when a target is created."); + + cm->DefineProperty ("ARCHIVE_OUTPUT_NAME", cmProperty::TARGET, "Output name for ARCHIVE target files.", "This property specifies the base name for archive target files. " @@ -1263,6 +1293,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); + this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("Fortran_FORMAT", 0); this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); this->SetPropertyDefault("GNUtoMS", 0); @@ -1282,6 +1313,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) "ARCHIVE_OUTPUT_DIRECTORY_", "LIBRARY_OUTPUT_DIRECTORY_", "RUNTIME_OUTPUT_DIRECTORY_", + "PDB_OUTPUT_DIRECTORY_", 0}; for(std::vector<std::string>::iterator ci = configNames.begin(); ci != configNames.end(); ++ci) @@ -2539,6 +2571,7 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config) OutputInfo info; this->ComputeOutputDir(config, false, info.OutDir); this->ComputeOutputDir(config, true, info.ImpDir); + this->ComputePDBOutputDir(config, info.PdbDir); OutputInfoMapType::value_type entry(config_upper, info); i = this->Internal->OutputInfoMap.insert(entry).first; } @@ -2564,6 +2597,17 @@ std::string cmTarget::GetDirectory(const char* config, bool implib) } //---------------------------------------------------------------------------- +std::string cmTarget::GetPDBDirectory(const char* config) +{ + if(OutputInfo const* info = this->GetOutputInfo(config)) + { + // Return the directory in which the target will be built. + return info->PdbDir; + } + return ""; +} + +//---------------------------------------------------------------------------- const char* cmTarget::GetLocation(const char* config) { if (this->IsImported()) @@ -3028,6 +3072,26 @@ std::string cmTarget::GetPDBName(const char* config) std::string base; std::string suffix; this->GetFullNameInternal(config, false, prefix, base, suffix); + + std::vector<std::string> props; + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + if(!configUpper.empty()) + { + // PDB_NAME_<CONFIG> + props.push_back("PDB_NAME_" + configUpper); + } + + // PDB_NAME + props.push_back("PDB_NAME"); + + for(std::vector<std::string>::const_iterator i = props.begin(); i != props.end(); ++i) + { + if(const char* outName = this->GetProperty(i->c_str())) + { + base = outName; + break; + } + } return prefix+base+".pdb"; } @@ -3412,7 +3476,7 @@ void cmTarget::GetLibraryNames(std::string& name, } // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3491,7 +3555,7 @@ void cmTarget::GetExecutableNames(std::string& name, impName = this->GetFullNameInternal(config, true); // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3570,7 +3634,7 @@ void cmTarget::GenerateTargetManifest(const char* config) } if(!pdbName.empty()) { - f = dir; + f = this->GetPDBDirectory(config); f += "/"; f += pdbName; gg->AddToManifest(config? config:"", f); @@ -3880,6 +3944,65 @@ bool cmTarget::ComputeOutputDir(const char* config, } //---------------------------------------------------------------------------- +void cmTarget::ComputePDBOutputDir(const char* config, std::string& out) +{ + // Look for a target property defining the target output directory + // based on the target type. + std::string targetTypeName = "PDB"; + const char* propertyName = 0; + std::string propertyNameStr = targetTypeName; + if(!propertyNameStr.empty()) + { + propertyNameStr += "_OUTPUT_DIRECTORY"; + propertyName = propertyNameStr.c_str(); + } + + // Check for a per-configuration output directory target property. + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + const char* configProp = 0; + std::string configPropStr = targetTypeName; + if(!configPropStr.empty()) + { + configPropStr += "_OUTPUT_DIRECTORY_"; + configPropStr += configUpper; + configProp = configPropStr.c_str(); + } + + // Select an output directory. + if(const char* config_outdir = this->GetProperty(configProp)) + { + // Use the user-specified per-configuration output directory. + out = config_outdir; + + // Skip per-configuration subdirectory. + config = 0; + } + else if(const char* outdir = this->GetProperty(propertyName)) + { + // Use the user-specified output directory. + out = outdir; + } + if(out.empty()) + { + // Default to the current output directory. + out = "."; + } + + // Convert the output path to a full path in case it is + // specified as a relative path. Treat a relative path as + // relative to the current output directory for this makefile. + out = (cmSystemTools::CollapseFullPath + (out.c_str(), this->Makefile->GetStartOutputDirectory())); + + // The generator may add the configuration's subdirectory. + if(config && *config) + { + this->Makefile->GetLocalGenerator()->GetGlobalGenerator()-> + AppendDirectoryForConfig("/", config, "", out); + } +} + +//---------------------------------------------------------------------------- bool cmTarget::UsesDefaultOutputDir(const char* config, bool implib) { std::string dir; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 98eaeec..5ecc59b 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -301,6 +301,12 @@ public: output directory is given. */ std::string GetDirectory(const char* config = 0, bool implib = false); + /** Get the directory in which this targets .pdb files will be placed. If the + configuration name is given then the generator will add its + subdirectory for that configuration. Otherwise just the canonical + pdb output directory is given. */ + std::string GetPDBDirectory(const char* config = 0); + /** Get the location of the target in the build tree for the given configuration. This location is suitable for use as the LOCATION target property. */ @@ -593,6 +599,7 @@ private: struct OutputInfo; OutputInfo const* GetOutputInfo(const char* config); bool ComputeOutputDir(const char* config, bool implib, std::string& out); + void ComputePDBOutputDir(const char* config, std::string& out); // Cache import information from properties for each configuration. struct ImportInfo; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 3d2828d..6ce3fe2 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1284,9 +1284,8 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3); if(this->Target->GetType() != cmTarget::OBJECT_LIBRARY) { - // TODO: PDB for object library? this->WriteString("<ProgramDataBaseFileName>", 3); - *this->BuildFileStream << this->Target->GetDirectory(configName.c_str()) + *this->BuildFileStream << this->Target->GetPDBDirectory(configName.c_str()) << "/" << this->Target->GetPDBName(configName.c_str()) << "</ProgramDataBaseFileName>\n"; @@ -1511,9 +1510,8 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& config.c_str()); } - std::string dir = this->Target->GetDirectory(config.c_str()); - dir += "/"; - std::string pdb = dir; + std::string pdb = this->Target->GetPDBDirectory(config.c_str()); + pdb += "/"; pdb += targetNamePDB; std::string imLib = this->Target->GetDirectory(config.c_str(), true); imLib += "/"; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index e03b926..4d071cb 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1259,6 +1259,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ if(CMAKE_TEST_MSVC OR "${CMAKE_TEST_GENERATOR}" MATCHES "(MSYS|MinGW) Makefiles") ADD_TEST_MACRO(ModuleDefinition example_exe) + ADD_TEST_MACRO(PDBDirectoryAndName myexe) endif() ADD_TEST_MACRO(CheckCompilerRelatedVariables CheckCompilerRelatedVariables) diff --git a/Tests/PDBDirectoryAndName/CMakeLists.txt b/Tests/PDBDirectoryAndName/CMakeLists.txt new file mode 100644 index 0000000..ef1cae1 --- /dev/null +++ b/Tests/PDBDirectoryAndName/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 2.8) +project(PDBDirectoryAndName C) + +if(NOT MSVC) + MESSAGE(FATAL_ERROR "The PDB file test works only with MSVC") +endif() + +add_library(mylibA SHARED mylibA.c) +set_target_properties(mylibA PROPERTIES + PDB_NAME "mylibA_Special" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mylibA_PDB" +) + +add_library(mylibB STATIC mylibB.c) +set_target_properties(mylibB PROPERTIES + PDB_NAME "mylibB_Special" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mylibB_PDB" +) + +add_library(mylibC SHARED mylibC.c) +set_target_properties(mylibC PROPERTIES + PDB_NAME "mylibC_Special" +) + +add_library(mylibD STATIC mylibD.c) +set_target_properties(mylibD PROPERTIES + PDB_NAME "mylibD_Special" +) + +add_executable(myexe myexe.c) +set_target_properties(myexe PROPERTIES + PDB_NAME "myexe_Special" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/myexe_PDB" +) + +target_link_libraries(myexe mylibA mylibB mylibC mylibD) + +add_executable(myexe2 myexe2.c) +set_target_properties(myexe2 PROPERTIES + PDB_NAME "myexe2_Special" +) + +target_link_libraries(myexe2 mylibA mylibD) diff --git a/Tests/PDBDirectoryAndName/myexe.c b/Tests/PDBDirectoryAndName/myexe.c new file mode 100644 index 0000000..f6230b1 --- /dev/null +++ b/Tests/PDBDirectoryAndName/myexe.c @@ -0,0 +1,6 @@ +extern int mylibA(); +extern int mylibB(); +extern int mylibC(); +extern int mylibD(); +int main() { return mylibA() + mylibB() + mylibC() + mylibD(); } + diff --git a/Tests/PDBDirectoryAndName/myexe2.c b/Tests/PDBDirectoryAndName/myexe2.c new file mode 100644 index 0000000..5373bbd --- /dev/null +++ b/Tests/PDBDirectoryAndName/myexe2.c @@ -0,0 +1,4 @@ +extern int mylibA(); +extern int mylibD(); +int main() { return mylibA() + mylibD(); } + diff --git a/Tests/PDBDirectoryAndName/mylibA.c b/Tests/PDBDirectoryAndName/mylibA.c new file mode 100644 index 0000000..cb54437 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibA.c @@ -0,0 +1,2 @@ +__declspec(dllexport) int mylibA() { return 1; } + diff --git a/Tests/PDBDirectoryAndName/mylibB.c b/Tests/PDBDirectoryAndName/mylibB.c new file mode 100644 index 0000000..d203bd6 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibB.c @@ -0,0 +1,2 @@ +int mylibB() { return -1; } + diff --git a/Tests/PDBDirectoryAndName/mylibC.c b/Tests/PDBDirectoryAndName/mylibC.c new file mode 100644 index 0000000..fd1cc29 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibC.c @@ -0,0 +1,2 @@ +__declspec(dllexport) int mylibC() { return 1; } + diff --git a/Tests/PDBDirectoryAndName/mylibD.c b/Tests/PDBDirectoryAndName/mylibD.c new file mode 100644 index 0000000..1945360 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibD.c @@ -0,0 +1,2 @@ +int mylibD() { return -1; } + -- 1.7.11.msysgit.1 d550801a+0001-Add-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-target-propert.patch [^] (21,380 bytes) 2012-09-25 15:26 [Show Content] [Hide Content] From 3f60dbf1484575f4c28a15c89e1af071648c8f2d Mon Sep 17 00:00:00 2001 Message-Id: <3f60dbf1484575f4c28a15c89e1af071648c8f2d.1348601067.git.brad.king@kitware.com> From: Yuchen Deng <loaden@gmail.com> Date: Tue, 25 Sep 2012 09:30:42 +0800 Subject: [PATCH 1/3] Add PDB_OUTPUT_DIRECTORY and PDB_NAME target properties (#10830) This enables changing the name and output folder of the debug symbol files produced by MS compilers. Inspired-by: Thomas Bernard <thomas.bernard@ipetronik.com> --- Source/cmDocumentVariables.cxx | 9 ++ Source/cmLocalVisualStudio7Generator.cxx | 6 +- Source/cmMakefileExecutableTargetGenerator.cxx | 7 +- Source/cmMakefileLibraryTargetGenerator.cxx | 6 +- Source/cmMakefileTargetGenerator.cxx | 2 +- Source/cmNinjaTargetGenerator.cxx | 4 +- Source/cmTarget.cxx | 131 +++++++++++++++++++++++- Source/cmTarget.h | 7 ++ Source/cmVisualStudio10TargetGenerator.cxx | 8 +- Tests/CMakeLists.txt | 1 + Tests/PDBDirectoryAndName/CMakeLists.txt | 43 ++++++++ Tests/PDBDirectoryAndName/myexe.c | 5 + Tests/PDBDirectoryAndName/myexe2.c | 3 + Tests/PDBDirectoryAndName/mylibA.c | 1 + Tests/PDBDirectoryAndName/mylibB.c | 1 + Tests/PDBDirectoryAndName/mylibC.c | 1 + Tests/PDBDirectoryAndName/mylibD.c | 1 + 17 files changed, 220 insertions(+), 16 deletions(-) create mode 100644 Tests/PDBDirectoryAndName/CMakeLists.txt create mode 100644 Tests/PDBDirectoryAndName/myexe.c create mode 100644 Tests/PDBDirectoryAndName/myexe2.c create mode 100644 Tests/PDBDirectoryAndName/mylibA.c create mode 100644 Tests/PDBDirectoryAndName/mylibB.c create mode 100644 Tests/PDBDirectoryAndName/mylibC.c create mode 100644 Tests/PDBDirectoryAndName/mylibD.c diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 5e7e081..db3d055 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1211,6 +1211,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables that Control the Build"); cm->DefineProperty + ("CMAKE_PDB_OUTPUT_DIRECTORY", cmProperty::VARIABLE, + "Where to put all the MS debug symbol files.", + "This variable is used to initialize the " + "PDB_OUTPUT_DIRECTORY property on all the targets. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); + + cm->DefineProperty ("CMAKE_AUTOMOC", cmProperty::VARIABLE, "Whether to handle moc automatically for Qt targets.", "This variable is used to initialize the " diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 2dfca02..ed17786 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -847,7 +847,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, // non-debug configurations because VS still creates .idb files. fout << "\t\t\t\tProgramDataBaseFileName=\"" << this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()) + target.GetPDBDirectory(configName).c_str()) << "/" << target.GetPDBName(configName) << "\"\n"; } @@ -1125,7 +1125,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, fout << "\t\t\t\tAdditionalLibraryDirectories=\""; this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; - temp = target.GetDirectory(configName); + temp = target.GetPDBDirectory(configName); temp += "/"; temp += targetNamePDB; fout << "\t\t\t\tProgramDatabaseFile=\"" << @@ -1211,7 +1211,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; std::string path = this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()); + target.GetPDBDirectory(configName).c_str()); fout << "\t\t\t\tProgramDatabaseFile=\"" << path << "/" << targetNamePDB << "\"\n"; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index ab5150a..d06dfc0 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -131,9 +131,14 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) outpathImp += "/"; } } + + std::string pdbOutputPath = this->Target->GetPDBDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + pdbOutputPath += "/"; + std::string targetFullPath = outpath + targetName; std::string targetFullPathReal = outpath + targetNameReal; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + targetNamePDB; std::string targetFullPathImport = outpathImp + targetNameImport; std::string targetOutPathPDB = this->Convert(targetFullPathPDB.c_str(), diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 577e5fd..95b71f2 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -328,8 +328,12 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules } } + std::string pdbOutputPath = this->Target->GetPDBDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + pdbOutputPath += "/"; + std::string targetFullPath = outpath + targetName; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + targetNamePDB; std::string targetFullPathSO = outpath + targetNameSO; std::string targetFullPathReal = outpath + targetNameReal; std::string targetFullPathImport = outpathImp + targetNameImport; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 95738c4..ab25907 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -652,7 +652,7 @@ cmMakefileTargetGenerator this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - targetFullPathPDB = this->Target->GetDirectory(this->ConfigName); + targetFullPathPDB = this->Target->GetPDBDirectory(this->ConfigName); targetFullPathPDB += "/"; targetFullPathPDB += this->Target->GetPDBName(this->ConfigName); } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 385b4a0..2456bfc 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -335,10 +335,10 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - pdbPath = this->Target->GetDirectory(this->GetConfigName()); + pdbPath = this->Target->GetPDBDirectory(this->GetConfigName()); pdbPath += "/"; pdbPath += this->Target->GetPDBName(this->GetConfigName()); - } + } vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat( ConvertToNinjaPath(pdbPath.c_str()).c_str(), diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 9a3812c..b932afc 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -57,6 +57,7 @@ struct cmTarget::OutputInfo { std::string OutDir; std::string ImpDir; + std::string PdbDir; }; //---------------------------------------------------------------------------- @@ -741,6 +742,18 @@ void cmTarget::DefineProperties(cmake *cm) "Use OUTPUT_NAME_<CONFIG> instead."); cm->DefineProperty + ("PDB_NAME", cmProperty::TARGET, + "Output name for MS debug symbols .pdb file.", + "Set the base name for debug symbols file created for an " + "executable or library target. " + "If not set, the logical target name is used by default."); + + cm->DefineProperty + ("PDB_NAME_<CONFIG>", cmProperty::TARGET, + "Per-configuration name for MS debug symbols .pdb file. ", + "This is the configuration-specific version of PDB_NAME."); + + cm->DefineProperty ("PRE_INSTALL_SCRIPT", cmProperty::TARGET, "Deprecated install support.", "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the " @@ -1190,6 +1203,23 @@ void cmTarget::DefineProperties(cmake *cm) CM_TARGET_OUTDIR_CONFIG_DOC(RUNTIME)); cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY", cmProperty::TARGET, + "Output directory for MS debug symbols .pdb files.", + "This property specifies the directory into which the MS debug symbols " + "will be placed. " + "This property is initialized by the value of the variable " + "CMAKE_PDB_OUTPUT_DIRECTORY if it is set when a target is created."); + cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY_<CONFIG>", cmProperty::TARGET, + "Per-configuration output directory for MS debug symbols .pdb files.", + "This is a per-configuration version of PDB_OUTPUT_DIRECTORY, " + "but multi-configuration generators (VS, Xcode) do NOT append " + "a per-configuration subdirectory to the specified directory. " + "This property is initialized by the value of the variable " + "CMAKE_PDB_OUTPUT_DIRECTORY_<CONFIG> " + "if it is set when a target is created."); + + cm->DefineProperty ("ARCHIVE_OUTPUT_NAME", cmProperty::TARGET, "Output name for ARCHIVE target files.", "This property specifies the base name for archive target files. " @@ -1263,6 +1293,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); + this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("Fortran_FORMAT", 0); this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); this->SetPropertyDefault("GNUtoMS", 0); @@ -1282,6 +1313,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) "ARCHIVE_OUTPUT_DIRECTORY_", "LIBRARY_OUTPUT_DIRECTORY_", "RUNTIME_OUTPUT_DIRECTORY_", + "PDB_OUTPUT_DIRECTORY_", 0}; for(std::vector<std::string>::iterator ci = configNames.begin(); ci != configNames.end(); ++ci) @@ -2539,6 +2571,7 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config) OutputInfo info; this->ComputeOutputDir(config, false, info.OutDir); this->ComputeOutputDir(config, true, info.ImpDir); + this->ComputePDBOutputDir(config, info.PdbDir); OutputInfoMapType::value_type entry(config_upper, info); i = this->Internal->OutputInfoMap.insert(entry).first; } @@ -2564,6 +2597,17 @@ std::string cmTarget::GetDirectory(const char* config, bool implib) } //---------------------------------------------------------------------------- +std::string cmTarget::GetPDBDirectory(const char* config) +{ + if(OutputInfo const* info = this->GetOutputInfo(config)) + { + // Return the directory in which the target will be built. + return info->PdbDir; + } + return ""; +} + +//---------------------------------------------------------------------------- const char* cmTarget::GetLocation(const char* config) { if (this->IsImported()) @@ -3028,6 +3072,28 @@ std::string cmTarget::GetPDBName(const char* config) std::string base; std::string suffix; this->GetFullNameInternal(config, false, prefix, base, suffix); + + std::vector<std::string> props; + std::string configUpper = + cmSystemTools::UpperCase(config? config : ""); + if(!configUpper.empty()) + { + // PDB_NAME_<CONFIG> + props.push_back("PDB_NAME_" + configUpper); + } + + // PDB_NAME + props.push_back("PDB_NAME"); + + for(std::vector<std::string>::const_iterator i = props.begin(); + i != props.end(); ++i) + { + if(const char* outName = this->GetProperty(i->c_str())) + { + base = outName; + break; + } + } return prefix+base+".pdb"; } @@ -3412,7 +3478,7 @@ void cmTarget::GetLibraryNames(std::string& name, } // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3491,7 +3557,7 @@ void cmTarget::GetExecutableNames(std::string& name, impName = this->GetFullNameInternal(config, true); // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3570,7 +3636,7 @@ void cmTarget::GenerateTargetManifest(const char* config) } if(!pdbName.empty()) { - f = dir; + f = this->GetPDBDirectory(config); f += "/"; f += pdbName; gg->AddToManifest(config? config:"", f); @@ -3880,6 +3946,65 @@ bool cmTarget::ComputeOutputDir(const char* config, } //---------------------------------------------------------------------------- +void cmTarget::ComputePDBOutputDir(const char* config, std::string& out) +{ + // Look for a target property defining the target output directory + // based on the target type. + std::string targetTypeName = "PDB"; + const char* propertyName = 0; + std::string propertyNameStr = targetTypeName; + if(!propertyNameStr.empty()) + { + propertyNameStr += "_OUTPUT_DIRECTORY"; + propertyName = propertyNameStr.c_str(); + } + + // Check for a per-configuration output directory target property. + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + const char* configProp = 0; + std::string configPropStr = targetTypeName; + if(!configPropStr.empty()) + { + configPropStr += "_OUTPUT_DIRECTORY_"; + configPropStr += configUpper; + configProp = configPropStr.c_str(); + } + + // Select an output directory. + if(const char* config_outdir = this->GetProperty(configProp)) + { + // Use the user-specified per-configuration output directory. + out = config_outdir; + + // Skip per-configuration subdirectory. + config = 0; + } + else if(const char* outdir = this->GetProperty(propertyName)) + { + // Use the user-specified output directory. + out = outdir; + } + if(out.empty()) + { + // Default to the current output directory. + out = "."; + } + + // Convert the output path to a full path in case it is + // specified as a relative path. Treat a relative path as + // relative to the current output directory for this makefile. + out = (cmSystemTools::CollapseFullPath + (out.c_str(), this->Makefile->GetStartOutputDirectory())); + + // The generator may add the configuration's subdirectory. + if(config && *config) + { + this->Makefile->GetLocalGenerator()->GetGlobalGenerator()-> + AppendDirectoryForConfig("/", config, "", out); + } +} + +//---------------------------------------------------------------------------- bool cmTarget::UsesDefaultOutputDir(const char* config, bool implib) { std::string dir; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 98eaeec..e1a9de7 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -301,6 +301,12 @@ public: output directory is given. */ std::string GetDirectory(const char* config = 0, bool implib = false); + /** Get the directory in which this targets .pdb files will be placed. + If the configuration name is given then the generator will add its + subdirectory for that configuration. Otherwise just the canonical + pdb output directory is given. */ + std::string GetPDBDirectory(const char* config = 0); + /** Get the location of the target in the build tree for the given configuration. This location is suitable for use as the LOCATION target property. */ @@ -593,6 +599,7 @@ private: struct OutputInfo; OutputInfo const* GetOutputInfo(const char* config); bool ComputeOutputDir(const char* config, bool implib, std::string& out); + void ComputePDBOutputDir(const char* config, std::string& out); // Cache import information from properties for each configuration. struct ImportInfo; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 3d2828d..6ce3fe2 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1284,9 +1284,8 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3); if(this->Target->GetType() != cmTarget::OBJECT_LIBRARY) { - // TODO: PDB for object library? this->WriteString("<ProgramDataBaseFileName>", 3); - *this->BuildFileStream << this->Target->GetDirectory(configName.c_str()) + *this->BuildFileStream << this->Target->GetPDBDirectory(configName.c_str()) << "/" << this->Target->GetPDBName(configName.c_str()) << "</ProgramDataBaseFileName>\n"; @@ -1511,9 +1510,8 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& config.c_str()); } - std::string dir = this->Target->GetDirectory(config.c_str()); - dir += "/"; - std::string pdb = dir; + std::string pdb = this->Target->GetPDBDirectory(config.c_str()); + pdb += "/"; pdb += targetNamePDB; std::string imLib = this->Target->GetDirectory(config.c_str(), true); imLib += "/"; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index e03b926..4d071cb 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1259,6 +1259,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ if(CMAKE_TEST_MSVC OR "${CMAKE_TEST_GENERATOR}" MATCHES "(MSYS|MinGW) Makefiles") ADD_TEST_MACRO(ModuleDefinition example_exe) + ADD_TEST_MACRO(PDBDirectoryAndName myexe) endif() ADD_TEST_MACRO(CheckCompilerRelatedVariables CheckCompilerRelatedVariables) diff --git a/Tests/PDBDirectoryAndName/CMakeLists.txt b/Tests/PDBDirectoryAndName/CMakeLists.txt new file mode 100644 index 0000000..ef1cae1 --- /dev/null +++ b/Tests/PDBDirectoryAndName/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 2.8) +project(PDBDirectoryAndName C) + +if(NOT MSVC) + MESSAGE(FATAL_ERROR "The PDB file test works only with MSVC") +endif() + +add_library(mylibA SHARED mylibA.c) +set_target_properties(mylibA PROPERTIES + PDB_NAME "mylibA_Special" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mylibA_PDB" +) + +add_library(mylibB STATIC mylibB.c) +set_target_properties(mylibB PROPERTIES + PDB_NAME "mylibB_Special" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mylibB_PDB" +) + +add_library(mylibC SHARED mylibC.c) +set_target_properties(mylibC PROPERTIES + PDB_NAME "mylibC_Special" +) + +add_library(mylibD STATIC mylibD.c) +set_target_properties(mylibD PROPERTIES + PDB_NAME "mylibD_Special" +) + +add_executable(myexe myexe.c) +set_target_properties(myexe PROPERTIES + PDB_NAME "myexe_Special" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/myexe_PDB" +) + +target_link_libraries(myexe mylibA mylibB mylibC mylibD) + +add_executable(myexe2 myexe2.c) +set_target_properties(myexe2 PROPERTIES + PDB_NAME "myexe2_Special" +) + +target_link_libraries(myexe2 mylibA mylibD) diff --git a/Tests/PDBDirectoryAndName/myexe.c b/Tests/PDBDirectoryAndName/myexe.c new file mode 100644 index 0000000..c6d9065 --- /dev/null +++ b/Tests/PDBDirectoryAndName/myexe.c @@ -0,0 +1,5 @@ +extern int mylibA(); +extern int mylibB(); +extern int mylibC(); +extern int mylibD(); +int main() { return mylibA() + mylibB() + mylibC() + mylibD(); } diff --git a/Tests/PDBDirectoryAndName/myexe2.c b/Tests/PDBDirectoryAndName/myexe2.c new file mode 100644 index 0000000..75b39cd --- /dev/null +++ b/Tests/PDBDirectoryAndName/myexe2.c @@ -0,0 +1,3 @@ +extern int mylibA(); +extern int mylibD(); +int main() { return mylibA() + mylibD(); } diff --git a/Tests/PDBDirectoryAndName/mylibA.c b/Tests/PDBDirectoryAndName/mylibA.c new file mode 100644 index 0000000..f4c553f --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibA.c @@ -0,0 +1 @@ +__declspec(dllexport) int mylibA() { return 1; } diff --git a/Tests/PDBDirectoryAndName/mylibB.c b/Tests/PDBDirectoryAndName/mylibB.c new file mode 100644 index 0000000..2040c67 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibB.c @@ -0,0 +1 @@ +int mylibB() { return -1; } diff --git a/Tests/PDBDirectoryAndName/mylibC.c b/Tests/PDBDirectoryAndName/mylibC.c new file mode 100644 index 0000000..adf7c70 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibC.c @@ -0,0 +1 @@ +__declspec(dllexport) int mylibC() { return 1; } diff --git a/Tests/PDBDirectoryAndName/mylibD.c b/Tests/PDBDirectoryAndName/mylibD.c new file mode 100644 index 0000000..efa8a82 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibD.c @@ -0,0 +1 @@ +int mylibD() { return -1; } -- 1.7.10.4 d550801a+0002-Verify-that-PDB_-NAME-OUTPUT_DIRECTORY-are-honored-i.patch [^] (3,550 bytes) 2012-09-25 15:26 [Show Content] [Hide Content] From b294457e2b96f40d01a22b867666277495977fa8 Mon Sep 17 00:00:00 2001 Message-Id: <b294457e2b96f40d01a22b867666277495977fa8.1348601067.git.brad.king@kitware.com> In-Reply-To: <3f60dbf1484575f4c28a15c89e1af071648c8f2d.1348601067.git.brad.king@kitware.com> References: <3f60dbf1484575f4c28a15c89e1af071648c8f2d.1348601067.git.brad.king@kitware.com> From: Brad King <brad.king@kitware.com> Date: Tue, 25 Sep 2012 14:29:41 -0400 Subject: [PATCH 2/3] Verify that PDB_(NAME|OUTPUT_DIRECTORY) are honored in test Teach the PDBDirectoryAndName test to check that the .pdb files appear where expected. --- Tests/PDBDirectoryAndName/CMakeLists.txt | 26 ++++++++++++++++++++++++++ Tests/PDBDirectoryAndName/check_pdbs.cmake | 10 ++++++++++ 2 files changed, 36 insertions(+) create mode 100644 Tests/PDBDirectoryAndName/check_pdbs.cmake diff --git a/Tests/PDBDirectoryAndName/CMakeLists.txt b/Tests/PDBDirectoryAndName/CMakeLists.txt index ef1cae1..a9d46ca 100644 --- a/Tests/PDBDirectoryAndName/CMakeLists.txt +++ b/Tests/PDBDirectoryAndName/CMakeLists.txt @@ -5,33 +5,40 @@ if(NOT MSVC) MESSAGE(FATAL_ERROR "The PDB file test works only with MSVC") endif() +set(my_targets "") + add_library(mylibA SHARED mylibA.c) set_target_properties(mylibA PROPERTIES PDB_NAME "mylibA_Special" PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mylibA_PDB" ) +list(APPEND my_targets mylibA) add_library(mylibB STATIC mylibB.c) set_target_properties(mylibB PROPERTIES PDB_NAME "mylibB_Special" PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mylibB_PDB" ) +list(APPEND my_targets mylibB) add_library(mylibC SHARED mylibC.c) set_target_properties(mylibC PROPERTIES PDB_NAME "mylibC_Special" ) +list(APPEND my_targets mylibC) add_library(mylibD STATIC mylibD.c) set_target_properties(mylibD PROPERTIES PDB_NAME "mylibD_Special" ) +list(APPEND my_targets mylibD) add_executable(myexe myexe.c) set_target_properties(myexe PROPERTIES PDB_NAME "myexe_Special" PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/myexe_PDB" ) +list(APPEND my_targets myexe) target_link_libraries(myexe mylibA mylibB mylibC mylibD) @@ -39,5 +46,24 @@ add_executable(myexe2 myexe2.c) set_target_properties(myexe2 PROPERTIES PDB_NAME "myexe2_Special" ) +list(APPEND my_targets myexe2) target_link_libraries(myexe2 mylibA mylibD) + +#----------------------------------------------------------------------------- +# Check that PDB files actually appear where expected. + +set(pdbs "") +foreach(t ${my_targets}) + get_property(pdb_name TARGET ${t} PROPERTY PDB_NAME) + get_property(pdb_dir TARGET ${t} PROPERTY PDB_OUTPUT_DIRECTORY) + if(NOT pdb_dir) + set(pdb_dir ${CMAKE_CURRENT_BINARY_DIR}) + endif() + list(APPEND pdbs ${pdb_dir}/${CMAKE_CFG_INTDIR}/${pdb_name}.pdb) +endforeach() +add_custom_target(check_pdbs ALL VERBATIM + COMMAND ${CMAKE_COMMAND} -Dconfig=$<CONFIGURATION> "-Dpdbs=${pdbs}" + -P ${CMAKE_CURRENT_SOURCE_DIR}/check_pdbs.cmake + ) +add_dependencies(check_pdbs ${my_targets}) diff --git a/Tests/PDBDirectoryAndName/check_pdbs.cmake b/Tests/PDBDirectoryAndName/check_pdbs.cmake new file mode 100644 index 0000000..89cdb3c --- /dev/null +++ b/Tests/PDBDirectoryAndName/check_pdbs.cmake @@ -0,0 +1,10 @@ +if(NOT "${config}" MATCHES "[Dd][Ee][Bb]") + return() +endif() +foreach(pdb ${pdbs}) + if(EXISTS "${pdb}") + message(STATUS "PDB Exists: ${pdb}") + else() + message(SEND_ERROR "PDB MISSING: ${pdb}") + endif() +endforeach() -- 1.7.10.4 d550801a+0003-Document-that-PDB_-NAME-OUTPUT_DIRECTORY-are-ignored.patch [^] (3,512 bytes) 2012-09-25 15:26 [Show Content] [Hide Content] From efc83b369b26624e7f0fb90d9125ef5ec6d1f7fa Mon Sep 17 00:00:00 2001 Message-Id: <efc83b369b26624e7f0fb90d9125ef5ec6d1f7fa.1348601067.git.brad.king@kitware.com> In-Reply-To: <3f60dbf1484575f4c28a15c89e1af071648c8f2d.1348601067.git.brad.king@kitware.com> References: <3f60dbf1484575f4c28a15c89e1af071648c8f2d.1348601067.git.brad.king@kitware.com> From: Brad King <brad.king@kitware.com> Date: Tue, 25 Sep 2012 14:36:03 -0400 Subject: [PATCH 3/3] Document that PDB_(NAME|OUTPUT_DIRECTORY) are ignored for VS 6 --- Source/cmTarget.cxx | 16 ++++++++++++---- Tests/PDBDirectoryAndName/CMakeLists.txt | 5 +++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index b932afc..64950d8 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -746,12 +746,16 @@ void cmTarget::DefineProperties(cmake *cm) "Output name for MS debug symbols .pdb file.", "Set the base name for debug symbols file created for an " "executable or library target. " - "If not set, the logical target name is used by default."); + "If not set, the logical target name is used by default. " + "\n" + "This property is not implemented by the Visual Studio 6 generator."); cm->DefineProperty ("PDB_NAME_<CONFIG>", cmProperty::TARGET, "Per-configuration name for MS debug symbols .pdb file. ", - "This is the configuration-specific version of PDB_NAME."); + "This is the configuration-specific version of PDB_NAME. " + "\n" + "This property is not implemented by the Visual Studio 6 generator."); cm->DefineProperty ("PRE_INSTALL_SCRIPT", cmProperty::TARGET, @@ -1208,7 +1212,9 @@ void cmTarget::DefineProperties(cmake *cm) "This property specifies the directory into which the MS debug symbols " "will be placed. " "This property is initialized by the value of the variable " - "CMAKE_PDB_OUTPUT_DIRECTORY if it is set when a target is created."); + "CMAKE_PDB_OUTPUT_DIRECTORY if it is set when a target is created." + "\n" + "This property is not implemented by the Visual Studio 6 generator."); cm->DefineProperty ("PDB_OUTPUT_DIRECTORY_<CONFIG>", cmProperty::TARGET, "Per-configuration output directory for MS debug symbols .pdb files.", @@ -1217,7 +1223,9 @@ void cmTarget::DefineProperties(cmake *cm) "a per-configuration subdirectory to the specified directory. " "This property is initialized by the value of the variable " "CMAKE_PDB_OUTPUT_DIRECTORY_<CONFIG> " - "if it is set when a target is created."); + "if it is set when a target is created." + "\n" + "This property is not implemented by the Visual Studio 6 generator."); cm->DefineProperty ("ARCHIVE_OUTPUT_NAME", cmProperty::TARGET, diff --git a/Tests/PDBDirectoryAndName/CMakeLists.txt b/Tests/PDBDirectoryAndName/CMakeLists.txt index a9d46ca..865d278 100644 --- a/Tests/PDBDirectoryAndName/CMakeLists.txt +++ b/Tests/PDBDirectoryAndName/CMakeLists.txt @@ -53,6 +53,11 @@ target_link_libraries(myexe2 mylibA mylibD) #----------------------------------------------------------------------------- # Check that PDB files actually appear where expected. +# The PDB_NAME and PDB_OUTPUT_DIRECTORY options do not work in VS 6. +if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6") + return() +endif() + set(pdbs "") foreach(t ${my_targets}) get_property(pdb_name TARGET ${t} PROPERTY PDB_NAME) -- 1.7.10.4 | ||||||||
Relationships | |||||||||||
|
Relationships |
Notes | |
(0021064) Andreas Johansen (reporter) 2010-06-17 09:52 edited on: 2010-06-17 10:17 |
Attached a patch that adds "DEBUG_SYMBOLS_NAME" property for a target. When set, the VS7 generator will use this for the name of the .pdb file. Tested with VS2008. |
(0023693) Nodrev (reporter) 2010-12-03 09:39 |
Problem still exist, no options are provided |
(0024153) Brad King (manager) 2010-12-15 10:21 |
I propose patch 0001-Add-target-property-PDB_NAME-to-set-MS-.pdb-names.patch instead. I'd like to name the property "PDB_NAME" for now to reserve the name "SYMBOLS_NAME" until we have first-class support for debug symbol files on a cross-platform basis. Meanwhile, please apply my version of the patch locally and amend it to add a test (possibly modifying one of the existing tests). |
(0025064) Thomas Bernard (reporter) 2011-01-25 03:34 |
May I propose a small variation of your other patch in order to be able to set the whole PDB file path using the PDB_NAME target property. |
(0025068) Brad King (manager) 2011-01-25 08:54 |
0010830:0025064: That would not be consistent with all the other properties ending in "_NAME". To accomplish that we would need a new "SYMBOLS_OUTPUT_DIRECTORY" (matching "SYMBOLS_NAME") similar to the current RUNTIME_OUTPUT_DIRECTORY, LIBRARY_OUTPUT_DIRECTORY, and ARCHIVE_OUTPUT_DIRECTORY properties. The advantage of a separate property for the directory is that it can be set for all targets by setting CMAKE_SYMBOLS_OUTPUT_DIRECTORY as a variable before creating targets. That makes it easy to put all .pdb files together. Again, however, until we have full cross-platform debug symbol file support the name "SYMBOLS_" should be reserved. Therefore the name should be PDB_OUTPUT_DIRECTORY for now. Can anyone pick up the patch mentioned in 0010830:0024153 and add the requested test? |
(0025120) Thomas Bernard (reporter) 2011-01-28 08:42 |
The patch 0001-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch is an improved version of the PDB_NAME patch which also implements the PDB_OUTPUT_DIRECTORY logic suggested by Brad. I added a test for the properties but I don't know how the make the test fail if the pdb file names don't match what is expected. I've checked that manually for nmake, VS 2008 and 2010 targets. The test at least makes sure the targets using the properties can be build. |
(0025123) Brad King (manager) 2011-01-28 10:32 |
0010830:0025120: Thanks, Thomas! I look forward to reviewing the patch as soon as I get a chance. |
(0025599) Brad King (manager) 2011-02-28 10:11 |
Issue 0011899 brings up a complicating factor. There is a distinction between the .pdb files generated by the compiler and those generated by the linker. The compiler-generated pdb is temporary for .dll and .exe targets so the output name/directory applies to that generated by the linker. However, for static libraries the compiler-generated pdb file *is* the .pdb file that goes with the static (.lib) library. |
(0030479) Brad King (manager) 2012-08-13 10:36 |
Sending issues I'm not actively working on to the backlog to await someone with time for them. If an issue you care about is sent to the backlog when you feel it should have been addressed in a different manner, please bring it up on the CMake mailing list for discussion. Sign up for the mailing list here, if you're not already on it: http://www.cmake.org/mailman/listinfo/cmake [^] It's easy to re-activate a bug here if you can find a CMake developer or contributor who has the bandwidth to take it on. |
(0030961) Yuchen Deng (reporter) 2012-09-09 00:20 |
I need change the pdb filename to support share PCH file using MSVC. For now I can't find any valid way. Can this patch still has chance to applied? |
(0031084) Yuchen Deng (reporter) 2012-09-22 04:54 |
Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch [^] (19,057 bytes) 2012-09-22 04:48 Rebase + cleanup + code_style_fix + test:STATIC->SHARED changed. |
(0031085) Yuchen Deng (reporter) 2012-09-22 08:31 |
2-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch Test can passed for STATIC lib. But still failed for SHARED library. Because can't create the .lib files. |
(0031086) Yuchen Deng (reporter) 2012-09-22 10:26 |
loaden-v3-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch [^] (21,091 bytes) 2012-09-22 10:24 [Show Content] Should works well now. Fix all issue as I know. Add Nanja Generator support. Only tested on Command Line (Windows SDK 7.1). |
(0031087) Yuchen Deng (reporter) 2012-09-22 10:53 |
loaden-V4-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch [^] (21,090 bytes) 2012-09-22 10:52 Pdb -> PDB |
(0031088) Yuchen Deng (reporter) 2012-09-22 21:16 |
loaden-V5-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch [^] (21,180 bytes) 2012-09-22 21:15 - typo fix - little change |
(0031092) Brad King (manager) 2012-09-24 09:38 |
Re 0010830:0031088: Thanks for working on this! The patch looks pretty good at quick glance. On what version of CMake was this based? The patch does not apply cleanly on top of a recent master (f31de15b). |
(0031098) Yuchen Deng (reporter) 2012-09-24 21:26 |
It based the release branch. I will post a new patch for master soon. |
(0031103) Brad King (manager) 2012-09-25 15:28 |
Re 0010830:0031098: Thanks! I tweaked the patch for some style and documentation typos and extended the series with a test. Please try attached patches d550801a+0001-Add-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-target-propert.patch d550801a+0002-Verify-that-PDB_-NAME-OUTPUT_DIRECTORY-are-honored-i.patch d550801a+0003-Document-that-PDB_-NAME-OUTPUT_DIRECTORY-are-ignored.patch based on commit d550801a. |
(0031108) Yuchen Deng (reporter) 2012-09-27 02:47 |
Start 128: PDBDirectoryAndName 128/229 Test 0000128: PDBDirectoryAndName ......................... Passed 3.99 sec It seems works well. |
(0031109) Brad King (manager) 2012-09-27 08:43 |
Applied: http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3f60dbf1 [^] http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b294457e [^] http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=efc83b36 [^] |
(0032462) Robert Maynard (manager) 2013-03-04 08:38 |
Closing resolved issues that have not been updated in more than 4 months. |
Notes |
Issue History | |||
Date Modified | Username | Field | Change |
2010-06-14 17:35 | Andreas Johansen | New Issue | |
2010-06-17 09:52 | Andreas Johansen | Note Added: 0021064 | |
2010-06-17 09:52 | Andreas Johansen | File Added: set_debug_symbols_name.patch | |
2010-06-17 10:16 | Andreas Johansen | Note Edited: 0021064 | |
2010-06-17 10:17 | Andreas Johansen | Note Edited: 0021064 | |
2010-12-03 09:39 | Nodrev | Note Added: 0023693 | |
2010-12-15 09:55 | David Cole | Assigned To | => Brad King |
2010-12-15 09:55 | David Cole | Status | new => assigned |
2010-12-15 10:19 | Brad King | File Added: 0001-Add-target-property-PDB_NAME-to-set-MS-.pdb-names.patch | |
2010-12-15 10:21 | Brad King | Note Added: 0024153 | |
2011-01-25 03:34 | Thomas Bernard | Note Added: 0025064 | |
2011-01-25 03:34 | Thomas Bernard | File Added: 0001-PDB_NAME-target-property-to-set-full-PDB-file-path.patch | |
2011-01-25 08:54 | Brad King | Note Added: 0025068 | |
2011-01-28 08:42 | Thomas Bernard | Note Added: 0025120 | |
2011-01-28 08:43 | Thomas Bernard | File Added: 0001-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch | |
2011-01-28 10:32 | Brad King | Note Added: 0025123 | |
2011-02-28 09:02 | Brad King | Relationship added | has duplicate 0011899 |
2011-02-28 09:02 | Brad King | Relationship deleted | has duplicate 0011899 |
2011-02-28 09:32 | Brad King | Relationship added | related to 0011899 |
2011-02-28 10:11 | Brad King | Note Added: 0025599 | |
2012-08-13 10:36 | Brad King | Status | assigned => backlog |
2012-08-13 10:36 | Brad King | Note Added: 0030479 | |
2012-09-09 00:20 | Yuchen Deng | Note Added: 0030961 | |
2012-09-22 04:48 | Yuchen Deng | File Added: Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch | |
2012-09-22 04:54 | Yuchen Deng | Note Added: 0031084 | |
2012-09-22 08:30 | Yuchen Deng | File Added: 2-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch | |
2012-09-22 08:31 | Yuchen Deng | Note Added: 0031085 | |
2012-09-22 10:24 | Yuchen Deng | File Added: loaden-v3-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch | |
2012-09-22 10:26 | Yuchen Deng | Note Added: 0031086 | |
2012-09-22 10:52 | Yuchen Deng | File Added: loaden-V4-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch | |
2012-09-22 10:53 | Yuchen Deng | Note Added: 0031087 | |
2012-09-22 21:15 | Yuchen Deng | File Added: loaden-V5-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch | |
2012-09-22 21:16 | Yuchen Deng | Note Added: 0031088 | |
2012-09-24 09:38 | Brad King | Note Added: 0031092 | |
2012-09-24 21:26 | Yuchen Deng | Note Added: 0031098 | |
2012-09-24 21:32 | Yuchen Deng | File Added: loaden-V6-based-master-d550801a-Added-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-as-target-pr.patch | |
2012-09-25 15:25 | Brad King | Status | backlog => assigned |
2012-09-25 15:26 | Brad King | File Added: d550801a+0001-Add-PDB_OUTPUT_DIRECTORY-and-PDB_NAME-target-propert.patch | |
2012-09-25 15:26 | Brad King | File Added: d550801a+0002-Verify-that-PDB_-NAME-OUTPUT_DIRECTORY-are-honored-i.patch | |
2012-09-25 15:26 | Brad King | File Added: d550801a+0003-Document-that-PDB_-NAME-OUTPUT_DIRECTORY-are-ignored.patch | |
2012-09-25 15:28 | Brad King | Note Added: 0031103 | |
2012-09-27 02:47 | Yuchen Deng | Note Added: 0031108 | |
2012-09-27 08:43 | Brad King | Note Added: 0031109 | |
2012-09-27 08:43 | Brad King | Status | assigned => resolved |
2012-09-27 08:43 | Brad King | Resolution | open => fixed |
2012-10-01 14:05 | Brad King | Fixed in Version | => CMake 2.8.10 |
2012-10-01 14:05 | Brad King | Target Version | => CMake 2.8.10 |
2013-03-04 08:38 | Robert Maynard | Note Added: 0032462 | |
2013-03-04 08:38 | Robert Maynard | Status | resolved => closed |
2013-04-05 07:58 | Brad King | Relationship added | related to 0014062 |
Issue History |
Copyright © 2000 - 2018 MantisBT Team |