Skip to content

Commit 2c72582

Browse files
committed
ClangImporter: inject modulemaps via the VFS
This is the second step towards removal of the content injection into the Visual Studio installation. With this the new path is enabled to create the mappings to the SDK shared content. Subsequent improvements involve the introduction of new options to the Swift driver and Swift frontend: 1. `-windows-sdk-root` 2. `-windows-sdk-version` 3. `-visualc-tools-root` 4. `-visualc-tools-version` The introduction of these options will then feed into the path selection here enabling granular control over the VCRuntime and Windows SDK by the user. Thanks to @artemcm for the very helpful discussion and help on identifying a good set of options for the driver. Thanks to @stevapple for the inspiration for this patch.
1 parent 68378b8 commit 2c72582

File tree

3 files changed

+139
-16
lines changed

3 files changed

+139
-16
lines changed

lib/ClangImporter/ClangIncludePaths.cpp

Lines changed: 109 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "clang/Driver/Driver.h"
1919
#include "clang/Driver/ToolChain.h"
2020
#include "clang/Frontend/CompilerInstance.h"
21+
#include "llvm/WindowsDriver/MSVCPaths.h"
2122

2223
using namespace swift;
2324

@@ -296,14 +297,119 @@ getLibStdCxxFileMapping(ASTContext &ctx) {
296297
};
297298
}
298299

300+
namespace {
301+
std::string
302+
GetWindowsAuxiliaryFile(StringRef modulemap, const SearchPathOptions &Options) {
303+
StringRef SDKPath = Options.getSDKPath();
304+
if (!SDKPath.empty()) {
305+
llvm::SmallString<261> path{SDKPath};
306+
llvm::sys::path::append(path, "usr", "share", modulemap);
307+
if (llvm::sys::fs::exists(path))
308+
return path.str().str();
309+
}
310+
311+
if (!Options.RuntimeResourcePath.empty()) {
312+
llvm::SmallString<261> path{Options.RuntimeResourcePath};
313+
llvm::sys::path::append(path, "windows", modulemap);
314+
if (llvm::sys::fs::exists(path))
315+
return path.str().str();
316+
}
317+
318+
return "";
319+
}
320+
321+
SmallVector<std::pair<std::string, std::string>, 2>
322+
GetWindowsFileMappings(ASTContext &Context) {
323+
const llvm::Triple &Triple = Context.LangOpts.Target;
324+
const SearchPathOptions &SearchPathOpts = Context.SearchPathOpts;
325+
SmallVector<std::pair<std::string, std::string>, 2> Mappings;
326+
std::string AuxiliaryFile;
327+
328+
if (!Triple.isWindowsMSVCEnvironment())
329+
return Mappings;
330+
331+
clang::driver::Driver Driver = createClangDriver(Context);
332+
const llvm::opt::InputArgList Args = createClangArgs(Context, Driver);
333+
const clang::driver::ToolChain &ToolChain = Driver.getToolChain(Args, Triple);
334+
llvm::vfs::FileSystem &VFS = ToolChain.getVFS();
335+
336+
struct {
337+
std::string Path;
338+
std::string IncludeVersion;
339+
std::string LibraryVersion;
340+
int MajorVersion;
341+
} WindowsSDK;
342+
if (llvm::getWindowsSDKDir(VFS, {}, {}, {},
343+
WindowsSDK.Path, WindowsSDK.MajorVersion,
344+
WindowsSDK.IncludeVersion,
345+
WindowsSDK.LibraryVersion)) {
346+
llvm::SmallString<261> WinSDKInjection{WindowsSDK.Path};
347+
llvm::sys::path::append(WinSDKInjection, "Include");
348+
if (WindowsSDK.MajorVersion > 8)
349+
llvm::sys::path::append(WinSDKInjection, WindowsSDK.IncludeVersion, "um");
350+
llvm::sys::path::append(WinSDKInjection, "module.modulemap");
351+
352+
AuxiliaryFile = GetWindowsAuxiliaryFile("winsdk.modulemap", SearchPathOpts);
353+
if (!AuxiliaryFile.empty())
354+
Mappings.emplace_back(std::string(WinSDKInjection), AuxiliaryFile);
355+
}
356+
357+
struct {
358+
std::string Path;
359+
std::string Version;
360+
} UCRTSDK;
361+
if (llvm::getUniversalCRTSdkDir(VFS, {}, {}, {},
362+
UCRTSDK.Path, UCRTSDK.Version)) {
363+
llvm::SmallString<261> UCRTInjection{UCRTSDK.Path};
364+
llvm::sys::path::append(UCRTInjection, "Include", UCRTSDK.Version, "ucrt");
365+
llvm::sys::path::append(UCRTInjection, "module.modulemap");
366+
367+
AuxiliaryFile = GetWindowsAuxiliaryFile("ucrt.modulemap", SearchPathOpts);
368+
if (!AuxiliaryFile.empty())
369+
Mappings.emplace_back(std::string(UCRTInjection), AuxiliaryFile);
370+
}
371+
372+
struct {
373+
std::string Path;
374+
llvm::ToolsetLayout Layout;
375+
} VCTools;
376+
if (llvm::findVCToolChainViaCommandLine(VFS, {}, {}, {}, VCTools.Path, VCTools.Layout) ||
377+
llvm::findVCToolChainViaEnvironment(VFS, VCTools.Path, VCTools.Layout) ||
378+
llvm::findVCToolChainViaSetupConfig(VFS, VCTools.Path, VCTools.Layout)) {
379+
assert(VCTools.Layout == llvm::ToolsetLayout::VS2017OrNewer &&
380+
"unsupported toolset layout (VS2017+ required)");
381+
382+
llvm::SmallString<261> VCToolsInjection{VCTools.Path};
383+
llvm::sys::path::append(VCToolsInjection, "include");
384+
385+
llvm::sys::path::append(VCToolsInjection, "module.modulemap");
386+
AuxiliaryFile =
387+
GetWindowsAuxiliaryFile("vcruntime.modulemap", SearchPathOpts);
388+
if (!AuxiliaryFile.empty())
389+
Mappings.emplace_back(std::string(VCToolsInjection), AuxiliaryFile);
390+
391+
llvm::sys::path::remove_filename(VCToolsInjection);
392+
llvm::sys::path::append(VCToolsInjection, "vcruntime.apinotes");
393+
AuxiliaryFile =
394+
GetWindowsAuxiliaryFile("vcruntime.apinotes", SearchPathOpts);
395+
if (!AuxiliaryFile.empty())
396+
Mappings.emplace_back(std::string(VCToolsInjection), AuxiliaryFile);
397+
}
398+
399+
return Mappings;
400+
}
401+
}
402+
299403
SmallVector<std::pair<std::string, std::string>, 2>
300404
swift::getClangInvocationFileMapping(ASTContext &ctx) {
301405
SmallVector<std::pair<std::string, std::string>, 2> result;
302406

407+
// Android/BSD/Linux Mappings
303408
result.append(getGlibcFileMapping(ctx));
304-
305-
if (ctx.LangOpts.EnableCXXInterop) {
409+
if (ctx.LangOpts.EnableCXXInterop)
306410
result.append(getLibStdCxxFileMapping(ctx));
307-
}
411+
412+
result.append(GetWindowsFileMappings(ctx));
413+
308414
return result;
309415
}

