summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Modules/Platform/gcc.cmake4
-rw-r--r--Source/cmLocalGenerator.cxx14
-rw-r--r--Source/cmLocalGenerator.h4
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx36
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h6
-rw-r--r--Source/cmMakefileTargetGenerator.cxx98
6 files changed, 160 insertions, 2 deletions
diff --git a/Modules/Platform/gcc.cmake b/Modules/Platform/gcc.cmake
index 6543f5c..be09e37 100644
--- a/Modules/Platform/gcc.cmake
+++ b/Modules/Platform/gcc.cmake
@@ -4,6 +4,8 @@ IF(CMAKE_COMPILER_IS_GNUCC)
SET (CMAKE_C_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
SET (CMAKE_C_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
SET (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")
+ SET (CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <FLAGS> -o <PREPROCESSED_SOURCE> -E <SOURCE>")
+ SET (CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <FLAGS> -o <ASSEMBLY_SOURCE> -S <SOURCE>")
ENDIF(CMAKE_COMPILER_IS_GNUCC)
IF(CMAKE_COMPILER_IS_GNUCXX)
@@ -12,5 +14,7 @@ IF(CMAKE_COMPILER_IS_GNUCXX)
SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")
+ SET (CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <FLAGS> -o <PREPROCESSED_SOURCE> -E <SOURCE>")
+ SET (CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <FLAGS> -o <ASSEMBLY_SOURCE> -S <SOURCE>")
ENDIF(CMAKE_COMPILER_IS_GNUCXX)
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index fdeed5b..8447cb9 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -749,6 +749,20 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
return replaceValues.Source;
}
}
+ if(replaceValues.PreprocessedSource)
+ {
+ if(variable == "PREPROCESSED_SOURCE")
+ {
+ return replaceValues.PreprocessedSource;
+ }
+ }
+ if(replaceValues.AssemblySource)
+ {
+ if(variable == "ASSEMBLY_SOURCE")
+ {
+ return replaceValues.AssemblySource;
+ }
+ }
if(replaceValues.Object)
{
if(variable == "OBJECT")
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index ec0aafa..03df6cb 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -186,6 +186,8 @@ public:
this->Target= 0;
this->LinkLibraries= 0;
this->Source= 0;
+ this->AssemblySource = 0;
+ this->PreprocessedSource = 0;
this->Object= 0;
this->ObjectDir= 0;
this->Flags= 0;
@@ -200,6 +202,8 @@ public:
const char* Target;
const char* LinkLibraries;
const char* Source;
+ const char* AssemblySource;
+ const char* PreprocessedSource;
const char* Object;
const char* ObjectDir;
const char* Flags;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index dc301de..4386ccc 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -274,16 +274,41 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
gg->WriteConvenienceRules(ruleFileStream,emittedTargets);
}
-
+
+ bool do_preprocess_rules =
+ this->GetCreatePreprocessedSourceRules();
+ bool do_assembly_rules =
+ this->GetCreateAssemblySourceRules();
+
// now write out the object rules
// for each object file name
for (std::map<cmStdString,std::vector<cmTarget *> >::iterator lo =
this->LocalObjectFiles.begin();
lo != this->LocalObjectFiles.end(); ++lo)
{
+ // Add a convenience rule for building the object file.
this->WriteObjectConvenienceRule(ruleFileStream,
"target to build an object file",
lo->first.c_str(), lo->second);
+
+ // Add convenience rules for preprocessed and assembly files.
+ if(do_preprocess_rules || do_assembly_rules)
+ {
+ std::string::size_type dot_pos = lo->first.rfind(".");
+ std::string base = lo->first.substr(0, dot_pos);
+ if(do_preprocess_rules)
+ {
+ this->WriteObjectConvenienceRule(
+ ruleFileStream, "target to preprocess a source file",
+ (base + ".E").c_str(), lo->second);
+ }
+ if(do_assembly_rules)
+ {
+ this->WriteObjectConvenienceRule(
+ ruleFileStream, "target to generate assembly for a file",
+ (base + ".S").c_str(), lo->second);
+ }
+ }
}
// add a help target as long as there isn;t a real target named help
@@ -706,10 +731,17 @@ cmLocalUnixMakefileGenerator3
commands, false);
}
- // Special target to cleanup operation of make tool.
+ // Special symbolic target that never exists to force dependers to
+ // run their rules.
std::vector<std::string> depends;
this->WriteMakeRule
(makefileStream,
+ "A target that is always out of date.",
+ "cmake_force", depends, commands, true);
+
+ // Special target to cleanup operation of make tool.
+ this->WriteMakeRule
+ (makefileStream,
"Disable implicit rules so canoncical targets will work.",
".SUFFIXES",
depends, commands, false);
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 9a61b30..7c6597a 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -209,6 +209,12 @@ public:
unsigned long GetNumberOfProgressActions();
unsigned long GetNumberOfProgressActionsForTarget(const char *);
+ /** Get whether to create rules to generate preprocessed and
+ assembly sources. This could be converted to a variable lookup
+ later. */
+ bool GetCreatePreprocessedSourceRules() { return true; }
+ bool GetCreateAssemblySourceRules() { return true; }
+
protected:
// these two methods just compute reasonable values for LibraryOutputPath
// and ExecutableOutputPath
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index cadd0cb..c85a981 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -495,6 +495,104 @@ cmMakefileTargetGenerator
relativeObj.c_str(),
depends, commands, false);
+ bool do_preprocess_rules =
+ this->LocalGenerator->GetCreatePreprocessedSourceRules();
+ bool do_assembly_rules =
+ this->LocalGenerator->GetCreateAssemblySourceRules();
+ if(do_preprocess_rules || do_assembly_rules)
+ {
+ std::vector<std::string> force_depends;
+ force_depends.push_back("cmake_force");
+ std::string::size_type dot_pos = relativeObj.rfind(".");
+ std::string relativeObjBase = relativeObj.substr(0, dot_pos);
+
+ if(do_preprocess_rules)
+ {
+ commands.clear();
+ std::string relativeObjE = relativeObjBase + ".E";
+
+ std::string preprocessEcho = "Preprocessing ";
+ preprocessEcho += lang;
+ preprocessEcho += " source to ";
+ preprocessEcho += relativeObjE;
+ this->LocalGenerator->AppendEcho(
+ commands, preprocessEcho.c_str(),
+ cmLocalUnixMakefileGenerator3::EchoBuild
+ );
+
+ std::string preprocessRuleVar = "CMAKE_";
+ preprocessRuleVar += lang;
+ preprocessRuleVar += "_CREATE_PREPROCESSED_SOURCE";
+ if(const char* preprocessRule =
+ this->Makefile->GetDefinition(preprocessRuleVar.c_str()))
+ {
+ cmSystemTools::ExpandListArgument(preprocessRule, commands);
+
+ vars.PreprocessedSource = relativeObjE.c_str();
+
+ // Expand placeholders in the commands.
+ for(std::vector<std::string>::iterator i = commands.begin();
+ i != commands.end(); ++i)
+ {
+ this->LocalGenerator->ExpandRuleVariables(*i, vars);
+ }
+ }
+ else
+ {
+ std::string cmd = "$(CMAKE_COMMAND) -E cmake_unimplemented_variable ";
+ cmd += preprocessRuleVar;
+ commands.push_back(cmd);
+ }
+
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+ relativeObjE.c_str(),
+ force_depends, commands, false);
+ }
+
+ if(do_assembly_rules)
+ {
+ commands.clear();
+ std::string relativeObjS = relativeObjBase + ".S";
+
+ std::string assemblyEcho = "Compiling ";
+ assemblyEcho += lang;
+ assemblyEcho += " source to assembly ";
+ assemblyEcho += relativeObjS;
+ this->LocalGenerator->AppendEcho(
+ commands, assemblyEcho.c_str(),
+ cmLocalUnixMakefileGenerator3::EchoBuild
+ );
+
+ std::string assemblyRuleVar = "CMAKE_";
+ assemblyRuleVar += lang;
+ assemblyRuleVar += "_CREATE_ASSEMBLY_SOURCE";
+ if(const char* assemblyRule =
+ this->Makefile->GetDefinition(assemblyRuleVar.c_str()))
+ {
+ cmSystemTools::ExpandListArgument(assemblyRule, commands);
+
+ vars.AssemblySource = relativeObjS.c_str();
+
+ // Expand placeholders in the commands.
+ for(std::vector<std::string>::iterator i = commands.begin();
+ i != commands.end(); ++i)
+ {
+ this->LocalGenerator->ExpandRuleVariables(*i, vars);
+ }
+ }
+ else
+ {
+ std::string cmd = "$(CMAKE_COMMAND) -E cmake_unimplemented_variable ";
+ cmd += assemblyRuleVar;
+ commands.push_back(cmd);
+ }
+
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+ relativeObjS.c_str(),
+ force_depends, commands, false);
+ }
+ }
+
// If the language needs provides-requires mode, create the
// corresponding targets.
std::string objectRequires = relativeObj;