summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2006-06-01 15:45:51 (GMT)
committerBrad King <brad.king@kitware.com>2006-06-01 15:45:51 (GMT)
commit4189370497f4f00c7a7d3ec6ba221879bfc8b58c (patch)
tree40e1ca868cd74dd3f3cb21644d7d43107183282f
parentf54d254a814ff37bf9ad5992c9646bd975822178 (diff)
downloadCMake-4189370497f4f00c7a7d3ec6ba221879bfc8b58c.zip
CMake-4189370497f4f00c7a7d3ec6ba221879bfc8b58c.tar.gz
CMake-4189370497f4f00c7a7d3ec6ba221879bfc8b58c.tar.bz2
BUG: Custom command outputs listed explicitly as source files in a target should be generated whether or not an object file in the target needs them. This useful and makes Makefile builds more consistent with VS IDE builds.
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx26
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx27
-rw-r--r--Source/cmMakefileTargetGenerator.cxx177
-rw-r--r--Source/cmMakefileTargetGenerator.h13
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx17
5 files changed, 141 insertions, 119 deletions
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 7bca8bb..7b30dd2 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -29,12 +29,15 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
// create the build.make file and directory, put in the common blocks
this->CreateRuleFile();
- // Add in any rules for custom commands
- this->WriteCustomCommandsForTarget();
-
- // write in rules for object files
+ // write rules used to help build object files
this->WriteCommonCodeRules();
+ // write in rules for object files and custom commands
+ this->WriteTargetBuildRules();
+
+ // write the per-target per-language flags
+ this->WriteTargetLanguageFlags();
+
// Write the dependency generation rule.
this->WriteTargetDependRules();
@@ -379,19 +382,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
depends, commands, false);
}
- // Write convenience targets.
- std::string dir = this->Makefile->GetStartOutputDirectory();
- dir += "/";
- dir += this->LocalGenerator->GetTargetDirectory(*this->Target);
- std::string buildTargetRuleName = dir;
- buildTargetRuleName += relink?"/preinstall":"/build";
- buildTargetRuleName =
- this->Convert(buildTargetRuleName.c_str(),
- cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
- this->LocalGenerator->WriteConvenienceRule(*this->BuildFileStream,
- targetFullPath.c_str(),
- buildTargetRuleName.c_str());
+ // Write the main driver rule to build everything in this target.
+ this->WriteTargetDriverRule(targetFullPath.c_str(), relink);
// Clean all the possible executable names and symlinks and object files.
this->CleanFiles.insert(this->CleanFiles.end(),
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index a8a186c..c3df2a5 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -28,13 +28,16 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
{
// create the build.make file and directory, put in the common blocks
this->CreateRuleFile();
-
- // Add in any rules for custom commands
- this->WriteCustomCommandsForTarget();
- // write in rules for object files
+ // write rules used to help build object files
this->WriteCommonCodeRules();
-
+
+ // write in rules for object files and custom commands
+ this->WriteTargetBuildRules();
+
+ // write the per-target per-language flags
+ this->WriteTargetLanguageFlags();
+
// Write the dependency generation rule.
this->WriteTargetDependRules();
@@ -522,18 +525,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
depends, commands, false);
}
- // Write convenience targets.
- std::string dir = this->Makefile->GetStartOutputDirectory();
- dir += "/";
- dir += this->LocalGenerator->GetTargetDirectory(*this->Target);
- std::string buildTargetRuleName = dir;
- buildTargetRuleName += relink?"/preinstall":"/build";
- buildTargetRuleName =
- this->Convert(buildTargetRuleName.c_str(),
- cmLocalGenerator::HOME_OUTPUT,cmLocalGenerator::MAKEFILE);
- this->LocalGenerator->WriteConvenienceRule(*this->BuildFileStream,
- targetFullPath.c_str(),
- buildTargetRuleName.c_str());
+ // Write the main driver rule to build everything in this target.
+ this->WriteTargetDriverRule(targetFullPath.c_str(), relink);
// Clean all the possible library names and symlinks and object files.
this->CleanFiles.insert(this->CleanFiles.end(),
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 96700b5..5a6df64 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -99,7 +99,7 @@ void cmMakefileTargetGenerator::CreateRuleFile()
}
//----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::WriteCustomCommandsForTarget()
+void cmMakefileTargetGenerator::WriteTargetBuildRules()
{
// write the custom commands for this target
// Look for files registered for cleaning in this directory.
@@ -110,7 +110,56 @@ void cmMakefileTargetGenerator::WriteCustomCommandsForTarget()
cmSystemTools::ExpandListArgument(additional_clean_files,
this->CleanFiles);
}
- this->WriteCustomCommands();
+
+ // add custom commands to the clean rules?
+ const char* clean_no_custom =
+ this->Makefile->GetProperty("CLEAN_NO_CUSTOM");
+ bool clean = cmSystemTools::IsOff(clean_no_custom);
+
+ // First generate the object rule files. Save a list of all object
+ // files for this target.
+ const std::vector<cmSourceFile*>& sources = this->Target->GetSourceFiles();
+ for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
+ source != sources.end(); ++source)
+ {
+ if(cmCustomCommand* cc = (*source)->GetCustomCommand())
+ {
+ this->GenerateCustomRuleFile(*cc);
+ if (clean)
+ {
+ const std::vector<std::string>& outputs = cc->GetOutputs();
+ for(std::vector<std::string>::const_iterator o = outputs.begin();
+ o != outputs.end(); ++o)
+ {
+ this->CleanFiles.push_back
+ (this->Convert(o->c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
+ }
+ }
+ }
+ else if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY"))
+ {
+ if(!this->GlobalGenerator->IgnoreFile
+ ((*source)->GetSourceExtension().c_str()))
+ {
+ // Generate this object file's rule file.
+ this->WriteObjectRuleFiles(*(*source));
+ }
+ else if((*source)->GetPropertyAsBool("EXTERNAL_OBJECT"))
+ {
+ // This is an external object file. Just add it.
+ this->ExternalObjects.push_back((*source)->GetFullPath());
+ }
+ else
+ {
+ // We only get here if a source file is not an external object
+ // and has an extension that is listed as an ignored file type
+ // for this language. No message or diagnosis should be
+ // given.
+ }
+ }
+ }
}
@@ -159,37 +208,11 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
cmLocalGenerator::HOME_OUTPUT,
cmLocalGenerator::MAKEFILE)
<< "\n\n";
-
- // First generate the object rule files. Save a list of all object
- // files for this target.
- const std::vector<cmSourceFile*>& sources = this->Target->GetSourceFiles();
- for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
- source != sources.end(); ++source)
- {
- if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY") &&
- !(*source)->GetCustomCommand())
- {
- if(!this->GlobalGenerator->IgnoreFile
- ((*source)->GetSourceExtension().c_str()))
- {
- // Generate this object file's rule file.
- this->WriteObjectRuleFiles(*(*source));
- }
- else if((*source)->GetPropertyAsBool("EXTERNAL_OBJECT"))
- {
- // This is an external object file. Just add it.
- this->ExternalObjects.push_back((*source)->GetFullPath());
- }
- else
- {
- // We only get here if a source file is not an external object
- // and has an extension that is listed as an ignored file type
- // for this language. No message or diagnosis should be
- // given.
- }
- }
- }
-
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
+{
// write language flags for target
std::map<cmStdString,cmLocalUnixMakefileGenerator3::IntegrityCheckSet>&
checkSet =
@@ -654,39 +677,6 @@ void cmMakefileTargetGenerator
}
//----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::WriteCustomCommands()
-{
- // add custom commands to the clean rules?
- const char* clean_no_custom =
- this->Makefile->GetProperty("CLEAN_NO_CUSTOM");
- bool clean = cmSystemTools::IsOff(clean_no_custom);
-
- // Generate the rule files for each custom command.
- const std::vector<cmSourceFile*> &classes =
- this->Makefile->GetSourceFiles();
- for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
- i != classes.end(); i++)
- {
- if(cmCustomCommand* cc = (*i)->GetCustomCommand())
- {
- this->GenerateCustomRuleFile(*cc);
- if (clean)
- {
- const std::vector<std::string>& outputs = cc->GetOutputs();
- for(std::vector<std::string>::const_iterator o = outputs.begin();
- o != outputs.end(); ++o)
- {
- this->CleanFiles.push_back
- (this->Convert(o->c_str(),
- cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::UNCHANGED));
- }
- }
- }
- }
-}
-
-//----------------------------------------------------------------------------
void cmMakefileTargetGenerator
::GenerateCustomRuleFile(const cmCustomCommand& cc)
{
@@ -815,6 +805,61 @@ cmMakefileTargetGenerator
*this->BuildFileStream << "\n" << "\n";
}
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteTargetDriverRule(const char* main_output,
+ bool relink)
+{
+ // Compute the name of the driver target.
+ std::string dir = this->Makefile->GetStartOutputDirectory();
+ dir += "/";
+ dir += this->LocalGenerator->GetTargetDirectory(*this->Target);
+ std::string buildTargetRuleName = dir;
+ buildTargetRuleName += relink?"/preinstall":"/build";
+ buildTargetRuleName = this->Convert(buildTargetRuleName.c_str(),
+ cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::MAKEFILE);
+
+ // Build the list of target outputs to drive.
+ std::vector<std::string> depends;
+ if(main_output)
+ {
+ depends.push_back(main_output);
+ }
+
+ const char* comment = 0;
+ if(relink)
+ {
+ // Setup the comment for the preinstall driver.
+ comment = "Rule to relink during preinstall.";
+ }
+ else
+ {
+ // Setup the comment for the main build driver.
+ comment = "Rule to build all files generated by this target.";
+
+ // Make sure all custom command outputs in this target are built.
+ const std::vector<cmSourceFile*>& sources = this->Target->GetSourceFiles();
+ for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
+ source != sources.end(); ++source)
+ {
+ if(cmCustomCommand* cc = (*source)->GetCustomCommand())
+ {
+ const std::vector<std::string>& outputs = cc->GetOutputs();
+ for(std::vector<std::string>::const_iterator o = outputs.begin();
+ o != outputs.end(); ++o)
+ {
+ depends.push_back(*o);
+ }
+ }
+ }
+ }
+
+ // Write the driver rule.
+ std::vector<std::string> no_commands;
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, comment,
+ buildTargetRuleName.c_str(),
+ depends, no_commands, true);
+}
//----------------------------------------------------------------------------
std::string cmMakefileTargetGenerator::GetFrameworkFlags()
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index c2422d7..35c702d 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -55,11 +55,13 @@ protected:
// create the file and directory etc
void CreateRuleFile();
- // outputs the rules for any custom commands used by this target
- void WriteCustomCommandsForTarget();
+ // outputs the rules for object files and custom commands used by
+ // this target
+ void WriteTargetBuildRules();
// write some common code at the top of build.make
void WriteCommonCodeRules();
+ void WriteTargetLanguageFlags();
// write the provide require rules for this target
void WriteTargetRequiresRules();
@@ -83,15 +85,16 @@ protected:
void WriteObjectDependRules(cmSourceFile& source,
std::vector<std::string>& depends);
- // this is responsible for writing all of the rules for all this
- // directories custom commands (but not utility targets)
- void WriteCustomCommands();
+ // write the build rule for a custom command
void GenerateCustomRuleFile(const cmCustomCommand& cc);
// write out the variable that lists the objects for this target
void WriteObjectsVariable(std::string& variableName,
std::string& variableNameExternal);
+ // write the driver rule to build target outputs
+ void WriteTargetDriverRule(const char* main_output, bool relink);
+
// Return the a string with -F flags on apple
std::string GetFrameworkFlags();
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index 474f850..51a848f 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -33,7 +33,7 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
<< "# Utility rule file for " << this->Target->GetName() << ".\n\n";
// write the custom commands for this target
- this->WriteCustomCommandsForTarget();
+ this->WriteTargetBuildRules();
// Collect the commands and dependencies.
std::vector<std::string> commands;
@@ -63,19 +63,8 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
this->Target->GetName(),
depends, commands, true);
- // Write convenience targets.
- std::string dir = this->Makefile->GetStartOutputDirectory();
- dir += "/";
- dir += this->LocalGenerator->GetTargetDirectory(*this->Target);
- std::string buildTargetRuleName = dir;
- buildTargetRuleName += "/build";
- buildTargetRuleName =
- this->LocalGenerator->Convert(buildTargetRuleName.c_str(),
- cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
- this->LocalGenerator->WriteConvenienceRule(*this->BuildFileStream,
- this->Target->GetName(),
- buildTargetRuleName.c_str());
+ // Write the main driver rule to build everything in this target.
+ this->WriteTargetDriverRule(this->Target->GetName(), false);
// Write clean target
this->WriteTargetCleanRules();