diff options
Diffstat (limited to 'Source/cmNinjaNormalTargetGenerator.cxx')
-rw-r--r-- | Source/cmNinjaNormalTargetGenerator.cxx | 87 |
1 files changed, 51 insertions, 36 deletions
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index a923d6068..6c54ced9a 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -153,7 +153,7 @@ cmNinjaNormalTargetGenerator cmTarget::TargetType targetType = this->GetTarget()->GetType(); std::string ruleName = this->LanguageLinkerRule(); if (useResponseFile) - ruleName += "_RSPFILE"; + ruleName += "_RSP_FILE"; // Select whether to use a response file for objects. std::string rspfile; @@ -168,20 +168,29 @@ cmNinjaNormalTargetGenerator std::string responseFlag; if (!useResponseFile) { vars.Objects = "$in"; - vars.LinkLibraries = "$LINK_LIBRARIES"; + vars.LinkLibraries = "$LINK_PATH $LINK_LIBRARIES"; } else { - // handle response file - std::string cmakeLinkVar = std::string("CMAKE_") + - this->TargetLinkLanguage + "_RESPONSE_FILE_LINK_FLAG"; + std::string cmakeVarLang = "CMAKE_"; + cmakeVarLang += this->TargetLinkLanguage; + + // build response file name + std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG"; const char * flag = GetMakefile()->GetDefinition(cmakeLinkVar.c_str()); if(flag) { responseFlag = flag; } else { responseFlag = "@"; } - rspfile = "$out.rsp"; + rspfile = "$RSP_FILE"; responseFlag += rspfile; - rspcontent = "$in $LINK_LIBRARIES"; + + // build response file content + std::string linkOptionVar = cmakeVarLang; + linkOptionVar += "_COMPILER_LINKER_OPTION_FLAG_"; + linkOptionVar += cmTarget::GetTargetTypeName(targetType); + const std::string linkOption = + GetMakefile()->GetSafeDefinition(linkOptionVar.c_str()); + rspcontent = "$in " + linkOption + " $LINK_PATH $LINK_LIBRARIES"; vars.Objects = responseFlag.c_str(); vars.LinkLibraries = ""; } @@ -420,12 +429,17 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() cmNinjaDeps explicitDeps = this->GetObjects(); cmNinjaDeps implicitDeps = this->ComputeLinkDeps(); + std::string frameworkPath; + std::string linkPath; this->GetLocalGenerator()->GetTargetFlags(vars["LINK_LIBRARIES"], vars["FLAGS"], vars["LINK_FLAGS"], - *this->GetTarget()); + frameworkPath, + linkPath, + this->GetGeneratorTarget()); this->AddModuleDefinitionFlag(vars["LINK_FLAGS"]); + vars["LINK_PATH"] = frameworkPath + linkPath; // Compute architecture specific link flags. Yes, these go into a different // variable for executables, probably due to a mistake made when duplicating @@ -434,7 +448,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() ? vars["FLAGS"] : vars["ARCH_FLAGS"]); this->GetLocalGenerator()->AddArchitectureFlags(flags, - this->GetTarget(), + this->GetGeneratorTarget(), this->TargetLinkLanguage, this->GetConfigName()); if (targetType == cmTarget::EXECUTABLE) { @@ -459,25 +473,16 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() } } - std::string path; if (!this->TargetNameImport.empty()) { - path = this->GetLocalGenerator()->ConvertToOutputFormat( - targetOutputImplib.c_str(), cmLocalGenerator::SHELL); - vars["TARGET_IMPLIB"] = path; - EnsureParentDirectoryExists(path); + const std::string impLibPath = this->GetLocalGenerator() + ->ConvertToOutputFormat(targetOutputImplib.c_str(), + cmLocalGenerator::SHELL); + vars["TARGET_IMPLIB"] = impLibPath; + EnsureParentDirectoryExists(impLibPath); } cmMakefile* mf = this->GetMakefile(); - if (mf->GetDefinition("MSVC_C_ARCHITECTURE_ID") || - mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID")) - { - path = this->GetTargetPDB(); - vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat( - ConvertToNinjaPath(path.c_str()).c_str(), - cmLocalGenerator::SHELL); - EnsureParentDirectoryExists(path); - } - else + if (!this->SetMsvcTargetPdbVariable(vars)) { // It is common to place debug symbols at a specific place, // so we need a plain target name in the rule available. @@ -494,9 +499,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() if (mf->IsOn("CMAKE_COMPILER_IS_MINGW")) { - path = GetTarget()->GetSupportDirectory(); - vars["OBJECT_DIR"] = ConvertToNinjaPath(path.c_str()); - EnsureDirectoryExists(path); + const std::string objPath = GetTarget()->GetSupportDirectory(); + vars["OBJECT_DIR"] = ConvertToNinjaPath(objPath.c_str()); + EnsureDirectoryExists(objPath); // ar.exe can't handle backslashes in rsp files (implictly used by gcc) std::string& linkLibraries = vars["LINK_LIBRARIES"]; std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/'); @@ -527,10 +532,10 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() // If we have any PRE_LINK commands, we need to go back to HOME_OUTPUT for // the link commands. if (!preLinkCmdLines.empty()) { - path = this->GetLocalGenerator()->ConvertToOutputFormat( - this->GetMakefile()->GetHomeOutputDirectory(), - cmLocalGenerator::SHELL); - preLinkCmdLines.push_back("cd " + path); + const std::string homeOutDir = this->GetLocalGenerator() + ->ConvertToOutputFormat(this->GetMakefile()->GetHomeOutputDirectory(), + cmLocalGenerator::SHELL); + preLinkCmdLines.push_back("cd " + homeOutDir); } vars["PRE_LINK"] = @@ -548,15 +553,24 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() int linkRuleLength = this->GetGlobalGenerator()-> GetRuleCmdLength(this->LanguageLinkerRule()); + + int commandLineLengthLimit = 1; + const char* forceRspFile = "CMAKE_NINJA_FORCE_RESPONSE_FILE"; + if (!this->GetMakefile()->IsDefinitionSet(forceRspFile) && + cmSystemTools::GetEnv(forceRspFile) == 0) { #ifdef _WIN32 - int commandLineLengthLimit = 8000 - linkRuleLength; + commandLineLengthLimit = 8000 - linkRuleLength; #elif defined(__linux) || defined(__APPLE__) - // for instance ARG_MAX is 2096152 on Ubuntu or 262144 on Mac - int commandLineLengthLimit = ((int)sysconf(_SC_ARG_MAX)) - - linkRuleLength - 1000; + // for instance ARG_MAX is 2096152 on Ubuntu or 262144 on Mac + commandLineLengthLimit = ((int)sysconf(_SC_ARG_MAX))-linkRuleLength-1000; #else - int commandLineLengthLimit = -1; + commandLineLengthLimit = -1; #endif + } + + const std::string rspfile = std::string + (cmake::GetCMakeFilesDirectoryPostSlash()) + + this->GetTarget()->GetName() + ".rsp"; // Write the build statement for this target. cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(), @@ -567,6 +581,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() implicitDeps, emptyDeps, vars, + rspfile, commandLineLengthLimit); if (targetOutput != targetOutputReal) { |