Skip to content

ClangImporter: inject modulemaps via the VFS #63887

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 109 additions & 3 deletions lib/ClangImporter/ClangIncludePaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "clang/Driver/Driver.h"
#include "clang/Driver/ToolChain.h"
#include "clang/Frontend/CompilerInstance.h"
#include "llvm/WindowsDriver/MSVCPaths.h"

using namespace swift;

Expand Down Expand Up @@ -296,14 +297,119 @@ getLibStdCxxFileMapping(ASTContext &ctx) {
};
}

namespace {
std::string
GetWindowsAuxiliaryFile(StringRef modulemap, const SearchPathOptions &Options) {
StringRef SDKPath = Options.getSDKPath();
if (!SDKPath.empty()) {
llvm::SmallString<261> path{SDKPath};
llvm::sys::path::append(path, "usr", "share", modulemap);
if (llvm::sys::fs::exists(path))
return path.str().str();
}

if (!Options.RuntimeResourcePath.empty()) {
llvm::SmallString<261> path{Options.RuntimeResourcePath};
llvm::sys::path::append(path, "windows", modulemap);
if (llvm::sys::fs::exists(path))
return path.str().str();
}

return "";
}

SmallVector<std::pair<std::string, std::string>, 2>
GetWindowsFileMappings(ASTContext &Context) {
const llvm::Triple &Triple = Context.LangOpts.Target;
const SearchPathOptions &SearchPathOpts = Context.SearchPathOpts;
SmallVector<std::pair<std::string, std::string>, 2> Mappings;
std::string AuxiliaryFile;

if (!Triple.isWindowsMSVCEnvironment())
return Mappings;

clang::driver::Driver Driver = createClangDriver(Context);
const llvm::opt::InputArgList Args = createClangArgs(Context, Driver);
const clang::driver::ToolChain &ToolChain = Driver.getToolChain(Args, Triple);
llvm::vfs::FileSystem &VFS = ToolChain.getVFS();

struct {
std::string Path;
std::string IncludeVersion;
std::string LibraryVersion;
int MajorVersion;
} WindowsSDK;
if (llvm::getWindowsSDKDir(VFS, {}, {}, {},
WindowsSDK.Path, WindowsSDK.MajorVersion,
WindowsSDK.IncludeVersion,
WindowsSDK.LibraryVersion)) {
llvm::SmallString<261> WinSDKInjection{WindowsSDK.Path};
llvm::sys::path::append(WinSDKInjection, "Include");
if (WindowsSDK.MajorVersion > 8)
llvm::sys::path::append(WinSDKInjection, WindowsSDK.IncludeVersion, "um");
llvm::sys::path::append(WinSDKInjection, "module.modulemap");

AuxiliaryFile = GetWindowsAuxiliaryFile("winsdk.modulemap", SearchPathOpts);
if (!AuxiliaryFile.empty())
Mappings.emplace_back(std::string(WinSDKInjection), AuxiliaryFile);
}

struct {
std::string Path;
std::string Version;
} UCRTSDK;
if (llvm::getUniversalCRTSdkDir(VFS, {}, {}, {},
UCRTSDK.Path, UCRTSDK.Version)) {
llvm::SmallString<261> UCRTInjection{UCRTSDK.Path};
llvm::sys::path::append(UCRTInjection, "Include", UCRTSDK.Version, "ucrt");
llvm::sys::path::append(UCRTInjection, "module.modulemap");

AuxiliaryFile = GetWindowsAuxiliaryFile("ucrt.modulemap", SearchPathOpts);
if (!AuxiliaryFile.empty())
Mappings.emplace_back(std::string(UCRTInjection), AuxiliaryFile);
}

struct {
std::string Path;
llvm::ToolsetLayout Layout;
} VCTools;
if (llvm::findVCToolChainViaCommandLine(VFS, {}, {}, {}, VCTools.Path, VCTools.Layout) ||
llvm::findVCToolChainViaEnvironment(VFS, VCTools.Path, VCTools.Layout) ||
llvm::findVCToolChainViaSetupConfig(VFS, VCTools.Path, VCTools.Layout)) {
assert(VCTools.Layout == llvm::ToolsetLayout::VS2017OrNewer &&
"unsupported toolset layout (VS2017+ required)");

llvm::SmallString<261> VCToolsInjection{VCTools.Path};
llvm::sys::path::append(VCToolsInjection, "include");

llvm::sys::path::append(VCToolsInjection, "module.modulemap");
AuxiliaryFile =
GetWindowsAuxiliaryFile("vcruntime.modulemap", SearchPathOpts);
if (!AuxiliaryFile.empty())
Mappings.emplace_back(std::string(VCToolsInjection), AuxiliaryFile);

llvm::sys::path::remove_filename(VCToolsInjection);
llvm::sys::path::append(VCToolsInjection, "vcruntime.apinotes");
AuxiliaryFile =
GetWindowsAuxiliaryFile("vcruntime.apinotes", SearchPathOpts);
if (!AuxiliaryFile.empty())
Mappings.emplace_back(std::string(VCToolsInjection), AuxiliaryFile);
}

return Mappings;
}
}

