mirror of
https://github.com/Kitware/CMake.git
synced 2026-07-02 12:47:48 +00:00
CUDA: Add separable compilation support to the makefile generator.
This commit is contained in:
committed by
Brad King
parent
43ce4414c4
commit
d038559e49
@@ -10,6 +10,7 @@
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalUnixMakefileGenerator3.h"
|
||||
#include "cmLinkLineComputer.h"
|
||||
#include "cmLinkLineDeviceComputer.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmLocalUnixMakefileGenerator3.h"
|
||||
#include "cmMakefile.h"
|
||||
@@ -56,6 +57,9 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
|
||||
// write in rules for object files and custom commands
|
||||
this->WriteTargetBuildRules();
|
||||
|
||||
// write the device link rules
|
||||
this->WriteDeviceExecutableRule(false);
|
||||
|
||||
// write the link rules
|
||||
this->WriteExecutableRule(false);
|
||||
if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName)) {
|
||||
@@ -77,6 +81,218 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
|
||||
this->CloseFileStreams();
|
||||
}
|
||||
|
||||
void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
|
||||
bool relink)
|
||||
{
|
||||
#ifdef CMAKE_BUILD_WITH_CMAKE
|
||||
const std::string cuda_lang("CUDA");
|
||||
cmGeneratorTarget::LinkClosure const* closure =
|
||||
this->GeneratorTarget->GetLinkClosure(this->ConfigName);
|
||||
|
||||
const bool hasCUDA =
|
||||
(std::find(closure->Languages.begin(), closure->Languages.end(),
|
||||
cuda_lang) != closure->Languages.end());
|
||||
if (!hasCUDA) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> commands;
|
||||
|
||||
// Build list of dependencies.
|
||||
std::vector<std::string> depends;
|
||||
this->AppendLinkDepends(depends);
|
||||
|
||||
// Get the language to use for linking this library.
|
||||
std::string linkLanguage = "CUDA";
|
||||
|
||||
// Get the name of the device object to generate.
|
||||
std::string const targetOutputReal =
|
||||
this->GeneratorTarget->ObjectDirectory + "cmake_device_link.o";
|
||||
this->DeviceLinkObject = targetOutputReal;
|
||||
|
||||
this->NumberOfProgressActions++;
|
||||
if (!this->NoRuleMessages) {
|
||||
cmLocalUnixMakefileGenerator3::EchoProgress progress;
|
||||
this->MakeEchoProgress(progress);
|
||||
// Add the link message.
|
||||
std::string buildEcho = "Linking ";
|
||||
buildEcho += linkLanguage;
|
||||
buildEcho += " device code ";
|
||||
buildEcho += targetOutputReal;
|
||||
this->LocalGenerator->AppendEcho(
|
||||
commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress);
|
||||
}
|
||||
|
||||
// Build a list of compiler flags and linker flags.
|
||||
std::string flags;
|
||||
std::string linkFlags;
|
||||
|
||||
// Add flags to create an executable.
|
||||
// Add symbol export flags if necessary.
|
||||
if (this->GeneratorTarget->IsExecutableWithExports()) {
|
||||
std::string export_flag_var = "CMAKE_EXE_EXPORTS_";
|
||||
export_flag_var += linkLanguage;
|
||||
export_flag_var += "_FLAG";
|
||||
this->LocalGenerator->AppendFlags(
|
||||
linkFlags, this->Makefile->GetDefinition(export_flag_var));
|
||||
}
|
||||
|
||||
this->LocalGenerator->AppendFlags(linkFlags,
|
||||
this->LocalGenerator->GetLinkLibsCMP0065(
|
||||
linkLanguage, *this->GeneratorTarget));
|
||||
|
||||
// Add language feature flags.
|
||||
this->AddFeatureFlags(flags, linkLanguage);
|
||||
|
||||
this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
|
||||
linkLanguage, this->ConfigName);
|
||||
|
||||
// Add target-specific linker flags.
|
||||
this->LocalGenerator->AppendFlags(
|
||||
linkFlags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
|
||||
std::string linkFlagsConfig = "LINK_FLAGS_";
|
||||
linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
|
||||
this->LocalGenerator->AppendFlags(
|
||||
linkFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
|
||||
|
||||
{
|
||||
CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
|
||||
this->CreateLinkLineComputer(
|
||||
this->LocalGenerator,
|
||||
this->LocalGenerator->GetStateSnapshot().GetDirectory()));
|
||||
|
||||
this->AddModuleDefinitionFlag(linkLineComputer.get(), linkFlags);
|
||||
}
|
||||
|
||||
// Construct a list of files associated with this executable that
|
||||
// may need to be cleaned.
|
||||
std::vector<std::string> exeCleanFiles;
|
||||
exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal));
|
||||
|
||||
// Determine whether a link script will be used.
|
||||
bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();
|
||||
|
||||
// Construct the main link rule.
|
||||
std::vector<std::string> real_link_commands;
|
||||
const std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_EXECUTABLE";
|
||||
const std::string linkRule = this->GetLinkRule(linkRuleVar);
|
||||
std::vector<std::string> commands1;
|
||||
cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
|
||||
|
||||
bool useResponseFileForObjects =
|
||||
this->CheckUseResponseFileForObjects(linkLanguage);
|
||||
bool const useResponseFileForLibs =
|
||||
this->CheckUseResponseFileForLibraries(linkLanguage);
|
||||
|
||||
// Expand the rule variables.
|
||||
{
|
||||
bool useWatcomQuote =
|
||||
this->Makefile->IsOn(linkRuleVar + "_USE_WATCOM_QUOTE");
|
||||
|
||||
// Set path conversion for link script shells.
|
||||
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
|
||||
|
||||
CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
|
||||
new cmLinkLineDeviceComputer(
|
||||
this->LocalGenerator,
|
||||
this->LocalGenerator->GetStateSnapshot().GetDirectory()));
|
||||
linkLineComputer->SetForResponse(useResponseFileForLibs);
|
||||
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
|
||||
linkLineComputer->SetRelink(relink);
|
||||
|
||||
// Collect up flags to link in needed libraries.
|
||||
std::string linkLibs;
|
||||
this->CreateLinkLibs(linkLineComputer.get(), linkLibs,
|
||||
useResponseFileForLibs, depends);
|
||||
|
||||
// Construct object file lists that may be needed to expand the
|
||||
// rule.
|
||||
std::string buildObjs;
|
||||
this->CreateObjectLists(useLinkScript, false, useResponseFileForObjects,
|
||||
buildObjs, depends, useWatcomQuote);
|
||||
|
||||
cmRulePlaceholderExpander::RuleVariables vars;
|
||||
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
|
||||
|
||||
objectDir = this->LocalGenerator->ConvertToOutputFormat(
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory(), objectDir),
|
||||
cmOutputConverter::SHELL);
|
||||
|
||||
cmOutputConverter::OutputFormat output = (useWatcomQuote)
|
||||
? cmOutputConverter::WATCOMQUOTE
|
||||
: cmOutputConverter::SHELL;
|
||||
std::string target = this->LocalGenerator->ConvertToOutputFormat(
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal),
|
||||
output);
|
||||
|
||||
vars.Language = linkLanguage.c_str();
|
||||
vars.Objects = buildObjs.c_str();
|
||||
vars.ObjectDir = objectDir.c_str();
|
||||
vars.Target = target.c_str();
|
||||
vars.LinkLibraries = linkLibs.c_str();
|
||||
vars.Flags = flags.c_str();
|
||||
vars.LinkFlags = linkFlags.c_str();
|
||||
|
||||
std::string launcher;
|
||||
|
||||
const char* val = this->LocalGenerator->GetRuleLauncher(
|
||||
this->GeneratorTarget, "RULE_LAUNCH_LINK");
|
||||
if (val && *val) {
|
||||
launcher = val;
|
||||
launcher += " ";
|
||||
}
|
||||
|
||||
CM_AUTO_PTR<cmRulePlaceholderExpander> rulePlaceholderExpander(
|
||||
this->LocalGenerator->CreateRulePlaceholderExpander());
|
||||
|
||||
// Expand placeholders in the commands.
|
||||
rulePlaceholderExpander->SetTargetImpLib(targetOutputReal);
|
||||
for (std::vector<std::string>::iterator i = real_link_commands.begin();
|
||||
i != real_link_commands.end(); ++i) {
|
||||
*i = launcher + *i;
|
||||
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, *i,
|
||||
vars);
|
||||
}
|
||||
|
||||
// Restore path conversion to normal shells.
|
||||
this->LocalGenerator->SetLinkScriptShell(false);
|
||||
}
|
||||
|
||||
// Optionally convert the build rule to use a script to avoid long
|
||||
// command lines in the make shell.
|
||||
if (useLinkScript) {
|
||||
// Use a link script.
|
||||
const char* name = (relink ? "drelink.txt" : "dlink.txt");
|
||||
this->CreateLinkScript(name, real_link_commands, commands1, depends);
|
||||
} else {
|
||||
// No link script. Just use the link rule directly.
|
||||
commands1 = real_link_commands;
|
||||
}
|
||||
this->LocalGenerator->CreateCDCommand(
|
||||
commands1, this->Makefile->GetCurrentBinaryDirectory(),
|
||||
this->LocalGenerator->GetBinaryDirectory());
|
||||
commands.insert(commands.end(), commands1.begin(), commands1.end());
|
||||
commands1.clear();
|
||||
|
||||
// Write the build rule.
|
||||
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, CM_NULLPTR,
|
||||
targetOutputReal, depends, commands,
|
||||
false);
|
||||
|
||||
// Write the main driver rule to build everything in this target.
|
||||
this->WriteTargetDriverRule(targetOutputReal, relink);
|
||||
|
||||
// Clean all the possible executable names and symlinks.
|
||||
this->CleanFiles.insert(this->CleanFiles.end(), exeCleanFiles.begin(),
|
||||
exeCleanFiles.end());
|
||||
#else
|
||||
static_cast<void>(relink);
|
||||
#endif
|
||||
}
|
||||
|
||||
void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||
{
|
||||
std::vector<std::string> commands;
|
||||
@@ -84,6 +300,9 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||
// Build list of dependencies.
|
||||
std::vector<std::string> depends;
|
||||
this->AppendLinkDepends(depends);
|
||||
if (!this->DeviceLinkObject.empty()) {
|
||||
depends.push_back(this->DeviceLinkObject);
|
||||
}
|
||||
|
||||
// Get the name of the executable to generate.
|
||||
std::string targetName;
|
||||
@@ -327,6 +546,14 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||
std::string buildObjs;
|
||||
this->CreateObjectLists(useLinkScript, false, useResponseFileForObjects,
|
||||
buildObjs, depends, useWatcomQuote);
|
||||
if (!this->DeviceLinkObject.empty()) {
|
||||
buildObjs += " " +
|
||||
this->LocalGenerator->ConvertToOutputFormat(
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory(),
|
||||
this->DeviceLinkObject),
|
||||
cmOutputConverter::SHELL);
|
||||
}
|
||||
|
||||
// maybe create .def file from list of objects
|
||||
if (this->GeneratorTarget->IsExecutableWithExports() &&
|
||||
|
||||
@@ -21,6 +21,10 @@ public:
|
||||
|
||||
protected:
|
||||
virtual void WriteExecutableRule(bool relink);
|
||||
virtual void WriteDeviceExecutableRule(bool relink);
|
||||
|
||||
private:
|
||||
std::string DeviceLinkObject;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalUnixMakefileGenerator3.h"
|
||||
#include "cmLinkLineComputer.h"
|
||||
#include "cmLinkLineDeviceComputer.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmLocalUnixMakefileGenerator3.h"
|
||||
#include "cmMakefile.h"
|
||||
@@ -151,6 +152,24 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
|
||||
this->WriteFrameworkRules(relink);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!relink) {
|
||||
const std::string cuda_lang("CUDA");
|
||||
cmGeneratorTarget::LinkClosure const* closure =
|
||||
this->GeneratorTarget->GetLinkClosure(this->ConfigName);
|
||||
|
||||
const bool hasCUDA =
|
||||
(std::find(closure->Languages.begin(), closure->Languages.end(),
|
||||
cuda_lang) != closure->Languages.end());
|
||||
if (hasCUDA) {
|
||||
std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
|
||||
std::string extraFlags;
|
||||
this->LocalGenerator->AppendFlags(
|
||||
extraFlags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
|
||||
this->WriteDeviceLibraryRules(linkRuleVar, extraFlags, relink);
|
||||
}
|
||||
}
|
||||
|
||||
std::string linkLanguage =
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
|
||||
std::string linkRuleVar = "CMAKE_";
|
||||
@@ -183,6 +202,24 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
|
||||
|
||||
void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
|
||||
{
|
||||
|
||||
if (!relink) {
|
||||
const std::string cuda_lang("CUDA");
|
||||
cmGeneratorTarget::LinkClosure const* closure =
|
||||
this->GeneratorTarget->GetLinkClosure(this->ConfigName);
|
||||
|
||||
const bool hasCUDA =
|
||||
(std::find(closure->Languages.begin(), closure->Languages.end(),
|
||||
cuda_lang) != closure->Languages.end());
|
||||
if (hasCUDA) {
|
||||
std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
|
||||
std::string extraFlags;
|
||||
this->LocalGenerator->AppendFlags(
|
||||
extraFlags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
|
||||
this->WriteDeviceLibraryRules(linkRuleVar, extraFlags, relink);
|
||||
}
|
||||
}
|
||||
|
||||
std::string linkLanguage =
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
|
||||
std::string linkRuleVar = "CMAKE_";
|
||||
@@ -230,6 +267,180 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
|
||||
this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
|
||||
}
|
||||
|
||||
void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
|
||||
const std::string& linkRuleVar, const std::string& extraFlags, bool relink)
|
||||
{
|
||||
#ifdef CMAKE_BUILD_WITH_CMAKE
|
||||
// TODO: Merge the methods that call this method to avoid
|
||||
// code duplication.
|
||||
std::vector<std::string> commands;
|
||||
|
||||
// Build list of dependencies.
|
||||
std::vector<std::string> depends;
|
||||
this->AppendLinkDepends(depends);
|
||||
|
||||
// Get the language to use for linking this library.
|
||||
std::string linkLanguage = "CUDA";
|
||||
|
||||
// Create set of linking flags.
|
||||
std::string linkFlags;
|
||||
this->LocalGenerator->AppendFlags(linkFlags, extraFlags);
|
||||
|
||||
// Get the name of the device object to generate.
|
||||
std::string const targetOutputReal =
|
||||
this->GeneratorTarget->ObjectDirectory + "cmake_device_link.o";
|
||||
this->DeviceLinkObject = targetOutputReal;
|
||||
|
||||
this->NumberOfProgressActions++;
|
||||
if (!this->NoRuleMessages) {
|
||||
cmLocalUnixMakefileGenerator3::EchoProgress progress;
|
||||
this->MakeEchoProgress(progress);
|
||||
// Add the link message.
|
||||
std::string buildEcho = "Linking " + linkLanguage + " device code";
|
||||
buildEcho += targetOutputReal;
|
||||
this->LocalGenerator->AppendEcho(
|
||||
commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress);
|
||||
}
|
||||
// Clean files associated with this library.
|
||||
std::vector<std::string> libCleanFiles;
|
||||
libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal));
|
||||
|
||||
// Determine whether a link script will be used.
|
||||
bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();
|
||||
|
||||
bool useResponseFileForObjects =
|
||||
this->CheckUseResponseFileForObjects(linkLanguage);
|
||||
bool const useResponseFileForLibs =
|
||||
this->CheckUseResponseFileForLibraries(linkLanguage);
|
||||
|
||||
cmRulePlaceholderExpander::RuleVariables vars;
|
||||
vars.Language = linkLanguage.c_str();
|
||||
|
||||
// Expand the rule variables.
|
||||
std::vector<std::string> real_link_commands;
|
||||
{
|
||||
bool useWatcomQuote =
|
||||
this->Makefile->IsOn(linkRuleVar + "_USE_WATCOM_QUOTE");
|
||||
|
||||
// Set path conversion for link script shells.
|
||||
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
|
||||
|
||||
// Collect up flags to link in needed libraries.
|
||||
std::string linkLibs;
|
||||
if (this->GeneratorTarget->GetType() != cmStateEnums::STATIC_LIBRARY) {
|
||||
|
||||
CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
|
||||
new cmLinkLineDeviceComputer(
|
||||
this->LocalGenerator,
|
||||
this->LocalGenerator->GetStateSnapshot().GetDirectory()));
|
||||
linkLineComputer->SetForResponse(useResponseFileForLibs);
|
||||
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
|
||||
linkLineComputer->SetRelink(relink);
|
||||
|
||||
this->CreateLinkLibs(linkLineComputer.get(), linkLibs,
|
||||
useResponseFileForLibs, depends);
|
||||
}
|
||||
|
||||
// Construct object file lists that may be needed to expand the
|
||||
// rule.
|
||||
std::string buildObjs;
|
||||
this->CreateObjectLists(useLinkScript, false, // useArchiveRules
|
||||
useResponseFileForObjects, buildObjs, depends,
|
||||
useWatcomQuote);
|
||||
|
||||
cmOutputConverter::OutputFormat output = (useWatcomQuote)
|
||||
? cmOutputConverter::WATCOMQUOTE
|
||||
: cmOutputConverter::SHELL;
|
||||
|
||||
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
|
||||
objectDir = this->LocalGenerator->ConvertToOutputFormat(
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory(), objectDir),
|
||||
cmOutputConverter::SHELL);
|
||||
|
||||
std::string target = this->LocalGenerator->ConvertToOutputFormat(
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal),
|
||||
output);
|
||||
|
||||
vars.Objects = buildObjs.c_str();
|
||||
vars.ObjectDir = objectDir.c_str();
|
||||
vars.Target = target.c_str();
|
||||
vars.LinkLibraries = linkLibs.c_str();
|
||||
vars.ObjectsQuoted = buildObjs.c_str();
|
||||
vars.LinkFlags = linkFlags.c_str();
|
||||
|
||||
// Add language feature flags.
|
||||
std::string langFlags;
|
||||
this->AddFeatureFlags(langFlags, linkLanguage);
|
||||
|
||||
vars.LanguageCompileFlags = langFlags.c_str();
|
||||
|
||||
std::string launcher;
|
||||
const char* val = this->LocalGenerator->GetRuleLauncher(
|
||||
this->GeneratorTarget, "RULE_LAUNCH_LINK");
|
||||
if (val && *val) {
|
||||
launcher = val;
|
||||
launcher += " ";
|
||||
}
|
||||
|
||||
CM_AUTO_PTR<cmRulePlaceholderExpander> rulePlaceholderExpander(
|
||||
this->LocalGenerator->CreateRulePlaceholderExpander());
|
||||
|
||||
// Construct the main link rule and expand placeholders.
|
||||
rulePlaceholderExpander->SetTargetImpLib(targetOutputReal);
|
||||
std::string linkRule = this->GetLinkRule(linkRuleVar);
|
||||
cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
|
||||
|
||||
// Expand placeholders.
|
||||
for (std::vector<std::string>::iterator i = real_link_commands.begin();
|
||||
i != real_link_commands.end(); ++i) {
|
||||
*i = launcher + *i;
|
||||
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, *i,
|
||||
vars);
|
||||
}
|
||||
// Restore path conversion to normal shells.
|
||||
this->LocalGenerator->SetLinkScriptShell(false);
|
||||
|
||||
// Clean all the possible library names and symlinks.
|
||||
this->CleanFiles.insert(this->CleanFiles.end(), libCleanFiles.begin(),
|
||||
libCleanFiles.end());
|
||||
}
|
||||
|
||||
std::vector<std::string> commands1;
|
||||
// Optionally convert the build rule to use a script to avoid long
|
||||
// command lines in the make shell.
|
||||
if (useLinkScript) {
|
||||
// Use a link script.
|
||||
const char* name = (relink ? "drelink.txt" : "dlink.txt");
|
||||
this->CreateLinkScript(name, real_link_commands, commands1, depends);
|
||||
} else {
|
||||
// No link script. Just use the link rule directly.
|
||||
commands1 = real_link_commands;
|
||||
}
|
||||
this->LocalGenerator->CreateCDCommand(
|
||||
commands1, this->Makefile->GetCurrentBinaryDirectory(),
|
||||
this->LocalGenerator->GetBinaryDirectory());
|
||||
commands.insert(commands.end(), commands1.begin(), commands1.end());
|
||||
commands1.clear();
|
||||
|
||||
// Compute the list of outputs.
|
||||
std::vector<std::string> outputs(1, targetOutputReal);
|
||||
|
||||
// Write the build rule.
|
||||
this->WriteMakeRule(*this->BuildFileStream, CM_NULLPTR, outputs, depends,
|
||||
commands, false);
|
||||
|
||||
// Write the main driver rule to build everything in this target.
|
||||
this->WriteTargetDriverRule(targetOutputReal, relink);
|
||||
#else
|
||||
static_cast<void>(linkRuleVar);
|
||||
static_cast<void>(extraFlags);
|
||||
static_cast<void>(relink);
|
||||
#endif
|
||||
}
|
||||
|
||||
void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
const std::string& linkRuleVar, const std::string& extraFlags, bool relink)
|
||||
{
|
||||
@@ -240,6 +451,9 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
// Build list of dependencies.
|
||||
std::vector<std::string> depends;
|
||||
this->AppendLinkDepends(depends);
|
||||
if (!this->DeviceLinkObject.empty()) {
|
||||
depends.push_back(this->DeviceLinkObject);
|
||||
}
|
||||
|
||||
// Get the language to use for linking this library.
|
||||
std::string linkLanguage =
|
||||
@@ -518,6 +732,14 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
this->CreateObjectLists(useLinkScript, useArchiveRules,
|
||||
useResponseFileForObjects, buildObjs, depends,
|
||||
useWatcomQuote);
|
||||
if (!this->DeviceLinkObject.empty()) {
|
||||
buildObjs += " " +
|
||||
this->LocalGenerator->ConvertToOutputFormat(
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory(),
|
||||
this->DeviceLinkObject),
|
||||
cmOutputConverter::SHELL);
|
||||
}
|
||||
|
||||
// maybe create .def file from list of objects
|
||||
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY &&
|
||||
|
||||
@@ -26,6 +26,9 @@ protected:
|
||||
void WriteStaticLibraryRules();
|
||||
void WriteSharedLibraryRules(bool relink);
|
||||
void WriteModuleLibraryRules(bool relink);
|
||||
|
||||
void WriteDeviceLibraryRules(const std::string& linkRule,
|
||||
const std::string& extraFlags, bool relink);
|
||||
void WriteLibraryRules(const std::string& linkRule,
|
||||
const std::string& extraFlags, bool relink);
|
||||
// MacOSX Framework support methods
|
||||
@@ -33,6 +36,9 @@ protected:
|
||||
|
||||
// Store the computd framework version for OS X Frameworks.
|
||||
std::string FrameworkVersion;
|
||||
|
||||
private:
|
||||
std::string DeviceLinkObject;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user