Skip to content

DependencyScanner: add a new extraPcmArgs field for each Swift module #32304

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 3 commits into from
Jun 16, 2020
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
24 changes: 22 additions & 2 deletions include/swift/AST/ModuleDependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ class SwiftModuleDependenciesStorage : public ModuleDependenciesStorageBase {
/// interface.
const std::vector<std::string> buildCommandLine;

/// To build a PCM to be used by this Swift module, we need to append these
/// arguments to the generic PCM build arguments reported from the dependency
/// graph.
const std::vector<std::string> extraPCMArgs;

/// The hash value that will be used for the generated module
const std::string contextHash;

Expand All @@ -92,10 +97,12 @@ class SwiftModuleDependenciesStorage : public ModuleDependenciesStorageBase {
const std::string &compiledModulePath,
const Optional<std::string> &swiftInterfaceFile,
ArrayRef<StringRef> buildCommandLine,
ArrayRef<StringRef> extraPCMArgs,
StringRef contextHash
) : ModuleDependenciesStorageBase(/*isSwiftModule=*/true, compiledModulePath),
swiftInterfaceFile(swiftInterfaceFile),
buildCommandLine(buildCommandLine.begin(), buildCommandLine.end()),
extraPCMArgs(extraPCMArgs.begin(), extraPCMArgs.end()),
contextHash(contextHash) { }

ModuleDependenciesStorageBase *clone() const override {
Expand Down Expand Up @@ -176,18 +183,31 @@ class ModuleDependencies {
const std::string &compiledModulePath,
const std::string &swiftInterfaceFile,
ArrayRef<StringRef> buildCommands,
ArrayRef<StringRef> extraPCMArgs,
StringRef contextHash) {
return ModuleDependencies(
std::make_unique<SwiftModuleDependenciesStorage>(
compiledModulePath, swiftInterfaceFile, buildCommands, contextHash));
compiledModulePath, swiftInterfaceFile, buildCommands,
extraPCMArgs, contextHash));
}

/// Describe the module dependencies for a serialized or parsed Swift module.
static ModuleDependencies forSwiftModule(
const std::string &compiledModulePath) {
return ModuleDependencies(
std::make_unique<SwiftModuleDependenciesStorage>(
compiledModulePath, None, ArrayRef<StringRef>(), StringRef()));
compiledModulePath, None, ArrayRef<StringRef>(),
ArrayRef<StringRef>(), StringRef()));
}

/// Describe the main Swift module.
static ModuleDependencies forMainSwiftModule(
const std::string &compiledModulePath,
ArrayRef<StringRef> extraPCMArgs) {
return ModuleDependencies(
std::make_unique<SwiftModuleDependenciesStorage>(
compiledModulePath, None, ArrayRef<StringRef>(), extraPCMArgs,
StringRef()));
}

/// Describe the module dependencies for a Clang module that can be
Expand Down
4 changes: 3 additions & 1 deletion include/swift/AST/ModuleLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ struct SubCompilerInstanceInfo {
CompilerInstance* Instance;
StringRef Hash;
ArrayRef<StringRef> BuildArguments;
ArrayRef<StringRef> ExtraPCMArgs;
};

