@@ -81,8 +81,9 @@ findVCToolChainViaCommandLine(const ArgList &Args, std::string &Path,
81
81
}
82
82
83
83
// Check various environment variables to try and find a toolchain.
84
- static bool findVCToolChainViaEnvironment (std::string &Path,
85
- MSVCToolChain::ToolsetLayout &VSLayout) {
84
+ static bool
85
+ findVCToolChainViaEnvironment (std::string &Path,
86
+ MSVCToolChain::ToolsetLayout &VSLayout) {
86
87
// These variables are typically set by vcvarsall.bat
87
88
// when launching a developer command prompt.
88
89
if (llvm::Optional<std::string> VCToolsInstallDir =
@@ -355,13 +356,13 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
355
356
356
357
if (TC.useUniversalCRT ()) {
357
358
std::string UniversalCRTLibPath;
358
- if (TC.getUniversalCRTLibraryPath (UniversalCRTLibPath))
359
+ if (TC.getUniversalCRTLibraryPath (Args, UniversalCRTLibPath))
359
360
CmdArgs.push_back (
360
361
Args.MakeArgString (Twine (" -libpath:" ) + UniversalCRTLibPath));
361
362
}
362
363
363
364
std::string WindowsSdkLibPath;
364
- if (TC.getWindowsSDKLibraryPath (WindowsSdkLibPath))
365
+ if (TC.getWindowsSDKLibraryPath (Args, WindowsSdkLibPath))
365
366
CmdArgs.push_back (
366
367
Args.MakeArgString (std::string (" -libpath:" ) + WindowsSdkLibPath));
367
368
}
@@ -1088,12 +1089,43 @@ static bool getWindows10SDKVersionFromPath(const std::string &SDKPath,
1088
1089
return !SDKVersion.empty ();
1089
1090
}
1090
1091
1092
+ static bool getWindowsSDKDirViaCommandLine (const ArgList &Args,
1093
+ std::string &Path, int &Major,
1094
+ std::string &Version) {
1095
+ if (Arg *A = Args.getLastArg (options::OPT__SLASH_winsdkdir)) {
1096
+ // Don't validate the input; trust the value supplied by the user.
1097
+ // The motivation is to prevent unnecessary file and registry access.
1098
+ Path = A->getValue ();
1099
+ if (Arg *A = Args.getLastArg (options::OPT__SLASH_winsdkversion)) {
1100
+ StringRef WinSdkVersion = A->getValue ();
1101
+ Version = WinSdkVersion.str ();
1102
+ if (WinSdkVersion.consumeInteger (10 , Major))
1103
+ return false ;
1104
+ if (!(WinSdkVersion.empty () || WinSdkVersion.startswith (" ." )))
1105
+ return false ;
1106
+ } else if (getWindows10SDKVersionFromPath (Path, Version)) {
1107
+ Major = 10 ;
1108
+ }
1109
+ return true ;
1110
+ }
1111
+ return false ;
1112
+ }
1113
+
1091
1114
// / Get Windows SDK installation directory.
1092
- static bool getWindowsSDKDir (std::string &Path, int &Major,
1115
+ static bool getWindowsSDKDir (const ArgList &Args, std::string &Path, int &Major,
1093
1116
std::string &WindowsSDKIncludeVersion,
1094
1117
std::string &WindowsSDKLibVersion) {
1095
- std::string RegistrySDKVersion;
1118
+ // Trust /winsdkdir: and /winsdkversion: if present.
1119
+ if (getWindowsSDKDirViaCommandLine (
1120
+ Args, Path, Major, WindowsSDKIncludeVersion)) {
1121
+ WindowsSDKLibVersion = WindowsSDKIncludeVersion;
1122
+ return true ;
1123
+ }
1124
+
1125
+ // FIXME: Try env vars (%WindowsSdkDir%, %UCRTVersion%) before going to registry.
1126
+
1096
1127
// Try the Windows registry.
1128
+ std::string RegistrySDKVersion;
1097
1129
if (!getSystemRegistryString (
1098
1130
" SOFTWARE\\ Microsoft\\ Microsoft SDKs\\ Windows\\ $VERSION" ,
1099
1131
" InstallationFolder" , Path, &RegistrySDKVersion))
@@ -1133,14 +1165,15 @@ static bool getWindowsSDKDir(std::string &Path, int &Major,
1133
1165
}
1134
1166
1135
1167
// Gets the library path required to link against the Windows SDK.
1136
- bool MSVCToolChain::getWindowsSDKLibraryPath (std::string &path) const {
1168
+ bool MSVCToolChain::getWindowsSDKLibraryPath (
1169
+ const ArgList &Args, std::string &path) const {
1137
1170
std::string sdkPath;
1138
1171
int sdkMajor = 0 ;
1139
1172
std::string windowsSDKIncludeVersion;
1140
1173
std::string windowsSDKLibVersion;
1141
1174
1142
1175
path.clear ();
1143
- if (!getWindowsSDKDir (sdkPath, sdkMajor, windowsSDKIncludeVersion,
1176
+ if (!getWindowsSDKDir (Args, sdkPath, sdkMajor, windowsSDKIncludeVersion,
1144
1177
windowsSDKLibVersion))
1145
1178
return false ;
1146
1179
@@ -1178,7 +1211,17 @@ bool MSVCToolChain::useUniversalCRT() const {
1178
1211
return !llvm::sys::fs::exists (TestPath);
1179
1212
}
1180
1213
1181
- static bool getUniversalCRTSdkDir (std::string &Path, std::string &UCRTVersion) {
1214
+ static bool getUniversalCRTSdkDir (const ArgList &Args, std::string &Path,
1215
+ std::string &UCRTVersion) {
1216
+ // If /winsdkdir: is passed, use it as location for the UCRT too.
1217
+ // FIXME: Should there be a dedicated /ucrtdir: to override /winsdkdir:?
1218
+ int Major;
1219
+ if (getWindowsSDKDirViaCommandLine (Args, Path, Major, UCRTVersion))
1220
+ return true ;
1221
+
1222
+ // FIXME: Try env vars (%UniversalCRTSdkDir%, %UCRTVersion%) before going to
1223
+ // registry.
1224
+
1182
1225
// vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
1183
1226
// for the specific key "KitsRoot10". So do we.
1184
1227
if (!getSystemRegistryString (
@@ -1189,12 +1232,13 @@ static bool getUniversalCRTSdkDir(std::string &Path, std::string &UCRTVersion) {
1189
1232
return getWindows10SDKVersionFromPath (Path, UCRTVersion);
1190
1233
}
1191
1234
1192
- bool MSVCToolChain::getUniversalCRTLibraryPath (std::string &Path) const {
1235
+ bool MSVCToolChain::getUniversalCRTLibraryPath (const ArgList &Args,
1236
+ std::string &Path) const {
1193
1237
std::string UniversalCRTSdkPath;
1194
1238
std::string UCRTVersion;
1195
1239
1196
1240
Path.clear ();
1197
- if (!getUniversalCRTSdkDir (UniversalCRTSdkPath, UCRTVersion))
1241
+ if (!getUniversalCRTSdkDir (Args, UniversalCRTSdkPath, UCRTVersion))
1198
1242
return false ;
1199
1243
1200
1244
StringRef ArchName = llvmArchToWindowsSDKArch (getArch ());
@@ -1304,7 +1348,7 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1304
1348
if (useUniversalCRT ()) {
1305
1349
std::string UniversalCRTSdkPath;
1306
1350
std::string UCRTVersion;
1307
- if (getUniversalCRTSdkDir (UniversalCRTSdkPath, UCRTVersion)) {
1351
+ if (getUniversalCRTSdkDir (DriverArgs, UniversalCRTSdkPath, UCRTVersion)) {
1308
1352
AddSystemIncludeWithSubfolder (DriverArgs, CC1Args, UniversalCRTSdkPath,
1309
1353
" Include" , UCRTVersion, " ucrt" );
1310
1354
}
@@ -1314,23 +1358,23 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1314
1358
int major;
1315
1359
std::string windowsSDKIncludeVersion;
1316
1360
std::string windowsSDKLibVersion;
1317
- if (getWindowsSDKDir (WindowsSDKDir, major, windowsSDKIncludeVersion ,
1318
- windowsSDKLibVersion)) {
1361
+ if (getWindowsSDKDir (DriverArgs, WindowsSDKDir, major ,
1362
+ windowsSDKIncludeVersion, windowsSDKLibVersion)) {
1319
1363
if (major >= 8 ) {
1320
1364
// Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
1321
1365
// Anyway, llvm::sys::path::append is able to manage it.
1322
1366
AddSystemIncludeWithSubfolder (DriverArgs, CC1Args, WindowsSDKDir,
1323
- " include " , windowsSDKIncludeVersion,
1367
+ " Include " , windowsSDKIncludeVersion,
1324
1368
" shared" );
1325
1369
AddSystemIncludeWithSubfolder (DriverArgs, CC1Args, WindowsSDKDir,
1326
- " include " , windowsSDKIncludeVersion,
1370
+ " Include " , windowsSDKIncludeVersion,
1327
1371
" um" );
1328
1372
AddSystemIncludeWithSubfolder (DriverArgs, CC1Args, WindowsSDKDir,
1329
- " include " , windowsSDKIncludeVersion,
1373
+ " Include " , windowsSDKIncludeVersion,
1330
1374
" winrt" );
1331
1375
} else {
1332
1376
AddSystemIncludeWithSubfolder (DriverArgs, CC1Args, WindowsSDKDir,
1333
- " include " );
1377
+ " Include " );
1334
1378
}
1335
1379
}
1336
1380
0 commit comments