diff options
Diffstat (limited to 'Source/cmNinjaTargetGenerator.cxx')
-rw-r--r-- | Source/cmNinjaTargetGenerator.cxx | 195 |
1 files changed, 118 insertions, 77 deletions
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 3532c8b..0f10152 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -134,7 +134,7 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, this->AddFeatureFlags(flags, language.c_str()); this->GetLocalGenerator()->AddArchitectureFlags(flags, - this->GetTarget(), + this->GeneratorTarget, language.c_str(), this->GetConfigName()); @@ -152,8 +152,10 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, // Add include directory flags. { std::vector<std::string> includes; - this->LocalGenerator->GetIncludeDirectories(includes, this->Target, - language.c_str()); + const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget, + language.c_str(), config); std::string includeFlags = this->LocalGenerator->GetIncludeFlags(includes, language.c_str(), language == "RC" ? true : false); // full include paths for RC @@ -167,11 +169,41 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, // Append old-style preprocessor definition flags. this->LocalGenerator->AppendFlags(flags, this->Makefile->GetDefineFlags()); - // Add target-specific and source-specific flags. - this->LocalGenerator->AppendFlags(flags, - this->Target->GetProperty("COMPILE_FLAGS")); - this->LocalGenerator->AppendFlags(flags, - source->GetProperty("COMPILE_FLAGS")); + // Add target-specific flags. + if(this->Target->GetProperty("COMPILE_FLAGS")) + { + std::string langIncludeExpr = "CMAKE_"; + langIncludeExpr += language; + langIncludeExpr += "_FLAG_REGEX"; + const char* regex = this->Makefile-> + GetDefinition(langIncludeExpr.c_str()); + if(regex) + { + cmsys::RegularExpression r(regex); + std::vector<std::string> args; + cmSystemTools::ParseWindowsCommandLine( + this->Target->GetProperty("COMPILE_FLAGS"), + args); + for(std::vector<std::string>::iterator i = args.begin(); + i != args.end(); ++i) + { + if(r.find(i->c_str())) + { + this->LocalGenerator->AppendFlags + (flags, i->c_str()); + } + } + } + else + { + this->LocalGenerator->AppendFlags + (flags, this->Target->GetProperty("COMPILE_FLAGS")); + } + } + + // Add source file specific flags. + this->LocalGenerator->AppendFlags(flags, + source->GetProperty("COMPILE_FLAGS")); // TODO: Handle Apple frameworks. @@ -184,46 +216,37 @@ std::string cmNinjaTargetGenerator:: ComputeDefines(cmSourceFile *source, const std::string& language) { - std::string defines; + std::set<std::string> defines; // Add the export symbol definition for shared library objects. if(const char* exportMacro = this->Target->GetExportMacro()) { - this->LocalGenerator->AppendDefines(defines, exportMacro, - language.c_str()); + this->LocalGenerator->AppendDefines(defines, exportMacro); } // Add preprocessor definitions for this target and configuration. this->LocalGenerator->AppendDefines (defines, - this->Makefile->GetProperty("COMPILE_DEFINITIONS"), - language.c_str()); + this->GeneratorTarget->GetCompileDefinitions()); this->LocalGenerator->AppendDefines (defines, - this->Target->GetProperty("COMPILE_DEFINITIONS"), - language.c_str()); - this->LocalGenerator->AppendDefines - (defines, - source->GetProperty("COMPILE_DEFINITIONS"), - language.c_str()); + source->GetProperty("COMPILE_DEFINITIONS")); { std::string defPropName = "COMPILE_DEFINITIONS_"; defPropName += cmSystemTools::UpperCase(this->GetConfigName()); this->LocalGenerator->AppendDefines (defines, - this->Makefile->GetProperty(defPropName.c_str()), - language.c_str()); - this->LocalGenerator->AppendDefines - (defines, - this->Target->GetProperty(defPropName.c_str()), - language.c_str()); + this->GeneratorTarget->GetCompileDefinitions(this->GetConfigName())); this->LocalGenerator->AppendDefines (defines, - source->GetProperty(defPropName.c_str()), - language.c_str()); + source->GetProperty(defPropName.c_str())); } - return defines; + std::string definesString; + this->LocalGenerator->JoinDefines(defines, definesString, + language.c_str()); + + return definesString; } cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const @@ -234,7 +257,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const return cmNinjaDeps(); cmComputeLinkInformation* cli = - this->Target->GetLinkInformation(this->GetConfigName()); + this->GeneratorTarget->GetLinkInformation(this->GetConfigName()); if(!cli) return cmNinjaDeps(); @@ -295,23 +318,33 @@ std::string cmNinjaTargetGenerator::GetTargetName() const return this->Target->GetName(); } -std::string cmNinjaTargetGenerator::GetTargetPDB() const + +bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const { - std::string targetFullPathPDB; - if(this->Target->GetType() == cmTarget::EXECUTABLE || - this->Target->GetType() == cmTarget::STATIC_LIBRARY || - this->Target->GetType() == cmTarget::SHARED_LIBRARY || - this->Target->GetType() == cmTarget::MODULE_LIBRARY) + cmMakefile* mf = this->GetMakefile(); + if (mf->GetDefinition("MSVC_C_ARCHITECTURE_ID") || + mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID")) { - targetFullPathPDB = this->Target->GetDirectory(this->GetConfigName()); - targetFullPathPDB += "/"; - targetFullPathPDB += this->Target->GetPDBName(this->GetConfigName()); - } + std::string pdbPath; + if(this->Target->GetType() == cmTarget::EXECUTABLE || + this->Target->GetType() == cmTarget::STATIC_LIBRARY || + this->Target->GetType() == cmTarget::SHARED_LIBRARY || + this->Target->GetType() == cmTarget::MODULE_LIBRARY) + { + pdbPath = this->Target->GetPDBDirectory(this->GetConfigName()); + pdbPath += "/"; + pdbPath += this->Target->GetPDBName(this->GetConfigName()); + } - return targetFullPathPDB.c_str(); + vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat( + ConvertToNinjaPath(pdbPath.c_str()).c_str(), + cmLocalGenerator::SHELL); + EnsureParentDirectoryExists(pdbPath); + return true; + } + return false; } - void cmNinjaTargetGenerator ::WriteLanguageRules(const std::string& language) @@ -337,29 +370,30 @@ cmNinjaTargetGenerator std::string flags = "$FLAGS"; vars.Defines = "$DEFINES"; vars.TargetPDB = "$TARGET_PDB"; - + vars.ObjectDir = "$OBJECT_DIR"; cmMakefile* mf = this->GetMakefile(); bool useClDeps = false; + std::string clBinary; std::string clDepsBinary; std::string clShowPrefix; if (lang == "C" || lang == "CXX" || lang == "RC") { - const char* depsPtr = mf->GetDefinition("CMAKE_CMCLDEPS_EXECUTABLE"); - const char* showPtr = mf->GetDefinition("CMAKE_CL_SHOWINCLUDE_PREFIX"); - if (depsPtr && showPtr) + clDepsBinary = mf->GetSafeDefinition("CMAKE_CMCLDEPS_EXECUTABLE"); + if (!clDepsBinary.empty() && !mf->GetIsSourceFileTryCompile()) { - // don't wrap for try_compile, - // TODO but why doesn't it work with cmcldeps? - const std::string projectName = mf->GetProjectName() ? - mf->GetProjectName() : ""; - if (projectName != "CMAKE_TRY_COMPILE") + clShowPrefix = mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDE_PREFIX"); + clBinary = mf->GetDefinition("CMAKE_C_COMPILER") ? + mf->GetSafeDefinition("CMAKE_C_COMPILER") : + mf->GetSafeDefinition("CMAKE_CXX_COMPILER"); + if (!clBinary.empty() && !clShowPrefix.empty()) { useClDeps = true; - std::string qu = "\""; - clDepsBinary = qu + depsPtr + qu; - clShowPrefix = qu + showPtr + qu; + const std::string quote = " \""; + clBinary = quote + clBinary + "\" "; + clDepsBinary = quote + clDepsBinary + "\" "; + clShowPrefix = quote + clShowPrefix + "\" "; vars.DependencyFile = "$DEP_FILE"; } } @@ -393,16 +427,14 @@ cmNinjaTargetGenerator i != compileCmds.end(); ++i) this->GetLocalGenerator()->ExpandRuleVariables(*i, vars); - std::string cmdLine = - this->GetLocalGenerator()->BuildCommandLine(compileCmds); - + std::string cmdLine; if(useClDeps) { - std::string cl = mf->GetDefinition("CMAKE_C_COMPILER"); - cl = "\"" + cl + "\" "; - cmdLine = clDepsBinary + " " + lang + " $in \"$DEP_FILE\" $out " - + clShowPrefix + " " + cl + cmdLine; + cmdLine = clDepsBinary + lang + " $in \"$DEP_FILE\" $out " + + clShowPrefix + clBinary; } + cmdLine += this->GetLocalGenerator()->BuildCommandLine(compileCmds); + // Write the rule for compiling file of the given language. cmOStringStream comment; @@ -478,8 +510,6 @@ void cmNinjaTargetGenerator ::WriteObjectBuildStatement(cmSourceFile* source) { - cmNinjaDeps emptyDeps; - std::string comment; const std::string language = source->GetLanguage(); std::string rule = this->LanguageCompilerRule(language); @@ -503,11 +533,12 @@ cmNinjaTargetGenerator cmNinjaDeps orderOnlyDeps; this->GetLocalGenerator()->AppendTargetDepends(this->Target, orderOnlyDeps); + cmNinjaDeps implicitDeps; if(const char* objectDeps = source->GetProperty("OBJECT_DEPENDS")) { std::vector<std::string> depList; cmSystemTools::ExpandListArgument(objectDeps, depList); std::transform(depList.begin(), depList.end(), - std::back_inserter(orderOnlyDeps), MapToNinjaPath()); + std::back_inserter(implicitDeps), MapToNinjaPath()); } // Add order-only dependencies on custom command outputs. @@ -518,7 +549,7 @@ cmNinjaTargetGenerator cmCustomCommand const* cc = (*si)->GetCustomCommand(); const std::vector<std::string>& ccoutputs = cc->GetOutputs(); std::transform(ccoutputs.begin(), ccoutputs.end(), - std::back_inserter(orderOnlyDeps), MapToNinjaPath()); + std::back_inserter(implicitDeps), MapToNinjaPath()); } // If the source file is GENERATED and does not have a custom command @@ -537,15 +568,14 @@ cmNinjaTargetGenerator vars["DEP_FILE"] = objectFileName + ".d";; EnsureParentDirectoryExists(objectFileName); - // TODO move to GetTargetPDB - cmMakefile* mf = this->GetMakefile(); - if (mf->GetDefinition("MSVC_C_ARCHITECTURE_ID") || - mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID")) - { - vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat( - ConvertToNinjaPath(GetTargetPDB().c_str()).c_str(), - cmLocalGenerator::SHELL); - } + std::string objectDir = cmSystemTools::GetFilenamePath(objectFileName); + objectDir = this->GetLocalGenerator()->Convert(objectDir.c_str(), + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::SHELL); + vars["OBJECT_DIR"] = objectDir; + + + this->SetMsvcTargetPdbVariable(vars); if(this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS")) { @@ -569,6 +599,7 @@ cmNinjaTargetGenerator compileObjectVars.Source = escapedSourceFileName.c_str(); compileObjectVars.Object = objectFileName.c_str(); + compileObjectVars.ObjectDir = objectDir.c_str(); compileObjectVars.Flags = vars["FLAGS"].c_str(); compileObjectVars.Defines = vars["DEFINES"].c_str(); @@ -597,7 +628,7 @@ cmNinjaTargetGenerator rule, outputs, explicitDeps, - emptyDeps, + implicitDeps, orderOnlyDeps, vars); @@ -641,14 +672,24 @@ cmNinjaTargetGenerator void cmNinjaTargetGenerator -::EnsureDirectoryExists(const std::string& dir) +::EnsureDirectoryExists(const std::string& path) const { - cmSystemTools::MakeDirectory(dir.c_str()); + if (cmSystemTools::FileIsFullPath(path.c_str())) + { + cmSystemTools::MakeDirectory(path.c_str()); + } + else + { + const std::string fullPath = std::string(this->GetGlobalGenerator()-> + GetCMakeInstance()->GetHomeOutputDirectory()) + + "/" + path; + cmSystemTools::MakeDirectory(fullPath.c_str()); + } } void cmNinjaTargetGenerator -::EnsureParentDirectoryExists(const std::string& path) +::EnsureParentDirectoryExists(const std::string& path) const { EnsureDirectoryExists(cmSystemTools::GetParentDirectory(path.c_str())); } |