diff options
-rw-r--r-- | Source/cmComputeLinkDepends.cxx | 19 | ||||
-rw-r--r-- | Source/cmComputeLinkDepends.h | 1 | ||||
-rw-r--r-- | Source/cmExportFileGenerator.cxx | 6 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 34 | ||||
-rw-r--r-- | Source/cmTarget.h | 3 | ||||
-rw-r--r-- | Source/cmTargetLinkLibrariesCommand.cxx | 41 | ||||
-rw-r--r-- | Source/cmTargetLinkLibrariesCommand.h | 12 | ||||
-rw-r--r-- | Source/cmake.cxx | 51 | ||||
-rw-r--r-- | Source/cmake.h | 5 | ||||
-rw-r--r-- | Tests/ExportImport/Export/CMakeLists.txt | 4 | ||||
-rw-r--r-- | Tests/ExportImport/Import/CMakeLists.txt | 9 |
11 files changed, 138 insertions, 47 deletions
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index cc60e09..7b768dc 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -188,6 +188,7 @@ cmComputeLinkDepends // The configuration being linked. this->Config = (config && *config)? config : 0; + this->LinkType = this->Target->ComputeLinkType(this->Config); // Enable debug mode if requested. this->DebugMode = this->Makefile->IsOn("CMAKE_LINK_DEPENDS_DEBUG_MODE"); @@ -446,13 +447,6 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index, std::vector<std::string> deplist; cmSystemTools::ExpandListArgument(value, deplist); - // Compute which library configuration to link. - cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED; - if(this->Config && cmSystemTools::UpperCase(this->Config) == "DEBUG") - { - linkType = cmTarget::DEBUG; - } - // Look for entries meant for this configuration. std::vector<std::string> actual_libs; cmTarget::LinkLibraryType llt = cmTarget::GENERAL; @@ -500,7 +494,7 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index, } // If the library is meant for this link type then use it. - if(llt == cmTarget::GENERAL || llt == linkType) + if(llt == cmTarget::GENERAL || llt == this->LinkType) { actual_libs.push_back(*di); } @@ -524,19 +518,12 @@ void cmComputeLinkDepends::AddTargetLinkEntries(int depender_index, LinkLibraryVectorType const& libs) { - // Compute which library configuration to link. - cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED; - if(this->Config && cmSystemTools::UpperCase(this->Config) == "DEBUG") - { - linkType = cmTarget::DEBUG; - } - // Look for entries meant for this configuration. std::vector<std::string> actual_libs; for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin(); li != libs.end(); ++li) { - if(li->second == cmTarget::GENERAL || li->second == linkType) + if(li->second == cmTarget::GENERAL || li->second == this->LinkType) { actual_libs.push_back(li->first); } diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index 3cbb99a..47fa648 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -72,6 +72,7 @@ private: // Configuration information. const char* Config; + cmTarget::LinkLibraryType LinkType; // Output information. EntryVector FinalLinkEntries; diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index e1bbe29..dc2efc5 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -177,11 +177,7 @@ cmExportFileGenerator cmTarget* target, ImportPropertyMap& properties) { // Compute which library configuration to link. - cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED; - if(config && cmSystemTools::UpperCase(config) == "DEBUG") - { - linkType = cmTarget::DEBUG; - } + cmTarget::LinkLibraryType linkType = target->ComputeLinkType(config); // Construct the list of libs linked for this configuration. std::vector<std::string> actual_libs; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 0fbae69..177db54 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -1257,6 +1257,34 @@ const std::vector<std::string>& cmTarget::GetLinkDirectories() } //---------------------------------------------------------------------------- +cmTarget::LinkLibraryType cmTarget::ComputeLinkType(const char* config) +{ + // No configuration is always optimized. + if(!(config && *config)) + { + return cmTarget::OPTIMIZED; + } + + // Get the list of configurations considered to be DEBUG. + std::vector<std::string> const& debugConfigs = + this->Makefile->GetCMakeInstance()->GetDebugConfigs(); + + // Check if any entry in the list matches this configuration. + std::string configUpper = cmSystemTools::UpperCase(config); + for(std::vector<std::string>::const_iterator i = debugConfigs.begin(); + i != debugConfigs.end(); ++i) + { + if(*i == configUpper) + { + return cmTarget::DEBUG; + } + } + + // The current configuration is not a debug configuration. + return cmTarget::OPTIMIZED; +} + +//---------------------------------------------------------------------------- void cmTarget::ClearDependencyInformation( cmMakefile& mf, const char* target ) { @@ -3620,11 +3648,7 @@ cmTargetLinkInterface* cmTarget::ComputeLinkInterface(const char* config) } // Compute which library configuration to link. - cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED; - if(config && cmSystemTools::UpperCase(config) == "DEBUG") - { - linkType = cmTarget::DEBUG; - } + cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config); // Construct the list of libs linked for this configuration. cmTarget::LinkLibraryVectorType const& llibs = diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 695d9e8..dce4feb 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -186,6 +186,9 @@ public: const LinkLibraryVectorType &GetOriginalLinkLibraries() const {return this->OriginalLinkLibraries;} + /** Compute the link type to use for the given configuration. */ + LinkLibraryType ComputeLinkType(const char* config); + /** * Clear the dependency information recorded for this target, if any. */ diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 0bccd27..d84e144 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -188,28 +188,39 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib, return; } + // Get the list of configurations considered to be DEBUG. + std::vector<std::string> const& debugConfigs = + this->Makefile->GetCMakeInstance()->GetDebugConfigs(); + std::string prop; + // Include this library in the link interface for the target. - if(llt == cmTarget::DEBUG) + if(llt == cmTarget::DEBUG || llt == cmTarget::GENERAL) { - // Put in only the DEBUG configuration interface. - this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES_DEBUG", lib); + // Put in the DEBUG configuration interfaces. + for(std::vector<std::string>::const_iterator i = debugConfigs.begin(); + i != debugConfigs.end(); ++i) + { + prop = "LINK_INTERFACE_LIBRARIES_"; + prop += *i; + this->Target->AppendProperty(prop.c_str(), lib); + } } - else if(llt == cmTarget::OPTIMIZED) + if(llt == cmTarget::OPTIMIZED || llt == cmTarget::GENERAL) { - // Put in only the non-DEBUG configuration interface. + // Put in the non-DEBUG configuration interfaces. this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib); - // Make sure the DEBUG configuration interface exists so that this - // one will not be used as a fall-back. - if(!this->Target->GetProperty("LINK_INTERFACE_LIBRARIES_DEBUG")) + // Make sure the DEBUG configuration interfaces exist so that the + // general one will not be used as a fall-back. + for(std::vector<std::string>::const_iterator i = debugConfigs.begin(); + i != debugConfigs.end(); ++i) { - this->Target->SetProperty("LINK_INTERFACE_LIBRARIES_DEBUG", ""); + prop = "LINK_INTERFACE_LIBRARIES_"; + prop += *i; + if(!this->Target->GetProperty(prop.c_str())) + { + this->Target->SetProperty(prop.c_str(), ""); + } } } - else - { - // Put in both the DEBUG and non-DEBUG configuration interfaces. - this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib); - this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES_DEBUG", lib); - } } diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h index cc37608..e18ed4d 100644 --- a/Source/cmTargetLinkLibrariesCommand.h +++ b/Source/cmTargetLinkLibrariesCommand.h @@ -74,7 +74,9 @@ public: "A \"debug\", \"optimized\", or \"general\" keyword indicates that " "the library immediately following it is to be used only for the " "corresponding build configuration. " - "The \"debug\" keyword corresponds to the Debug configuration. " + "The \"debug\" keyword corresponds to the Debug configuration " + "(or to configurations named in the DEBUG_CONFIGURATIONS global " + "property if it is set). " "The \"optimized\" keyword corresponds to all other configurations. " "The \"general\" keyword corresponds to all configurations, and is " "purely optional (assumed if omitted). " @@ -93,14 +95,16 @@ public: " target_link_libraries(<target> LINK_INTERFACE_LIBRARIES\n" " [[debug|optimized|general] <lib>] ...)\n" "The LINK_INTERFACE_LIBRARIES mode appends the libraries " - "to the LINK_INTERFACE_LIBRARIES and LINK_INTERFACE_LIBRARIES_DEBUG " + "to the LINK_INTERFACE_LIBRARIES and its per-configuration equivalent " "target properties instead of using them for linking. " "Libraries specified as \"debug\" are appended to the " - "the LINK_INTERFACE_LIBRARIES_DEBUG property. " + "the LINK_INTERFACE_LIBRARIES_DEBUG property (or to the properties " + "corresponding to configurations listed in the DEBUG_CONFIGURATIONS " + "global property if it is set). " "Libraries specified as \"optimized\" are appended to the " "the LINK_INTERFACE_LIBRARIES property. " "Libraries specified as \"general\" (or without any keyword) are " - "appended to both properties." + "treated as if specified for both \"debug\" and \"optimized\"." ; } diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 0fde396..b053fb5 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -3364,6 +3364,19 @@ void cmake::DefineProperties(cmake *cm) "Used to detect compiler changes, Do not set."); cm->DefineProperty( + "DEBUG_CONFIGURATIONS", cmProperty::GLOBAL, + "Specify which configurations are for debugging.", + "The value must be a semi-colon separated list of configuration names. " + "Currently this property is used only by the target_link_libraries " + "command (see its documentation for details). " + "Additional uses may be defined in the future. " + "\n" + "This property must be set at the top level of the project and before " + "the first target_link_libraries command invocation. " + "If any entry in the list does not match a valid configuration for " + "the project the behavior is undefined."); + + cm->DefineProperty( "GLOBAL_DEPENDS_DEBUG_MODE", cmProperty::GLOBAL, "Enable global target dependency graph debug mode.", "CMake automatically analyzes the global inter-target dependency graph " @@ -3551,6 +3564,12 @@ void cmake::SetProperty(const char* prop, const char* value) return; } + // Special hook to invalidate cached value. + if(strcmp(prop, "DEBUG_CONFIGURATIONS") == 0) + { + this->DebugConfigs.clear(); + } + this->Properties.SetProperty(prop, value, cmProperty::GLOBAL); } @@ -3560,6 +3579,13 @@ void cmake::AppendProperty(const char* prop, const char* value) { return; } + + // Special hook to invalidate cached value. + if(strcmp(prop, "DEBUG_CONFIGURATIONS") == 0) + { + this->DebugConfigs.clear(); + } + this->Properties.AppendProperty(prop, value, cmProperty::GLOBAL); } @@ -4270,3 +4296,28 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text, cmSystemTools::Message(msg.str().c_str(), "Warning"); } } + +//---------------------------------------------------------------------------- +std::vector<std::string> const& cmake::GetDebugConfigs() +{ + // Compute on-demand. + if(this->DebugConfigs.empty()) + { + if(const char* config_list = this->GetProperty("DEBUG_CONFIGURATIONS")) + { + // Expand the specified list and convert to upper-case. + cmSystemTools::ExpandListArgument(config_list, this->DebugConfigs); + for(std::vector<std::string>::iterator i = this->DebugConfigs.begin(); + i != this->DebugConfigs.end(); ++i) + { + *i = cmSystemTools::UpperCase(*i); + } + } + // If no configurations were specified, use a default list. + if(this->DebugConfigs.empty()) + { + this->DebugConfigs.push_back("DEBUG"); + } + } + return this->DebugConfigs; +} diff --git a/Source/cmake.h b/Source/cmake.h index 8d030c7..eca9064 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -332,6 +332,10 @@ class cmake bool IsPropertyDefined(const char *name, cmProperty::ScopeType scope); bool IsPropertyChained(const char *name, cmProperty::ScopeType scope); + /** Get the list of configurations (in upper case) considered to be + debugging configurations.*/ + std::vector<std::string> const& GetDebugConfigs(); + // record accesses of properties and variables void RecordPropertyAccess(const char *name, cmProperty::ScopeType scope); void ReportUndefinedPropertyAccesses(const char *filename); @@ -456,6 +460,7 @@ private: bool DebugTryCompile; cmFileTimeComparison* FileComparison; std::string GraphVizFile; + std::vector<std::string> DebugConfigs; void UpdateConversionPathTable(); }; diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index 5955307..26687b1 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -6,6 +6,10 @@ if(CMAKE_ANSI_CFLAGS) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}") endif(CMAKE_ANSI_CFLAGS) +# Pretend that RelWithDebInfo should link to debug libraries to test +# the DEBUG_CONFIGURATIONS property. +set_property(GLOBAL PROPERTY DEBUG_CONFIGURATIONS Debug RelWithDebInfo) + add_library(testExe1lib STATIC testExe1lib.c) # not exported add_executable(testExe1 testExe1.c) target_link_libraries(testExe1 testExe1lib) diff --git a/Tests/ExportImport/Import/CMakeLists.txt b/Tests/ExportImport/Import/CMakeLists.txt index 1ac9d3a..27f2910 100644 --- a/Tests/ExportImport/Import/CMakeLists.txt +++ b/Tests/ExportImport/Import/CMakeLists.txt @@ -32,7 +32,6 @@ add_executable(imp_testExe1 # Try linking to a library imported from the install tree. target_link_libraries(imp_testExe1 exp_testLib2 exp_testLib3 exp_testLib4) -set_property(TARGET imp_testExe1 PROPERTY COMPILE_DEFINITIONS_DEBUG EXE_DBG) # Try building a plugin to an executable imported from the install tree. add_library(imp_mod1 MODULE imp_mod1.c) @@ -58,8 +57,14 @@ add_executable(imp_testExe1b # Try linking to a library imported from the build tree. target_link_libraries(imp_testExe1b bld_testLib2 bld_testLib3 bld_testLib4) -set_property(TARGET imp_testExe1b PROPERTY COMPILE_DEFINITIONS_DEBUG EXE_DBG) # Try building a plugin to an executable imported from the build tree. add_library(imp_mod1b MODULE imp_mod1.c) target_link_libraries(imp_mod1b bld_testExe2) + +# Export/CMakeLists.txt pretends the RelWithDebInfo (as well as Debug) +# configuration should link to debug libs. +foreach(c DEBUG RELWITHDEBINFO) + set_property(TARGET imp_testExe1 PROPERTY COMPILE_DEFINITIONS_${c} EXE_DBG) + set_property(TARGET imp_testExe1b PROPERTY COMPILE_DEFINITIONS_${c} EXE_DBG) +endforeach(c) |