/// Abstract interface to run an action in a sub ASTContext.
Expand All @@ -97,7 +98,8 @@ struct InterfaceSubContextDelegate {
StringRef interfacePath,
StringRef outputPath,
SourceLoc diagLoc,
llvm::function_ref<bool(ASTContext&,ArrayRef<StringRef>, StringRef)> action) = 0;
llvm::function_ref<bool(ASTContext&,ArrayRef<StringRef>,
ArrayRef<StringRef>, StringRef)> action) = 0;
virtual bool runInSubCompilerInstance(StringRef moduleName,
StringRef interfacePath,
StringRef outputPath,
Expand Down
3 changes: 2 additions & 1 deletion include/swift/Frontend/ModuleInterfaceLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,8 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
StringRef interfacePath,
StringRef outputPath,
SourceLoc diagLoc,
llvm::function_ref<bool(ASTContext&, ArrayRef<StringRef>, StringRef)> action) override;
llvm::function_ref<bool(ASTContext&, ArrayRef<StringRef>,
ArrayRef<StringRef>, StringRef)> action) override;
bool runInSubCompilerInstance(StringRef moduleName,
StringRef interfacePath,
StringRef outputPath,
Expand Down
18 changes: 16 additions & 2 deletions lib/ClangImporter/ClangModuleDependencyScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,23 @@ void ClangImporter::recordModuleDependencies(
swiftArgs.push_back(arg.str());
};
// Add all args inheritted from creating the importer.
for (auto arg: allArgs) {
addClangArg(arg);
auto It = allArgs.begin();
while(It != allArgs.end()) {
StringRef arg = *It;
// Remove the -target arguments because we should use the target triple
// from the depending Swift modules.
if (arg == "-target") {
It += 2;
} else if (arg.startswith("-fapinotes-swift-version=")) {
// Remove the apinotes version because we should use the language version
// specified in the interface file.
It += 1;
} else {
addClangArg(*It);
++ It;
}
}

// Swift frontend action: -emit-pcm
swiftArgs.push_back("-emit-pcm");
swiftArgs.push_back("-module-name");
Expand Down
21 changes: 20 additions & 1 deletion lib/Frontend/ModuleInterfaceLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,13 @@ void InterfaceSubContextDelegateImpl::inheritOptionsForBuildingInterface(
GenericArgs.push_back(triple);
}

// Inherit the Swift language version
subInvocation.getLangOptions().EffectiveLanguageVersion =
LangOpts.EffectiveLanguageVersion;
GenericArgs.push_back("-swift-version");
GenericArgs.push_back(ArgSaver.save(subInvocation.getLangOptions()
.EffectiveLanguageVersion.asAPINotesVersionString()));

subInvocation.setImportSearchPaths(SearchPathOpts.ImportSearchPaths);
llvm::for_each(SearchPathOpts.ImportSearchPaths,
[&](const std::string &path) {
Expand Down Expand Up @@ -1323,10 +1330,12 @@ bool InterfaceSubContextDelegateImpl::runInSubContext(StringRef moduleName,
StringRef interfacePath,
StringRef outputPath,
SourceLoc diagLoc,
llvm::function_ref<bool(ASTContext&, ArrayRef<StringRef>, StringRef)> action) {
llvm::function_ref<bool(ASTContext&, ArrayRef<StringRef>,
ArrayRef<StringRef>, StringRef)> action) {
return runInSubCompilerInstance(moduleName, interfacePath, outputPath, diagLoc,
[&](SubCompilerInstanceInfo &info){
return action(info.Instance->getASTContext(), info.BuildArguments,
info.ExtraPCMArgs,
info.Hash);
});
}
Expand Down Expand Up @@ -1398,6 +1407,16 @@ bool InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleN
}
info.BuildArguments = BuildArgs;
info.Hash = CacheHash;
auto target = *(std::find(BuildArgs.rbegin(), BuildArgs.rend(), "-target") - 1);
auto langVersion = *(std::find(BuildArgs.rbegin(), BuildArgs.rend(),
"-swift-version") - 1);
std::array<StringRef, 6> ExtraPCMArgs = {
// PCMs should use the target triple the interface will be using to build
"-Xcc", "-target", "-Xcc", target,
// PCMs should use the effective Swift language version for apinotes.
"-Xcc", ArgSaver.save((llvm::Twine("-fapinotes-swift-version=") + langVersion).str())
};
info.ExtraPCMArgs = ExtraPCMArgs;
// Run the action under the sub compiler instance.
return action(info);
}
Expand Down
25 changes: 23 additions & 2 deletions lib/FrontendTool/ScanDependencies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,21 @@ static void writeJSON(llvm::raw_ostream &out,
out << "\n";
}
out.indent(5 * 2);
out << "]\n";
out << "],\n";
}

if (!swiftDeps->extraPCMArgs.empty()) {
out.indent(5 * 2);
out << "\"extraPcmArgs\": [\n";
for (auto &arg :swiftDeps->extraPCMArgs) {
out.indent(6 * 2);
out << "\"" << arg << "\"";
if (&arg != &swiftDeps->extraPCMArgs.back())
out << ",";
out << "\n";
}
out.indent(5 * 2);
out << (swiftDeps->bridgingHeaderFile.hasValue() ? "],\n" : "]\n");
}

/// Bridging header and its source file dependencies, if any.
Expand Down Expand Up @@ -412,9 +426,16 @@ bool swift::scanDependencies(CompilerInstance &instance) {
llvm::SmallString<32> mainModulePath = mainModule->getName().str();
llvm::sys::path::replace_extension(mainModulePath, newExt);

std::string apinotesVer = (llvm::Twine("-fapinotes-swift-version=")
+ instance.getASTContext().LangOpts.EffectiveLanguageVersion
.asAPINotesVersionString()).str();
// Compute the dependencies of the main module.
auto mainDependencies =
ModuleDependencies::forSwiftModule(mainModulePath.str().str());
ModuleDependencies::forMainSwiftModule(mainModulePath.str().str(), {
// ExtraPCMArgs
"-Xcc", "-target", "-Xcc", instance.getASTContext().LangOpts.Target.str(),
"-Xcc", apinotesVer
});
{
llvm::StringSet<> alreadyAddedModules;
for (auto fileUnit : mainModule->getFiles()) {
Expand Down
4 changes: 3 additions & 1 deletion lib/Serialization/ModuleDependencyScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,12 @@ ErrorOr<ModuleDependencies> ModuleDependencyScanner::scanInterfaceFile(
moduleInterfacePath.str(),
StringRef(),
SourceLoc(),
[&](ASTContext &Ctx, ArrayRef<StringRef> Args, StringRef Hash) {
[&](ASTContext &Ctx, ArrayRef<StringRef> Args,
ArrayRef<StringRef> PCMArgs, StringRef Hash) {
Result = ModuleDependencies::forSwiftInterface(modulePath.str().str(),
moduleInterfacePath.str(),
Args,
PCMArgs,
Hash);
// Open the interface file.
auto &fs = *Ctx.SourceMgr.getFileSystem();
Expand Down
5 changes: 5 additions & 0 deletions test/ScanDependencies/Inputs/ModuleDependencyGraph.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ struct SwiftModuleDetails: Codable {
/// The Swift command line arguments that need to be passed through
/// to the -compile-module-from-interface action to build this module.
var commandLine: [String]?

/// To build a PCM to be used by this Swift module, we need to append these
/// arguments to the generic PCM build arguments reported from the dependency
/// graph.
var extraPcmArgs: [String]?
}

/// Details specific to Clang modules.
Expand Down
36 changes: 12 additions & 24 deletions test/ScanDependencies/module_deps.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,6 @@
// RUN: %target-codesign %t/main
// RUN: %target-run %t/main %t/deps.json

// RUN: mkdir -p %t/BuildModules
// RUN: cp %S/Inputs/BuildModulesFromGraph.swift %t/BuildModules/main.swift
// RUN: %target-build-swift %S/Inputs/ModuleDependencyGraph.swift %t/BuildModules/main.swift -o %t/ModuleBuilder
// RUN: %target-codesign %t/ModuleBuilder

// RUN: %target-run %t/ModuleBuilder %t/deps.json %swift-path SwiftShims.pcm -o %t/clang-module-cache/SwiftShims.pcm | %S/Inputs/CommandRunner.py
// RUN: ls %t/clang-module-cache/SwiftShims.pcm
// RUN: %target-run %t/ModuleBuilder %t/deps.json %swift-path A.pcm -o %t/clang-module-cache/A.pcm | %S/Inputs/CommandRunner.py
// RUN: ls %t/clang-module-cache/A.pcm
// RUN: %target-run %t/ModuleBuilder %t/deps.json %swift-path B.pcm -o %t/clang-module-cache/B.pcm -Xcc -Xclang -Xcc -fmodule-map-file=%S/Inputs/CHeaders/module.modulemap -Xcc -Xclang -Xcc -fmodule-file=%t/clang-module-cache/A.pcm | %S/Inputs/CommandRunner.py
// RUN: ls %t/clang-module-cache/B.pcm
// RUN: %target-run %t/ModuleBuilder %t/deps.json %swift-path C.pcm -o %t/clang-module-cache/C.pcm -Xcc -Xclang -Xcc -fmodule-map-file=%S/Inputs/CHeaders/module.modulemap -Xcc -Xclang -Xcc -fmodule-file=%t/clang-module-cache/B.pcm | %S/Inputs/CommandRunner.py
// RUN: ls %t/clang-module-cache/C.pcm

// RUN: %target-run %t/ModuleBuilder %t/deps.json %swift-path A.swiftmodule -o %t/clang-module-cache/A.swiftmodule -Xcc -Xclang -Xcc -fmodule-map-file=%S/Inputs/CHeaders/module.modulemap -Xcc -Xclang -Xcc -fmodule-file=%t/clang-module-cache/A.pcm -Xcc -Xclang -Xcc -fmodule-file=%t/clang-module-cache/SwiftShims.pcm | %S/Inputs/CommandRunner.py
// RUN: ls %t/clang-module-cache/A.swiftmodule

// RUN: %target-run %t/ModuleBuilder %t/deps.json %swift-path E.swiftmodule -o %t/clang-module-cache/E.swiftmodule -Xcc -Xclang -Xcc -fmodule-map-file=%S/Inputs/CHeaders/module.modulemap -Xcc -Xclang -Xcc -fmodule-file=%t/clang-module-cache/SwiftShims.pcm | %S/Inputs/CommandRunner.py
// RUN: ls %t/clang-module-cache/E.swiftmodule

// RUN: %target-run %t/ModuleBuilder %t/deps.json %swift-path SubE.swiftmodule -o %t/clang-module-cache/SubE.swiftmodule -Xcc -Xclang -Xcc -fmodule-map-file=%S/Inputs/CHeaders/module.modulemap -Xcc -Xclang -Xcc -fmodule-file=%t/clang-module-cache/SwiftShims.pcm -swift-module-file %t/clang-module-cache/E.swiftmodule | %S/Inputs/CommandRunner.py
// RUN: ls %t/clang-module-cache/SubE.swiftmodule

// REQUIRES: executable_test
// REQUIRES: objc_interop

Expand Down Expand Up @@ -83,6 +60,13 @@ import SubE
// CHECK-NEXT: {
// CHECK-NEXT: "swift": "_cross_import_E"
// CHECK-NEXT: }
// CHECK-NEXT: ],

// CHECK: "extraPcmArgs": [
// CHECK-NEXT: "-Xcc",
// CHECK-NEXT: "-target",
// CHECK-NEXT: "-Xcc",
// CHECK: "-fapinotes-swift-version=4"

// CHECK: "bridgingHeader":
// CHECK-NEXT: "path":
Expand Down Expand Up @@ -151,7 +135,11 @@ import SubE
// CHECK: "G"
// CHECK: "-swift-version"
// CHECK: "5"
// CHECK: ]
// CHECK: ],
// CHECK" "extraPcmArgs": [
// CHECK" "-target",
// CHECK" "-fapinotes-swift-version=5"
// CHECK" ]

/// --------Swift module Swift
// CHECK-LABEL: "modulePath": "Swift.swiftmodule",
Expand Down