utils/build-windows-toolchain.bat

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ set TMPDIR=%BuildRoot%\tmp
4242

4343
set NINJA_STATUS=[%%f/%%t][%%p][%%es]
4444

45+
rem TODO(compnerd) remove this clean up code once we have had enough time for
46+
rem the injection to soak.
47+
:: Clean up old deployments as that breaks the tests
48+
del /f /q "%UniversalCRTSdkDir%\Include\%UCRTVersion%\ucrt\module.modulemap"
49+
del /f /q "%UniversalCRTSdkDir%\Include\%UCRTVersion%\um\module.modulemap"
50+
del /f /q "%VCToolsInstallDir%\include\module.modulemap"
51+
del /f /q "%VCToolsInstallDir%\include\vcruntime.apinotes"
52+
4553
call :CloneDependencies || (exit /b)
4654
call :CloneRepositories || (exit /b)
4755

@@ -178,12 +186,6 @@ cmake ^
178186
cmake --build "%BuildRoot%\curl" || (exit /b)
179187
cmake --build "%BuildRoot%\curl" --target install || (exit /b)
180188

181-
:: Prepare system modules
182-
copy /y "%SourceRoot%\swift\stdlib\public\Platform\ucrt.modulemap" "%UniversalCRTSdkDir%\Include\%UCRTVersion%\ucrt\module.modulemap" || (exit /b)
183-
copy /y "%SourceRoot%\swift\stdlib\public\Platform\winsdk.modulemap" "%UniversalCRTSdkDir%\Include\%UCRTVersion%\um\module.modulemap" || (exit /b)
184-
copy /y "%SourceRoot%\swift\stdlib\public\Platform\vcruntime.modulemap" "%VCToolsInstallDir%\include\module.modulemap" || (exit /b)
185-
copy /y "%SourceRoot%\swift\stdlib\public\Platform\vcruntime.apinotes" "%VCToolsInstallDir%\include\vcruntime.apinotes" || (exit /b)
186-
187189
:: Build Toolchain
188190
cmake ^
189191
-B "%BuildRoot%\1" ^
@@ -273,6 +275,7 @@ cmake ^
273275
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
274276
-D CMAKE_MT=mt ^
275277
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
278+
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%\2\stdlib\windows-vfs-overlay.yaml" ^
276279
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
277280
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^
278281

@@ -296,6 +299,7 @@ cmake ^
296299
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
297300
-D CMAKE_MT=mt ^
298301
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
302+
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%\2\stdlib\windows-vfs-overlay.yaml" ^
299303
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
300304
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^
301305

@@ -331,6 +335,7 @@ cmake ^
331335
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
332336
-D CMAKE_MT=mt ^
333337
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
338+
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%\2\stdlib\windows-vfs-overlay.yaml" ^
334339
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
335340
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^
336341