SmallVector<std::pair<std::string, std::string>, 2>
swift::getClangInvocationFileMapping(ASTContext &ctx) {
SmallVector<std::pair<std::string, std::string>, 2> result;

// Android/BSD/Linux Mappings
result.append(getGlibcFileMapping(ctx));

if (ctx.LangOpts.EnableCXXInterop) {
if (ctx.LangOpts.EnableCXXInterop)
result.append(getLibStdCxxFileMapping(ctx));
}

result.append(GetWindowsFileMappings(ctx));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind splitting VC and WinSDK stuffs into separate functions? They come from different places and use completely distinct searching strategies.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather that we don't do that. This function really should just call the platform specific handler for any of the platforms required, ideally pushing the platform check here instead of inside the function. Splitting up the function internally is possible, but seems like it doesn't aid clarity.


return result;
}
29 changes: 22 additions & 7 deletions utils/build-windows-toolchain.bat
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ set TMPDIR=%BuildRoot%\tmp

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

rem TODO(compnerd) remove this clean up code once we have had enough time for
rem the injection to soak.
:: Clean up old deployments as that breaks the tests
del /f /q "%UniversalCRTSdkDir%\Include\%UCRTVersion%\ucrt\module.modulemap"
del /f /q "%UniversalCRTSdkDir%\Include\%UCRTVersion%\um\module.modulemap"
del /f /q "%VCToolsInstallDir%\include\module.modulemap"
del /f /q "%VCToolsInstallDir%\include\vcruntime.apinotes"

call :CloneDependencies || (exit /b)
call :CloneRepositories || (exit /b)

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

:: Prepare system modules
copy /y "%SourceRoot%\swift\stdlib\public\Platform\ucrt.modulemap" "%UniversalCRTSdkDir%\Include\%UCRTVersion%\ucrt\module.modulemap" || (exit /b)
copy /y "%SourceRoot%\swift\stdlib\public\Platform\winsdk.modulemap" "%UniversalCRTSdkDir%\Include\%UCRTVersion%\um\module.modulemap" || (exit /b)
copy /y "%SourceRoot%\swift\stdlib\public\Platform\vcruntime.modulemap" "%VCToolsInstallDir%\include\module.modulemap" || (exit /b)
copy /y "%SourceRoot%\swift\stdlib\public\Platform\vcruntime.apinotes" "%VCToolsInstallDir%\include\vcruntime.apinotes" || (exit /b)

:: Build Toolchain
cmake ^
-B "%BuildRoot%\1" ^
Expand Down Expand Up @@ -273,6 +275,7 @@ cmake ^
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
-D CMAKE_MT=mt ^
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%/2/stdlib/windows-vfs-overlay.yaml" ^
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^

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

Expand Down Expand Up @@ -331,6 +335,7 @@ cmake ^
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
-D CMAKE_MT=mt ^
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%/2/stdlib/windows-vfs-overlay.yaml" ^
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^

Expand Down Expand Up @@ -358,6 +363,7 @@ cmake ^
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
-D CMAKE_MT=mt ^
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%/2/stdlib/windows-vfs-overlay.yaml" ^
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^

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

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

Expand Down Expand Up @@ -434,6 +442,7 @@ cmake ^
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
-D CMAKE_MT=mt ^
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%/2/stdlib/windows-vfs-overlay.yaml" ^
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^

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

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

Expand Down Expand Up @@ -518,6 +528,7 @@ cmake ^
-D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^
-D CMAKE_MT=mt ^
-D CMAKE_Swift_COMPILER=%BuildRoot%/1/bin/swiftc.exe ^
-D CMAKE_Swift_FLAGS="-vfsoverlay %BuildRoot%/2/stdlib/windows-vfs-overlay.yaml" ^
-D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^
-D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^

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

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

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

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

Expand Down
14 changes: 8 additions & 6 deletions utils/build-windows.bat
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ set SWIFTPM_MODULECACHE_OVERRIDE=%build_root%\tmp\org.swift.package-manager
set RunTest=1
if "%1"=="-notest" set RunTest=0

rem TODO(compnerd) remove this clean up code once we have had enough time for
rem the injection to soak.
:: Clean up old deployments as that breaks the tests
del /f /q "%UniversalCRTSdkDir%\Include\%UCRTVersion%\ucrt\module.modulemap"
del /f /q "%UniversalCRTSdkDir%\Include\%UCRTVersion%\um\module.modulemap"
del /f /q "%VCToolsInstallDir%\include\module.modulemap"
del /f /q "%VCToolsInstallDir%\include\vcruntime.apinotes"

call :clone_repositories %exitOnError%
:: TODO: Disabled until we need Foundation in this build script.
:: call :download_icu %exitOnError%
Expand Down Expand Up @@ -228,12 +236,6 @@ endlocal
:: Configures, builds, and installs Swift and the Swift Standard Library
setlocal enableextensions enabledelayedexpansion

:: Clean up old deployments as that breaks the tests
del /f /q "%UniversalCRTSdkDir%\Include\%UCRTVersion%\ucrt\module.modulemap"
del /f /q "%UniversalCRTSdkDir%\Include\%UCRTVersion%\um\module.modulemap"
del /f /q "%VCToolsInstallDir%\include\module.modulemap"
del /f /q "%VCToolsInstallDir%\include\vcruntime.apinotes"

:: SWIFT_PARALLEL_LINK_JOBS=8 allows the build machine to use as many CPU as
:: possible, while not exhausting the RAM.
cmake^
Expand Down