Skip to content

Commit 6377a43

Browse files
committed
CUDA: Support response files with nvcc
1 parent 87273cc commit 6377a43

File tree

6 files changed

+83
-49
lines changed

6 files changed

+83
-49
lines changed

Modules/Compiler/NVIDIA-CUDA.cmake

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,15 +127,19 @@ else()
127127

128128
endif()
129129

130-
# FIXME: investigate use of --options-file.
131-
# Tell Makefile generator that nvcc does not support @<rspfile> syntax.
132-
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES 0)
133-
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES 0)
134-
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS 0)
135-
136130
if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "9.0")
137131
set(CMAKE_CUDA_RESPONSE_FILE_DEVICE_LINK_FLAG "--options-file ")
138132
set(CMAKE_CUDA_RESPONSE_FILE_FLAG "--options-file ")
139133
endif()
140134

135+
if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "11.0")
136+
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES 1)
137+
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES 1)
138+
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS 1)
139+
else()
140+
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES 0)
141+
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES 0)
142+
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS 0)
143+
endif()
144+
141145
__compiler_check_default_language_standard(CUDA 6.0 03)

Source/cmCoreTryCompile.cxx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,15 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
605605
// does not include any system headers anyway.
606606
fprintf(fout,
607607
"set_property(DIRECTORY PROPERTY INCLUDE_DIRECTORIES \"\")\n");
608+
609+
// The link and compile lines for ABI detection step need to not use
610+
// response files so we can extract implicit includes given to
611+
// the underlying host compiler
612+
if (testLangs.find("CUDA") != testLangs.end()) {
613+
fprintf(fout, "set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES OFF)\n");
614+
fprintf(fout, "set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES OFF)\n");
615+
fprintf(fout, "set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS OFF)\n");
616+
}
608617
}
609618
fprintf(fout, "set(CMAKE_VERBOSE_MAKEFILE 1)\n");
610619
for (std::string const& li : testLangs) {

Source/cmMakefileExecutableTargetGenerator.cxx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,16 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
182182

183183
// Collect up flags to link in needed libraries.
184184
std::string linkLibs;
185-
this->CreateLinkLibs(linkLineComputer.get(), linkLibs,
186-
useResponseFileForLibs, depends);
185+
this->CreateLinkLibs(
186+
linkLineComputer.get(), linkLibs, useResponseFileForLibs, depends,
187+
cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
187188

188189
// Construct object file lists that may be needed to expand the
189190
// rule.
190191
std::string buildObjs;
191-
this->CreateObjectLists(useLinkScript, false, useResponseFileForObjects,
192-
buildObjs, depends, false);
192+
this->CreateObjectLists(
193+
useLinkScript, false, useResponseFileForObjects, buildObjs, depends,
194+
false, cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
193195

194196
cmRulePlaceholderExpander::RuleVariables vars;
195197
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();

Source/cmMakefileLibraryTargetGenerator.cxx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -322,15 +322,17 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
322322
linkLineComputer->SetForResponse(useResponseFileForLibs);
323323
linkLineComputer->SetRelink(relink);
324324

325-
this->CreateLinkLibs(linkLineComputer.get(), linkLibs,
326-
useResponseFileForLibs, depends);
325+
this->CreateLinkLibs(
326+
linkLineComputer.get(), linkLibs, useResponseFileForLibs, depends,
327+
cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
327328

328329
// Construct object file lists that may be needed to expand the
329330
// rule.
330331
std::string buildObjs;
331-
this->CreateObjectLists(useLinkScript, false, // useArchiveRules
332-
useResponseFileForObjects, buildObjs, depends,
333-
false);
332+
this->CreateObjectLists(
333+
useLinkScript, false, // useArchiveRules
334+
useResponseFileForObjects, buildObjs, depends, false,
335+
cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
334336

335337
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
336338
objectDir = this->LocalGenerator->ConvertToOutputFormat(

Source/cmMakefileTargetGenerator.cxx

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ std::unique_ptr<cmMakefileTargetGenerator> cmMakefileTargetGenerator::New(
107107
return result;
108108
}
109109

110-
std::string cmMakefileTargetGenerator::GetConfigName()
110+
std::string cmMakefileTargetGenerator::GetConfigName() const
111111
{
112112
auto const& configNames = this->LocalGenerator->GetConfigNames();
113113
assert(configNames.size() == 1);
@@ -2080,7 +2080,7 @@ bool cmMakefileTargetGenerator::CheckUseResponseFileForLibraries(
20802080
}
20812081

20822082
std::string cmMakefileTargetGenerator::CreateResponseFile(
2083-
const char* name, std::string const& options,
2083+
const std::string& name, std::string const& options,
20842084
std::vector<std::string>& makefile_depends)
20852085
{
20862086
// FIXME: Find a better way to determine the response file encoding,
@@ -2126,7 +2126,8 @@ cmMakefileTargetGenerator::CreateLinkLineComputer(
21262126

21272127
void cmMakefileTargetGenerator::CreateLinkLibs(
21282128
cmLinkLineComputer* linkLineComputer, std::string& linkLibs,
2129-
bool useResponseFile, std::vector<std::string>& makefile_depends)
2129+
bool useResponseFile, std::vector<std::string>& makefile_depends,
2130+
ResponseFlagFor responseMode)
21302131
{
21312132
std::string frameworkPath;
21322133
std::string linkPath;
@@ -2139,20 +2140,13 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
21392140
if (useResponseFile &&
21402141
linkLibs.find_first_not_of(' ') != std::string::npos) {
21412142
// Lookup the response file reference flag.
2142-
std::string responseFlagVar =
2143-
cmStrCat("CMAKE_",
2144-
this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
2145-
"_RESPONSE_FILE_LINK_FLAG");
2146-
std::string responseFlag;
2147-
if (cmValue p = this->Makefile->GetDefinition(responseFlagVar)) {
2148-
responseFlag = *p;
2149-
} else {
2150-
responseFlag = "@";
2151-
}
2143+
std::string responseFlag = this->GetResponseFlag(responseMode);
21522144

21532145
// Create this response file.
2146+
std::string responseFileName =
2147+
(responseMode == Link) ? "linkLibs.rsp" : "deviceLinkLibs.rsp";
21542148
std::string link_rsp =
2155-
this->CreateResponseFile("linklibs.rsp", linkLibs, makefile_depends);
2149+
this->CreateResponseFile(responseFileName, linkLibs, makefile_depends);
21562150

21572151
// Reference the response file.
21582152
linkLibs = cmStrCat(responseFlag,
@@ -2164,7 +2158,7 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
21642158
void cmMakefileTargetGenerator::CreateObjectLists(
21652159
bool useLinkScript, bool useArchiveRules, bool useResponseFile,
21662160
std::string& buildObjs, std::vector<std::string>& makefile_depends,
2167-
bool useWatcomQuote)
2161+
bool useWatcomQuote, ResponseFlagFor responseMode)
21682162
{
21692163
std::string variableName;
21702164
std::string variableNameExternal;
@@ -2179,27 +2173,19 @@ void cmMakefileTargetGenerator::CreateObjectLists(
21792173
this->WriteObjectsStrings(object_strings, responseFileLimit);
21802174

21812175
// Lookup the response file reference flag.
2182-
std::string responseFlagVar =
2183-
cmStrCat("CMAKE_",
2184-
this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
2185-
"_RESPONSE_FILE_LINK_FLAG");
2186-
std::string responseFlag;
2187-
if (cmValue p = this->Makefile->GetDefinition(responseFlagVar)) {
2188-
responseFlag = *p;
2189-
} else {
2190-
responseFlag = "@";
2191-
}
2176+
std::string responseFlag = this->GetResponseFlag(responseMode);
21922177

21932178
// Write a response file for each string.
21942179
const char* sep = "";
21952180
for (unsigned int i = 0; i < object_strings.size(); ++i) {
21962181
// Number the response files.
2197-
char rsp[32];
2198-
snprintf(rsp, sizeof(rsp), "objects%u.rsp", i + 1);
2182+
std::string responseFileName =
2183+
(responseMode == Link) ? "objects" : "deviceObjects";
2184+
responseFileName += std::to_string(i + 1);
21992185

22002186
// Create this response file.
2201-
std::string objects_rsp =
2202-
this->CreateResponseFile(rsp, object_strings[i], makefile_depends);
2187+
std::string objects_rsp = this->CreateResponseFile(
2188+
responseFileName, object_strings[i], makefile_depends);
22032189

22042190
// Separate from previous response file references.
22052191
buildObjs += sep;
@@ -2251,7 +2237,7 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
22512237
}
22522238
std::string name = cmStrCat("includes_", lang, ".rsp");
22532239
std::string arg = std::move(responseFlag) +
2254-
this->CreateResponseFile(name.c_str(), includeFlags,
2240+
this->CreateResponseFile(name, includeFlags,
22552241
this->FlagFileDepends[lang]);
22562242
this->LocalGenerator->AppendFlags(flags, arg);
22572243
} else {
@@ -2304,3 +2290,22 @@ void cmMakefileTargetGenerator::GenDefFile(
23042290
fout << src->GetFullPath() << "\n";
23052291
}
23062292
}
2293+
2294+
std::string cmMakefileTargetGenerator::GetResponseFlag(
2295+
ResponseFlagFor mode) const
2296+
{
2297+
std::string responseFlag = "@";
2298+
std::string responseFlagVar;
2299+
2300+
auto lang = this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
2301+
if (mode == cmMakefileTargetGenerator::ResponseFlagFor::Link) {
2302+
responseFlagVar = cmStrCat("CMAKE_", lang, "_RESPONSE_FILE_LINK_FLAG");
2303+
} else if (mode == cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink) {
2304+
responseFlagVar = "CMAKE_CUDA_RESPONSE_FILE_DEVICE_LINK_FLAG";
2305+
}
2306+
2307+
if (cmValue p = this->Makefile->GetDefinition(responseFlagVar)) {
2308+
responseFlag = *p;
2309+
}
2310+
return responseFlag;
2311+
}

Source/cmMakefileTargetGenerator.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class cmMakefileTargetGenerator : public cmCommonTargetGenerator
5656

5757
cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget; }
5858

59-
std::string GetConfigName();
59+
std::string GetConfigName() const;
6060

6161
protected:
6262
void GetDeviceLinkFlags(std::string& linkFlags,
@@ -157,29 +157,41 @@ class cmMakefileTargetGenerator : public cmCommonTargetGenerator
157157
/** Create a response file with the given set of options. Returns
158158
the relative path from the target build working directory to the
159159
response file name. */
160-
std::string CreateResponseFile(const char* name, std::string const& options,
160+
std::string CreateResponseFile(const std::string& name,
161+
std::string const& options,
161162
std::vector<std::string>& makefile_depends);
162163

163164
bool CheckUseResponseFileForObjects(std::string const& l) const;
164165
bool CheckUseResponseFileForLibraries(std::string const& l) const;
165166

167+
enum ResponseFlagFor
168+
{
169+
Link,
170+
DeviceLink
171+
};
172+
166173
/** Create list of flags for link libraries. */
167174
void CreateLinkLibs(cmLinkLineComputer* linkLineComputer,
168175
std::string& linkLibs, bool useResponseFile,
169-
std::vector<std::string>& makefile_depends);
176+
std::vector<std::string>& makefile_depends,
177+
ResponseFlagFor responseMode = ResponseFlagFor::Link);
170178

171179
/** Create lists of object files for linking and cleaning. */
172180
void CreateObjectLists(bool useLinkScript, bool useArchiveRules,
173181
bool useResponseFile, std::string& buildObjs,
174182
std::vector<std::string>& makefile_depends,
175-
bool useWatcomQuote);
183+
bool useWatcomQuote,
184+
ResponseFlagFor responseMode = ResponseFlagFor::Link);
176185

177186
/** Add commands for generate def files */
178187
void GenDefFile(std::vector<std::string>& real_link_commands);
179188

180189
void AddIncludeFlags(std::string& flags, const std::string& lang,
181190
const std::string& config) override;
182191

192+
/** Return the response flag for the given configuration */
193+
std::string GetResponseFlag(ResponseFlagFor mode) const;
194+
183195
virtual void CloseFileStreams();
184196
cmLocalUnixMakefileGenerator3* LocalGenerator;
185197
cmGlobalUnixMakefileGenerator3* GlobalGenerator;

0 commit comments

Comments
 (0)