On Wed, Jan 12, 2011 at 10:29 AM, Brad King <[email protected]> wrote:
> On 1/12/2011 1:19 PM, Manuel Klimek wrote:
>> I actually don't think writing out a single text file will be
>> noticeable in the overall generation. If I assume that I can write 60
>> MB/s, I'd need a code base 250 times the size of the cmake code base
>> before hitting 1 second. Since the cmake code base seems to be around
>> 200k LOC C++ code, this would be a 50M LOC code base. I don't expect
>> one second in the generation phase to matter for such a code base.
>
> Don't bother with the option for now. It is easily added after testing.
> Please refactor your patch into multiple commits as I previously
> requested and then we can review in more detail.
Split up the patch - apparently I need ssh access to push the topic
stuff, so I'm just attaching the patches.
Cheers,
/Manuel
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 9dcd8f1..52b6bb7 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -249,6 +249,62 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
}
//----------------------------------------------------------------------------
+std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) {
+ std::string flags;
+ const char *lang = l.c_str();
+
+ bool shared = ((this->Target->GetType() == cmTarget::SHARED_LIBRARY) ||
+ (this->Target->GetType() == cmTarget::MODULE_LIBRARY));
+
+ // Add language feature flags.
+ this->AddFeatureFlags(flags, lang);
+
+ this->LocalGenerator->AddArchitectureFlags(flags, this->Target,
+ lang, this->ConfigName);
+
+ // Fortran-specific flags computed for this target.
+ if(l == "Fortran")
+ {
+ this->AddFortranFlags(flags);
+ }
+
+ // Add shared-library flags if needed.
+ this->LocalGenerator->AddSharedFlags(flags, lang, shared);
+
+ // Add include directory flags.
+ this->LocalGenerator->
+ AppendFlags(flags, this->LocalGenerator->GetIncludeFlags(lang));
+ // Add include directory flags.
+ this->LocalGenerator->
+ AppendFlags(flags,this->GetFrameworkFlags().c_str());
+
+ return flags;
+}
+
+std::string cmMakefileTargetGenerator::GetDefines(const std::string &l) {
+ std::string defines;
+ const char *lang = l.c_str();
+ // Add the export symbol definition for shared library objects.
+ if(const char* exportMacro = this->Target->GetExportMacro())
+ {
+ this->LocalGenerator->AppendDefines(defines, exportMacro, lang);
+ }
+
+ // Add preprocessor definitions for this target and configuration.
+ this->LocalGenerator->AppendDefines
+ (defines, this->Makefile->GetProperty("COMPILE_DEFINITIONS"), lang);
+ this->LocalGenerator->AppendDefines
+ (defines, this->Target->GetProperty("COMPILE_DEFINITIONS"), lang);
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName +=
+ cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName);
+ this->LocalGenerator->AppendDefines
+ (defines, this->Makefile->GetProperty(defPropName.c_str()), lang);
+ this->LocalGenerator->AppendDefines
+ (defines, this->Target->GetProperty(defPropName.c_str()), lang);
+ return defines;
+}
+
void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
{
// write language flags for target
@@ -262,68 +318,22 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
cmStdString compiler = "CMAKE_";
compiler += *l;
compiler += "_COMPILER";
- *this->FlagFileStream << "# compile " << l->c_str() << " with " <<
+ *this->FlagFileStream << "# compile " << l->c_str() << " with " <<
this->Makefile->GetSafeDefinition(compiler.c_str()) << "\n";
}
for(std::set<cmStdString>::const_iterator l = languages.begin();
l != languages.end(); ++l)
{
- const char *lang = l->c_str();
- std::string flags;
- std::string defines;
- bool shared = ((this->Target->GetType() == cmTarget::SHARED_LIBRARY) ||
- (this->Target->GetType() == cmTarget::MODULE_LIBRARY));
-
- // Add the export symbol definition for shared library objects.
- if(const char* exportMacro = this->Target->GetExportMacro())
- {
- this->LocalGenerator->AppendDefines(defines, exportMacro, lang);
- }
-
- // Add preprocessor definitions for this target and configuration.
- this->LocalGenerator->AppendDefines
- (defines, this->Makefile->GetProperty("COMPILE_DEFINITIONS"), lang);
- this->LocalGenerator->AppendDefines
- (defines, this->Target->GetProperty("COMPILE_DEFINITIONS"), lang);
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName +=
- cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName);
- this->LocalGenerator->AppendDefines
- (defines, this->Makefile->GetProperty(defPropName.c_str()), lang);
- this->LocalGenerator->AppendDefines
- (defines, this->Target->GetProperty(defPropName.c_str()), lang);
-
- // Add language feature flags.
- this->AddFeatureFlags(flags, lang);
-
- this->LocalGenerator->AddArchitectureFlags(flags, this->Target,
- lang, this->ConfigName);
-
- // Fortran-specific flags computed for this target.
- if(*l == "Fortran")
- {
- this->AddFortranFlags(flags);
- }
-
- // Add shared-library flags if needed.
- this->LocalGenerator->AddSharedFlags(flags, lang, shared);
-
- // Add include directory flags.
- this->LocalGenerator->
- AppendFlags(flags, this->LocalGenerator->GetIncludeFlags(lang));
- // Add include directory flags.
- this->LocalGenerator->
- AppendFlags(flags,this->GetFrameworkFlags().c_str());
-
- *this->FlagFileStream << lang << "_FLAGS = " << flags << "\n\n";
- *this->FlagFileStream << lang << "_DEFINES = " << defines << "\n\n";
+ *this->FlagFileStream << *l << "_FLAGS = " << this->GetFlags(*l) << "\n\n";
+ *this->FlagFileStream << *l << "_DEFINES = " << this->GetDefines(*l) <<
+ "\n\n";
}
// Add target-specific flags.
if(this->Target->GetProperty("COMPILE_FLAGS"))
{
- std::string flags;
+ std::string flags;
this->LocalGenerator->AppendFlags
(flags, this->Target->GetProperty("COMPILE_FLAGS"));
*this->FlagFileStream << "# TARGET_FLAGS = " << flags << "\n\n";
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index c9aede2..12dbb25 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -212,6 +212,9 @@ protected:
std::string MacContentDirectory;
std::set<cmStdString> MacContentFolders;
+ std::string GetFlags(const std::string &l);
+ std::string GetDefines(const std::string &l);
+
// Target-wide Fortran module output directory.
bool FortranModuleDirectoryComputed;
std::string FortranModuleDirectory;
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index d9a341c..92f87c9 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -31,6 +31,7 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
#else
this->UseLinkScript = true;
#endif
+ this->CommandDatabase = NULL;
}
void cmGlobalUnixMakefileGenerator3
@@ -139,6 +140,17 @@ void cmGlobalUnixMakefileGenerator3
}
//----------------------------------------------------------------------------
+std::string EscapeJSON(const std::string& s) {
+ std::string result;
+ for (int i = 0; i < s.size(); ++i) {
+ if (s[i] == '"' || s[i] == '\\') {
+ result += '\\';
+ }
+ result += s[i];
+ }
+ return result;
+}
+
void cmGlobalUnixMakefileGenerator3::Generate()
{
// first do superclass method
@@ -189,6 +201,35 @@ void cmGlobalUnixMakefileGenerator3::Generate()
// write the main makefile
this->WriteMainMakefile2();
this->WriteMainCMakefile();
+
+ if (this->CommandDatabase != NULL) {
+ *this->CommandDatabase << std::endl << "]";
+ delete this->CommandDatabase;
+ this->CommandDatabase = NULL;
+ }
+}
+
+void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand(
+ const std::string &sourceFile, const std::string &workingDirectory,
+ const std::string &compileCommand) {
+ if (this->CommandDatabase == NULL)
+ {
+ std::string commandDatabaseName =
+ std::string(this->GetCMakeInstance()->GetHomeOutputDirectory())
+ + "/cxx_commands.json";
+ this->CommandDatabase =
+ new cmGeneratedFileStream(commandDatabaseName.c_str());
+ *this->CommandDatabase << "[" << std::endl;
+ } else {
+ *this->CommandDatabase << "," << std::endl;
+ }
+ *this->CommandDatabase << "{" << std::endl
+ << " \"directory\": \"" << EscapeJSON(workingDirectory) << "\","
+ << std::endl
+ << " \"command\": \"" << EscapeJSON(compileCommand) << "\","
+ << std::endl
+ << " \"file\": \"" << EscapeJSON(sourceFile) << "\""
+ << std::endl << "}";
}
void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index cdc9460..a152e01 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -112,6 +112,10 @@ public:
/** Record per-target progress information. */
void RecordTargetProgress(cmMakefileTargetGenerator* tg);
+ void AddCXXCompileCommand(const std::string &sourceFile,
+ const std::string &workingDirectory,
+ const std::string &compileCommand);
+
protected:
void WriteMainMakefile2();
void WriteMainCMakefile();
@@ -178,6 +182,8 @@ protected:
size_t CountProgressMarksInTarget(cmTarget* target,
std::set<cmTarget*>& emitted);
size_t CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg);
+
+ cmGeneratedFileStream *CommandDatabase;
};
#endif
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 52b6bb7..c0085f9 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -645,6 +645,9 @@ cmMakefileTargetGenerator
vars.Flags = flags.c_str();
vars.Defines = defines.c_str();
+ bool lang_is_c_or_cxx = ((strcmp(lang, "C") == 0) ||
+ (strcmp(lang, "CXX") == 0));
+
// Construct the compile rules.
{
std::string compileRuleVar = "CMAKE_";
@@ -655,6 +658,22 @@ cmMakefileTargetGenerator
std::vector<std::string> compileCommands;
cmSystemTools::ExpandListArgument(compileRule, compileCommands);
+ if (lang_is_c_or_cxx && compileCommands.size() == 1)
+ {
+ std::string compileCommand = compileCommands[0];
+ this->LocalGenerator->ExpandRuleVariables(compileCommand, vars);
+ std::string workingDirectory =
+ this->LocalGenerator->Convert(
+ this->Makefile->GetStartOutputDirectory(), cmLocalGenerator::FULL);
+ compileCommand.replace(compileCommand.find(langFlags),
+ langFlags.size(), this->GetFlags(lang));
+ std::string langDefines = std::string("$(") + lang + "_DEFINES)";
+ compileCommand.replace(compileCommand.find(langDefines),
+ langDefines.size(), this->GetDefines(lang));
+ this->GlobalGenerator->AddCXXCompileCommand(
+ source.GetFullPath(), workingDirectory, compileCommand);
+ }
+
// Expand placeholders in the commands.
for(std::vector<std::string>::iterator i = compileCommands.begin();
i != compileCommands.end(); ++i)
@@ -695,8 +714,6 @@ cmMakefileTargetGenerator
}
}
- bool lang_is_c_or_cxx = ((strcmp(lang, "C") == 0) ||
- (strcmp(lang, "CXX") == 0));
bool do_preprocess_rules = lang_is_c_or_cxx &&
this->LocalGenerator->GetCreatePreprocessedSourceRules();
bool do_assembly_rules = lang_is_c_or_cxx &&
_______________________________________________
cmake-developers mailing list
[email protected]
http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-developers