Merge remote-tracking branch 'origin/main' into rebranch

This commit is contained in:
swift-ci
2025-09-25 15:15:11 -07:00
18 changed files with 266 additions and 162 deletions

View File

@@ -583,9 +583,9 @@ bool extractCompilerFlagsFromInterface(
llvm::VersionTuple extractUserModuleVersionFromInterface(StringRef moduleInterfacePath); llvm::VersionTuple extractUserModuleVersionFromInterface(StringRef moduleInterfacePath);
/// Extract embedded bridging header from binary module. /// Extract embedded bridging header from binary module.
std::string std::unique_ptr<llvm::MemoryBuffer>
extractEmbeddedBridgingHeaderContent(std::unique_ptr<llvm::MemoryBuffer> file, extractEmbeddedBridgingHeaderContent(std::unique_ptr<llvm::MemoryBuffer> file,
ASTContext &Context); StringRef headerPath, ASTContext &Context);
} // end namespace swift } // end namespace swift
#endif #endif

View File

@@ -1364,12 +1364,8 @@ void ModuleDependencyScanner::resolveHeaderDependenciesForModule(
if (!moduleBuf) if (!moduleBuf)
return nullptr; return nullptr;
auto content = extractEmbeddedBridgingHeaderContent(std::move(*moduleBuf), return extractEmbeddedBridgingHeaderContent(std::move(*moduleBuf), header,
ScanASTContext); ScanASTContext);
if (content.empty())
return nullptr;
return llvm::MemoryBuffer::getMemBufferCopy(content, header);
}; };
if (isBinaryModuleWithHeaderInput) { if (isBinaryModuleWithHeaderInput) {
@@ -1643,28 +1639,24 @@ void ModuleDependencyScanner::resolveCrossImportOverlayDependencies(
allModules.end(), action); allModules.end(), action);
} }
static void appendHeaderContent(llvm::raw_ostream &OS,
llvm::MemoryBufferRef buffer,
ModuleDependencyID fromModule) {
// Use preprocessor directives to add some clues for where the content is
// coming from.
OS << "# 1 \"<module-" << fromModule.ModuleName << ">/"
<< llvm::sys::path::filename(buffer.getBufferIdentifier()) << "\" 1\n";
OS << buffer.getBuffer();
}
llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining( llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining(
const ModuleDependencyID &rootModuleID, ModuleDependenciesCache &cache, const ModuleDependencyID &rootModuleID, ModuleDependenciesCache &cache,
ModuleDependencyIDSetVector &allModules) { ModuleDependencyIDSetVector &allModules) {
if (rootModuleID.Kind != ModuleDependencyKind::SwiftSource) if (rootModuleID.Kind != ModuleDependencyKind::SwiftSource)
return llvm::Error::success(); return llvm::Error::success();
bool hasBridgingHeader = false; llvm::SmallString<256> chainedHeaderBuffer;
llvm::vfs::OnDiskOutputBackend outputBackend; llvm::raw_svector_ostream outOS(chainedHeaderBuffer);
SmallString<256> outputPath(
ScanCompilerInvocation.getFrontendOptions().ScannerOutputDir);
if (outputPath.empty())
outputPath = "/<compiler-generated>";
llvm::sys::path::append(
outputPath, ScanCompilerInvocation.getFrontendOptions().ModuleName + "-" +
ScanCompilerInvocation.getModuleScanningHash() +
"-ChainedBridgingHeader.h");
llvm::SmallString<256> sourceBuf;
llvm::raw_svector_ostream outOS(sourceBuf);
// Iterate through all the modules and collect all the bridging header // Iterate through all the modules and collect all the bridging header
// and chain them into a single file. The allModules list is in the order of // and chain them into a single file. The allModules list is in the order of
@@ -1672,16 +1664,14 @@ llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining(
// buffer. // buffer.
auto FS = ScanASTContext.SourceMgr.getFileSystem(); auto FS = ScanASTContext.SourceMgr.getFileSystem();
for (const auto &moduleID : allModules) { for (const auto &moduleID : allModules) {
if (moduleID.Kind != ModuleDependencyKind::SwiftSource && if (moduleID.Kind != ModuleDependencyKind::SwiftBinary)
moduleID.Kind != ModuleDependencyKind::SwiftBinary)
continue; continue;
auto moduleDependencyInfo = cache.findKnownDependency(moduleID); auto moduleDependencyInfo = cache.findKnownDependency(moduleID);
if (auto *binaryMod = moduleDependencyInfo.getAsSwiftBinaryModule()) { if (auto *binaryMod = moduleDependencyInfo.getAsSwiftBinaryModule()) {
if (!binaryMod->headerImport.empty()) { if (!binaryMod->headerImport.empty()) {
hasBridgingHeader = true; if (auto buffer= FS->getBufferForFile(binaryMod->headerImport)) {
if (FS->exists(binaryMod->headerImport)) { appendHeaderContent(outOS, (*buffer)->getMemBufferRef(), moduleID);
outOS << "#include \"" << binaryMod->headerImport << "\"\n";
} else { } else {
// Extract the embedded bridging header // Extract the embedded bridging header
auto moduleBuf = FS->getBufferForFile(binaryMod->compiledModulePath); auto moduleBuf = FS->getBufferForFile(binaryMod->compiledModulePath);
@@ -1689,39 +1679,76 @@ llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining(
return llvm::errorCodeToError(moduleBuf.getError()); return llvm::errorCodeToError(moduleBuf.getError());
auto content = extractEmbeddedBridgingHeaderContent( auto content = extractEmbeddedBridgingHeaderContent(
std::move(*moduleBuf), ScanASTContext); std::move(*moduleBuf), /*headerPath=*/"", ScanASTContext);
if (content.empty()) if (!content)
return llvm::createStringError("can't load embedded header from " + return llvm::createStringError("can't load embedded header from " +
binaryMod->compiledModulePath); binaryMod->compiledModulePath);
outOS << content << "\n"; outOS << content->getBuffer() << "\n";
} }
} }
} else if (auto *srcMod = moduleDependencyInfo.getAsSwiftSourceModule()) {
if (srcMod->textualModuleDetails.bridgingHeaderFile) {
hasBridgingHeader = true;
outOS << "#include \""
<< *srcMod->textualModuleDetails.bridgingHeaderFile << "\"\n";
}
} }
} }
if (!hasBridgingHeader) // Handle bridging header in main module.
return llvm::Error::success(); auto mainModuleDeps = cache.findKnownDependency(rootModuleID);
auto *mainModule = mainModuleDeps.getAsSwiftSourceModule();
assert(mainModule && "expect main module to be a swift source module");
std::unique_ptr<llvm::MemoryBuffer> sourceBuffer;
bool needChainedHeader = !chainedHeaderBuffer.empty();
if (!needChainedHeader) {
// There is no bridging header chained from dependencies.
// If main module also has no bridging header, ther is nothing to scan.
if (!mainModule->textualModuleDetails.bridgingHeaderFile)
return llvm::Error::success();
if (ScanCompilerInvocation.getFrontendOptions().WriteScannerOutput) { // Otherwise, there is no chaining needed. Just use the bridging header from
auto outFile = outputBackend.createFile(outputPath); // main module.
if (!outFile) if (auto headerBuffer = FS->getBufferForFile(
return outFile.takeError(); *mainModule->textualModuleDetails.bridgingHeaderFile))
*outFile << sourceBuf; sourceBuffer = std::move(*headerBuffer);
if (auto err = outFile->keep()) else
return err; return llvm::errorCodeToError(headerBuffer.getError());
} else {
// There are bridging header needed to be chained. Append the bridging
// header from main module if needed and create use a new source buffer.
if (mainModule->textualModuleDetails.bridgingHeaderFile) {
auto srcBuf = FS->getBufferForFile(
*mainModule->textualModuleDetails.bridgingHeaderFile);
if (!srcBuf)
return llvm::errorCodeToError(srcBuf.getError());
appendHeaderContent(outOS, (*srcBuf)->getMemBufferRef(), rootModuleID);
}
SmallString<256> outputPath(
ScanCompilerInvocation.getFrontendOptions().ScannerOutputDir);
if (outputPath.empty())
outputPath = "/<compiler-generated>";
// Use the hash of the file content to differentiate the chained header.
auto fileHash =
llvm::toString(llvm::APInt(64, llvm::hash_value(chainedHeaderBuffer)),
36, /*Signed=*/false);
llvm::sys::path::append(
outputPath, ScanCompilerInvocation.getFrontendOptions().ModuleName +
"-" + fileHash + "-ChainedBridgingHeader.h");
if (ScanCompilerInvocation.getFrontendOptions().WriteScannerOutput) {
llvm::vfs::OnDiskOutputBackend outputBackend;
auto outFile = outputBackend.createFile(outputPath);
if (!outFile)
return outFile.takeError();
*outFile << chainedHeaderBuffer;
if (auto err = outFile->keep())
return err;
}
sourceBuffer =
llvm::MemoryBuffer::getMemBufferCopy(chainedHeaderBuffer, outputPath);
} }
auto sourceBuffer =
llvm::MemoryBuffer::getMemBufferCopy(sourceBuf, outputPath);
// Scan and update the main module dependency. // Scan and update the main module dependency.
auto mainModuleDeps = cache.findKnownDependency(rootModuleID);
ModuleDependencyIDSetVector headerClangModuleDependencies; ModuleDependencyIDSetVector headerClangModuleDependencies;
std::optional<std::string> includeTreeID; std::optional<std::string> includeTreeID;
auto err = withDependencyScanningWorker( auto err = withDependencyScanningWorker(
@@ -1740,7 +1767,8 @@ llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining(
if (!headerScanResult) if (!headerScanResult)
return llvm::createStringError( return llvm::createStringError(
"failed to scan generated bridging header " + outputPath); "failed to scan generated bridging header " +
sourceBuffer->getBufferIdentifier());
// Record module dependencies for each new module we found. // Record module dependencies for each new module we found.
cache.recordClangDependencies( cache.recordClangDependencies(
@@ -1781,9 +1809,25 @@ llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining(
} }
mainModuleDeps.updateBridgingHeaderCommandLine( mainModuleDeps.updateBridgingHeaderCommandLine(
bridgingHeaderCommandLine); bridgingHeaderCommandLine);
if (needChainedHeader) {
// As only the chained bridging header is scanned, the dependency will
// not include the original bridging header passed by user. Fixup the
// headerFileInputs to include original bridging header and not
// include the generated header so build system can correctly computes
// the dependencies.
auto generated =
llvm::find(headerFileInputs, sourceBuffer->getBufferIdentifier());
if (generated != headerFileInputs.end()) {
if (mainModule->textualModuleDetails.bridgingHeaderFile)
*generated = *mainModule->textualModuleDetails.bridgingHeaderFile;
else
headerFileInputs.erase(generated);
}
}
mainModuleDeps.setHeaderSourceFiles(headerFileInputs); mainModuleDeps.setHeaderSourceFiles(headerFileInputs);
mainModuleDeps.setChainedBridgingHeaderBuffer( if (needChainedHeader)
outputPath, sourceBuffer->getBuffer()); mainModuleDeps.setChainedBridgingHeaderBuffer(
sourceBuffer->getBufferIdentifier(), sourceBuffer->getBuffer());
// Update the set of visible Clang modules // Update the set of visible Clang modules
mainModuleDeps.addVisibleClangModules(headerScanResult->VisibleModules); mainModuleDeps.addVisibleClangModules(headerScanResult->VisibleModules);

View File

@@ -675,9 +675,9 @@ public:
} }
/// Get embedded bridging header. /// Get embedded bridging header.
std::string getEmbeddedHeader() const { StringRef getEmbeddedHeader() const {
// Don't include the '\0' in the end. // Don't include the '\0' in the end.
return importedHeaderInfo.contents.drop_back().str(); return importedHeaderInfo.contents.drop_back();
} }
/// If the module-defining `.swiftinterface` file is an SDK-relative path, /// If the module-defining `.swiftinterface` file is an SDK-relative path,

View File

@@ -1492,8 +1492,9 @@ swift::extractUserModuleVersionFromInterface(StringRef moduleInterfacePath) {
return result; return result;
} }
std::string swift::extractEmbeddedBridgingHeaderContent( std::unique_ptr<llvm::MemoryBuffer> swift::extractEmbeddedBridgingHeaderContent(
std::unique_ptr<llvm::MemoryBuffer> file, ASTContext &Context) { std::unique_ptr<llvm::MemoryBuffer> file, StringRef headerPath,
ASTContext &Context) {
std::shared_ptr<const ModuleFileSharedCore> loadedModuleFile; std::shared_ptr<const ModuleFileSharedCore> loadedModuleFile;
serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load( serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load(
"", "", std::move(file), nullptr, nullptr, false, "", "", std::move(file), nullptr, nullptr, false,
@@ -1503,9 +1504,10 @@ std::string swift::extractEmbeddedBridgingHeaderContent(
loadedModuleFile); loadedModuleFile);
if (loadInfo.status != serialization::Status::Valid) if (loadInfo.status != serialization::Status::Valid)
return {}; return nullptr;;
return loadedModuleFile->getEmbeddedHeader(); return llvm::MemoryBuffer::getMemBufferCopy(
loadedModuleFile->getEmbeddedHeader(), headerPath);
} }
bool SerializedModuleLoaderBase::canImportModule( bool SerializedModuleLoaderBase::canImportModule(

View File

@@ -127,9 +127,6 @@ else()
set(clang_headers_location "${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION_MAJOR}") set(clang_headers_location "${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION_MAJOR}")
endif() endif()
# Normalize the path.
cmake_path(CONVERT "${clang_headers_location}" TO_CMAKE_PATH_LIST clang_headers_location NORMALIZE)
add_custom_command_target(unused_var add_custom_command_target(unused_var
COMMAND COMMAND
"${CMAKE_COMMAND}" "-E" "make_directory" "${SWIFTLIB_DIR}" "${CMAKE_COMMAND}" "-E" "make_directory" "${SWIFTLIB_DIR}"

View File

@@ -31,7 +31,8 @@ with open(input_json, "r") as file:
cmd = info["bridgingHeader"]["commandLine"][1:] cmd = info["bridgingHeader"]["commandLine"][1:]
printCmd(cmd) printCmd(cmd)
# print input file name. # print input file name.
print(info["chainedBridgingHeaderPath"]) if "chainedBridgingHeaderPath" in info:
print(info["chainedBridgingHeaderPath"])
else: else:
module_names = deps["modules"][::2] module_names = deps["modules"][::2]
module_details = deps["modules"][1::2] module_details = deps["modules"][1::2]

View File

@@ -10,6 +10,7 @@ module_name = sys.argv[2]
key = sys.argv[3] key = sys.argv[3]
mode = 'swift' mode = 'swift'
is_bridging_header = False
if module_name.startswith('clang:'): if module_name.startswith('clang:'):
mode = 'clang' mode = 'clang'
@@ -17,6 +18,9 @@ if module_name.startswith('clang:'):
elif module_name.startswith('swiftPrebuiltExternal:'): elif module_name.startswith('swiftPrebuiltExternal:'):
mode = 'swiftPrebuiltExternal' mode = 'swiftPrebuiltExternal'
module_name = module_name[22:] module_name = module_name[22:]
elif module_name.startswith('bridgingHeader:'):
is_bridging_header = True
module_name = module_name[15:]
with open(input_json, 'r') as file: with open(input_json, 'r') as file:
deps = json.load(file) deps = json.load(file)
@@ -30,5 +34,10 @@ with open(input_json, 'r') as file:
json.dump(detail[key], sys.stdout, indent=2) json.dump(detail[key], sys.stdout, indent=2)
break break
if is_bridging_header:
json.dump(detail['details'][mode]['bridgingHeader']
[key], sys.stdout, indent=2)
break
json.dump(detail['details'][mode][key], sys.stdout, indent=2) json.dump(detail['details'][mode][key], sys.stdout, indent=2)
break break

View File

@@ -0,0 +1,88 @@
// RUN: %empty-directory(%t)
// RUN: split-file %s %t
/// Test prefix mapped bridging header path will result in the same cache key.
// RUN: %target-swift-frontend -scan-dependencies -module-name Test -module-cache-path %t/clang-module-cache -O \
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
// RUN: %t/test.swift -o %t/deps-1.json -auto-bridging-header-chaining -cache-compile-job -cas-path %t/cas \
// RUN: -scanner-prefix-map-paths %swift_src_root /^src -scanner-prefix-map-paths %t /^tmp \
// RUN: -scanner-prefix-map-paths %t/header-1 /^header \
// RUN: -scanner-output-dir %t/header-1 -import-objc-header %t/header-1/Bridging.h
// RUN: %target-swift-frontend -scan-dependencies -module-name Test -module-cache-path %t/clang-module-cache -O \
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
// RUN: %t/test.swift -o %t/deps-2.json -auto-bridging-header-chaining -cache-compile-job -cas-path %t/cas \
// RUN: -scanner-prefix-map-paths %swift_src_root /^src -scanner-prefix-map-paths %t /^tmp \
// RUN: -scanner-prefix-map-paths %t/header-2 /^header \
// RUN: -scanner-output-dir %t/header-2 -import-objc-header %t/header-2/Bridging.h
// RUN: %{python} %S/Inputs/SwiftDepsExtractor.py %t/deps-1.json bridgingHeader:Test includeTree > %t/includeTree-1.casid
// RUN: %{python} %S/Inputs/SwiftDepsExtractor.py %t/deps-2.json bridgingHeader:Test includeTree > %t/includeTree-2.casid
// RUN: diff %t/includeTree-1.casid %t/includeTree-2.casid
// RUN: %{python} %S/Inputs/SwiftDepsExtractor.py %t/deps-1.json Test casFSRootID > %t/root-1.casid
// RUN: %{python} %S/Inputs/SwiftDepsExtractor.py %t/deps-2.json Test casFSRootID > %t/root-2.casid
// RUN: diff %t/root-1.casid %t/root-2.casid
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps-1.json clang:SwiftShims > %t/shim.cmd
// RUN: %swift_frontend_plain @%t/shim.cmd
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps-1.json bridgingHeader > %t/header.cmd
// RUN: %target-swift-frontend @%t/header.cmd /^header/Bridging.h -disable-implicit-swift-modules -O -o %t/bridging.pch
// RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \
// RUN: %target-swift-frontend @%t/header.cmd /^header/Bridging.h -disable-implicit-swift-modules -O -o %t/bridging.pch > %t/keys.json
// RUN: %{python} %S/Inputs/ExtractOutputKey.py %t/keys.json > %t/key
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps-1.json Test > %t/MyApp.cmd
// RUN: echo "\"-disable-implicit-string-processing-module-import\"" >> %t/MyApp.cmd
// RUN: echo "\"-disable-implicit-concurrency-module-import\"" >> %t/MyApp.cmd
// RUN: echo "\"-disable-implicit-swift-modules\"" >> %t/MyApp.cmd
// RUN: echo "\"-import-objc-header\"" >> %t/MyApp.cmd
// RUN: echo "\"/^header/Bridging.h\"" >> %t/MyApp.cmd
// RUN: echo "\"-import-pch\"" >> %t/MyApp.cmd
// RUN: echo "\"%t/bridging.pch\"" >> %t/MyApp.cmd
// RUN: echo "\"-bridging-header-pch-key\"" >> %t/MyApp.cmd
// RUN: echo "\"@%t/key\"" >> %t/MyApp.cmd
// RUN: echo "\"-explicit-swift-module-map-file\"" >> %t/MyApp.cmd
// RUN: echo "\"@%t/map.casid\"" >> %t/MyApp.cmd
// RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps-1.json > %t/map.json
// RUN: llvm-cas --cas %t/cas --make-blob --data %t/map.json > %t/map.casid
// RUN: %target-swift-frontend -cache-compile-job -module-name Test -O -cas-path %t/cas @%t/MyApp.cmd /^tmp/test.swift \
// RUN: -emit-module -o %t/Test.swiftmodule
// RUN: %target-swift-frontend -scan-dependencies -module-name User -module-cache-path %t/clang-module-cache -O \
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
// RUN: %t/user.swift -o %t/deps-3.json -auto-bridging-header-chaining -cache-compile-job -cas-path %t/cas \
// RUN: -scanner-prefix-map-paths %swift_src_root /^src -scanner-prefix-map-paths %t /^tmp \
// RUN: -scanner-prefix-map-paths %t/header-1 /^header \
// RUN: -scanner-output-dir %t/header-1 -I %t
// RUN: %target-swift-frontend -scan-dependencies -module-name User -module-cache-path %t/clang-module-cache -O \
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
// RUN: %t/user.swift -o %t/deps-4.json -auto-bridging-header-chaining -cache-compile-job -cas-path %t/cas \
// RUN: -scanner-prefix-map-paths %swift_src_root /^src -scanner-prefix-map-paths %t /^tmp \
// RUN: -scanner-prefix-map-paths %t/header-2 /^header \
// RUN: -scanner-output-dir %t/header-2 -I %t
// RUN: %{python} %S/Inputs/SwiftDepsExtractor.py %t/deps-3.json bridgingHeader:Test includeTree > %t/includeTree-3.casid
// RUN: %{python} %S/Inputs/SwiftDepsExtractor.py %t/deps-4.json bridgingHeader:Test includeTree > %t/includeTree-4.casid
// RUN: diff %t/includeTree-3.casid %t/includeTree-4.casid
//--- test.swift
public func test() {
b()
}
//--- user.swift
import Test
//--- header-1/Bridging.h
#include "Foo.h"
//--- header-1/Foo.h
void b(void);
//--- header-2/Bridging.h
#include "Foo.h"
//--- header-2/Foo.h
void b(void);

View File

@@ -41,9 +41,9 @@
// RUN: llvm-cas --cas %t/cas --make-blob --data %t/map.json > %t/map.casid // RUN: llvm-cas --cas %t/cas --make-blob --data %t/map.json > %t/map.casid
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader > %t/header.cmd // RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader > %t/header.cmd
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/bridging.pch // RUN: %target-swift-frontend @%t/header.cmd %t/Bridging.h -disable-implicit-swift-modules -O -o %t/bridging.pch
// RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \ // RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/bridging.pch > %t/keys.json // RUN: %target-swift-frontend @%t/header.cmd %t/Bridging.h -disable-implicit-swift-modules -O -o %t/bridging.pch > %t/keys.json
// RUN: %{python} %S/Inputs/ExtractOutputKey.py %t/keys.json > %t/key // RUN: %{python} %S/Inputs/ExtractOutputKey.py %t/keys.json > %t/key
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json Test > %t/MyApp.cmd // RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json Test > %t/MyApp.cmd

View File

@@ -8,9 +8,9 @@
// RUN: %swift_frontend_plain @%t/shim.cmd // RUN: %swift_frontend_plain @%t/shim.cmd
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader > %t/header.cmd // RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader > %t/header.cmd
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/objc.pch 2>&1 | %FileCheck %s -check-prefix CHECK-BRIDGE // RUN: %target-swift-frontend @%t/header.cmd %S/Inputs/objc.h -disable-implicit-swift-modules -O -o %t/objc.pch 2>&1 | %FileCheck %s -check-prefix CHECK-BRIDGE
// RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \ // RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/objc.pch > %t/keys.json // RUN: %target-swift-frontend @%t/header.cmd %S/Inputs/objc.h -disable-implicit-swift-modules -O -o %t/objc.pch > %t/keys.json
// RUN: %{python} %S/Inputs/ExtractOutputKey.py %t/keys.json > %t/key // RUN: %{python} %S/Inputs/ExtractOutputKey.py %t/keys.json > %t/key
// RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json // RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json

View File

@@ -7,11 +7,11 @@
// RUN: %t/test.swift -o %t/deps.json -cache-compile-job -cas-path %t/cas -scanner-prefix-map-paths %t /^test -scanner-output-dir %t.noremap // RUN: %t/test.swift -o %t/deps.json -cache-compile-job -cas-path %t/cas -scanner-prefix-map-paths %t /^test -scanner-output-dir %t.noremap
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader > %t/header.cmd // RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader > %t/header.cmd
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/objc.pch 2>&1 | %FileCheck %s -check-prefix BRIDGE // RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules /^test/objc.h -O -o %t/objc.pch 2>&1 | %FileCheck %s -check-prefix BRIDGE
// RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \ // RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/objc.pch > %t/keys.json // RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules /^test/objc.h -O -o %t/objc.pch > %t/keys.json
// RUN: %cache-tool -cas-path %t/cas -cache-tool-action render-diags %t/keys.json -- \ // RUN: %cache-tool -cas-path %t/cas -cache-tool-action render-diags %t/keys.json -- \
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/objc.pch -cache-replay-prefix-map /^test %t 2>&1 \ // RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules /^test/objc.h -O -o %t/objc.pch -cache-replay-prefix-map /^test %t 2>&1 \
// RUN: | %FileCheck %s -check-prefix BRIDGE -check-prefix BRIDGE-REMAP // RUN: | %FileCheck %s -check-prefix BRIDGE -check-prefix BRIDGE-REMAP
// RUN: %{python} %S/Inputs/ExtractOutputKey.py %t/keys.json > %t/key // RUN: %{python} %S/Inputs/ExtractOutputKey.py %t/keys.json > %t/key

View File

@@ -29,9 +29,9 @@
// RUN: %swift_frontend_plain @%t/dummy.cmd // RUN: %swift_frontend_plain @%t/dummy.cmd
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader > %t/header.cmd // RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader > %t/header.cmd
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/objc.pch // RUN: %target-swift-frontend @%t/header.cmd %t/Bridge.h -disable-implicit-swift-modules -O -o %t/objc.pch
// RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \ // RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/objc.pch > %t/keys.json // RUN: %target-swift-frontend @%t/header.cmd %t/Bridge.h -disable-implicit-swift-modules -O -o %t/objc.pch > %t/keys.json
// RUN: %{python} %S/Inputs/ExtractOutputKey.py %t/keys.json > %t/key // RUN: %{python} %S/Inputs/ExtractOutputKey.py %t/keys.json > %t/key
// RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json // RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json

View File

@@ -72,7 +72,6 @@ import SubE
// CHECK-SAME: Bridging.h // CHECK-SAME: Bridging.h
// CHECK-NEXT: "sourceFiles": // CHECK-NEXT: "sourceFiles":
// CHECK-NEXT: ChainedBridgingHeader.h
// CHECK-NEXT: Bridging.h // CHECK-NEXT: Bridging.h
// CHECK-NEXT: BridgingOther.h // CHECK-NEXT: BridgingOther.h

View File

@@ -62,7 +62,6 @@ import SubE
// CHECK-SAME: Bridging.h // CHECK-SAME: Bridging.h
// CHECK-NEXT: "sourceFiles": // CHECK-NEXT: "sourceFiles":
// CHECK-NEXT: ChainedBridgingHeader.h
// CHECK-NEXT: Bridging.h // CHECK-NEXT: Bridging.h
// CHECK-NEXT: BridgingOther.h // CHECK-NEXT: BridgingOther.h

View File

@@ -14,9 +14,9 @@
// RUN: %swift_frontend_plain @%t/simple.cmd // RUN: %swift_frontend_plain @%t/simple.cmd
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader > %t/header.cmd // RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader > %t/header.cmd
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/bridging.pch // RUN: %target-swift-frontend @%t/header.cmd %t/Bridging.h -disable-implicit-swift-modules -O -o %t/bridging.pch
// RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \ // RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/bridging.pch > %t/keys.json // RUN: %target-swift-frontend @%t/header.cmd %t/Bridging.h -disable-implicit-swift-modules -O -o %t/bridging.pch > %t/keys.json
// RUN: %{python} %S/Inputs/ExtractOutputKey.py %t/keys.json > %t/key // RUN: %{python} %S/Inputs/ExtractOutputKey.py %t/keys.json > %t/key
// RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json // RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json

View File

@@ -15,9 +15,9 @@
// RUN: llvm-cas --cas %t/cas --make-blob --data %t/map.json > %t/map.casid // RUN: llvm-cas --cas %t/cas --make-blob --data %t/map.json > %t/map.casid
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader > %t/header.cmd // RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader > %t/header.cmd
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/bridging.pch // RUN: %target-swift-frontend @%t/header.cmd %t/base/Bridging.h -disable-implicit-swift-modules -O -o %t/bridging.pch
// RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \ // RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/bridging.pch > %t/keys.json // RUN: %target-swift-frontend @%t/header.cmd %t/base/Bridging.h -disable-implicit-swift-modules -O -o %t/bridging.pch > %t/keys.json
// RUN: %{python} %S/Inputs/ExtractOutputKey.py %t/keys.json > %t/key // RUN: %{python} %S/Inputs/ExtractOutputKey.py %t/keys.json > %t/key
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json Test > %t/MyApp.cmd // RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json Test > %t/MyApp.cmd

View File

@@ -25,7 +25,7 @@
// RUN: %{python} %S/../CAS/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json // RUN: %{python} %S/../CAS/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader > %t/header.cmd // RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader > %t/header.cmd
// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules -O -o %t/bridging.pch // RUN: %target-swift-frontend @%t/header.cmd %t/Bridging.h -disable-implicit-swift-modules -O -o %t/bridging.pch
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json Test > %t/MyApp.cmd // RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json Test > %t/MyApp.cmd
// RUN: echo "\"-disable-implicit-string-processing-module-import\"" >> %t/MyApp.cmd // RUN: echo "\"-disable-implicit-string-processing-module-import\"" >> %t/MyApp.cmd
@@ -60,8 +60,9 @@
// RUN: %t/user.swift -auto-bridging-header-chaining -o %t/User.swiftmodule \ // RUN: %t/user.swift -auto-bridging-header-chaining -o %t/User.swiftmodule \
// RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap -I %t > %t/header1.h // RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap -I %t > %t/header1.h
// RUN: %FileCheck %s --check-prefix=HEADER1 --input-file=%t/header1.h // RUN: %FileCheck %s --check-prefix=HEADER1 --input-file=%t/header1.h
// HEADER1: #include // HEADER1: # 1 "<module-Test>/Bridging.h" 1
// HEADER1-SAME: Bridging.h // HEADER1: #include "Foo.h"
// HEADER1: #include "Foo2.h"
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps2.json bridgingHeader > %t/header1.cmd // RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps2.json bridgingHeader > %t/header1.cmd
// RUN: %target-swift-frontend @%t/header1.cmd -disable-implicit-swift-modules -O -o %t/bridging1.pch // RUN: %target-swift-frontend @%t/header1.cmd -disable-implicit-swift-modules -O -o %t/bridging1.pch
@@ -93,10 +94,17 @@
// RUN: %t/user.swift -auto-bridging-header-chaining -o %t/User.swiftmodule -import-objc-header %t/Bridging2.h \ // RUN: %t/user.swift -auto-bridging-header-chaining -o %t/User.swiftmodule -import-objc-header %t/Bridging2.h \
// RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap -I %t > %t/header2.h // RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap -I %t > %t/header2.h
// RUN: %FileCheck %s --check-prefix=HEADER2 --input-file=%t/header2.h // RUN: %FileCheck %s --check-prefix=HEADER2 --input-file=%t/header2.h
// HEADER2: #include // HEADER2: # 1 "<module-Test>/Bridging.h" 1
// HEADER2-SAME: Bridging2.h // HEADER2: # 1 "<module-User>/Bridging2.h" 1
// HEADER2: #include
// HEADER2-SAME: Bridging.h // RUN: %FileCheck %s --check-prefix DEPS_JSON --input-file=%t/deps3.json
// DEPS_JSON: "chainedBridgingHeaderPath":
// DEPS_JSON-SAME: -ChainedBridgingHeader.h
// DEPS_JSON: "bridgingHeader":
// DEPS_JSON-NEXT: "path":
// DEPS_JSON-SAME: Bridging2.h
// DEPS_JSON-NEXT: "sourceFiles":
// DEPS_JSON-NEXT: Bridging2.h
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps3.json clang:SwiftShims > %t/shim2.cmd // RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps3.json clang:SwiftShims > %t/shim2.cmd
// RUN: %swift_frontend_plain @%t/shim2.cmd // RUN: %swift_frontend_plain @%t/shim2.cmd
@@ -133,6 +141,15 @@
// RUN: -I %t %t/user2.swift -import-objc-header %t/Bridging3.h -auto-bridging-header-chaining -scanner-output-dir %t -scanner-debug-write-output \ // RUN: -I %t %t/user2.swift -import-objc-header %t/Bridging3.h -auto-bridging-header-chaining -scanner-output-dir %t -scanner-debug-write-output \
// RUN: -o %t/deps4.json -Rdependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache // RUN: -o %t/deps4.json -Rdependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache
// RUN: %FileCheck %s --check-prefix DEPS_JSON2 --input-file=%t/deps4.json
// DEPS_JSON2: "chainedBridgingHeaderPath":
// DEPS_JSON2-SAME: -ChainedBridgingHeader.h
// DEPS_JSON2: "bridgingHeader":
// DEPS_JSON2-NEXT: "path":
// DEPS_JSON2-SAME: Bridging3.h
// DEPS_JSON2-NEXT: "sourceFiles":
// DEPS_JSON2-NEXT: Bridging3.h
/// Make sure the cache is correct. /// Make sure the cache is correct.
// RUN: %target-swift-frontend -scan-dependencies -module-name User -O -module-load-mode prefer-serialized \ // RUN: %target-swift-frontend -scan-dependencies -module-name User -O -module-load-mode prefer-serialized \
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -scanner-module-validation \ // RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -scanner-module-validation \

View File

@@ -520,15 +520,6 @@ function Get-CMake {
throw "CMake not found on Path nor in the Visual Studio Installation. Please Install CMake to continue." throw "CMake not found on Path nor in the Visual Studio Installation. Please Install CMake to continue."
} }
$cmake = Get-CMake
$CMakeVersionString = & $cmake --version | Select-String -Pattern 'cmake version ([\d\.]+)' | ForEach-Object { $_.Matches[0].Groups[1].Value }
$CMakeVersion = [Version]$CMakeVersionString
# Starting with CMake 3.30, CMake propagates linker flags to Swift.
$CMakePassesSwiftLinkerFlags = $CMakeVersion -ge [version]'3.30'
# CMP0181 enables support for the `LINKER:flag1,flag2,...` syntax in
# `CMAKE_[EXE|SHARED|MODULE]_LINKER_FLAGS[_<CONFIG>]` variables.
$CMakeSupportsCMP0181 = $CMakeVersion -ge [version]'4.0'
function Get-Ninja { function Get-Ninja {
try { try {
return (Get-Command "Ninja.exe" -ErrorAction Stop).Source return (Get-Command "Ninja.exe" -ErrorAction Stop).Source
@@ -540,6 +531,7 @@ function Get-Ninja {
throw "Ninja not found on Path nor in the Visual Studio Installation. Please Install Ninja to continue." throw "Ninja not found on Path nor in the Visual Studio Installation. Please Install Ninja to continue."
} }
$cmake = Get-CMake
$ninja = Get-Ninja $ninja = Get-Ninja
$NugetRoot = "$BinaryCache\nuget" $NugetRoot = "$BinaryCache\nuget"
@@ -1489,32 +1481,9 @@ function Build-CMakeProject {
$UseCXX = $UseBuiltCompilers.Contains("CXX") -or $UseMSVCCompilers.Contains("CXX") -or $UsePinnedCompilers.Contains("CXX") $UseCXX = $UseBuiltCompilers.Contains("CXX") -or $UseMSVCCompilers.Contains("CXX") -or $UsePinnedCompilers.Contains("CXX")
$UseSwift = $UseBuiltCompilers.Contains("Swift") -or $UsePinnedCompilers.Contains("Swift") $UseSwift = $UseBuiltCompilers.Contains("Swift") -or $UsePinnedCompilers.Contains("Swift")
# We need to manually prefix linker flags with `-Xlinker` if we are using
# the GNU driver or if Swift is used as the linker driver.
# This is not necessary with CMake 4.0+ as CMP0181 simplifies the handling
# of linker arguments.
$PrefixLinkerFlags = if ($Platform.OS -eq [OS]::Android) {
# We pass the linker location to the driver, not to the linker.
$false
} elseif ($CMakeSupportsCMP0181) {
# Not necessary if CMP0181 is supported.
$false
} elseif ($UseGnuDriver) {
# Always necessary with the GNU driver.
$true
} else {
# Only necessary with Swift projects, when CMake is not passing the linker flags.
$UseSwift -and $CMakePassesSwiftLinkerFlags
}
# Add additional defines (unless already present) # Add additional defines (unless already present)
$Defines = $Defines.Clone() $Defines = $Defines.Clone()
# Always enable CMP0181 if available.
if ($CMakeSupportsCMP0181) {
Add-KeyValueIfNew $Defines CMAKE_POLICY_DEFAULT_CMP0181 NEW
}
Add-KeyValueIfNew $Defines CMAKE_BUILD_TYPE Release Add-KeyValueIfNew $Defines CMAKE_BUILD_TYPE Release
# Avoid specifying `CMAKE_SYSTEM_NAME` and `CMAKE_SYSTEM_PROCESSOR` on # Avoid specifying `CMAKE_SYSTEM_NAME` and `CMAKE_SYSTEM_PROCESSOR` on
@@ -1685,30 +1654,22 @@ function Build-CMakeProject {
@("-gnone") @("-gnone")
} }
if (-not $CMakePassesSwiftLinkerFlags) { # Disable EnC as that introduces padding in the conformance tables
# Disable EnC as that introduces padding in the conformance tables $SwiftFlags += @("-Xlinker", "/INCREMENTAL:NO")
$SwiftFlags += @("-Xlinker", "/INCREMENTAL:NO") # Swift requires COMDAT folding and de-duplication
# Swift requires COMDAT folding and de-duplication $SwiftFlags += @("-Xlinker", "/OPT:REF", "-Xlinker", "/OPT:ICF")
$SwiftFlags += @("-Xlinker", "/OPT:REF", "-Xlinker", "/OPT:ICF")
}
Add-FlagsDefine $Defines CMAKE_Swift_FLAGS $SwiftFlags Add-FlagsDefine $Defines CMAKE_Swift_FLAGS $SwiftFlags
# Workaround CMake 3.26+ enabling `-wmo` by default on release builds # Workaround CMake 3.26+ enabling `-wmo` by default on release builds
Add-FlagsDefine $Defines CMAKE_Swift_FLAGS_RELEASE "-O" Add-FlagsDefine $Defines CMAKE_Swift_FLAGS_RELEASE "-O"
Add-FlagsDefine $Defines CMAKE_Swift_FLAGS_RELWITHDEBINFO "-O" Add-FlagsDefine $Defines CMAKE_Swift_FLAGS_RELWITHDEBINFO "-O"
if ($CMakePassesSwiftLinkerFlags) {
# CMake 3.30+ passes all linker flags to Swift as the linker driver,
# including those from the internal CMake modules files, without
# a `-Xlinker` prefix. This causes build failures as Swift cannot
# parse linker flags.
# Overwrite the release linker flags to be empty to avoid this.
Add-KeyValueIfNew $Defines CMAKE_EXE_LINKER_FLAGS_RELEASE ""
Add-KeyValueIfNew $Defines CMAKE_SHARED_LINKER_FLAGS_RELEASE ""
}
} }
$LinkerFlags = @("/INCREMENTAL:NO", "/OPT:REF", "/OPT:ICF") $LinkerFlags = if ($UseGNUDriver) {
@("-Xlinker", "/INCREMENTAL:NO", "-Xlinker", "/OPT:REF", "-Xlinker", "/OPT:ICF")
} else {
@("/INCREMENTAL:NO", "/OPT:REF", "/OPT:ICF")
}
if ($DebugInfo) { if ($DebugInfo) {
if ($UseASM -or $UseC -or $UseCXX) { if ($UseASM -or $UseC -or $UseCXX) {
@@ -1719,14 +1680,10 @@ function Build-CMakeProject {
Add-KeyValueIfNew $Defines CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded Add-KeyValueIfNew $Defines CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded
Add-KeyValueIfNew $Defines CMAKE_POLICY_DEFAULT_CMP0141 NEW Add-KeyValueIfNew $Defines CMAKE_POLICY_DEFAULT_CMP0141 NEW
$LinkerFlags += @("/DEBUG") $LinkerFlags += if ($UseGNUDriver) {
@("-Xlinker", "/DEBUG")
# The linker flags are shared across every language, and `/IGNORE:longsections` is an } else {
# `lld-link.exe` argument, not `link.exe`, so this can only be enabled when we use @("/DEBUG")
# `lld-link.exe` for linking.
# TODO: Investigate supporting fission with PE/COFF, this should avoid this warning.
if ($SwiftDebugFormat -eq "dwarf" -and -not ($UseMSVCCompilers.Contains("C") -or $UseMSVCCompilers.Contains("CXX"))) {
$LinkerFlags += @("/IGNORE:longsections")
} }
# The linker flags are shared across every language, and `/IGNORE:longsections` is an # The linker flags are shared across every language, and `/IGNORE:longsections` is an
@@ -1877,33 +1834,24 @@ function Build-CMakeProject {
$Value = $Define.Value.Replace("\", "/") $Value = $Define.Value.Replace("\", "/")
} else { } else {
# Flags array, multiple tokens, quoting needed for tokens containing spaces # Flags array, multiple tokens, quoting needed for tokens containing spaces
$EscapedArgs = $Define.Value | ForEach-Object { $Value = ""
$Arg = $_.Replace("\", "/") foreach ($Arg in $Define.Value) {
if ($Arg.Contains(" ")) { if ($Value.Length -gt 0) {
$Value += " "
}
$ArgWithForwardSlashes = $Arg.Replace("\", "/")
if ($ArgWithForwardSlashes.Contains(" ")) {
# Escape the quote so it makes it through. PowerShell 5 and Core # Escape the quote so it makes it through. PowerShell 5 and Core
# handle quotes differently, so we need to check the version. # handle quotes differently, so we need to check the version.
$quote = if ($PSEdition -eq "Core") { '"' } else { '\"' } $quote = if ($PSEdition -eq "Core") { '"' } else { '\"' }
"$quote$Arg$quote" $Value += "$quote$ArgWithForwardSlashes$quote"
} else { } else {
$Arg $Value += $ArgWithForwardSlashes
} }
} }
# Linker flags are handled differently depending on the CMake version.
$IsLinkerFlag = $Define.Key -match "_LINKER_FLAGS" -and ($Platform.OS -ne [OS]::Android)
$Value = if ($IsLinkerFlag) {
if ($CMakeSupportsCMP0181) { "LINKER:" } elseif ($PrefixLinkerFlags) { "-Xlinker " } else { "" }
} else {
""
}
$Separator = if ($IsLinkerFlag) {
if ($CMakeSupportsCMP0181) { "," } elseif ($PrefixLinkerFlags) { " -Xlinker " } else { " " }
} else {
" "
}
$Value += $EscapedArgs -join $Separator
} }
$cmakeGenerateArgs += @("-D", "$($Define.Key)=$Value") $cmakeGenerateArgs += @("-D", "$($Define.Key)=$Value")
} }