From a765c491adc47c05ce0da933c9cb8aae84f5e530 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 8 Dec 2010 12:22:13 -0500 Subject: 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 | 50 +++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index ca61b1f..c82c11e 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 0828343..e65e362 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}) +# Drive the header generation through an indirect chain of imported +# target dependencies. + +# testLib2tmp1.h add_custom_command( - OUTPUT testLib2.h + OUTPUT testLib2tmp1.h VERBATIM COMMAND - ${CMAKE_COMMAND} -E echo "extern int testLib2(void);" > testLib2.h + ${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) -# Drive the header generation through an indirect chain of imported -# target dependencies. 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) -- cgit v0.12 From e30a775f68ddae48ca6987fc2c21c07844a26804 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 8 Dec 2010 16:51:16 -0500 Subject: 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 2f7bc44..29c2d06 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 5bffd52..6b37eaf 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 43bf1e7..486c385 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 c5d8c0d..15ae139 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 eb4e4a4..b50c133 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 7fd7fd2..9a87cc4 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 524be8b..1d885e0 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); -- cgit v0.12 From ced1d5eccd4ae08a6431a5c163be3dd52ca9d59a Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 8 Dec 2010 17:05:23 -0500 Subject: 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 6b37eaf..b7d694c 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 486c385..870ce36 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 76208d4..746c9a7 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 -- cgit v0.12 From 6fe5b3db0b2ca3f9203a54589de0d744d59744c0 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 7 Dec 2010 13:44:54 -0500 Subject: 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 b50c133..851c526 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 9a87cc4..b22c429 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); -- cgit v0.12 From 542b517449e8c7101ac6fbd316749bd461b48588 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 7 Dec 2010 16:23:38 -0500 Subject: 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 718e52e..49412d8 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 0000000..890ac9c --- /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 0000000..5417ec5 --- /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 29c2d06..e13acda 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 15ae139..ff48009 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 79dd1df..6d43dc4 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 0da868d..b4e19ef 100755 --- a/bootstrap +++ b/bootstrap @@ -215,6 +215,7 @@ CMAKE_CXX_SOURCES="\ cmTarget \ cmTest \ cmCustomCommand \ + cmCustomCommandGenerator \ cmDocumentVariables \ cmCacheManager \ cmListFileCache \ -- cgit v0.12 From 1a29ccaf9a2604ad405035a4a6f51413f74a1145 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 7 Dec 2010 16:28:56 -0500 Subject: 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 890ac9c..2a3b553 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 b7d694c..d3cbc1f 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1913,24 +1913,6 @@ bool cmLocalGenerator::GetRealDependency(const char* inName, } //---------------------------------------------------------------------------- -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, bool shared) diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 870ce36..35aab99 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); -- cgit v0.12 From bfb7288f8103298bf4cabb60a13208f95595a7db Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 6 Dec 2010 14:33:59 -0500 Subject: 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 5db88fa..bd860ee 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; } //---------------------------------------------------------------------------- @@ -131,6 +146,12 @@ void cmCustomCommand::SetEscapeAllowMakeVars(bool 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 c9adddf..dd92e34 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 15abd02..f558509 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 851c526..7aabf4d 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 6d43dc4..a044363 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 56e0ed9..3bce01c 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); -- cgit v0.12 From 4091bca4ecf4a7f9c2099a7d34e125494de60e1c Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 6 Dec 2010 17:11:36 -0500 Subject: 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 49412d8..f183eb4 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 79fb481..1cc86c4 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 0000000..5359013 --- /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 -- cgit v0.12 From 45e1953c4037d4492668651ae3bbfd6a4a875bc1 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 7 Dec 2010 17:36:24 -0500 Subject: 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/PerConfig/pcShared.c | 5 +++++ Tests/PerConfig/pcShared.h | 16 ++++++++++++++++ Tests/PerConfig/pcStatic.c | 4 ++++ Tests/PerConfig/perconfig.c | 8 ++++++++ Tests/PerConfig/perconfig.cmake | 40 ++++++++++++++++++++++++++++++++++++++++ Tests/Testing/CMakeLists.txt | 34 +++------------------------------- Tests/Testing/driver.cmake | 40 ---------------------------------------- Tests/Testing/pcShared.c | 5 ----- Tests/Testing/pcShared.h | 16 ---------------- Tests/Testing/pcStatic.c | 4 ---- Tests/Testing/perconfig.c | 8 -------- 12 files changed, 109 insertions(+), 104 deletions(-) create mode 100644 Tests/PerConfig/CMakeLists.txt create mode 100644 Tests/PerConfig/pcShared.c create mode 100644 Tests/PerConfig/pcShared.h create mode 100644 Tests/PerConfig/pcStatic.c create mode 100644 Tests/PerConfig/perconfig.c create mode 100644 Tests/PerConfig/perconfig.cmake delete mode 100644 Tests/Testing/driver.cmake delete mode 100644 Tests/Testing/pcShared.c delete mode 100644 Tests/Testing/pcShared.h delete mode 100644 Tests/Testing/pcStatic.c delete mode 100644 Tests/Testing/perconfig.c diff --git a/Tests/PerConfig/CMakeLists.txt b/Tests/PerConfig/CMakeLists.txt new file mode 100644 index 0000000..a45abc8 --- /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/PerConfig/pcShared.c b/Tests/PerConfig/pcShared.c new file mode 100644 index 0000000..b08fadc --- /dev/null +++ b/Tests/PerConfig/pcShared.c @@ -0,0 +1,5 @@ +#include "pcShared.h" +const char* pcShared(void) +{ + return "INFO:symbol[pcShared]"; +} diff --git a/Tests/PerConfig/pcShared.h b/Tests/PerConfig/pcShared.h new file mode 100644 index 0000000..59a6ef4 --- /dev/null +++ b/Tests/PerConfig/pcShared.h @@ -0,0 +1,16 @@ +#ifndef pcShared_h +#define pcShared_h + +#ifdef _WIN32 +# ifdef pcShared_EXPORTS +# define PC_EXPORT __declspec(dllexport) +# else +# define PC_EXPORT __declspec(dllimport) +# endif +#else +# define PC_EXPORT +#endif + +PC_EXPORT const char* pcShared(void); + +#endif diff --git a/Tests/PerConfig/pcStatic.c b/Tests/PerConfig/pcStatic.c new file mode 100644 index 0000000..7e1bf51 --- /dev/null +++ b/Tests/PerConfig/pcStatic.c @@ -0,0 +1,4 @@ +const char* pcStatic(void) +{ + return "INFO:symbol[pcStatic]"; +} diff --git a/Tests/PerConfig/perconfig.c b/Tests/PerConfig/perconfig.c new file mode 100644 index 0000000..d942d45 --- /dev/null +++ b/Tests/PerConfig/perconfig.c @@ -0,0 +1,8 @@ +#include "pcShared.h" +extern const char* pcStatic(void); +int main() +{ + pcStatic(); + pcShared(); + return 0; +} diff --git a/Tests/PerConfig/perconfig.cmake b/Tests/PerConfig/perconfig.cmake new file mode 100644 index 0000000..4a93acc --- /dev/null +++ b/Tests/PerConfig/perconfig.cmake @@ -0,0 +1,40 @@ +# Print values for human reference. +foreach(v + configuration + perconfig_file_dir + perconfig_file_name + perconfig_file + pcStatic_file + pcStatic_linker_file + pcShared_file + pcShared_linker_file + pcShared_soname_file + ) + message("${v}=${${v}}") +endforeach() + +# Verify that file names match as expected. +set(pc_file_components ${perconfig_file_dir}/${perconfig_file_name}) +if(NOT "${pc_file_components}" STREQUAL "${perconfig_file}") + message(SEND_ERROR + "File components ${pc_file_components} do not match ${perconfig_file}") +endif() +if(NOT "${pcStatic_file}" STREQUAL "${pcStatic_linker_file}") + message(SEND_ERROR + "pcStatic_file does not match pcStatic_linker_file:\n" + " ${pcStatic_file}\n" + " ${pcStatic_linker_file}\n" + ) +endif() + +# Verify that the implementation files are named correctly. +foreach(lib pcStatic pcShared) + file(STRINGS "${${lib}_file}" info LIMIT_COUNT 1 REGEX "INFO:[^[]*\\[") + if(NOT "${info}" MATCHES ".*INFO:symbol\\[${lib}\\].*") + message(SEND_ERROR "No INFO:symbol[${lib}] found in:\n ${${lib}_file}") + endif() +endforeach() +execute_process(COMMAND ${perconfig_file} RESULT_VARIABLE result) +if(result) + message(SEND_ERROR "Error running:\n ${perconfig_file}\n(${result})") +endif() diff --git a/Tests/Testing/CMakeLists.txt b/Tests/Testing/CMakeLists.txt index f857407..815b52b 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}) diff --git a/Tests/Testing/driver.cmake b/Tests/Testing/driver.cmake deleted file mode 100644 index 4a93acc..0000000 --- a/Tests/Testing/driver.cmake +++ /dev/null @@ -1,40 +0,0 @@ -# Print values for human reference. -foreach(v - configuration - perconfig_file_dir - perconfig_file_name - perconfig_file - pcStatic_file - pcStatic_linker_file - pcShared_file - pcShared_linker_file - pcShared_soname_file - ) - message("${v}=${${v}}") -endforeach() - -# Verify that file names match as expected. -set(pc_file_components ${perconfig_file_dir}/${perconfig_file_name}) -if(NOT "${pc_file_components}" STREQUAL "${perconfig_file}") - message(SEND_ERROR - "File components ${pc_file_components} do not match ${perconfig_file}") -endif() -if(NOT "${pcStatic_file}" STREQUAL "${pcStatic_linker_file}") - message(SEND_ERROR - "pcStatic_file does not match pcStatic_linker_file:\n" - " ${pcStatic_file}\n" - " ${pcStatic_linker_file}\n" - ) -endif() - -# Verify that the implementation files are named correctly. -foreach(lib pcStatic pcShared) - file(STRINGS "${${lib}_file}" info LIMIT_COUNT 1 REGEX "INFO:[^[]*\\[") - if(NOT "${info}" MATCHES ".*INFO:symbol\\[${lib}\\].*") - message(SEND_ERROR "No INFO:symbol[${lib}] found in:\n ${${lib}_file}") - endif() -endforeach() -execute_process(COMMAND ${perconfig_file} RESULT_VARIABLE result) -if(result) - message(SEND_ERROR "Error running:\n ${perconfig_file}\n(${result})") -endif() diff --git a/Tests/Testing/pcShared.c b/Tests/Testing/pcShared.c deleted file mode 100644 index b08fadc..0000000 --- a/Tests/Testing/pcShared.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "pcShared.h" -const char* pcShared(void) -{ - return "INFO:symbol[pcShared]"; -} diff --git a/Tests/Testing/pcShared.h b/Tests/Testing/pcShared.h deleted file mode 100644 index 59a6ef4..0000000 --- a/Tests/Testing/pcShared.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef pcShared_h -#define pcShared_h - -#ifdef _WIN32 -# ifdef pcShared_EXPORTS -# define PC_EXPORT __declspec(dllexport) -# else -# define PC_EXPORT __declspec(dllimport) -# endif -#else -# define PC_EXPORT -#endif - -PC_EXPORT const char* pcShared(void); - -#endif diff --git a/Tests/Testing/pcStatic.c b/Tests/Testing/pcStatic.c deleted file mode 100644 index 7e1bf51..0000000 --- a/Tests/Testing/pcStatic.c +++ /dev/null @@ -1,4 +0,0 @@ -const char* pcStatic(void) -{ - return "INFO:symbol[pcStatic]"; -} diff --git a/Tests/Testing/perconfig.c b/Tests/Testing/perconfig.c deleted file mode 100644 index d942d45..0000000 --- a/Tests/Testing/perconfig.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "pcShared.h" -extern const char* pcStatic(void); -int main() -{ - pcStatic(); - pcShared(); - return 0; -} -- cgit v0.12