Skip to content

ClangImporter: add support for Android API Notes #74829

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
Jul 1, 2024
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
51 changes: 44 additions & 7 deletions lib/ClangImporter/ClangIncludePaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,25 +396,49 @@ static void getLibStdCxxFileMapping(

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

return "";
}

SmallVector<std::pair<std::string, std::string>, 2>
GetAndroidFileMappings(
ASTContext &Context, const std::string &sysroot,
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS) {
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.isAndroid()) return Mappings;

llvm::SmallString<261> NDKInjection{sysroot};
llvm::sys::path::append(NDKInjection, "posix_filesystem.apinotes");

AuxiliaryFile =
GetPlatformAuxiliaryFile("android", "posix_filesystem.apinotes",
SearchPathOpts);
if (!AuxiliaryFile.empty())
Mappings.emplace_back(std::string(NDKInjection), AuxiliaryFile);

return Mappings;
}

SmallVector<std::pair<std::string, std::string>, 2> GetWindowsFileMappings(
ASTContext &Context,
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &driverVFS,
Expand Down Expand Up @@ -449,7 +473,8 @@ SmallVector<std::pair<std::string, std::string>, 2> GetWindowsFileMappings(
llvm::sys::path::append(WinSDKInjection, WindowsSDK.IncludeVersion, "um");
llvm::sys::path::append(WinSDKInjection, "module.modulemap");

AuxiliaryFile = GetWindowsAuxiliaryFile("winsdk.modulemap", SearchPathOpts);
AuxiliaryFile =
GetPlatformAuxiliaryFile("windows", "winsdk.modulemap", SearchPathOpts);
if (!AuxiliaryFile.empty())
Mappings.emplace_back(std::string(WinSDKInjection), AuxiliaryFile);
}
Expand All @@ -465,7 +490,8 @@ SmallVector<std::pair<std::string, std::string>, 2> GetWindowsFileMappings(
llvm::sys::path::append(UCRTInjection, "Include", UCRTSDK.Version, "ucrt");
llvm::sys::path::append(UCRTInjection, "module.modulemap");

AuxiliaryFile = GetWindowsAuxiliaryFile("ucrt.modulemap", SearchPathOpts);
AuxiliaryFile =
GetPlatformAuxiliaryFile("windows", "ucrt.modulemap", SearchPathOpts);
if (!AuxiliaryFile.empty()) {
// The ucrt module map has the C standard library headers all together.
// That leads to module cycles with the clang _Builtin_ modules. e.g.
Expand Down Expand Up @@ -502,14 +528,16 @@ SmallVector<std::pair<std::string, std::string>, 2> GetWindowsFileMappings(

llvm::sys::path::append(VCToolsInjection, "module.modulemap");
AuxiliaryFile =
GetWindowsAuxiliaryFile("vcruntime.modulemap", SearchPathOpts);
GetPlatformAuxiliaryFile("windows", "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);
GetPlatformAuxiliaryFile("windows", "vcruntime.apinotes",
SearchPathOpts);
if (!AuxiliaryFile.empty())
Mappings.emplace_back(std::string(VCToolsInjection), AuxiliaryFile);
}
Expand All @@ -525,6 +553,7 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
vfs = llvm::vfs::getRealFileSystem();

const llvm::Triple &triple = ctx.LangOpts.Target;
llvm::SmallString<256> sysroot;

// For modulemaps that have all the C standard library headers together in
// a single module, we end up with module cycles with the clang _Builtin_
Expand Down Expand Up @@ -560,6 +589,11 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
StringRef headerFiles[] = {"SwiftAndroidNDK.h", "SwiftBionic.h"};
libcFileMapping =
getLibcFileMapping(ctx, "android.modulemap", headerFiles, vfs);

if (!libcFileMapping.empty()) {
sysroot = libcFileMapping[0].first;
llvm::sys::path::remove_filename(sysroot);
}
} else if (triple.isOSGlibc() || triple.isOSOpenBSD() ||
triple.isOSFreeBSD()) {
// BSD/Linux Mappings
Expand All @@ -577,5 +611,8 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
result.redirectedFiles.append(GetWindowsFileMappings(
ctx, vfs, result.requiresBuiltinHeadersInSystemModules));

result.redirectedFiles.append(GetAndroidFileMappings(ctx, sysroot.str().str(),
vfs));

return result;
}
5 changes: 5 additions & 0 deletions stdlib/public/Platform/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,11 @@ if("ANDROID" IN_LIST SWIFT_SDKS)
COMPONENT sdk-overlay)
endif()
endforeach()

swift_install_in_component(FILES
posix_filesystem.apinotes
DESTINATION "share"
Copy link
Member

Choose a reason for hiding this comment

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

Do you install the compiler and this file on Windows before building swift-corelibs-foundation with that new installed location? I just tried using this with #5010 on Android and this file wasn't available, because build-script uses the freshly-built compiler in build/ to compile swift-corelibs-foundation, not the installed one from --install-prefix.

I will submit a change to place this file in build/ also, so we can use it when cross-compiling the corelibs for Android with build-script also.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, we install the compiler first to use it for the subsequent steps. I think that it makes more sense to change build-script to alter the behaviour and to stage the compiler first.

COMPONENT sdk-overlay)
endif()
add_custom_target(android_modulemap DEPENDS ${android_modulemap_target_list})
set_property(TARGET android_modulemap PROPERTY FOLDER "Miscellaneous")
Expand Down
7 changes: 7 additions & 0 deletions stdlib/public/Platform/posix_filesystem.apinotes
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
Name: bionic
Functions:
- Name: fts_open
Parameters:
- Position: 0
Type: "char * const _Nullable * _Nonnull"