From 3f60dbf1484575f4c28a15c89e1af071648c8f2d Mon Sep 17 00:00:00 2001 From: Yuchen Deng Date: Tue, 25 Sep 2012 09:30:42 +0800 Subject: [PATCH 1/4] 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 --- Source/cmDocumentVariables.cxx | 9 ++ Source/cmLocalVisualStudio7Generator.cxx | 6 +- .../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 5e7e081cf..db3d055ee 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1210,6 +1210,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) false, "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.", diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 2dfca025c..ed17786d9 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 ab5150a36..d06dfc002 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 577e5fd07..95b71f20d 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 95738c473..ab259072a 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 385b4a079..2456bfcb1 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 9a3812c2e..b932afc7e 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; }; //---------------------------------------------------------------------------- @@ -740,6 +741,18 @@ void cmTarget::DefineProperties(cmake *cm) "This is a configuration-specific version of OUTPUT_NAME. " "Use OUTPUT_NAME_ 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_", 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.", @@ -1189,6 +1202,23 @@ void cmTarget::DefineProperties(cmake *cm) "Per-configuration output directory for RUNTIME target files.", 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_", 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_ " + "if it is set when a target is created."); + cm->DefineProperty ("ARCHIVE_OUTPUT_NAME", cmProperty::TARGET, "Output 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::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; } @@ -2563,6 +2596,17 @@ std::string cmTarget::GetDirectory(const char* config, bool implib) return ""; } +//---------------------------------------------------------------------------- +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) { @@ -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 props; + std::string configUpper = + cmSystemTools::UpperCase(config? config : ""); + if(!configUpper.empty()) + { + // PDB_NAME_ + props.push_back("PDB_NAME_" + configUpper); + } + + // PDB_NAME + props.push_back("PDB_NAME"); + + for(std::vector::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); @@ -3879,6 +3945,65 @@ bool cmTarget::ComputeOutputDir(const char* config, return usesDefaultOutputDir; } +//---------------------------------------------------------------------------- +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) { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 98eaeec76..e1a9de7f3 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 3d2828dab..6ce3fe2d8 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1284,9 +1284,8 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( this->WriteString("$(IntDir)\n", 3); if(this->Target->GetType() != cmTarget::OBJECT_LIBRARY) { - // TODO: PDB for object library? this->WriteString("", 3); - *this->BuildFileStream << this->Target->GetDirectory(configName.c_str()) + *this->BuildFileStream << this->Target->GetPDBDirectory(configName.c_str()) << "/" << this->Target->GetPDBName(configName.c_str()) << "\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 e03b9268e..4d071cb6c 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 000000000..ef1cae1eb --- /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 000000000..c6d9065fe --- /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 000000000..75b39cd28 --- /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 000000000..f4c553f42 --- /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 000000000..2040c6795 --- /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 000000000..adf7c7098 --- /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 000000000..efa8a8234 --- /dev/null +++ b/Tests/PDBDirectoryAndName/mylibD.c @@ -0,0 +1 @@ +int mylibD() { return -1; } From b294457e2b96f40d01a22b867666277495977fa8 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 25 Sep 2012 14:29:41 -0400 Subject: [PATCH 2/4] 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 ef1cae1eb..a9d46ca58 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=$ "-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 000000000..89cdb3c72 --- /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() From efc83b369b26624e7f0fb90d9125ef5ec6d1f7fa Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 25 Sep 2012 14:36:03 -0400 Subject: [PATCH 3/4] 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 b932afc7e..64950d8a2 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_", 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_", 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_ " - "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 a9d46ca58..865d27872 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) From 2ccca05fade0014dbfbce906b20ab4073ecd8d9c Mon Sep 17 00:00:00 2001 From: Brad King Date: Sat, 29 Sep 2012 06:36:46 -0400 Subject: [PATCH 4/4] Run PDBDirectoryAndName test on MSVC and Intel Move it out of the condition that also accepts MinGW/MSYS. Teach the test to allow the Intel for Windows compiler but do not verify the results because the compiler does not seem to write PDB output in all cases. --- Tests/CMakeLists.txt | 2 +- Tests/PDBDirectoryAndName/CMakeLists.txt | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 4d071cb6c..ae69ce86b 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1254,12 +1254,12 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ if(CMAKE_TEST_MSVC) ADD_TEST_MACRO(ForceInclude foo) + ADD_TEST_MACRO(PDBDirectoryAndName myexe) ADD_TEST_MACRO(PrecompiledHeader foo) endif() 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 index 865d27872..bc2f01317 100644 --- a/Tests/PDBDirectoryAndName/CMakeLists.txt +++ b/Tests/PDBDirectoryAndName/CMakeLists.txt @@ -1,8 +1,9 @@ cmake_minimum_required(VERSION 2.8) project(PDBDirectoryAndName C) -if(NOT MSVC) - MESSAGE(FATAL_ERROR "The PDB file test works only with MSVC") +# Make sure the proper compiler is in use. +if(NOT MSVC AND NOT "${CMAKE_C_COMPILER_ID}" MATCHES "^(Intel)$") + message(FATAL_ERROR "The PDBDirectoryAndName test works only with MSVC or Intel") endif() set(my_targets "") @@ -57,6 +58,10 @@ target_link_libraries(myexe2 mylibA mylibD) if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6") return() endif() +# PDB output not fully implemented for Intel +if("${CMAKE_C_COMPILER_ID}" MATCHES "^(Intel)$") + return() +endif() set(pdbs "") foreach(t ${my_targets})