From a765c491adc47c05ce0da933c9cb8aae84f5e530 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 8 Dec 2010 12:22:13 -0500 Subject: [PATCH 1/9] Honor custom command dependencies on imported targets (#10395) Imported targets do not themselves build, but we can follow dependencies through them to find real targets. This allows imported targets to depend on custom targets that provide the underlying files at build time. --- Source/cmTarget.cxx | 8 ++-- Tests/ExportImport/Import/A/CMakeLists.txt | 56 ++++++++++++++++++---- 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index ca61b1fc3..c82c11ec5 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -1357,8 +1357,8 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep) util = cmSystemTools::GetFilenameWithoutLastExtension(util); } - // Check for a non-imported target with this name. - if(cmTarget* t = this->GlobalGenerator->FindTarget(0, util.c_str())) + // Check for a target with this name. + if(cmTarget* t = this->Makefile->FindTargetToUse(util.c_str())) { // If we find the target and the dep was given as a full path, // then make sure it was not a full path to something else, and @@ -1406,8 +1406,8 @@ cmTargetTraceDependencies cit != cc.GetCommandLines().end(); ++cit) { std::string const& command = *cit->begin(); - // Look for a non-imported target with this name. - if(cmTarget* t = this->GlobalGenerator->FindTarget(0, command.c_str())) + // Check for a target with this name. + if(cmTarget* t = this->Makefile->FindTargetToUse(command.c_str())) { if(t->GetType() == cmTarget::EXECUTABLE) { diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index 082834383..e65e362ec 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -75,24 +75,64 @@ foreach(c DEBUG RELWITHDEBINFO) set_property(TARGET imp_testExe1b PROPERTY COMPILE_DEFINITIONS_${c} EXE_DBG) endforeach(c) +#----------------------------------------------------------------------------- # Create a custom target to generate a header for the libraries below. -include_directories(${CMAKE_CURRENT_BINARY_DIR}) -add_custom_command( - OUTPUT testLib2.h - VERBATIM COMMAND - ${CMAKE_COMMAND} -E echo "extern int testLib2(void);" > testLib2.h - ) -add_custom_target(hdr_testLib2 DEPENDS testLib2.h) - # Drive the header generation through an indirect chain of imported # target dependencies. + +# testLib2tmp1.h +add_custom_command( + OUTPUT testLib2tmp1.h + VERBATIM COMMAND + ${CMAKE_COMMAND} -E echo "extern int testLib2(void);" > testLib2tmp1.h + ) + +# hdr_testLib2tmp1 needs testLib2tmp1.h +add_custom_target(hdr_testLib2tmp1 DEPENDS testLib2tmp1.h) + +# exp_testExe2 needs hdr_testLib2tmp1 +add_dependencies(exp_testExe2 hdr_testLib2tmp1) + +# testLib2tmp.h needs exp_testExe2 +add_custom_command( + OUTPUT testLib2tmp.h + VERBATIM COMMAND exp_testExe2 + COMMAND ${CMAKE_COMMAND} -E copy testLib2tmp1.h testLib2tmp.h + ) + +# hdr_testLib2tmp needs testLib2tmp.h +add_custom_target(hdr_testLib2tmp DEPENDS testLib2tmp.h) + +add_library(dep_testLib2tmp UNKNOWN IMPORTED) +set_property(TARGET dep_testLib2tmp PROPERTY + IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/testLib2tmp.h) + +# dep_testLib2tmp needs hdr_testLib2tmp +add_dependencies(dep_testLib2tmp hdr_testLib2tmp) + +# testLib2.h needs dep_testLib2tmp +add_custom_command( + OUTPUT testLib2.h + VERBATIM COMMAND ${CMAKE_COMMAND} -E copy testLib2tmp.h testLib2.h + DEPENDS dep_testLib2tmp + ) + +# hdr_testLib2 needs testLib2.h +add_custom_target(hdr_testLib2 DEPENDS testLib2.h) + add_library(dep_testLib2 UNKNOWN IMPORTED) + +# dep_testLib2 needs hdr_testLib2 add_dependencies(dep_testLib2 hdr_testLib2) + +# exp_testLib2 and bld_testLib2 both need dep_testLib2 add_dependencies(bld_testLib2 dep_testLib2) add_dependencies(exp_testLib2 dep_testLib2) +#----------------------------------------------------------------------------- # Create a library to be linked by another directory in this project # to test transitive linking to otherwise invisible imported targets. +include_directories(${CMAKE_CURRENT_BINARY_DIR}) add_library(imp_lib1 STATIC imp_lib1.c) target_link_libraries(imp_lib1 exp_testLib2) add_library(imp_lib1b STATIC imp_lib1.c) From e30a775f68ddae48ca6987fc2c21c07844a26804 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 8 Dec 2010 16:51:16 -0500 Subject: [PATCH 2/9] Improve signature of cmLocalGenerator::GetRealDependency Allow file-level custom command dependencies to be skipped. --- Source/cmGlobalXCodeGenerator.cxx | 12 +++++---- Source/cmLocalGenerator.cxx | 29 +++++++++++++--------- Source/cmLocalGenerator.h | 5 ++-- Source/cmLocalUnixMakefileGenerator3.cxx | 9 ++++--- Source/cmLocalVisualStudio6Generator.cxx | 10 +++++--- Source/cmLocalVisualStudio7Generator.cxx | 9 ++++--- Source/cmVisualStudio10TargetGenerator.cxx | 10 +++++--- 7 files changed, 51 insertions(+), 33 deletions(-) diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 2f7bc44ab..29c2d067a 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1334,11 +1334,13 @@ void cmGlobalXCodeGenerator cc.GetDepends().begin(); d != cc.GetDepends().end(); ++d) { - std::string dep = - this->CurrentLocalGenerator->GetRealDependency(d->c_str(), - configName); - makefileStream << "\\\n" << this - ->ConvertToRelativeForMake(dep.c_str()); + std::string dep; + if(this->CurrentLocalGenerator + ->GetRealDependency(d->c_str(), configName, dep)) + { + makefileStream << "\\\n" << + this->ConvertToRelativeForMake(dep.c_str()); + } } makefileStream << "\n"; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 5bffd5236..6b37eafe4 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1818,8 +1818,9 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags, } //---------------------------------------------------------------------------- -std::string cmLocalGenerator::GetRealDependency(const char* inName, - const char* config) +bool cmLocalGenerator::GetRealDependency(const char* inName, + const char* config, + std::string& dep) { // Older CMake code may specify the dependency using the target // output file rather than the target name. Such code would have @@ -1855,7 +1856,8 @@ std::string cmLocalGenerator::GetRealDependency(const char* inName, // it is a full path to a depend that has the same name // as a target but is in a different location so do not use // the target as the depend - return inName; + dep = inName; + return true; } } switch (target->GetType()) @@ -1869,7 +1871,8 @@ std::string cmLocalGenerator::GetRealDependency(const char* inName, // Get the location of the target's output file and depend on it. if(const char* location = target->GetLocation(config)) { - return location; + dep = location; + return true; } } break; @@ -1877,7 +1880,8 @@ std::string cmLocalGenerator::GetRealDependency(const char* inName, case cmTarget::GLOBAL_TARGET: // Depending on a utility target may not work but just trust // the user to have given a valid name. - return inName; + dep = inName; + return true; case cmTarget::INSTALL_FILES: case cmTarget::INSTALL_PROGRAMS: case cmTarget::INSTALL_DIRECTORY: @@ -1889,23 +1893,24 @@ std::string cmLocalGenerator::GetRealDependency(const char* inName, if(cmSystemTools::FileIsFullPath(inName)) { // This is a full path. Return it as given. - return inName; + dep = inName; + return true; } // Check for a source file in this directory that matches the // dependency. if(cmSourceFile* sf = this->Makefile->GetSource(inName)) { - name = sf->GetFullPath(); - return name; + dep = sf->GetFullPath(); + return true; } // Treat the name as relative to the source directory in which it // was given. - name = this->Makefile->GetCurrentDirectory(); - name += "/"; - name += inName; - return name; + dep = this->Makefile->GetCurrentDirectory(); + dep += "/"; + dep += inName; + return true; } //---------------------------------------------------------------------------- diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 43bf1e73b..486c385f7 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -164,8 +164,9 @@ public: Otherwise the name is treated as a relative path with respect to the source directory of this generator. This should only be used for dependencies of custom commands. */ - std::string GetRealDependency(const char* name, const char* config); - + bool GetRealDependency(const char* name, const char* config, + std::string& dep); + /** Translate a command as given in CMake code to the location of the executable if the command is the name of a CMake executable target. If that's not the case, just return the original name. */ diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index c5d8c0df5..15ae13994 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -902,9 +902,12 @@ cmLocalUnixMakefileGenerator3 d != cc.GetDepends().end(); ++d) { // Lookup the real name of the dependency in case it is a CMake target. - std::string dep = this->GetRealDependency - (d->c_str(), this->ConfigurationName.c_str()); - depends.push_back(dep); + std::string dep; + if(this->GetRealDependency(d->c_str(), this->ConfigurationName.c_str(), + dep)) + { + depends.push_back(dep); + } } } diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index eb4e4a4f2..b50c13345 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -686,10 +686,12 @@ cmLocalVisualStudio6Generator ++d) { // Lookup the real name of the dependency in case it is a CMake target. - std::string dep = this->GetRealDependency(d->c_str(), - config.c_str()); - fout << "\\\n\t" << - this->ConvertToOptionallyRelativeOutputPath(dep.c_str()); + std::string dep; + if(this->GetRealDependency(d->c_str(), config.c_str(), dep)) + { + fout << "\\\n\t" << + this->ConvertToOptionallyRelativeOutputPath(dep.c_str()); + } } fout << "\n"; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 7fd7fd254..9a87cc4c8 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -1624,9 +1624,12 @@ WriteCustomRule(std::ostream& fout, ++d) { // Get the real name of the dependency in case it is a CMake target. - std::string dep = this->GetRealDependency(d->c_str(), i->c_str()); - fout << this->ConvertToXMLOutputPath(dep.c_str()) - << ";"; + std::string dep; + if(this->GetRealDependency(d->c_str(), i->c_str(), dep)) + { + fout << this->ConvertToXMLOutputPath(dep.c_str()) + << ";"; + } } } fout << "\"\n"; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 524be8b48..1d885e0f4 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -386,10 +386,12 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source, d != command.GetDepends().end(); ++d) { - std::string dep = this->LocalGenerator-> - GetRealDependency(d->c_str(), i->c_str()); - this->ConvertToWindowsSlash(dep); - (*this->BuildFileStream ) << ";" << dep; + std::string dep; + if(this->LocalGenerator->GetRealDependency(d->c_str(), i->c_str(), dep)) + { + this->ConvertToWindowsSlash(dep); + (*this->BuildFileStream ) << ";" << dep; + } } (*this->BuildFileStream ) << ";%(AdditionalInputs)\n"; this->WritePlatformConfigTag("Outputs", i->c_str(), 3); From ced1d5eccd4ae08a6431a5c163be3dd52ca9d59a Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 8 Dec 2010 17:05:23 -0500 Subject: [PATCH 3/9] Skip file-level dependencies on custom targets (#11332) A custom command may name a target created by add_custom_target in its DEPENDS field. Treat this case as a target-level dependency only since a custom target provides no standard file on which to add a file-level dependency. --- Source/cmLocalGenerator.cxx | 7 +++---- Source/cmLocalGenerator.h | 1 + Tests/CustomCommand/CMakeLists.txt | 5 +---- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 6b37eafe4..b7d694c1d 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1878,10 +1878,9 @@ bool cmLocalGenerator::GetRealDependency(const char* inName, break; case cmTarget::UTILITY: case cmTarget::GLOBAL_TARGET: - // Depending on a utility target may not work but just trust - // the user to have given a valid name. - dep = inName; - return true; + // A utility target has no file on which to depend. This was listed + // only to get the target-level dependency. + return false; case cmTarget::INSTALL_FILES: case cmTarget::INSTALL_PROGRAMS: case cmTarget::INSTALL_DIRECTORY: diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 486c385f7..870ce361d 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -158,6 +158,7 @@ public: /** Translate a dependency as given in CMake code to the name to appear in a generated build file. If the given name is that of + a utility target, returns false. If the given name is that of a CMake target it will be transformed to the real output location of that target for the given configuration. If the given name is the full path to a file it will be returned. diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt index 76208d479..746c9a71b 100644 --- a/Tests/CustomCommand/CMakeLists.txt +++ b/Tests/CustomCommand/CMakeLists.txt @@ -130,6 +130,7 @@ ADD_CUSTOM_COMMAND( ################################################################ ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/foo.pre DEPENDS ${PROJECT_SOURCE_DIR}/foo.in + TDocument # Ensure doc1.h generates before this target COMMAND ${CMAKE_COMMAND} ARGS -E copy ${PROJECT_SOURCE_DIR}/foo.in ${PROJECT_BINARY_DIR}/foo.pre @@ -181,10 +182,6 @@ ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/generated.c TARGET_LINK_LIBRARIES(CustomCommand GeneratedHeader) -# must add a dependency on TDocument otherwise it might never build and -# the CustomCommand executable really needs doc1.h -ADD_DEPENDENCIES(CustomCommand TDocument) - ############################################################################## # Test for using just the target name as executable in the COMMAND # section. Has to be recognized and replaced by CMake with the output From 6fe5b3db0b2ca3f9203a54589de0d744d59744c0 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 7 Dec 2010 13:44:54 -0500 Subject: [PATCH 4/9] Simplify VS generator ConstructScript interface Pass to cmLocalVisualStudioGenerator::ConstructScript a cmCustomCommand instance instead of extracting arguments at all call sites. --- Source/cmLocalVisualStudio6Generator.cxx | 15 ++------------- Source/cmLocalVisualStudio7Generator.cxx | 14 ++------------ Source/cmLocalVisualStudioGenerator.cxx | 10 ++++++---- Source/cmLocalVisualStudioGenerator.h | 6 ++---- Source/cmVisualStudio10TargetGenerator.cxx | 16 ++-------------- 5 files changed, 14 insertions(+), 47 deletions(-) diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index b50c13345..851c52654 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -65,13 +65,7 @@ public: { this->Code += "\\\n\t"; } - this->Code += - this->LG->ConstructScript(cc.GetCommandLines(), - cc.GetWorkingDirectory(), - this->Config, - cc.GetEscapeOldStyle(), - cc.GetEscapeAllowMakeVars(), - "\\\n\t"); + this->Code += this->LG->ConstructScript(cc, this->Config, "\\\n\t"); } private: cmLocalVisualStudio6Generator* LG; @@ -659,12 +653,7 @@ cmLocalVisualStudio6Generator { std::string config = this->GetConfigName(*i); std::string script = - this->ConstructScript(command.GetCommandLines(), - command.GetWorkingDirectory(), - config.c_str(), - command.GetEscapeOldStyle(), - command.GetEscapeAllowMakeVars(), - "\\\n\t"); + this->ConstructScript(command, config.c_str(), "\\\n\t"); if (i == this->Configurations.begin()) { diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 9a87cc4c8..b22c429d5 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -546,12 +546,7 @@ public: { this->Stream << this->LG->EscapeForXML("\n"); } - std::string script = - this->LG->ConstructScript(cc.GetCommandLines(), - cc.GetWorkingDirectory(), - this->Config, - cc.GetEscapeOldStyle(), - cc.GetEscapeAllowMakeVars()); + std::string script = this->LG->ConstructScript(cc, this->Config); this->Stream << this->LG->EscapeForXML(script.c_str()); } private: @@ -1591,12 +1586,7 @@ WriteCustomRule(std::ostream& fout, << this->EscapeForXML(fc.CompileFlags.c_str()) << "\"/>\n"; } - std::string script = - this->ConstructScript(command.GetCommandLines(), - command.GetWorkingDirectory(), - i->c_str(), - command.GetEscapeOldStyle(), - command.GetEscapeAllowMakeVars()); + std::string script = this->ConstructScript(command, i->c_str()); fout << "\t\t\t\t\tend(); ++i) { std::string script = - cmVS10EscapeXML( - lg->ConstructScript(command.GetCommandLines(), - command.GetWorkingDirectory(), - i->c_str(), - command.GetEscapeOldStyle(), - command.GetEscapeAllowMakeVars()) - ); + cmVS10EscapeXML(lg->ConstructScript(command, i->c_str())); this->WritePlatformConfigTag("Message",i->c_str(), 3); (*this->BuildFileStream ) << cmVS10EscapeXML(comment) << "\n"; this->WritePlatformConfigTag("Command", i->c_str(), 3); @@ -1460,13 +1454,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent( script += pre; pre = "\n"; script += - cmVS10EscapeXML( - lg->ConstructScript(command.GetCommandLines(), - command.GetWorkingDirectory(), - configName.c_str(), - command.GetEscapeOldStyle(), - command.GetEscapeAllowMakeVars()) - ); + cmVS10EscapeXML(lg->ConstructScript(command, configName.c_str())); } comment = cmVS10EscapeComment(comment); this->WriteString("",3); From 542b517449e8c7101ac6fbd316749bd461b48588 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 7 Dec 2010 16:23:38 -0500 Subject: [PATCH 5/9] Factor out common custom command generator The Makefile, VS, and Xcode generators previously duplicated some custom command line generation code. Factor this out into a separate class cmCustomCommandGenerator shared by all generators. --- Source/CMakeLists.txt | 2 + Source/cmCustomCommandGenerator.cxx | 58 ++++++++++++++++++++++++ Source/cmCustomCommandGenerator.h | 37 +++++++++++++++ Source/cmGlobalXCodeGenerator.cxx | 31 +++---------- Source/cmLocalUnixMakefileGenerator3.cxx | 27 +++-------- Source/cmLocalVisualStudioGenerator.cxx | 39 ++++------------ bootstrap | 1 + 7 files changed, 119 insertions(+), 76 deletions(-) create mode 100644 Source/cmCustomCommandGenerator.cxx create mode 100644 Source/cmCustomCommandGenerator.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 718e52e8e..49412d8c2 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -131,6 +131,8 @@ SET(SRCS cmComputeTargetDepends.cxx cmCustomCommand.cxx cmCustomCommand.h + cmCustomCommandGenerator.cxx + cmCustomCommandGenerator.h cmDefinitions.cxx cmDefinitions.h cmDepends.cxx diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx new file mode 100644 index 000000000..890ac9c6d --- /dev/null +++ b/Source/cmCustomCommandGenerator.cxx @@ -0,0 +1,58 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2010 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmCustomCommandGenerator.h" + +#include "cmMakefile.h" +#include "cmCustomCommand.h" +#include "cmLocalGenerator.h" + +//---------------------------------------------------------------------------- +cmCustomCommandGenerator::cmCustomCommandGenerator( + cmCustomCommand const& cc, const char* config, cmMakefile* mf): + CC(cc), Config(config), Makefile(mf), LG(mf->GetLocalGenerator()), + OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars()) +{ +} + +//---------------------------------------------------------------------------- +unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const +{ + return static_cast(this->CC.GetCommandLines().size()); +} + +//---------------------------------------------------------------------------- +std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const +{ + std::string const& argv0 = this->CC.GetCommandLines()[c][0]; + return this->LG->GetRealLocation(argv0.c_str(), this->Config); +} + +//---------------------------------------------------------------------------- +void +cmCustomCommandGenerator +::AppendArguments(unsigned int c, std::string& cmd) const +{ + cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c]; + for(unsigned int j=1;j < commandLine.size(); ++j) + { + std::string const& arg = commandLine[j]; + cmd += " "; + if(this->OldStyle) + { + cmd += this->LG->EscapeForShellOldStyle(arg.c_str()); + } + else + { + cmd += this->LG->EscapeForShell(arg.c_str(), this->MakeVars); + } + } +} diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h new file mode 100644 index 000000000..5417ec546 --- /dev/null +++ b/Source/cmCustomCommandGenerator.h @@ -0,0 +1,37 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2010 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmCustomCommandGenerator_h +#define cmCustomCommandGenerator_h + +#include "cmStandardIncludes.h" + +class cmCustomCommand; +class cmMakefile; +class cmLocalGenerator; + +class cmCustomCommandGenerator +{ + cmCustomCommand const& CC; + const char* Config; + cmMakefile* Makefile; + cmLocalGenerator* LG; + bool OldStyle; + bool MakeVars; +public: + cmCustomCommandGenerator(cmCustomCommand const& cc, const char* config, + cmMakefile* mf); + unsigned int GetNumberOfCommands() const; + std::string GetCommand(unsigned int c) const; + void AppendArguments(unsigned int c, std::string& cmd) const; +}; + +#endif diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 29c2d067a..e13acda61 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -18,6 +18,7 @@ #include "cmGeneratedFileStream.h" #include "cmComputeLinkInformation.h" #include "cmSourceFile.h" +#include "cmCustomCommandGenerator.h" #include @@ -1314,8 +1315,7 @@ void cmGlobalXCodeGenerator cmCustomCommand const& cc = *i; if(!cc.GetCommandLines().empty()) { - bool escapeOldStyle = cc.GetEscapeOldStyle(); - bool escapeAllowMakeVars = cc.GetEscapeAllowMakeVars(); + cmCustomCommandGenerator ccg(cc, configName, this->CurrentMakefile); makefileStream << "\n"; const std::vector& outputs = cc.GetOutputs(); if(!outputs.empty()) @@ -1348,20 +1348,15 @@ void cmGlobalXCodeGenerator { std::string echo_cmd = "echo "; echo_cmd += (this->CurrentLocalGenerator-> - EscapeForShell(comment, escapeAllowMakeVars)); + EscapeForShell(comment, cc.GetEscapeAllowMakeVars())); makefileStream << "\t" << echo_cmd.c_str() << "\n"; } // Add each command line to the set of commands. - for(cmCustomCommandLines::const_iterator cl = - cc.GetCommandLines().begin(); - cl != cc.GetCommandLines().end(); ++cl) + for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c) { // Build the command line in a single string. - const cmCustomCommandLine& commandLine = *cl; - std::string cmd2 = this->CurrentLocalGenerator - ->GetRealLocation(commandLine[0].c_str(), configName); - + std::string cmd2 = ccg.GetCommand(c); cmSystemTools::ReplaceString(cmd2, "/./", "/"); cmd2 = this->ConvertToRelativeForMake(cmd2.c_str()); std::string cmd; @@ -1372,21 +1367,7 @@ void cmGlobalXCodeGenerator cmd += " && "; } cmd += cmd2; - for(unsigned int j=1; j < commandLine.size(); ++j) - { - cmd += " "; - if(escapeOldStyle) - { - cmd += (this->CurrentLocalGenerator - ->EscapeForShellOldStyle(commandLine[j].c_str())); - } - else - { - cmd += (this->CurrentLocalGenerator-> - EscapeForShell(commandLine[j].c_str(), - escapeAllowMakeVars)); - } - } + ccg.AppendArguments(c, cmd); makefileStream << "\t" << cmd.c_str() << "\n"; } } diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 15ae13994..ff48009ba 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -19,6 +19,7 @@ #include "cmake.h" #include "cmVersion.h" #include "cmFileTimeComparison.h" +#include "cmCustomCommandGenerator.h" // Include dependency scanners for supported languages. Only the // C/C++ scanner is needed for bootstrapping CMake. @@ -961,18 +962,15 @@ cmLocalUnixMakefileGenerator3 { *content << dir; } - bool escapeOldStyle = cc.GetEscapeOldStyle(); - bool escapeAllowMakeVars = cc.GetEscapeAllowMakeVars(); + cmCustomCommandGenerator ccg(cc, this->ConfigurationName.c_str(), + this->Makefile); // Add each command line to the set of commands. std::vector commands1; - for(cmCustomCommandLines::const_iterator cl = cc.GetCommandLines().begin(); - cl != cc.GetCommandLines().end(); ++cl) + for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c) { // Build the command line in a single string. - const cmCustomCommandLine& commandLine = *cl; - std::string cmd = GetRealLocation(commandLine[0].c_str(), - this->ConfigurationName.c_str()); + std::string cmd = ccg.GetCommand(c); if (cmd.size()) { // Use "call " before any invocations of .bat or .cmd files @@ -1025,19 +1023,8 @@ cmLocalUnixMakefileGenerator3 std::string launcher = this->MakeLauncher(cc, target, workingDir? NONE : START_OUTPUT); cmd = launcher + this->Convert(cmd.c_str(),NONE,SHELL); - for(unsigned int j=1; j < commandLine.size(); ++j) - { - cmd += " "; - if(escapeOldStyle) - { - cmd += this->EscapeForShellOldStyle(commandLine[j].c_str()); - } - else - { - cmd += this->EscapeForShell(commandLine[j].c_str(), - escapeAllowMakeVars); - } - } + + ccg.AppendArguments(c, cmd); if(content) { // Rule content does not include the launcher. diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 79dd1dfc5..6d43dc417 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -14,6 +14,7 @@ #include "cmMakefile.h" #include "cmSourceFile.h" #include "cmSystemTools.h" +#include "cmCustomCommandGenerator.h" #include "windows.h" //---------------------------------------------------------------------------- @@ -157,8 +158,8 @@ cmLocalVisualStudioGenerator { const cmCustomCommandLines& commandLines = cc.GetCommandLines(); const char* workingDirectory = cc.GetWorkingDirectory(); - bool escapeOldStyle = cc.GetEscapeOldStyle(); - bool escapeAllowMakeVars = cc.GetEscapeAllowMakeVars(); + cmCustomCommandGenerator ccg(cc, configName, this->Makefile); + RelativeRoot relativeRoot = workingDirectory? NONE : START_OUTPUT; // Avoid leading or trailing newlines. const char* newline = ""; @@ -198,40 +199,16 @@ cmLocalVisualStudioGenerator } } // Write each command on a single line. - for(cmCustomCommandLines::const_iterator cl = commandLines.begin(); - cl != commandLines.end(); ++cl) + for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c) { // Start a new line. script += newline; newline = newline_text; - // Start with the command name. - const cmCustomCommandLine& commandLine = *cl; - std::string commandName = this->GetRealLocation(commandLine[0].c_str(), - configName); - if(!workingDirectory) - { - script += this->Convert(commandName.c_str(),START_OUTPUT,SHELL); - } - else - { - script += this->Convert(commandName.c_str(),NONE,SHELL); - } - - // Add the arguments. - for(unsigned int j=1;j < commandLine.size(); ++j) - { - script += " "; - if(escapeOldStyle) - { - script += this->EscapeForShellOldStyle(commandLine[j].c_str()); - } - else - { - script += this->EscapeForShell(commandLine[j].c_str(), - escapeAllowMakeVars); - } - } + // Add this command line. + std::string cmd = ccg.GetCommand(c); + script += this->Convert(cmd.c_str(), relativeRoot, SHELL); + ccg.AppendArguments(c, script); // After each custom command, check for an error result. // If there was an error, jump to the VCReportError label, diff --git a/bootstrap b/bootstrap index 0da868d8f..b4e19ef22 100755 --- a/bootstrap +++ b/bootstrap @@ -215,6 +215,7 @@ CMAKE_CXX_SOURCES="\ cmTarget \ cmTest \ cmCustomCommand \ + cmCustomCommandGenerator \ cmDocumentVariables \ cmCacheManager \ cmListFileCache \ From 1a29ccaf9a2604ad405035a4a6f51413f74a1145 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 7 Dec 2010 16:28:56 -0500 Subject: [PATCH 6/9] Remove cmLocalGenerator::GetRealLocation The cmCustomCommandGenerator::GetCommand method completely replaces the purpose of this method. Re-implement GetRealLocation inline at the only remaining call site and remove it. --- Source/cmCustomCommandGenerator.cxx | 8 +++++++- Source/cmLocalGenerator.cxx | 18 ------------------ Source/cmLocalGenerator.h | 5 ----- 3 files changed, 7 insertions(+), 24 deletions(-) diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index 890ac9c6d..2a3b55385 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -33,7 +33,13 @@ unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const { std::string const& argv0 = this->CC.GetCommandLines()[c][0]; - return this->LG->GetRealLocation(argv0.c_str(), this->Config); + cmTarget* target = this->Makefile->FindTargetToUse(argv0.c_str()); + if(target && target->GetType() == cmTarget::EXECUTABLE && + (target->IsImported() || !this->Makefile->IsOn("CMAKE_CROSSCOMPILING"))) + { + return target->GetLocation(this->Config); + } + return argv0; } //---------------------------------------------------------------------------- diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index b7d694c1d..d3cbc1ff7 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1912,24 +1912,6 @@ bool cmLocalGenerator::GetRealDependency(const char* inName, return true; } -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::GetRealLocation(const char* inName, - const char* config) -{ - std::string outName=inName; - // Look for a CMake target with the given name, which is an executable - // and which can be run - cmTarget* target = this->Makefile->FindTargetToUse(inName); - if ((target != 0) - && (target->GetType() == cmTarget::EXECUTABLE) - && ((this->Makefile->IsOn("CMAKE_CROSSCOMPILING") == false) - || (target->IsImported() == true))) - { - outName = target->GetLocation( config ); - } - return outName; -} - //---------------------------------------------------------------------------- void cmLocalGenerator::AddSharedFlags(std::string& flags, const char* lang, diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 870ce361d..35aab99ec 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -168,11 +168,6 @@ public: bool GetRealDependency(const char* name, const char* config, std::string& dep); - /** Translate a command as given in CMake code to the location of the - executable if the command is the name of a CMake executable target. - If that's not the case, just return the original name. */ - std::string GetRealLocation(const char* inName, const char* config); - ///! for existing files convert to output path and short path if spaces std::string ConvertToOutputForExisting(const char* remote, RelativeRoot local = START_OUTPUT); From bfb7288f8103298bf4cabb60a13208f95595a7db Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 6 Dec 2010 14:33:59 -0500 Subject: [PATCH 7/9] Record backtrace in cmCustomCommand This will be used to report custom command errors to the user with a backtrace pointing at the add_custom_command or add_custom_target call. --- Source/cmCustomCommand.cxx | 27 +++++++++++++++++++++--- Source/cmCustomCommand.h | 11 +++++++++- Source/cmGlobalGenerator.cxx | 2 +- Source/cmLocalVisualStudio6Generator.cxx | 2 +- Source/cmLocalVisualStudioGenerator.cxx | 2 +- Source/cmMakefile.cxx | 5 +++-- 6 files changed, 40 insertions(+), 9 deletions(-) diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx index 5db88fa7b..bd860ee6a 100644 --- a/Source/cmCustomCommand.cxx +++ b/Source/cmCustomCommand.cxx @@ -11,6 +11,8 @@ ============================================================================*/ #include "cmCustomCommand.h" +#include "cmMakefile.h" + //---------------------------------------------------------------------------- cmCustomCommand::cmCustomCommand() { @@ -28,12 +30,14 @@ cmCustomCommand::cmCustomCommand(const cmCustomCommand& r): Comment(r.Comment), WorkingDirectory(r.WorkingDirectory), EscapeAllowMakeVars(r.EscapeAllowMakeVars), - EscapeOldStyle(r.EscapeOldStyle) + EscapeOldStyle(r.EscapeOldStyle), + Backtrace(new cmListFileBacktrace(*r.Backtrace)) { } //---------------------------------------------------------------------------- -cmCustomCommand::cmCustomCommand(const std::vector& outputs, +cmCustomCommand::cmCustomCommand(cmMakefile* mf, + const std::vector& outputs, const std::vector& depends, const cmCustomCommandLines& commandLines, const char* comment, @@ -45,10 +49,21 @@ cmCustomCommand::cmCustomCommand(const std::vector& outputs, Comment(comment?comment:""), WorkingDirectory(workingDirectory?workingDirectory:""), EscapeAllowMakeVars(false), - EscapeOldStyle(true) + EscapeOldStyle(true), + Backtrace(new cmListFileBacktrace) { this->EscapeOldStyle = true; this->EscapeAllowMakeVars = false; + if(mf) + { + mf->GetBacktrace(*this->Backtrace); + } +} + +//---------------------------------------------------------------------------- +cmCustomCommand::~cmCustomCommand() +{ + delete this->Backtrace; } //---------------------------------------------------------------------------- @@ -130,6 +145,12 @@ void cmCustomCommand::SetEscapeAllowMakeVars(bool b) this->EscapeAllowMakeVars = b; } +//---------------------------------------------------------------------------- +cmListFileBacktrace const& cmCustomCommand::GetBacktrace() const +{ + return *this->Backtrace; +} + //---------------------------------------------------------------------------- cmCustomCommand::ImplicitDependsList const& cmCustomCommand::GetImplicitDepends() const diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h index c9adddf05..dd92e34d7 100644 --- a/Source/cmCustomCommand.h +++ b/Source/cmCustomCommand.h @@ -13,6 +13,8 @@ #define cmCustomCommand_h #include "cmStandardIncludes.h" +class cmMakefile; +class cmListFileBacktrace; /** \class cmCustomCommand * \brief A class to encapsulate a custom command @@ -27,12 +29,15 @@ public: cmCustomCommand(const cmCustomCommand& r); /** Main constructor specifies all information for the command. */ - cmCustomCommand(const std::vector& outputs, + cmCustomCommand(cmMakefile* mf, + const std::vector& outputs, const std::vector& depends, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDirectory); + ~cmCustomCommand(); + /** Get the output file produced by the command. */ const std::vector& GetOutputs() const; @@ -63,6 +68,9 @@ public: bool GetEscapeAllowMakeVars() const; void SetEscapeAllowMakeVars(bool b); + /** Backtrace of the command that created this custom command. */ + cmListFileBacktrace const& GetBacktrace() const; + typedef std::pair ImplicitDependsPair; class ImplicitDependsList: public std::vector {}; void SetImplicitDepends(ImplicitDependsList const&); @@ -78,6 +86,7 @@ private: std::string WorkingDirectory; bool EscapeAllowMakeVars; bool EscapeOldStyle; + cmListFileBacktrace* Backtrace; ImplicitDependsList ImplicitDepends; }; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 15abd020a..f55850972 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1893,7 +1893,7 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget( std::vector no_outputs; std::vector no_depends; // Store the custom command in the target. - cmCustomCommand cc(no_outputs, no_depends, *commandLines, 0, + cmCustomCommand cc(0, no_outputs, no_depends, *commandLines, 0, workingDirectory); target.GetPostBuildCommands().push_back(cc); target.SetProperty("EchoString", message); diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 851c52654..7aabf4d99 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -838,7 +838,7 @@ cmLocalVisualStudio6Generator::MaybeCreateOutputDir(cmTarget& target, std::vector no_depends; cmCustomCommandLines commands; commands.push_back(command); - pcc.reset(new cmCustomCommand(no_output, no_depends, commands, 0, 0)); + pcc.reset(new cmCustomCommand(0, no_output, no_depends, commands, 0, 0)); pcc->SetEscapeOldStyle(false); pcc->SetEscapeAllowMakeVars(true); return pcc; diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 6d43dc417..a044363c9 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -53,7 +53,7 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target, std::vector no_depends; cmCustomCommandLines commands; commands.push_back(command); - pcc.reset(new cmCustomCommand(no_output, no_depends, commands, 0, 0)); + pcc.reset(new cmCustomCommand(0, no_output, no_depends, commands, 0, 0)); pcc->SetEscapeOldStyle(false); pcc->SetEscapeAllowMakeVars(true); return pcc; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 56e0ed933..3bce01c34 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -827,7 +827,8 @@ cmMakefile::AddCustomCommandToTarget(const char* target, { // Add the command to the appropriate build step for the target. std::vector no_output; - cmCustomCommand cc(no_output, depends, commandLines, comment, workingDir); + cmCustomCommand cc(this, no_output, depends, + commandLines, comment, workingDir); cc.SetEscapeOldStyle(escapeOldStyle); cc.SetEscapeAllowMakeVars(true); switch(type) @@ -947,7 +948,7 @@ cmMakefile::AddCustomCommandToOutput(const std::vector& outputs, if(file) { cmCustomCommand* cc = - new cmCustomCommand(outputs, depends2, commandLines, + new cmCustomCommand(this, outputs, depends2, commandLines, comment, workingDir); cc->SetEscapeOldStyle(escapeOldStyle); cc->SetEscapeAllowMakeVars(true); From 4091bca4ecf4a7f9c2099a7d34e125494de60e1c Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 6 Dec 2010 17:11:36 -0500 Subject: [PATCH 8/9] Factor generator expression docs out of add_test This documentation may be reused wherever generator expressions are supported. --- Source/CMakeLists.txt | 1 + Source/cmAddTestCommand.h | 15 ++----------- Source/cmDocumentGeneratorExpressions.h | 30 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 Source/cmDocumentGeneratorExpressions.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 49412d8c2..f183eb4c6 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -158,6 +158,7 @@ SET(SRCS cmDocumentationFormatterText.cxx cmDocumentationFormatterUsage.cxx cmDocumentationSection.cxx + cmDocumentGeneratorExpressions.h cmDocumentVariables.cxx cmDynamicLoader.cxx cmDynamicLoader.h diff --git a/Source/cmAddTestCommand.h b/Source/cmAddTestCommand.h index 79fb48150..1cc86c493 100644 --- a/Source/cmAddTestCommand.h +++ b/Source/cmAddTestCommand.h @@ -13,6 +13,7 @@ #define cmAddTestCommand_h #include "cmCommand.h" +#include "cmDocumentGeneratorExpressions.h" /** \class cmAddTestCommand * \brief Add a test to the lists of tests to run. @@ -77,19 +78,7 @@ public: "\n" "Arguments after COMMAND may use \"generator expressions\" with the " "syntax \"$<...>\". " - "These expressions are evaluted during build system generation and " - "produce information specific to each generated build configuration. " - "Valid expressions are:\n" - " $ = configuration name\n" - " $ = main file (.exe, .so.1.2, .a)\n" - " $ = file used to link (.a, .lib, .so)\n" - " $ = file with soname (.so.3)\n" - "where \"tgt\" is the name of a target. " - "Target file expressions produce a full path, but _DIR and _NAME " - "versions can produce the directory and file name components:\n" - " $/$\n" - " $/$\n" - " $/$\n" + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS "Example usage:\n" " add_test(NAME mytest\n" " COMMAND testDriver --config $\n" diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h new file mode 100644 index 000000000..535901397 --- /dev/null +++ b/Source/cmDocumentGeneratorExpressions.h @@ -0,0 +1,30 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2010 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmDocumentGeneratorExpressions_h +#define cmDocumentGeneratorExpressions_h + +#define CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS \ + "Generator expressions are evaluted during build system generation " \ + "to produce information specific to each build configuration. " \ + "Valid expressions are:\n" \ + " $ = configuration name\n" \ + " $ = main file (.exe, .so.1.2, .a)\n" \ + " $ = file used to link (.a, .lib, .so)\n" \ + " $ = file with soname (.so.3)\n" \ + "where \"tgt\" is the name of a target. " \ + "Target file expressions produce a full path, but _DIR and _NAME " \ + "versions can produce the directory and file name components:\n" \ + " $/$\n" \ + " $/$\n" \ + " $/$\n" + +#endif From 45e1953c4037d4492668651ae3bbfd6a4a875bc1 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 7 Dec 2010 17:36:24 -0500 Subject: [PATCH 9/9] Factor per-config sample targets out of 'Testing' test Put the source files, build rules, and test scripts for these targets under Tests/PerConfig and refer to it from Tests/Testing as a subdirectory. The targets and scripts will be useful in other tests. --- Tests/PerConfig/CMakeLists.txt | 33 ++++++++++++++++++ Tests/{Testing => PerConfig}/pcShared.c | 0 Tests/{Testing => PerConfig}/pcShared.h | 0 Tests/{Testing => PerConfig}/pcStatic.c | 0 Tests/{Testing => PerConfig}/perconfig.c | 0 .../perconfig.cmake} | 0 Tests/Testing/CMakeLists.txt | 34 ++----------------- 7 files changed, 36 insertions(+), 31 deletions(-) create mode 100644 Tests/PerConfig/CMakeLists.txt rename Tests/{Testing => PerConfig}/pcShared.c (100%) rename Tests/{Testing => PerConfig}/pcShared.h (100%) rename Tests/{Testing => PerConfig}/pcStatic.c (100%) rename Tests/{Testing => PerConfig}/perconfig.c (100%) rename Tests/{Testing/driver.cmake => PerConfig/perconfig.cmake} (100%) diff --git a/Tests/PerConfig/CMakeLists.txt b/Tests/PerConfig/CMakeLists.txt new file mode 100644 index 000000000..a45abc8e2 --- /dev/null +++ b/Tests/PerConfig/CMakeLists.txt @@ -0,0 +1,33 @@ +project(PerConfig C) + +# Targets with per-configuration names. +ADD_LIBRARY(pcStatic STATIC pcStatic.c) +SET_PROPERTY(TARGET pcStatic PROPERTY RELEASE_POSTFIX -opt) +SET_PROPERTY(TARGET pcStatic PROPERTY DEBUG_POSTFIX -dbg) +ADD_LIBRARY(pcShared SHARED pcShared.c) +SET_PROPERTY(TARGET pcShared PROPERTY RELEASE_POSTFIX -opt) +SET_PROPERTY(TARGET pcShared PROPERTY DEBUG_POSTFIX -dbg) +SET_PROPERTY(TARGET pcShared PROPERTY VERSION 1.2) +SET_PROPERTY(TARGET pcShared PROPERTY SOVERSION 3) +IF(NOT WIN32) + SET(soname_file -DpcShared_soname_file=$) +ENDIF() +ADD_EXECUTABLE(perconfig perconfig.c) +TARGET_LINK_LIBRARIES(perconfig pcStatic pcShared) +SET_PROPERTY(TARGET perconfig PROPERTY RELEASE_POSTFIX -opt) +SET_PROPERTY(TARGET perconfig PROPERTY DEBUG_POSTFIX -dbg) + +SET(PerConfig_COMMAND + ${CMAKE_COMMAND} + -Dconfiguration=$ + -Dperconfig_file_dir=$ + -Dperconfig_file_name=$ + -Dperconfig_file=$ + -DpcStatic_file=$ + -DpcStatic_linker_file=$ + -DpcShared_file=$ + -DpcShared_linker_file=$ + ${soname_file} + -P ${PerConfig_SOURCE_DIR}/perconfig.cmake + ) +SET(PerConfig_COMMAND "${PerConfig_COMMAND}" PARENT_SCOPE) diff --git a/Tests/Testing/pcShared.c b/Tests/PerConfig/pcShared.c similarity index 100% rename from Tests/Testing/pcShared.c rename to Tests/PerConfig/pcShared.c diff --git a/Tests/Testing/pcShared.h b/Tests/PerConfig/pcShared.h similarity index 100% rename from Tests/Testing/pcShared.h rename to Tests/PerConfig/pcShared.h diff --git a/Tests/Testing/pcStatic.c b/Tests/PerConfig/pcStatic.c similarity index 100% rename from Tests/Testing/pcStatic.c rename to Tests/PerConfig/pcStatic.c diff --git a/Tests/Testing/perconfig.c b/Tests/PerConfig/perconfig.c similarity index 100% rename from Tests/Testing/perconfig.c rename to Tests/PerConfig/perconfig.c diff --git a/Tests/Testing/driver.cmake b/Tests/PerConfig/perconfig.cmake similarity index 100% rename from Tests/Testing/driver.cmake rename to Tests/PerConfig/perconfig.cmake diff --git a/Tests/Testing/CMakeLists.txt b/Tests/Testing/CMakeLists.txt index f85740705..815b52b58 100644 --- a/Tests/Testing/CMakeLists.txt +++ b/Tests/Testing/CMakeLists.txt @@ -53,35 +53,7 @@ ADD_TEST(testing.1 ${Testing_BINARY_DIR}/bin/testing) # ADD_SUBDIRECTORY(Sub/Sub2) -# Per-config target name test. -ADD_LIBRARY(pcStatic STATIC pcStatic.c) -SET_PROPERTY(TARGET pcStatic PROPERTY RELEASE_POSTFIX -opt) -SET_PROPERTY(TARGET pcStatic PROPERTY DEBUG_POSTFIX -dbg) -ADD_LIBRARY(pcShared SHARED pcShared.c) -SET_PROPERTY(TARGET pcShared PROPERTY RELEASE_POSTFIX -opt) -SET_PROPERTY(TARGET pcShared PROPERTY DEBUG_POSTFIX -dbg) -SET_PROPERTY(TARGET pcShared PROPERTY VERSION 1.2) -SET_PROPERTY(TARGET pcShared PROPERTY SOVERSION 3) -IF(NOT WIN32) - SET(soname_file -DpcShared_soname_file=$) -ENDIF() -ADD_EXECUTABLE(perconfig perconfig.c) -TARGET_LINK_LIBRARIES(perconfig pcStatic pcShared) -SET_PROPERTY(TARGET perconfig PROPERTY RELEASE_POSTFIX -opt) -SET_PROPERTY(TARGET perconfig PROPERTY DEBUG_POSTFIX -dbg) +# Per-config target name and generator expressions. +ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../PerConfig PerConfig) ADD_TEST(NAME testing.perconfig COMMAND perconfig) - -# Test using a driver script with generator expressions. -ADD_TEST(NAME testing.driver - COMMAND ${CMAKE_COMMAND} - -Dconfiguration=$ - -Dperconfig_file_dir=$ - -Dperconfig_file_name=$ - -Dperconfig_file=$ - -DpcStatic_file=$ - -DpcStatic_linker_file=$ - -DpcShared_file=$ - -DpcShared_linker_file=$ - ${soname_file} - -P ${Testing_SOURCE_DIR}/driver.cmake - ) +ADD_TEST(NAME testing.driver COMMAND ${PerConfig_COMMAND})