Merge topic 'ninja-rspfile-link-libraries'
4bb94c9 Ninja: sysconf() is declared in unistd.h bb36759 Ninja: enable response file support on Mac (length 262144) 3a2c8e8 Ninja: disable work around when linking with mingw 3856e66 Ninja: error on missing rspfile_content 8c1e35c Ninja: remove some unused default arguments 7f647cf Ninja: also write link libraries to rsp file
This commit is contained in:
commit
58f5e77d6a
@ -115,7 +115,9 @@ macro(__windows_compiler_gnu lang)
|
|||||||
list(APPEND CMAKE_${lang}_ABI_FILES "Platform/Windows-GNU-${lang}-ABI")
|
list(APPEND CMAKE_${lang}_ABI_FILES "Platform/Windows-GNU-${lang}-ABI")
|
||||||
|
|
||||||
# Support very long lists of object files.
|
# Support very long lists of object files.
|
||||||
if("${CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG}" STREQUAL "@")
|
# TODO: check for which gcc versions this is still needed, not needed for gcc >= 4.4.
|
||||||
|
# Ninja generator doesn't support this work around.
|
||||||
|
if("${CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG}" STREQUAL "@" AND NOT CMAKE_GENERATOR MATCHES "Ninja")
|
||||||
foreach(rule CREATE_SHARED_MODULE CREATE_SHARED_LIBRARY LINK_EXECUTABLE)
|
foreach(rule CREATE_SHARED_MODULE CREATE_SHARED_LIBRARY LINK_EXECUTABLE)
|
||||||
# The gcc/collect2/ld toolchain does not use response files
|
# The gcc/collect2/ld toolchain does not use response files
|
||||||
# internally so we cannot pass long object lists. Instead pass
|
# internally so we cannot pass long object lists. Instead pass
|
||||||
|
@ -217,6 +217,7 @@ void cmGlobalNinjaGenerator::AddCustomCommandRule()
|
|||||||
"Rule for running custom commands.",
|
"Rule for running custom commands.",
|
||||||
/*depfile*/ "",
|
/*depfile*/ "",
|
||||||
/*rspfile*/ "",
|
/*rspfile*/ "",
|
||||||
|
/*rspcontent*/ "",
|
||||||
/*restat*/ true);
|
/*restat*/ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,6 +259,7 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os,
|
|||||||
const std::string& comment,
|
const std::string& comment,
|
||||||
const std::string& depfile,
|
const std::string& depfile,
|
||||||
const std::string& rspfile,
|
const std::string& rspfile,
|
||||||
|
const std::string& rspcontent,
|
||||||
bool restat,
|
bool restat,
|
||||||
bool generator)
|
bool generator)
|
||||||
{
|
{
|
||||||
@ -304,10 +306,15 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os,
|
|||||||
|
|
||||||
if(!rspfile.empty())
|
if(!rspfile.empty())
|
||||||
{
|
{
|
||||||
cmGlobalNinjaGenerator::Indent(os, 1);
|
if (rspcontent.empty())
|
||||||
os << "rspfile = " << rspfile << "\n";
|
{
|
||||||
cmGlobalNinjaGenerator::Indent(os, 1);
|
cmSystemTools::Error("No rspfile_content given!", comment.c_str());
|
||||||
os << "rspfile_content = $in" << "\n";
|
return;
|
||||||
|
}
|
||||||
|
cmGlobalNinjaGenerator::Indent(os, 1);
|
||||||
|
os << "rspfile = " << rspfile << "\n";
|
||||||
|
cmGlobalNinjaGenerator::Indent(os, 1);
|
||||||
|
os << "rspfile_content = " << rspcontent << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(restat)
|
if(restat)
|
||||||
@ -538,6 +545,7 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name,
|
|||||||
const std::string& comment,
|
const std::string& comment,
|
||||||
const std::string& depfile,
|
const std::string& depfile,
|
||||||
const std::string& rspfile,
|
const std::string& rspfile,
|
||||||
|
const std::string& rspcontent,
|
||||||
bool restat,
|
bool restat,
|
||||||
bool generator)
|
bool generator)
|
||||||
{
|
{
|
||||||
@ -555,6 +563,7 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name,
|
|||||||
comment,
|
comment,
|
||||||
depfile,
|
depfile,
|
||||||
rspfile,
|
rspfile,
|
||||||
|
rspcontent,
|
||||||
restat,
|
restat,
|
||||||
generator);
|
generator);
|
||||||
|
|
||||||
@ -911,6 +920,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
|
|||||||
"Rule for re-running cmake.",
|
"Rule for re-running cmake.",
|
||||||
/*depfile=*/ "",
|
/*depfile=*/ "",
|
||||||
/*rspfile=*/ "",
|
/*rspfile=*/ "",
|
||||||
|
/*rspcontent*/ "",
|
||||||
/*restat=*/ false,
|
/*restat=*/ false,
|
||||||
/*generator=*/ true);
|
/*generator=*/ true);
|
||||||
|
|
||||||
@ -960,6 +970,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
|
|||||||
"Rule for cleaning all built files.",
|
"Rule for cleaning all built files.",
|
||||||
/*depfile=*/ "",
|
/*depfile=*/ "",
|
||||||
/*rspfile=*/ "",
|
/*rspfile=*/ "",
|
||||||
|
/*rspcontent*/ "",
|
||||||
/*restat=*/ false,
|
/*restat=*/ false,
|
||||||
/*generator=*/ false);
|
/*generator=*/ false);
|
||||||
WriteBuild(os,
|
WriteBuild(os,
|
||||||
@ -981,6 +992,7 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os)
|
|||||||
"Rule for printing all primary targets available.",
|
"Rule for printing all primary targets available.",
|
||||||
/*depfile=*/ "",
|
/*depfile=*/ "",
|
||||||
/*rspfile=*/ "",
|
/*rspfile=*/ "",
|
||||||
|
/*rspcontent*/ "",
|
||||||
/*restat=*/ false,
|
/*restat=*/ false,
|
||||||
/*generator=*/ false);
|
/*generator=*/ false);
|
||||||
WriteBuild(os,
|
WriteBuild(os,
|
||||||
|
@ -114,11 +114,12 @@ public:
|
|||||||
const std::string& name,
|
const std::string& name,
|
||||||
const std::string& command,
|
const std::string& command,
|
||||||
const std::string& description,
|
const std::string& description,
|
||||||
const std::string& comment = "",
|
const std::string& comment,
|
||||||
const std::string& depfile = "",
|
const std::string& depfile,
|
||||||
const std::string& rspfile = "" ,
|
const std::string& rspfile,
|
||||||
bool restat = false,
|
const std::string& rspcontent,
|
||||||
bool generator = false);
|
bool restat,
|
||||||
|
bool generator);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a variable named @a name to @a os with value @a value and an
|
* Write a variable named @a name to @a os with value @a value and an
|
||||||
@ -231,9 +232,10 @@ public:
|
|||||||
void AddRule(const std::string& name,
|
void AddRule(const std::string& name,
|
||||||
const std::string& command,
|
const std::string& command,
|
||||||
const std::string& description,
|
const std::string& description,
|
||||||
const std::string& comment = "",
|
const std::string& comment,
|
||||||
const std::string& depfile = "",
|
const std::string& depfile = "",
|
||||||
const std::string& rspfile = "",
|
const std::string& rspfile = "",
|
||||||
|
const std::string& rspcontent = "",
|
||||||
bool restat = false,
|
bool restat = false,
|
||||||
bool generator = false);
|
bool generator = false);
|
||||||
|
|
||||||
|
@ -18,6 +18,12 @@
|
|||||||
#include "cmMakefile.h"
|
#include "cmMakefile.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
cmNinjaNormalTargetGenerator::
|
cmNinjaNormalTargetGenerator::
|
||||||
cmNinjaNormalTargetGenerator(cmTarget* target)
|
cmNinjaNormalTargetGenerator(cmTarget* target)
|
||||||
@ -75,10 +81,8 @@ void cmNinjaNormalTargetGenerator::Generate()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this->WriteLinkRule(false);
|
this->WriteLinkRule(false); // write rule without rspfile support
|
||||||
#ifdef _WIN32 // TODO response file support only Linux
|
this->WriteLinkRule(true); // write rule with rspfile support
|
||||||
this->WriteLinkRule(true);
|
|
||||||
#endif
|
|
||||||
this->WriteLinkStatement();
|
this->WriteLinkStatement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,6 +144,7 @@ cmNinjaNormalTargetGenerator
|
|||||||
|
|
||||||
// Select whether to use a response file for objects.
|
// Select whether to use a response file for objects.
|
||||||
std::string rspfile;
|
std::string rspfile;
|
||||||
|
std::string rspcontent;
|
||||||
|
|
||||||
if (!this->GetGlobalGenerator()->HasRule(ruleName)) {
|
if (!this->GetGlobalGenerator()->HasRule(ruleName)) {
|
||||||
cmLocalGenerator::RuleVariables vars;
|
cmLocalGenerator::RuleVariables vars;
|
||||||
@ -150,6 +155,7 @@ cmNinjaNormalTargetGenerator
|
|||||||
std::string responseFlag;
|
std::string responseFlag;
|
||||||
if (!useResponseFile) {
|
if (!useResponseFile) {
|
||||||
vars.Objects = "$in";
|
vars.Objects = "$in";
|
||||||
|
vars.LinkLibraries = "$LINK_LIBRARIES";
|
||||||
} else {
|
} else {
|
||||||
// handle response file
|
// handle response file
|
||||||
std::string cmakeLinkVar = std::string("CMAKE_") +
|
std::string cmakeLinkVar = std::string("CMAKE_") +
|
||||||
@ -162,7 +168,9 @@ cmNinjaNormalTargetGenerator
|
|||||||
}
|
}
|
||||||
rspfile = "$out.rsp";
|
rspfile = "$out.rsp";
|
||||||
responseFlag += rspfile;
|
responseFlag += rspfile;
|
||||||
|
rspcontent = "$in $LINK_LIBRARIES";
|
||||||
vars.Objects = responseFlag.c_str();
|
vars.Objects = responseFlag.c_str();
|
||||||
|
vars.LinkLibraries = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
vars.ObjectDir = "$OBJECT_DIR";
|
vars.ObjectDir = "$OBJECT_DIR";
|
||||||
@ -189,7 +197,6 @@ cmNinjaNormalTargetGenerator
|
|||||||
vars.TargetVersionMajor = targetVersionMajor.c_str();
|
vars.TargetVersionMajor = targetVersionMajor.c_str();
|
||||||
vars.TargetVersionMinor = targetVersionMinor.c_str();
|
vars.TargetVersionMinor = targetVersionMinor.c_str();
|
||||||
|
|
||||||
vars.LinkLibraries = "$LINK_LIBRARIES";
|
|
||||||
vars.Flags = "$FLAGS";
|
vars.Flags = "$FLAGS";
|
||||||
vars.LinkFlags = "$LINK_FLAGS";
|
vars.LinkFlags = "$LINK_FLAGS";
|
||||||
|
|
||||||
@ -227,7 +234,8 @@ cmNinjaNormalTargetGenerator
|
|||||||
description.str(),
|
description.str(),
|
||||||
comment.str(),
|
comment.str(),
|
||||||
/*depfile*/ "",
|
/*depfile*/ "",
|
||||||
rspfile);
|
rspfile,
|
||||||
|
rspcontent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->TargetNameOut != this->TargetNameReal) {
|
if (this->TargetNameOut != this->TargetNameReal) {
|
||||||
@ -365,8 +373,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
|||||||
outputs.push_back(targetOutputReal);
|
outputs.push_back(targetOutputReal);
|
||||||
|
|
||||||
// Compute specific libraries to link with.
|
// Compute specific libraries to link with.
|
||||||
cmNinjaDeps explicitDeps = this->GetObjects(),
|
cmNinjaDeps explicitDeps = this->GetObjects();
|
||||||
implicitDeps = this->ComputeLinkDeps();
|
cmNinjaDeps implicitDeps = this->ComputeLinkDeps();
|
||||||
|
|
||||||
this->GetLocalGenerator()->GetTargetFlags(vars["LINK_LIBRARIES"],
|
this->GetLocalGenerator()->GetTargetFlags(vars["LINK_LIBRARIES"],
|
||||||
vars["FLAGS"],
|
vars["FLAGS"],
|
||||||
@ -432,6 +440,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
|||||||
path = GetTarget()->GetSupportDirectory();
|
path = GetTarget()->GetSupportDirectory();
|
||||||
vars["OBJECT_DIR"] = ConvertToNinjaPath(path.c_str());
|
vars["OBJECT_DIR"] = ConvertToNinjaPath(path.c_str());
|
||||||
EnsureDirectoryExists(path);
|
EnsureDirectoryExists(path);
|
||||||
|
// 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(), '\\', '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<cmCustomCommand> *cmdLists[3] = {
|
std::vector<cmCustomCommand> *cmdLists[3] = {
|
||||||
@ -478,12 +489,15 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
|||||||
symlinkVars["POST_BUILD"] = postBuildCmdLine;
|
symlinkVars["POST_BUILD"] = postBuildCmdLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmdLineLimit;
|
int linkRuleLength = this->GetGlobalGenerator()->
|
||||||
#ifdef _WIN32
|
|
||||||
cmdLineLimit = 8000 - this->GetGlobalGenerator()->
|
|
||||||
GetRuleCmdLength(this->LanguageLinkerRule());
|
GetRuleCmdLength(this->LanguageLinkerRule());
|
||||||
|
#ifdef _WIN32
|
||||||
|
int commandLineLengthLimit = 8000 - linkRuleLength;
|
||||||
|
#elif defined(__linux) || defined(__APPLE__)
|
||||||
|
// for instance ARG_MAX is 2096152 on Ubuntu or 262144 on Mac
|
||||||
|
int commandLineLengthLimit = sysconf(_SC_ARG_MAX) - linkRuleLength - 1000;
|
||||||
#else
|
#else
|
||||||
cmdLineLimit = -1; // TODO
|
int commandLineLengthLimit = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Write the build statement for this target.
|
// Write the build statement for this target.
|
||||||
@ -495,7 +509,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
|||||||
implicitDeps,
|
implicitDeps,
|
||||||
emptyDeps,
|
emptyDeps,
|
||||||
vars,
|
vars,
|
||||||
cmdLineLimit);
|
commandLineLengthLimit);
|
||||||
|
|
||||||
if (targetOutput != targetOutputReal) {
|
if (targetOutput != targetOutputReal) {
|
||||||
if (targetType == cmTarget::EXECUTABLE) {
|
if (targetType == cmTarget::EXECUTABLE) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user