summaryrefslogtreecommitdiffstats
path: root/Source/cmNinjaNormalTargetGenerator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmNinjaNormalTargetGenerator.cxx')
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx60
1 files changed, 49 insertions, 11 deletions
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 3e91545..04ba842 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -41,15 +41,16 @@ cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator(
, TargetLinkLanguage("")
{
this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName());
- if (target->GetType() == cmState::EXECUTABLE)
+ if (target->GetType() == cmState::EXECUTABLE) {
this->GetGeneratorTarget()->GetExecutableNames(
this->TargetNameOut, this->TargetNameReal, this->TargetNameImport,
this->TargetNamePDB, GetLocalGenerator()->GetConfigName());
- else
+ } else {
this->GetGeneratorTarget()->GetLibraryNames(
this->TargetNameOut, this->TargetNameSO, this->TargetNameReal,
this->TargetNameImport, this->TargetNamePDB,
GetLocalGenerator()->GetConfigName());
+ }
if (target->GetType() != cmState::OBJECT_LIBRARY) {
// on Windows the output dir is already needed at compile time
@@ -125,10 +126,11 @@ const char* cmNinjaNormalTargetGenerator::GetVisibleTypeName() const
case cmState::SHARED_LIBRARY:
return "shared library";
case cmState::MODULE_LIBRARY:
- if (this->GetGeneratorTarget()->IsCFBundleOnApple())
+ if (this->GetGeneratorTarget()->IsCFBundleOnApple()) {
return "CFBundle shared module";
- else
+ } else {
return "shared module";
+ }
case cmState::EXECUTABLE:
return "executable";
default:
@@ -144,6 +146,14 @@ std::string cmNinjaNormalTargetGenerator::LanguageLinkerRule() const
this->GetGeneratorTarget()->GetName());
}
+struct cmNinjaRemoveNoOpCommands
+{
+ bool operator()(std::string const& cmd)
+ {
+ return cmd.empty() || cmd[0] == ':';
+ }
+};
+
void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
{
cmState::TargetType targetType = this->GetGeneratorTarget()->GetType();
@@ -231,6 +241,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
i != linkCmds.end(); ++i) {
this->GetLocalGenerator()->ExpandRuleVariables(*i, vars);
}
+ {
+ // If there is no ranlib the command will be ":". Skip it.
+ std::vector<std::string>::iterator newEnd = std::remove_if(
+ linkCmds.begin(), linkCmds.end(), cmNinjaRemoveNoOpCommands());
+ linkCmds.erase(newEnd, linkCmds.end());
+ }
+
linkCmds.insert(linkCmds.begin(), "$PRE_LINK");
linkCmds.push_back("$POST_BUILD");
std::string linkCmd =
@@ -256,7 +273,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
std::string cmakeCommand =
this->GetLocalGenerator()->ConvertToOutputFormat(
cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
- if (targetType == cmState::EXECUTABLE)
+ if (targetType == cmState::EXECUTABLE) {
this->GetGlobalGenerator()->AddRule(
"CMAKE_SYMLINK_EXECUTABLE",
cmakeCommand + " -E cmake_symlink_executable"
@@ -269,7 +286,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
/*rspcontent*/ "",
/*restat*/ "",
/*generator*/ false);
- else
+ } else {
this->GetGlobalGenerator()->AddRule(
"CMAKE_SYMLINK_LIBRARY",
cmakeCommand + " -E cmake_symlink_library"
@@ -282,6 +299,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
/*rspcontent*/ "",
/*restat*/ "",
/*generator*/ false);
+ }
}
}
@@ -295,6 +313,22 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
const char* linkCmd = mf->GetDefinition(linkCmdVar);
if (linkCmd) {
cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
+ if (this->GetGeneratorTarget()->GetProperty("LINK_WHAT_YOU_USE")) {
+ std::string cmakeCommand =
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
+ cmakeCommand += " -E __run_iwyu --lwyu=";
+ cmGeneratorTarget& gt = *this->GetGeneratorTarget();
+ const std::string cfgName = this->GetConfigName();
+ std::string targetOutput = ConvertToNinjaPath(gt.GetFullPath(cfgName));
+ std::string targetOutputReal =
+ this->ConvertToNinjaPath(gt.GetFullPath(cfgName,
+ /*implib=*/false,
+ /*realpath=*/true));
+ cmakeCommand += targetOutputReal;
+ cmakeCommand += " || true";
+ linkCmds.push_back(cmakeCommand);
+ }
return linkCmds;
}
}
@@ -434,9 +468,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
vars["TARGET_FILE"] =
localGen.ConvertToOutputFormat(targetOutputReal, cmOutputConverter::SHELL);
- localGen.GetTargetFlags(vars["LINK_LIBRARIES"], vars["FLAGS"],
- vars["LINK_FLAGS"], frameworkPath, linkPath,
- &genTarget, useWatcomQuote);
+ localGen.GetTargetFlags(this->GetConfigName(), vars["LINK_LIBRARIES"],
+ vars["FLAGS"], vars["LINK_FLAGS"], frameworkPath,
+ linkPath, &genTarget, useWatcomQuote);
if (this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") &&
gt.GetType() == cmState::SHARED_LIBRARY) {
if (gt.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) {
@@ -467,6 +501,10 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
vars["MANIFESTS"] = this->GetManifests();
vars["LINK_PATH"] = frameworkPath + linkPath;
+ std::string lwyuFlags;
+ if (genTarget.GetProperty("LINK_WHAT_YOU_USE")) {
+ lwyuFlags = " -Wl,--no-as-needed";
+ }
// Compute architecture specific link flags. Yes, these go into a different
// variable for executables, probably due to a mistake made when duplicating
@@ -474,16 +512,17 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
if (targetType == cmState::EXECUTABLE) {
std::string t = vars["FLAGS"];
localGen.AddArchitectureFlags(t, &genTarget, TargetLinkLanguage, cfgName);
+ t += lwyuFlags;
vars["FLAGS"] = t;
} else {
std::string t = vars["ARCH_FLAGS"];
localGen.AddArchitectureFlags(t, &genTarget, TargetLinkLanguage, cfgName);
vars["ARCH_FLAGS"] = t;
t = "";
+ t += lwyuFlags;
localGen.AddLanguageFlags(t, TargetLinkLanguage, cfgName);
vars["LANGUAGE_COMPILE_FLAGS"] = t;
}
-
if (this->GetGeneratorTarget()->HasSOName(cfgName)) {
vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage);
vars["SONAME"] = this->TargetNameSO;
@@ -607,7 +646,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
vars["POST_BUILD"] = ":";
symlinkVars["POST_BUILD"] = postBuildCmdLine;
}
-
cmGlobalNinjaGenerator& globalGen = *this->GetGlobalGenerator();
int commandLineLengthLimit = -1;