@@ -358,6 +363,7 @@ cmake ^
358363
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
359364
-D CMAKE_MT=mt ^
360365
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
366+
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%\2\stdlib\windows-vfs-overlay.yaml" ^
361367
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
362368
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^
363369

@@ -379,6 +385,7 @@ cmake ^
379385
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
380386
-D CMAKE_MT=mt ^
381387
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
388+
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%\2\stdlib\windows-vfs-overlay.yaml" ^
382389
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
383390
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^
384391

@@ -406,6 +413,7 @@ cmake ^
406413
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy -Xclang -fno-split-cold-code" ^
407414
-D CMAKE_MT=mt ^
408415
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
416+
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%\2\stdlib\windows-vfs-overlay.yaml" ^
409417
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
410418
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^
411419

@@ -434,6 +442,7 @@ cmake ^
434442
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
435443
-D CMAKE_MT=mt ^
436444
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
445+
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%\2\stdlib\windows-vfs-overlay.yaml" ^
437446
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
438447
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^
439448

@@ -460,7 +469,7 @@ cmake ^
460469
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
461470
-D CMAKE_MT=mt ^
462471
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
463-
-D CMAKE_Swift_FLAGS="-Xcc -DYAML_DECLARE_EXPORT -Xcc -DWIN32" ^
472+
-D CMAKE_Swift_FLAGS="-Xcc -DYAML_DECLARE_EXPORT -Xcc -DWIN32 -vfsoverlay %BuildRoot%\2\stdlib\windows-vfs-overlay.yaml" ^
464473
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
465474
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^
466475

@@ -485,6 +494,7 @@ cmake ^
485494
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
486495
-D CMAKE_MT=mt ^
487496
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
497+
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%\2\stdlib\windows-vfs-overlay.yaml" ^
488498
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
489499
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^
490500

@@ -518,6 +528,7 @@ cmake ^
518528
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
519529
-D CMAKE_MT=mt ^
520530
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
531+
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%\2\stdlib\windows-vfs-overlay.yaml" ^
521532
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
522533
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^
523534

@@ -541,6 +552,7 @@ cmake ^
541552
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
542553
-D CMAKE_MT=mt ^
543554
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
555+
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%\2\stdlib\windows-vfs-overlay.yaml" ^
544556
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
545557
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^
546558

@@ -562,6 +574,7 @@ cmake ^
562574
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
563575
-D CMAKE_MT=mt ^
564576
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
577+
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%\2\stdlib\windows-vfs-overlay.yaml" ^
565578
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
566579
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^
567580

@@ -597,6 +610,7 @@ cmake ^
597610
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy -Xclang -fno-split-cold-code" ^
598611
-D CMAKE_MT=mt ^
599612
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
613+
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%\2\stdlib\windows-vfs-overlay.yaml" ^
600614
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
601615
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^
602616

@@ -640,6 +654,7 @@ cmake ^
640654
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy -Xclang -fno-split-cold-code" ^
641655
-D CMAKE_MT=mt ^
642656
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
657+
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%\2\stdlib\windows-vfs-overlay.yaml" ^
643658
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
644659
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^
645660

utils/build-windows.bat

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ set SWIFTPM_MODULECACHE_OVERRIDE=%build_root%\tmp\org.swift.package-manager
6767
set RunTest=1
6868
if "%1"=="-notest" set RunTest=0
6969

70+
rem TODO(compnerd) remove this clean up code once we have had enough time for
71+
rem the injection to soak.
72+
:: Clean up old deployments as that breaks the tests
73+
del /f /q "%UniversalCRTSdkDir%\Include\%UCRTVersion%\ucrt\module.modulemap"
74+
del /f /q "%UniversalCRTSdkDir%\Include\%UCRTVersion%\um\module.modulemap"
75+
del /f /q "%VCToolsInstallDir%\include\module.modulemap"
76+
del /f /q "%VCToolsInstallDir%\include\vcruntime.apinotes"
77+
7078
call :clone_repositories %exitOnError%
7179
:: TODO: Disabled until we need Foundation in this build script.
7280
:: call :download_icu %exitOnError%
@@ -228,12 +236,6 @@ endlocal
228236
:: Configures, builds, and installs Swift and the Swift Standard Library
229237
setlocal enableextensions enabledelayedexpansion
230238

231-
:: Clean up old deployments as that breaks the tests
232-
del /f /q "%UniversalCRTSdkDir%\Include\%UCRTVersion%\ucrt\module.modulemap"
233-
del /f /q "%UniversalCRTSdkDir%\Include\%UCRTVersion%\um\module.modulemap"
234-
del /f /q "%VCToolsInstallDir%\include\module.modulemap"
235-
del /f /q "%VCToolsInstallDir%\include\vcruntime.apinotes"
236-
237239
:: SWIFT_PARALLEL_LINK_JOBS=8 allows the build machine to use as many CPU as
238240
:: possible, while not exhausting the RAM.
239241
cmake^

0 commit comments

Comments
 (0)