summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2005-01-28 19:17:48 (GMT)
committerBrad King <brad.king@kitware.com>2005-01-28 19:17:48 (GMT)
commit892a7c4fd929880d205a1e2cad05527494fc531f (patch)
treef0a0542dbe50717d234f7300e5ed7e6d9b784141
parent62aba58b82e200fb25dd67f48d12ecf1297e1228 (diff)
downloadCMake-892a7c4fd929880d205a1e2cad05527494fc531f.zip
CMake-892a7c4fd929880d205a1e2cad05527494fc531f.tar.gz
CMake-892a7c4fd929880d205a1e2cad05527494fc531f.tar.bz2
ENH: Implemented full per-object test for whether provides-requires mode is needed. This will still use a recursive make for any Fortran object even if it doesn't have requires. It is possible to avoid it but we can do that later.
-rw-r--r--Source/cmLocalUnixMakefileGenerator2.cxx198
-rw-r--r--Source/cmLocalUnixMakefileGenerator2.h21
2 files changed, 130 insertions, 89 deletions
diff --git a/Source/cmLocalUnixMakefileGenerator2.cxx b/Source/cmLocalUnixMakefileGenerator2.cxx
index cfd61bf..c2ff9ee 100644
--- a/Source/cmLocalUnixMakefileGenerator2.cxx
+++ b/Source/cmLocalUnixMakefileGenerator2.cxx
@@ -42,20 +42,12 @@
# define CMLUMG_MAKEFILE_NAME "Makefile2"
#endif
-#if 0
-# define CMLUMG_PROVIDES_REQUIRES
-#endif
-
// TODO: Add "help" target.
// TODO: Identify remaining relative path violations.
// TODO: Add test to drive installation through native build system.
// TODO: External object file feature.
// TODO: Need test for separate executable/library output path.
-// TODO: Fortran support:
-// - This needs a "provides-requires" mode for the .o files in a target.
-// - Driving target must be TGT.requires: account for this in jump-and-build.
-
//----------------------------------------------------------------------------
cmLocalUnixMakefileGenerator2::cmLocalUnixMakefileGenerator2()
{
@@ -287,6 +279,7 @@ cmLocalUnixMakefileGenerator2
// First generate the object rule files. Save a list of all object
// files for this target.
std::vector<std::string> objects;
+ std::vector<std::string> provides_requires;
const std::vector<cmSourceFile*>& sources = target.GetSourceFiles();
for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
source != sources.end(); ++source)
@@ -296,7 +289,8 @@ cmLocalUnixMakefileGenerator2
!m_GlobalGenerator->IgnoreFile((*source)->GetSourceExtension().c_str()))
{
// Generate this object file's rule file.
- this->GenerateObjectRuleFile(target, *(*source), objects);
+ this->GenerateObjectRuleFile(target, *(*source), objects,
+ provides_requires);
}
}
@@ -351,19 +345,19 @@ cmLocalUnixMakefileGenerator2
{
case cmTarget::STATIC_LIBRARY:
this->WriteStaticLibraryRule(ruleFileStream, ruleFileName.c_str(),
- target, objects);
+ target, objects, provides_requires);
break;
case cmTarget::SHARED_LIBRARY:
this->WriteSharedLibraryRule(ruleFileStream, ruleFileName.c_str(),
- target, objects);
+ target, objects, provides_requires);
break;
case cmTarget::MODULE_LIBRARY:
this->WriteModuleLibraryRule(ruleFileStream, ruleFileName.c_str(),
- target, objects);
+ target, objects, provides_requires);
break;
case cmTarget::EXECUTABLE:
this->WriteExecutableRule(ruleFileStream, ruleFileName.c_str(),
- target, objects);
+ target, objects, provides_requires);
break;
default:
break;
@@ -374,7 +368,8 @@ cmLocalUnixMakefileGenerator2
void
cmLocalUnixMakefileGenerator2
::GenerateObjectRuleFile(const cmTarget& target, const cmSourceFile& source,
- std::vector<std::string>& objects)
+ std::vector<std::string>& objects,
+ std::vector<std::string>& provides_requires)
{
// Identify the language of the source file.
const char* lang = this->GetSourceFileLanguage(source);
@@ -554,26 +549,35 @@ cmLocalUnixMakefileGenerator2
obj.c_str(), depends, commands);
}
-#ifdef CMLUMG_PROVIDES_REQUIRES
- std::string objectRequires = obj;
- std::string objectProvides = obj;
- objectRequires += ".requires";
- objectProvides += ".provides";
- {
- std::vector<std::string> no_commands;
- std::vector<std::string> depends;
- depends.push_back(obj);
- this->WriteMakeRule(ruleFileStream, 0, 0,
- objectProvides.c_str(), depends, no_commands);
- }
- {
- std::vector<std::string> no_depends;
- std::vector<std::string> commands;
- commands.push_back(this->GetRecursiveMakeCall(objectProvides.c_str()));
- this->WriteMakeRule(ruleFileStream, 0, 0,
- objectRequires.c_str(), no_depends, commands);
- }
-#endif
+ // If the language needs provides-requires mode, create the
+ // corresponding targets.
+ if(strcmp(lang, "Fortran") == 0)
+ {
+ std::string objectRequires = obj;
+ std::string objectProvides = obj;
+ objectRequires += ".requires";
+ objectProvides += ".provides";
+ {
+ // Add the provides target to build the object file.
+ std::vector<std::string> no_commands;
+ std::vector<std::string> depends;
+ depends.push_back(obj);
+ this->WriteMakeRule(ruleFileStream, 0, 0,
+ objectProvides.c_str(), depends, no_commands);
+ }
+ {
+ // Add the requires target to recursively build the provides
+ // target after needed information is up to date.
+ std::vector<std::string> no_depends;
+ std::vector<std::string> commands;
+ commands.push_back(this->GetRecursiveMakeCall(objectProvides.c_str()));
+ this->WriteMakeRule(ruleFileStream, 0, 0,
+ objectRequires.c_str(), no_depends, commands);
+ }
+
+ // Add this to the set of provides-requires objects on the target.
+ provides_requires.push_back(objectRequires);
+ }
}
//----------------------------------------------------------------------------
@@ -1403,7 +1407,8 @@ cmLocalUnixMakefileGenerator2
::WriteExecutableRule(std::ostream& ruleFileStream,
const char* ruleFileName,
const cmTarget& target,
- std::vector<std::string>& objects)
+ std::vector<std::string>& objects,
+ const std::vector<std::string>& provides_requires)
{
// Write the dependency generation rule.
this->WriteTargetDependsRule(ruleFileStream, ruleFileName, target, objects);
@@ -1538,42 +1543,8 @@ cmLocalUnixMakefileGenerator2
cleanFiles.push_back(objs);
this->WriteTargetCleanRule(ruleFileStream, target, cleanFiles);
- // Construct name of driving target listed in build.local rule.
- // TODO: See top of file description of Fortran support.
- std::string targetDriveName = target.GetName();
-
-#ifdef CMLUMG_PROVIDES_REQUIRES
- targetDriveName += ".requires";
- std::string targetProvides = target.GetName();
- targetProvides += ".provides";
- {
- std::vector<std::string> no_commands;
- std::vector<std::string> depends;
- depends.push_back(target.GetName());
- this->WriteMakeRule(ruleFileStream, 0, 0,
- targetProvides.c_str(), depends, no_commands);
- }
- {
- // Build list of require-level dependencies.
- std::vector<std::string> depends;
- for(std::vector<std::string>::const_iterator obj = objects.begin();
- obj != objects.end(); ++obj)
- {
- depends.push_back(*obj + ".requires");
- }
-
- std::vector<std::string> commands;
- commands.push_back(this->GetRecursiveMakeCall(targetProvides.c_str()));
- this->WriteMakeRule(ruleFileStream, 0, 0,
- targetDriveName.c_str(), depends, commands);
- }
-#endif
-
- // Add this to the list of build rules in this directory.
- if(target.IsInAll())
- {
- m_BuildTargets.push_back(targetDriveName);
- }
+ // Write the driving make target.
+ this->WriteTargetRequiresRule(ruleFileStream, target, provides_requires);
}
//----------------------------------------------------------------------------
@@ -1582,7 +1553,8 @@ cmLocalUnixMakefileGenerator2
::WriteStaticLibraryRule(std::ostream& ruleFileStream,
const char* ruleFileName,
const cmTarget& target,
- std::vector<std::string>& objects)
+ std::vector<std::string>& objects,
+ const std::vector<std::string>& provides_requires)
{
const char* linkLanguage =
target.GetLinkerLanguage(this->GetGlobalGenerator());
@@ -1593,7 +1565,8 @@ cmLocalUnixMakefileGenerator2
std::string extraFlags;
this->AppendFlags(extraFlags, target.GetProperty("STATIC_LIBRARY_FLAGS"));
this->WriteLibraryRule(ruleFileStream, ruleFileName, target, objects,
- linkRuleVar.c_str(), extraFlags.c_str());
+ linkRuleVar.c_str(), extraFlags.c_str(),
+ provides_requires);
}
//----------------------------------------------------------------------------
@@ -1602,7 +1575,8 @@ cmLocalUnixMakefileGenerator2
::WriteSharedLibraryRule(std::ostream& ruleFileStream,
const char* ruleFileName,
const cmTarget& target,
- std::vector<std::string>& objects)
+ std::vector<std::string>& objects,
+ const std::vector<std::string>& provides_requires)
{
const char* linkLanguage =
target.GetLinkerLanguage(this->GetGlobalGenerator());
@@ -1628,7 +1602,8 @@ cmLocalUnixMakefileGenerator2
}
}
this->WriteLibraryRule(ruleFileStream, ruleFileName, target, objects,
- linkRuleVar.c_str(), extraFlags.c_str());
+ linkRuleVar.c_str(), extraFlags.c_str(),
+ provides_requires);
}
//----------------------------------------------------------------------------
@@ -1637,7 +1612,8 @@ cmLocalUnixMakefileGenerator2
::WriteModuleLibraryRule(std::ostream& ruleFileStream,
const char* ruleFileName,
const cmTarget& target,
- std::vector<std::string>& objects)
+ std::vector<std::string>& objects,
+ const std::vector<std::string>& provides_requires)
{
const char* linkLanguage =
target.GetLinkerLanguage(this->GetGlobalGenerator());
@@ -1650,7 +1626,8 @@ cmLocalUnixMakefileGenerator2
this->AddConfigVariableFlags(extraFlags, "CMAKE_MODULE_LINKER_FLAGS");
// TODO: .def files should be supported here also.
this->WriteLibraryRule(ruleFileStream, ruleFileName, target, objects,
- linkRuleVar.c_str(), extraFlags.c_str());
+ linkRuleVar.c_str(), extraFlags.c_str(),
+ provides_requires);
}
//----------------------------------------------------------------------------
@@ -1661,7 +1638,8 @@ cmLocalUnixMakefileGenerator2
const cmTarget& target,
std::vector<std::string>& objects,
const char* linkRuleVar,
- const char* extraFlags)
+ const char* extraFlags,
+ const std::vector<std::string>& provides_requires)
{
// Write the dependency generation rule.
this->WriteTargetDependsRule(ruleFileStream, ruleFileName, target, objects);
@@ -1817,11 +1795,8 @@ cmLocalUnixMakefileGenerator2
cleanFiles.push_back(objs);
this->WriteTargetCleanRule(ruleFileStream, target, cleanFiles);
- // Add this to the list of build rules in this directory.
- if(target.IsInAll())
- {
- m_BuildTargets.push_back(target.GetName());
- }
+ // Write the driving make target.
+ this->WriteTargetRequiresRule(ruleFileStream, target, provides_requires);
}
//----------------------------------------------------------------------------
@@ -1931,6 +1906,62 @@ cmLocalUnixMakefileGenerator2
}
//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator2
+::WriteTargetRequiresRule(std::ostream& ruleFileStream, const cmTarget& target,
+ const std::vector<std::string>& provides_requires)
+{
+ // Create the driving make target.
+ std::string targetRequires = target.GetName();
+ targetRequires += ".requires";
+ if(provides_requires.empty())
+ {
+ // No provides-requires mode objects in this target. Anything
+ // that requires the target can build it directly.
+ std::vector<std::string> no_commands;
+ std::vector<std::string> depends;
+ depends.push_back(target.GetName());
+ this->WriteMakeRule(ruleFileStream, 0, 0,
+ targetRequires.c_str(), depends, no_commands);
+ }
+ else
+ {
+ // There are provides-requires mode objects in this target. Use
+ // provides-requires mode to build the target itself.
+ std::string targetProvides = target.GetName();
+ targetProvides += ".provides";
+ {
+ std::vector<std::string> no_commands;
+ std::vector<std::string> depends;
+ depends.push_back(target.GetName());
+ this->WriteMakeRule(ruleFileStream, 0, 0,
+ targetProvides.c_str(), depends, no_commands);
+ }
+ {
+ // Build list of require-level dependencies.
+ std::vector<std::string> depends;
+ for(std::vector<std::string>::const_iterator
+ pr = provides_requires.begin();
+ pr != provides_requires.end(); ++pr)
+ {
+ depends.push_back(*pr);
+ }
+
+ std::vector<std::string> commands;
+ commands.push_back(this->GetRecursiveMakeCall(targetProvides.c_str()));
+ this->WriteMakeRule(ruleFileStream, 0, 0,
+ targetRequires.c_str(), depends, commands);
+ }
+ }
+
+ // Add this to the list of build rules in this directory.
+ if(target.IsInAll())
+ {
+ m_BuildTargets.push_back(targetRequires);
+ }
+}
+
+//----------------------------------------------------------------------------
std::string
cmLocalUnixMakefileGenerator2
::GetTargetDirectory(const cmTarget& target)
@@ -2627,6 +2658,7 @@ cmLocalUnixMakefileGenerator2
dep += ".depends";
dep = this->ConvertToRelativeOutputPath(dep.c_str());
std::string tgt = jump->first;
+ tgt += ".requires";
tgt = this->ConvertToRelativeOutputPath(tgt.c_str());
// Build the jump-and-build command list.
diff --git a/Source/cmLocalUnixMakefileGenerator2.h b/Source/cmLocalUnixMakefileGenerator2.h
index e852ecb..41d5658 100644
--- a/Source/cmLocalUnixMakefileGenerator2.h
+++ b/Source/cmLocalUnixMakefileGenerator2.h
@@ -67,7 +67,8 @@ protected:
void GenerateTargetRuleFile(const cmTarget& target);
void GenerateObjectRuleFile(const cmTarget& target,
const cmSourceFile& source,
- std::vector<std::string>& objects);
+ std::vector<std::string>& objects,
+ std::vector<std::string>& provides_requires);
void GenerateCustomRuleFile(const cmCustomCommand& cc);
void GenerateUtilityRuleFile(const cmTarget& target);
bool GenerateDependsMakeFile(const std::string& lang,
@@ -107,25 +108,30 @@ protected:
void WriteExecutableRule(std::ostream& ruleFileStream,
const char* ruleFileName,
const cmTarget& target,
- std::vector<std::string>& objects);
+ std::vector<std::string>& objects,
+ const std::vector<std::string>& provides_requires);
void WriteStaticLibraryRule(std::ostream& ruleFileStream,
const char* ruleFileName,
const cmTarget& target,
- std::vector<std::string>& objects);
+ std::vector<std::string>& objects,
+ const std::vector<std::string>& provides_requires);
void WriteSharedLibraryRule(std::ostream& ruleFileStream,
const char* ruleFileName,
const cmTarget& target,
- std::vector<std::string>& objects);
+ std::vector<std::string>& objects,
+ const std::vector<std::string>& provides_requires);
void WriteModuleLibraryRule(std::ostream& ruleFileStream,
const char* ruleFileName,
const cmTarget& target,
- std::vector<std::string>& objects);
+ std::vector<std::string>& objects,
+ const std::vector<std::string>& provides_requires);
void WriteLibraryRule(std::ostream& ruleFileStream,
const char* ruleFileName,
const cmTarget& target,
std::vector<std::string>& objects,
const char* linkRuleVar,
- const char* extraLinkFlags);
+ const char* extraLinkFlags,
+ const std::vector<std::string>& provides_requires);
void WriteObjectsVariable(std::ostream& ruleFileStream,
const cmTarget& target,
const std::vector<std::string>& objects,
@@ -137,6 +143,9 @@ protected:
void WriteTargetCleanRule(std::ostream& ruleFileStream,
const cmTarget& target,
const std::vector<std::string>& files);
+ void WriteTargetRequiresRule(std::ostream& ruleFileStream,
+ const cmTarget& target,
+ const std::vector<std::string>& provides_requires);
std::string GetTargetDirectory(const cmTarget& target);
std::string GetSubdirTargetName(const char* pass, const char* subdir);
std::string GetObjectFileName(const cmTarget& target,