Merge branch 'custom-command-generator-expressions' into resolve/tests-if-CYGWIN

The tests-if-CYGWIN topic made a change to Tests/Testing/CMakeLists.txt
in code that the custom-command-generator-expressions topic moved to the
Tests/PerConfig/CMakeLists.txt file.  Make the same change to the same
content in the new file.  (Only a small part of the file moved so rename
detection did not do this automatically.)
This commit is contained in:
Brad King 2010-12-17 10:07:19 -05:00
commit 853de2ed12
29 changed files with 351 additions and 247 deletions

View File

@ -131,6 +131,8 @@ SET(SRCS
cmComputeTargetDepends.cxx cmComputeTargetDepends.cxx
cmCustomCommand.cxx cmCustomCommand.cxx
cmCustomCommand.h cmCustomCommand.h
cmCustomCommandGenerator.cxx
cmCustomCommandGenerator.h
cmDefinitions.cxx cmDefinitions.cxx
cmDefinitions.h cmDefinitions.h
cmDepends.cxx cmDepends.cxx
@ -156,6 +158,7 @@ SET(SRCS
cmDocumentationFormatterText.cxx cmDocumentationFormatterText.cxx
cmDocumentationFormatterUsage.cxx cmDocumentationFormatterUsage.cxx
cmDocumentationSection.cxx cmDocumentationSection.cxx
cmDocumentGeneratorExpressions.h
cmDocumentVariables.cxx cmDocumentVariables.cxx
cmDynamicLoader.cxx cmDynamicLoader.cxx
cmDynamicLoader.h cmDynamicLoader.h

View File

@ -13,6 +13,7 @@
#define cmAddTestCommand_h #define cmAddTestCommand_h
#include "cmCommand.h" #include "cmCommand.h"
#include "cmDocumentGeneratorExpressions.h"
/** \class cmAddTestCommand /** \class cmAddTestCommand
* \brief Add a test to the lists of tests to run. * \brief Add a test to the lists of tests to run.
@ -77,19 +78,7 @@ public:
"\n" "\n"
"Arguments after COMMAND may use \"generator expressions\" with the " "Arguments after COMMAND may use \"generator expressions\" with the "
"syntax \"$<...>\". " "syntax \"$<...>\". "
"These expressions are evaluted during build system generation and " CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
"produce information specific to each generated build configuration. "
"Valid expressions are:\n"
" $<CONFIGURATION> = configuration name\n"
" $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n"
" $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n"
" $<TARGET_SONAME_FILE:tgt> = 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"
" $<TARGET_FILE_DIR:tgt>/$<TARGET_FILE_NAME:tgt>\n"
" $<TARGET_LINKER_FILE_DIR:tgt>/$<TARGET_LINKER_FILE_NAME:tgt>\n"
" $<TARGET_SONAME_FILE_DIR:tgt>/$<TARGET_SONAME_FILE_NAME:tgt>\n"
"Example usage:\n" "Example usage:\n"
" add_test(NAME mytest\n" " add_test(NAME mytest\n"
" COMMAND testDriver --config $<CONFIGURATION>\n" " COMMAND testDriver --config $<CONFIGURATION>\n"

View File

@ -11,6 +11,8 @@
============================================================================*/ ============================================================================*/
#include "cmCustomCommand.h" #include "cmCustomCommand.h"
#include "cmMakefile.h"
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmCustomCommand::cmCustomCommand() cmCustomCommand::cmCustomCommand()
{ {
@ -28,12 +30,14 @@ cmCustomCommand::cmCustomCommand(const cmCustomCommand& r):
Comment(r.Comment), Comment(r.Comment),
WorkingDirectory(r.WorkingDirectory), WorkingDirectory(r.WorkingDirectory),
EscapeAllowMakeVars(r.EscapeAllowMakeVars), EscapeAllowMakeVars(r.EscapeAllowMakeVars),
EscapeOldStyle(r.EscapeOldStyle) EscapeOldStyle(r.EscapeOldStyle),
Backtrace(new cmListFileBacktrace(*r.Backtrace))
{ {
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmCustomCommand::cmCustomCommand(const std::vector<std::string>& outputs, cmCustomCommand::cmCustomCommand(cmMakefile* mf,
const std::vector<std::string>& outputs,
const std::vector<std::string>& depends, const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, const cmCustomCommandLines& commandLines,
const char* comment, const char* comment,
@ -45,10 +49,21 @@ cmCustomCommand::cmCustomCommand(const std::vector<std::string>& outputs,
Comment(comment?comment:""), Comment(comment?comment:""),
WorkingDirectory(workingDirectory?workingDirectory:""), WorkingDirectory(workingDirectory?workingDirectory:""),
EscapeAllowMakeVars(false), EscapeAllowMakeVars(false),
EscapeOldStyle(true) EscapeOldStyle(true),
Backtrace(new cmListFileBacktrace)
{ {
this->EscapeOldStyle = true; this->EscapeOldStyle = true;
this->EscapeAllowMakeVars = false; 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; this->EscapeAllowMakeVars = b;
} }
//----------------------------------------------------------------------------
cmListFileBacktrace const& cmCustomCommand::GetBacktrace() const
{
return *this->Backtrace;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmCustomCommand::ImplicitDependsList const& cmCustomCommand::ImplicitDependsList const&
cmCustomCommand::GetImplicitDepends() const cmCustomCommand::GetImplicitDepends() const

View File

@ -13,6 +13,8 @@
#define cmCustomCommand_h #define cmCustomCommand_h
#include "cmStandardIncludes.h" #include "cmStandardIncludes.h"
class cmMakefile;
class cmListFileBacktrace;
/** \class cmCustomCommand /** \class cmCustomCommand
* \brief A class to encapsulate a custom command * \brief A class to encapsulate a custom command
@ -27,12 +29,15 @@ public:
cmCustomCommand(const cmCustomCommand& r); cmCustomCommand(const cmCustomCommand& r);
/** Main constructor specifies all information for the command. */ /** Main constructor specifies all information for the command. */
cmCustomCommand(const std::vector<std::string>& outputs, cmCustomCommand(cmMakefile* mf,
const std::vector<std::string>& outputs,
const std::vector<std::string>& depends, const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, const cmCustomCommandLines& commandLines,
const char* comment, const char* comment,
const char* workingDirectory); const char* workingDirectory);
~cmCustomCommand();
/** Get the output file produced by the command. */ /** Get the output file produced by the command. */
const std::vector<std::string>& GetOutputs() const; const std::vector<std::string>& GetOutputs() const;
@ -63,6 +68,9 @@ public:
bool GetEscapeAllowMakeVars() const; bool GetEscapeAllowMakeVars() const;
void SetEscapeAllowMakeVars(bool b); void SetEscapeAllowMakeVars(bool b);
/** Backtrace of the command that created this custom command. */
cmListFileBacktrace const& GetBacktrace() const;
typedef std::pair<cmStdString, cmStdString> ImplicitDependsPair; typedef std::pair<cmStdString, cmStdString> ImplicitDependsPair;
class ImplicitDependsList: public std::vector<ImplicitDependsPair> {}; class ImplicitDependsList: public std::vector<ImplicitDependsPair> {};
void SetImplicitDepends(ImplicitDependsList const&); void SetImplicitDepends(ImplicitDependsList const&);
@ -78,6 +86,7 @@ private:
std::string WorkingDirectory; std::string WorkingDirectory;
bool EscapeAllowMakeVars; bool EscapeAllowMakeVars;
bool EscapeOldStyle; bool EscapeOldStyle;
cmListFileBacktrace* Backtrace;
ImplicitDependsList ImplicitDepends; ImplicitDependsList ImplicitDepends;
}; };

View File

@ -0,0 +1,64 @@
/*============================================================================
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<unsigned int>(this->CC.GetCommandLines().size());
}
//----------------------------------------------------------------------------
std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
{
std::string const& argv0 = this->CC.GetCommandLines()[c][0];
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;
}
//----------------------------------------------------------------------------
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);
}
}
}

View File

@ -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

View File

@ -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> = configuration name\n" \
" $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" \
" $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \
" $<TARGET_SONAME_FILE:tgt> = 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" \
" $<TARGET_FILE_DIR:tgt>/$<TARGET_FILE_NAME:tgt>\n" \
" $<TARGET_LINKER_FILE_DIR:tgt>/$<TARGET_LINKER_FILE_NAME:tgt>\n" \
" $<TARGET_SONAME_FILE_DIR:tgt>/$<TARGET_SONAME_FILE_NAME:tgt>\n"
#endif

View File

@ -1893,7 +1893,7 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(
std::vector<std::string> no_outputs; std::vector<std::string> no_outputs;
std::vector<std::string> no_depends; std::vector<std::string> no_depends;
// Store the custom command in the target. // 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); workingDirectory);
target.GetPostBuildCommands().push_back(cc); target.GetPostBuildCommands().push_back(cc);
target.SetProperty("EchoString", message); target.SetProperty("EchoString", message);

View File

@ -18,6 +18,7 @@
#include "cmGeneratedFileStream.h" #include "cmGeneratedFileStream.h"
#include "cmComputeLinkInformation.h" #include "cmComputeLinkInformation.h"
#include "cmSourceFile.h" #include "cmSourceFile.h"
#include "cmCustomCommandGenerator.h"
#include <cmsys/auto_ptr.hxx> #include <cmsys/auto_ptr.hxx>
@ -1314,8 +1315,7 @@ void cmGlobalXCodeGenerator
cmCustomCommand const& cc = *i; cmCustomCommand const& cc = *i;
if(!cc.GetCommandLines().empty()) if(!cc.GetCommandLines().empty())
{ {
bool escapeOldStyle = cc.GetEscapeOldStyle(); cmCustomCommandGenerator ccg(cc, configName, this->CurrentMakefile);
bool escapeAllowMakeVars = cc.GetEscapeAllowMakeVars();
makefileStream << "\n"; makefileStream << "\n";
const std::vector<std::string>& outputs = cc.GetOutputs(); const std::vector<std::string>& outputs = cc.GetOutputs();
if(!outputs.empty()) if(!outputs.empty())
@ -1334,11 +1334,13 @@ void cmGlobalXCodeGenerator
cc.GetDepends().begin(); cc.GetDepends().begin();
d != cc.GetDepends().end(); ++d) d != cc.GetDepends().end(); ++d)
{ {
std::string dep = std::string dep;
this->CurrentLocalGenerator->GetRealDependency(d->c_str(), if(this->CurrentLocalGenerator
configName); ->GetRealDependency(d->c_str(), configName, dep))
makefileStream << "\\\n" << this {
->ConvertToRelativeForMake(dep.c_str()); makefileStream << "\\\n" <<
this->ConvertToRelativeForMake(dep.c_str());
}
} }
makefileStream << "\n"; makefileStream << "\n";
@ -1346,20 +1348,15 @@ void cmGlobalXCodeGenerator
{ {
std::string echo_cmd = "echo "; std::string echo_cmd = "echo ";
echo_cmd += (this->CurrentLocalGenerator-> echo_cmd += (this->CurrentLocalGenerator->
EscapeForShell(comment, escapeAllowMakeVars)); EscapeForShell(comment, cc.GetEscapeAllowMakeVars()));
makefileStream << "\t" << echo_cmd.c_str() << "\n"; makefileStream << "\t" << echo_cmd.c_str() << "\n";
} }
// Add each command line to the set of commands. // Add each command line to the set of commands.
for(cmCustomCommandLines::const_iterator cl = for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
cc.GetCommandLines().begin();
cl != cc.GetCommandLines().end(); ++cl)
{ {
// Build the command line in a single string. // Build the command line in a single string.
const cmCustomCommandLine& commandLine = *cl; std::string cmd2 = ccg.GetCommand(c);
std::string cmd2 = this->CurrentLocalGenerator
->GetRealLocation(commandLine[0].c_str(), configName);
cmSystemTools::ReplaceString(cmd2, "/./", "/"); cmSystemTools::ReplaceString(cmd2, "/./", "/");
cmd2 = this->ConvertToRelativeForMake(cmd2.c_str()); cmd2 = this->ConvertToRelativeForMake(cmd2.c_str());
std::string cmd; std::string cmd;
@ -1370,21 +1367,7 @@ void cmGlobalXCodeGenerator
cmd += " && "; cmd += " && ";
} }
cmd += cmd2; cmd += cmd2;
for(unsigned int j=1; j < commandLine.size(); ++j) ccg.AppendArguments(c, cmd);
{
cmd += " ";
if(escapeOldStyle)
{
cmd += (this->CurrentLocalGenerator
->EscapeForShellOldStyle(commandLine[j].c_str()));
}
else
{
cmd += (this->CurrentLocalGenerator->
EscapeForShell(commandLine[j].c_str(),
escapeAllowMakeVars));
}
}
makefileStream << "\t" << cmd.c_str() << "\n"; makefileStream << "\t" << cmd.c_str() << "\n";
} }
} }

View File

@ -1818,8 +1818,9 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
std::string cmLocalGenerator::GetRealDependency(const char* inName, bool cmLocalGenerator::GetRealDependency(const char* inName,
const char* config) const char* config,
std::string& dep)
{ {
// Older CMake code may specify the dependency using the target // Older CMake code may specify the dependency using the target
// output file rather than the target name. Such code would have // 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 // 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 // as a target but is in a different location so do not use
// the target as the depend // the target as the depend
return inName; dep = inName;
return true;
} }
} }
switch (target->GetType()) switch (target->GetType())
@ -1869,15 +1871,16 @@ std::string cmLocalGenerator::GetRealDependency(const char* inName,
// Get the location of the target's output file and depend on it. // Get the location of the target's output file and depend on it.
if(const char* location = target->GetLocation(config)) if(const char* location = target->GetLocation(config))
{ {
return location; dep = location;
return true;
} }
} }
break; break;
case cmTarget::UTILITY: case cmTarget::UTILITY:
case cmTarget::GLOBAL_TARGET: case cmTarget::GLOBAL_TARGET:
// Depending on a utility target may not work but just trust // A utility target has no file on which to depend. This was listed
// the user to have given a valid name. // only to get the target-level dependency.
return inName; return false;
case cmTarget::INSTALL_FILES: case cmTarget::INSTALL_FILES:
case cmTarget::INSTALL_PROGRAMS: case cmTarget::INSTALL_PROGRAMS:
case cmTarget::INSTALL_DIRECTORY: case cmTarget::INSTALL_DIRECTORY:
@ -1889,41 +1892,24 @@ std::string cmLocalGenerator::GetRealDependency(const char* inName,
if(cmSystemTools::FileIsFullPath(inName)) if(cmSystemTools::FileIsFullPath(inName))
{ {
// This is a full path. Return it as given. // 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 // Check for a source file in this directory that matches the
// dependency. // dependency.
if(cmSourceFile* sf = this->Makefile->GetSource(inName)) if(cmSourceFile* sf = this->Makefile->GetSource(inName))
{ {
name = sf->GetFullPath(); dep = sf->GetFullPath();
return name; return true;
} }
// Treat the name as relative to the source directory in which it // Treat the name as relative to the source directory in which it
// was given. // was given.
name = this->Makefile->GetCurrentDirectory(); dep = this->Makefile->GetCurrentDirectory();
name += "/"; dep += "/";
name += inName; dep += inName;
return name; 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;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@ -158,18 +158,15 @@ public:
/** Translate a dependency as given in CMake code to the name to /** 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 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 a CMake target it will be transformed to the real output
location of that target for the given configuration. If the location of that target for the given configuration. If the
given name is the full path to a file it will be returned. given name is the full path to a file it will be returned.
Otherwise the name is treated as a relative path with respect to Otherwise the name is treated as a relative path with respect to
the source directory of this generator. This should only be the source directory of this generator. This should only be
used for dependencies of custom commands. */ 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. */
std::string GetRealLocation(const char* inName, const char* config);
///! for existing files convert to output path and short path if spaces ///! for existing files convert to output path and short path if spaces
std::string ConvertToOutputForExisting(const char* remote, std::string ConvertToOutputForExisting(const char* remote,

View File

@ -19,6 +19,7 @@
#include "cmake.h" #include "cmake.h"
#include "cmVersion.h" #include "cmVersion.h"
#include "cmFileTimeComparison.h" #include "cmFileTimeComparison.h"
#include "cmCustomCommandGenerator.h"
// Include dependency scanners for supported languages. Only the // Include dependency scanners for supported languages. Only the
// C/C++ scanner is needed for bootstrapping CMake. // C/C++ scanner is needed for bootstrapping CMake.
@ -902,10 +903,13 @@ cmLocalUnixMakefileGenerator3
d != cc.GetDepends().end(); ++d) d != cc.GetDepends().end(); ++d)
{ {
// Lookup the real name of the dependency in case it is a CMake target. // Lookup the real name of the dependency in case it is a CMake target.
std::string dep = this->GetRealDependency std::string dep;
(d->c_str(), this->ConfigurationName.c_str()); if(this->GetRealDependency(d->c_str(), this->ConfigurationName.c_str(),
dep))
{
depends.push_back(dep); depends.push_back(dep);
} }
}
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -958,18 +962,15 @@ cmLocalUnixMakefileGenerator3
{ {
*content << dir; *content << dir;
} }
bool escapeOldStyle = cc.GetEscapeOldStyle(); cmCustomCommandGenerator ccg(cc, this->ConfigurationName.c_str(),
bool escapeAllowMakeVars = cc.GetEscapeAllowMakeVars(); this->Makefile);
// Add each command line to the set of commands. // Add each command line to the set of commands.
std::vector<std::string> commands1; std::vector<std::string> commands1;
for(cmCustomCommandLines::const_iterator cl = cc.GetCommandLines().begin(); for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
cl != cc.GetCommandLines().end(); ++cl)
{ {
// Build the command line in a single string. // Build the command line in a single string.
const cmCustomCommandLine& commandLine = *cl; std::string cmd = ccg.GetCommand(c);
std::string cmd = GetRealLocation(commandLine[0].c_str(),
this->ConfigurationName.c_str());
if (cmd.size()) if (cmd.size())
{ {
// Use "call " before any invocations of .bat or .cmd files // Use "call " before any invocations of .bat or .cmd files
@ -1022,19 +1023,8 @@ cmLocalUnixMakefileGenerator3
std::string launcher = std::string launcher =
this->MakeLauncher(cc, target, workingDir? NONE : START_OUTPUT); this->MakeLauncher(cc, target, workingDir? NONE : START_OUTPUT);
cmd = launcher + this->Convert(cmd.c_str(),NONE,SHELL); cmd = launcher + this->Convert(cmd.c_str(),NONE,SHELL);
for(unsigned int j=1; j < commandLine.size(); ++j)
{ ccg.AppendArguments(c, cmd);
cmd += " ";
if(escapeOldStyle)
{
cmd += this->EscapeForShellOldStyle(commandLine[j].c_str());
}
else
{
cmd += this->EscapeForShell(commandLine[j].c_str(),
escapeAllowMakeVars);
}
}
if(content) if(content)
{ {
// Rule content does not include the launcher. // Rule content does not include the launcher.

View File

@ -65,13 +65,7 @@ public:
{ {
this->Code += "\\\n\t"; this->Code += "\\\n\t";
} }
this->Code += this->Code += this->LG->ConstructScript(cc, this->Config, "\\\n\t");
this->LG->ConstructScript(cc.GetCommandLines(),
cc.GetWorkingDirectory(),
this->Config,
cc.GetEscapeOldStyle(),
cc.GetEscapeAllowMakeVars(),
"\\\n\t");
} }
private: private:
cmLocalVisualStudio6Generator* LG; cmLocalVisualStudio6Generator* LG;
@ -659,12 +653,7 @@ cmLocalVisualStudio6Generator
{ {
std::string config = this->GetConfigName(*i); std::string config = this->GetConfigName(*i);
std::string script = std::string script =
this->ConstructScript(command.GetCommandLines(), this->ConstructScript(command, config.c_str(), "\\\n\t");
command.GetWorkingDirectory(),
config.c_str(),
command.GetEscapeOldStyle(),
command.GetEscapeAllowMakeVars(),
"\\\n\t");
if (i == this->Configurations.begin()) if (i == this->Configurations.begin())
{ {
@ -686,11 +675,13 @@ cmLocalVisualStudio6Generator
++d) ++d)
{ {
// Lookup the real name of the dependency in case it is a CMake target. // Lookup the real name of the dependency in case it is a CMake target.
std::string dep = this->GetRealDependency(d->c_str(), std::string dep;
config.c_str()); if(this->GetRealDependency(d->c_str(), config.c_str(), dep))
{
fout << "\\\n\t" << fout << "\\\n\t" <<
this->ConvertToOptionallyRelativeOutputPath(dep.c_str()); this->ConvertToOptionallyRelativeOutputPath(dep.c_str());
} }
}
fout << "\n"; fout << "\n";
fout << "# PROP Ignore_Default_Tool 1\n"; fout << "# PROP Ignore_Default_Tool 1\n";
@ -847,7 +838,7 @@ cmLocalVisualStudio6Generator::MaybeCreateOutputDir(cmTarget& target,
std::vector<std::string> no_depends; std::vector<std::string> no_depends;
cmCustomCommandLines commands; cmCustomCommandLines commands;
commands.push_back(command); 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->SetEscapeOldStyle(false);
pcc->SetEscapeAllowMakeVars(true); pcc->SetEscapeAllowMakeVars(true);
return pcc; return pcc;

View File

@ -546,12 +546,7 @@ public:
{ {
this->Stream << this->LG->EscapeForXML("\n"); this->Stream << this->LG->EscapeForXML("\n");
} }
std::string script = std::string script = this->LG->ConstructScript(cc, this->Config);
this->LG->ConstructScript(cc.GetCommandLines(),
cc.GetWorkingDirectory(),
this->Config,
cc.GetEscapeOldStyle(),
cc.GetEscapeAllowMakeVars());
this->Stream << this->LG->EscapeForXML(script.c_str()); this->Stream << this->LG->EscapeForXML(script.c_str());
} }
private: private:
@ -1591,12 +1586,7 @@ WriteCustomRule(std::ostream& fout,
<< this->EscapeForXML(fc.CompileFlags.c_str()) << "\"/>\n"; << this->EscapeForXML(fc.CompileFlags.c_str()) << "\"/>\n";
} }
std::string script = std::string script = this->ConstructScript(command, i->c_str());
this->ConstructScript(command.GetCommandLines(),
command.GetWorkingDirectory(),
i->c_str(),
command.GetEscapeOldStyle(),
command.GetEscapeAllowMakeVars());
fout << "\t\t\t\t\t<Tool\n" fout << "\t\t\t\t\t<Tool\n"
<< "\t\t\t\t\tName=\"" << customTool << "\"\n" << "\t\t\t\t\tName=\"" << customTool << "\"\n"
<< "\t\t\t\t\tDescription=\"" << "\t\t\t\t\tDescription=\""
@ -1624,11 +1614,14 @@ WriteCustomRule(std::ostream& fout,
++d) ++d)
{ {
// Get the real name of the dependency in case it is a CMake target. // 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()); std::string dep;
if(this->GetRealDependency(d->c_str(), i->c_str(), dep))
{
fout << this->ConvertToXMLOutputPath(dep.c_str()) fout << this->ConvertToXMLOutputPath(dep.c_str())
<< ";"; << ";";
} }
} }
}
fout << "\"\n"; fout << "\"\n";
fout << "\t\t\t\t\tOutputs=\""; fout << "\t\t\t\t\tOutputs=\"";
if(command.GetOutputs().empty()) if(command.GetOutputs().empty())

View File

@ -14,6 +14,7 @@
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmSourceFile.h" #include "cmSourceFile.h"
#include "cmSystemTools.h" #include "cmSystemTools.h"
#include "cmCustomCommandGenerator.h"
#include "windows.h" #include "windows.h"
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -52,7 +53,7 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target,
std::vector<std::string> no_depends; std::vector<std::string> no_depends;
cmCustomCommandLines commands; cmCustomCommandLines commands;
commands.push_back(command); 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->SetEscapeOldStyle(false);
pcc->SetEscapeAllowMakeVars(true); pcc->SetEscapeAllowMakeVars(true);
return pcc; return pcc;
@ -151,13 +152,15 @@ void cmLocalVisualStudioGenerator::ComputeObjectNameRequirements
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
std::string std::string
cmLocalVisualStudioGenerator cmLocalVisualStudioGenerator
::ConstructScript(const cmCustomCommandLines& commandLines, ::ConstructScript(cmCustomCommand const& cc,
const char* workingDirectory,
const char* configName, const char* configName,
bool escapeOldStyle,
bool escapeAllowMakeVars,
const char* newline_text) const char* newline_text)
{ {
const cmCustomCommandLines& commandLines = cc.GetCommandLines();
const char* workingDirectory = cc.GetWorkingDirectory();
cmCustomCommandGenerator ccg(cc, configName, this->Makefile);
RelativeRoot relativeRoot = workingDirectory? NONE : START_OUTPUT;
// Avoid leading or trailing newlines. // Avoid leading or trailing newlines.
const char* newline = ""; const char* newline = "";
@ -196,40 +199,16 @@ cmLocalVisualStudioGenerator
} }
} }
// Write each command on a single line. // Write each command on a single line.
for(cmCustomCommandLines::const_iterator cl = commandLines.begin(); for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
cl != commandLines.end(); ++cl)
{ {
// Start a new line. // Start a new line.
script += newline; script += newline;
newline = newline_text; newline = newline_text;
// Start with the command name. // Add this command line.
const cmCustomCommandLine& commandLine = *cl; std::string cmd = ccg.GetCommand(c);
std::string commandName = this->GetRealLocation(commandLine[0].c_str(), script += this->Convert(cmd.c_str(), relativeRoot, SHELL);
configName); ccg.AppendArguments(c, script);
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);
}
}
// After each custom command, check for an error result. // After each custom command, check for an error result.
// If there was an error, jump to the VCReportError label, // If there was an error, jump to the VCReportError label,

View File

@ -18,6 +18,7 @@
class cmSourceFile; class cmSourceFile;
class cmSourceGroup; class cmSourceGroup;
class cmCustomCommand;
/** \class cmLocalVisualStudioGenerator /** \class cmLocalVisualStudioGenerator
* \brief Base class for Visual Studio generators. * \brief Base class for Visual Studio generators.
@ -31,11 +32,8 @@ public:
cmLocalVisualStudioGenerator(); cmLocalVisualStudioGenerator();
virtual ~cmLocalVisualStudioGenerator(); virtual ~cmLocalVisualStudioGenerator();
/** Construct a script from the given list of command lines. */ /** Construct a script from the given list of command lines. */
std::string ConstructScript(const cmCustomCommandLines& commandLines, std::string ConstructScript(cmCustomCommand const& cc,
const char* workingDirectory,
const char* configName, const char* configName,
bool escapeOldStyle,
bool escapeAllowMakeVars,
const char* newline = "\n"); const char* newline = "\n");
protected: protected:

View File

@ -827,7 +827,8 @@ cmMakefile::AddCustomCommandToTarget(const char* target,
{ {
// Add the command to the appropriate build step for the target. // Add the command to the appropriate build step for the target.
std::vector<std::string> no_output; std::vector<std::string> no_output;
cmCustomCommand cc(no_output, depends, commandLines, comment, workingDir); cmCustomCommand cc(this, no_output, depends,
commandLines, comment, workingDir);
cc.SetEscapeOldStyle(escapeOldStyle); cc.SetEscapeOldStyle(escapeOldStyle);
cc.SetEscapeAllowMakeVars(true); cc.SetEscapeAllowMakeVars(true);
switch(type) switch(type)
@ -947,7 +948,7 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
if(file) if(file)
{ {
cmCustomCommand* cc = cmCustomCommand* cc =
new cmCustomCommand(outputs, depends2, commandLines, new cmCustomCommand(this, outputs, depends2, commandLines,
comment, workingDir); comment, workingDir);
cc->SetEscapeOldStyle(escapeOldStyle); cc->SetEscapeOldStyle(escapeOldStyle);
cc->SetEscapeAllowMakeVars(true); cc->SetEscapeAllowMakeVars(true);

View File

@ -1357,8 +1357,8 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
util = cmSystemTools::GetFilenameWithoutLastExtension(util); util = cmSystemTools::GetFilenameWithoutLastExtension(util);
} }
// Check for a non-imported target with this name. // Check for a target with this name.
if(cmTarget* t = this->GlobalGenerator->FindTarget(0, util.c_str())) if(cmTarget* t = this->Makefile->FindTargetToUse(util.c_str()))
{ {
// If we find the target and the dep was given as a full path, // 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 // then make sure it was not a full path to something else, and
@ -1406,8 +1406,8 @@ cmTargetTraceDependencies
cit != cc.GetCommandLines().end(); ++cit) cit != cc.GetCommandLines().end(); ++cit)
{ {
std::string const& command = *cit->begin(); std::string const& command = *cit->begin();
// Look for a non-imported target with this name. // Check for a target with this name.
if(cmTarget* t = this->GlobalGenerator->FindTarget(0, command.c_str())) if(cmTarget* t = this->Makefile->FindTargetToUse(command.c_str()))
{ {
if(t->GetType() == cmTarget::EXECUTABLE) if(t->GetType() == cmTarget::EXECUTABLE)
{ {

View File

@ -367,13 +367,7 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
i != configs->end(); ++i) i != configs->end(); ++i)
{ {
std::string script = std::string script =
cmVS10EscapeXML( cmVS10EscapeXML(lg->ConstructScript(command, i->c_str()));
lg->ConstructScript(command.GetCommandLines(),
command.GetWorkingDirectory(),
i->c_str(),
command.GetEscapeOldStyle(),
command.GetEscapeAllowMakeVars())
);
this->WritePlatformConfigTag("Message",i->c_str(), 3); this->WritePlatformConfigTag("Message",i->c_str(), 3);
(*this->BuildFileStream ) << cmVS10EscapeXML(comment) << "</Message>\n"; (*this->BuildFileStream ) << cmVS10EscapeXML(comment) << "</Message>\n";
this->WritePlatformConfigTag("Command", i->c_str(), 3); this->WritePlatformConfigTag("Command", i->c_str(), 3);
@ -386,11 +380,13 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
d != command.GetDepends().end(); d != command.GetDepends().end();
++d) ++d)
{ {
std::string dep = this->LocalGenerator-> std::string dep;
GetRealDependency(d->c_str(), i->c_str()); if(this->LocalGenerator->GetRealDependency(d->c_str(), i->c_str(), dep))
{
this->ConvertToWindowsSlash(dep); this->ConvertToWindowsSlash(dep);
(*this->BuildFileStream ) << ";" << dep; (*this->BuildFileStream ) << ";" << dep;
} }
}
(*this->BuildFileStream ) << ";%(AdditionalInputs)</AdditionalInputs>\n"; (*this->BuildFileStream ) << ";%(AdditionalInputs)</AdditionalInputs>\n";
this->WritePlatformConfigTag("Outputs", i->c_str(), 3); this->WritePlatformConfigTag("Outputs", i->c_str(), 3);
const char* sep = ""; const char* sep = "";
@ -1458,13 +1454,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
script += pre; script += pre;
pre = "\n"; pre = "\n";
script += script +=
cmVS10EscapeXML( cmVS10EscapeXML(lg->ConstructScript(command, configName.c_str()));
lg->ConstructScript(command.GetCommandLines(),
command.GetWorkingDirectory(),
configName.c_str(),
command.GetEscapeOldStyle(),
command.GetEscapeAllowMakeVars())
);
} }
comment = cmVS10EscapeComment(comment); comment = cmVS10EscapeComment(comment);
this->WriteString("<Message>",3); this->WriteString("<Message>",3);

View File

@ -130,6 +130,7 @@ ADD_CUSTOM_COMMAND(
################################################################ ################################################################
ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/foo.pre ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/foo.pre
DEPENDS ${PROJECT_SOURCE_DIR}/foo.in DEPENDS ${PROJECT_SOURCE_DIR}/foo.in
TDocument # Ensure doc1.h generates before this target
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
ARGS -E copy ${PROJECT_SOURCE_DIR}/foo.in ARGS -E copy ${PROJECT_SOURCE_DIR}/foo.in
${PROJECT_BINARY_DIR}/foo.pre ${PROJECT_BINARY_DIR}/foo.pre
@ -181,10 +182,6 @@ ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/generated.c
TARGET_LINK_LIBRARIES(CustomCommand GeneratedHeader) 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 # Test for using just the target name as executable in the COMMAND
# section. Has to be recognized and replaced by CMake with the output # section. Has to be recognized and replaced by CMake with the output

View File

@ -75,24 +75,64 @@ foreach(c DEBUG RELWITHDEBINFO)
set_property(TARGET imp_testExe1b PROPERTY COMPILE_DEFINITIONS_${c} EXE_DBG) set_property(TARGET imp_testExe1b PROPERTY COMPILE_DEFINITIONS_${c} EXE_DBG)
endforeach(c) endforeach(c)
#-----------------------------------------------------------------------------
# Create a custom target to generate a header for the libraries below. # 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 # Drive the header generation through an indirect chain of imported
# target dependencies. # 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) add_library(dep_testLib2 UNKNOWN IMPORTED)
# dep_testLib2 needs hdr_testLib2
add_dependencies(dep_testLib2 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(bld_testLib2 dep_testLib2)
add_dependencies(exp_testLib2 dep_testLib2) add_dependencies(exp_testLib2 dep_testLib2)
#-----------------------------------------------------------------------------
# Create a library to be linked by another directory in this project # Create a library to be linked by another directory in this project
# to test transitive linking to otherwise invisible imported targets. # to test transitive linking to otherwise invisible imported targets.
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_library(imp_lib1 STATIC imp_lib1.c) add_library(imp_lib1 STATIC imp_lib1.c)
target_link_libraries(imp_lib1 exp_testLib2) target_link_libraries(imp_lib1 exp_testLib2)
add_library(imp_lib1b STATIC imp_lib1.c) add_library(imp_lib1b STATIC imp_lib1.c)

View File

@ -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(UNIX AND NOT CYGWIN)
SET(soname_file -DpcShared_soname_file=$<TARGET_SONAME_FILE:pcShared>)
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=$<CONFIGURATION>
-Dperconfig_file_dir=$<TARGET_FILE_DIR:perconfig>
-Dperconfig_file_name=$<TARGET_FILE_NAME:perconfig>
-Dperconfig_file=$<TARGET_FILE:perconfig>
-DpcStatic_file=$<TARGET_FILE:pcStatic>
-DpcStatic_linker_file=$<TARGET_LINKER_FILE:pcStatic>
-DpcShared_file=$<TARGET_FILE:pcShared>
-DpcShared_linker_file=$<TARGET_LINKER_FILE:pcShared>
${soname_file}
-P ${PerConfig_SOURCE_DIR}/perconfig.cmake
)
SET(PerConfig_COMMAND "${PerConfig_COMMAND}" PARENT_SCOPE)

View File

@ -53,35 +53,7 @@ ADD_TEST(testing.1 ${Testing_BINARY_DIR}/bin/testing)
# #
ADD_SUBDIRECTORY(Sub/Sub2) ADD_SUBDIRECTORY(Sub/Sub2)
# Per-config target name test. # Per-config target name and generator expressions.
ADD_LIBRARY(pcStatic STATIC pcStatic.c) ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../PerConfig PerConfig)
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(UNIX AND NOT CYGWIN)
SET(soname_file -DpcShared_soname_file=$<TARGET_SONAME_FILE:pcShared>)
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)
ADD_TEST(NAME testing.perconfig COMMAND perconfig) ADD_TEST(NAME testing.perconfig COMMAND perconfig)
ADD_TEST(NAME testing.driver COMMAND ${PerConfig_COMMAND})
# Test using a driver script with generator expressions.
ADD_TEST(NAME testing.driver
COMMAND ${CMAKE_COMMAND}
-Dconfiguration=$<CONFIGURATION>
-Dperconfig_file_dir=$<TARGET_FILE_DIR:perconfig>
-Dperconfig_file_name=$<TARGET_FILE_NAME:perconfig>
-Dperconfig_file=$<TARGET_FILE:perconfig>
-DpcStatic_file=$<TARGET_FILE:pcStatic>
-DpcStatic_linker_file=$<TARGET_LINKER_FILE:pcStatic>
-DpcShared_file=$<TARGET_FILE:pcShared>
-DpcShared_linker_file=$<TARGET_LINKER_FILE:pcShared>
${soname_file}
-P ${Testing_SOURCE_DIR}/driver.cmake
)

View File

@ -215,6 +215,7 @@ CMAKE_CXX_SOURCES="\
cmTarget \ cmTarget \
cmTest \ cmTest \
cmCustomCommand \ cmCustomCommand \
cmCustomCommandGenerator \
cmDocumentVariables \ cmDocumentVariables \
cmCacheManager \ cmCacheManager \
cmListFileCache \ cmListFileCache \