Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -1311,9 +1311,9 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti
}

/// Compute the list of additional linker arguments to use when this tool is used for building with the given scope.
public func computeAdditionalLinkerArgs(_ producer: any CommandProducer, scope: MacroEvaluationScope, inputFileTypes: [FileTypeSpec], optionContext: (any BuildOptionGenerationContext)?, delegate: any TaskGenerationDelegate) async -> (args: [[String]], inputPaths: [Path]) {
public func computeAdditionalLinkerArgs(_ producer: any CommandProducer, scope: MacroEvaluationScope, lookup: @escaping ((MacroDeclaration) -> MacroStringExpression?), inputFileTypes: [FileTypeSpec], optionContext: (any BuildOptionGenerationContext)?, delegate: any TaskGenerationDelegate) async -> (args: [[String]], inputPaths: [Path]) {
// FIXME: Optimize the list to search here.
return (args: producer.effectiveFlattenedOrderedBuildOptions(self).map { $0.getAdditionalLinkerArgs(producer, scope: scope, inputFileTypes: inputFileTypes) }, inputPaths: [])
return (args: producer.effectiveFlattenedOrderedBuildOptions(self).map { $0.getAdditionalLinkerArgs(producer, scope: scope, lookup: lookup, inputFileTypes: inputFileTypes) }, inputPaths: [])
}

// Creates and returns the environment from the specification. This includes both the 'EnvironmentVariables' property for this tool spec, and any build options which define that their value should be exported via their 'SetValueInEnvironmentVariable' property.
Expand Down
17 changes: 10 additions & 7 deletions Sources/SWBCore/SpecImplementations/PropertyDomainSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1567,7 +1567,7 @@ private let buildOptionTypes: [String: any BuildOptionType] = [
}

/// Get the command line arguments to use for this option in the given scope.
func getAdditionalLinkerArgs(_ producer: any CommandProducer, scope: MacroEvaluationScope, inputFileTypes: [FileTypeSpec]) -> [String] {
func getAdditionalLinkerArgs(_ producer: any CommandProducer, scope: MacroEvaluationScope, lookup: @escaping ((MacroDeclaration) -> MacroStringExpression?), inputFileTypes: [FileTypeSpec]) -> [String] {
// Filter by (any) supported file type.
func supportsAnyFileType() -> Bool {
for fileType in inputFileTypes {
Expand All @@ -1582,7 +1582,7 @@ private let buildOptionTypes: [String: any BuildOptionType] = [
}

// Filter by macro condition expression. If we don't have one, or we do have one and it evaluates to true, then we can proceed with argument generation.
guard condition == nil || condition!.evaluateAsBoolean(scope) else {
guard condition == nil || condition!.evaluateAsBoolean(scope, lookup: lookup) else {
return []
}

Expand All @@ -1594,16 +1594,16 @@ private let buildOptionTypes: [String: any BuildOptionType] = [
guard let valueDefnOpt = scope.evaluate(self.macro as! BooleanMacroDeclaration) ? otherValueDefn : emptyValueDefn else { return [] }

guard let expr = valueDefnOpt.additionalLinkerArgs else { return [] }
return scope.evaluate(expr)
return scope.evaluate(expr, lookup: lookup)
}

// Handle list typed options.
guard !type.isListType else {
let values = switch self.macro {
case let macro as StringListMacroDeclaration:
scope.evaluate(macro)
scope.evaluate(macro, lookup: lookup)
case let macro as PathListMacroDeclaration:
scope.evaluate(macro)
scope.evaluate(macro, lookup: lookup)
default:
fatalError("invalid macro type for List option")
}
Expand All @@ -1612,11 +1612,11 @@ private let buildOptionTypes: [String: any BuildOptionType] = [
let valueDefnOpt = values.isEmpty ? emptyValueDefn : otherValueDefn

guard let expr = valueDefnOpt?.additionalLinkerArgs else { return [] }
return scope.evaluate(expr)
return scope.evaluate(expr, lookup: lookup)
}

// Otherwise, we have a scalar option.
let value = scope.evaluateAsString(self.macro)
let value = scope.evaluateAsString(self.macro, lookup: lookup)

// Get the value expression to use.
let valueDefnOpt = valueDefns.flatMap { $0[value] } ?? (value.isEmpty ? emptyValueDefn : otherValueDefn)
Expand All @@ -1627,6 +1627,9 @@ private let buildOptionTypes: [String: any BuildOptionType] = [
if macro === BuiltinMacros.value {
return scope.table.namespace.parseLiteralString(value)
}
if let lookupResult = lookup(macro) {
return lookupResult
}
return nil
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/SWBCore/SpecImplementations/Tools/LinkerTools.swift
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ public final class LdLinkerSpec : GenericLinkerSpec, SpecIdentifierType, @unchec

let spec = info.key
let inputFileTypes = info.value
let (args, inputs) = await spec.computeAdditionalLinkerArgs(cbc.producer, scope: cbc.scope, inputFileTypes: [FileTypeSpec](inputFileTypes), optionContext: spec.discoveredCommandLineToolSpecInfo(cbc.producer, cbc.scope, delegate), delegate: delegate)
let (args, inputs) = await spec.computeAdditionalLinkerArgs(cbc.producer, scope: cbc.scope, lookup: linkerDriverLookup, inputFileTypes: [FileTypeSpec](inputFileTypes), optionContext: spec.discoveredCommandLineToolSpecInfo(cbc.producer, cbc.scope, delegate), delegate: delegate)
additionalLinkerArgsArray.append(contentsOf: args)
inputPaths.append(contentsOf: inputs)
}
Expand All @@ -531,7 +531,7 @@ public final class LdLinkerSpec : GenericLinkerSpec, SpecIdentifierType, @unchec
for scope in depScopes {
if scope.evaluate(BuiltinMacros.SWIFT_OBJC_INTEROP_MODE) == "objcxx" {
let optionContext = await cbc.producer.swiftCompilerSpec.discoveredCommandLineToolSpecInfo(cbc.producer, scope, delegate)
additionalLinkerArgsArray.append(contentsOf: await cbc.producer.swiftCompilerSpec.computeAdditionalLinkerArgs(cbc.producer, scope: cbc.scope, inputFileTypes: [FileTypeSpec](), optionContext: optionContext, delegate: delegate).args)
additionalLinkerArgsArray.append(contentsOf: await cbc.producer.swiftCompilerSpec.computeAdditionalLinkerArgs(cbc.producer, scope: cbc.scope, lookup: linkerDriverLookup, inputFileTypes: [FileTypeSpec](), optionContext: optionContext, delegate: delegate).args)
additionalLinkerArgsArray.append(["-l\(cbc.scope.evaluate(BuiltinMacros.SWIFT_STDLIB))"])
break
}
Expand Down
42 changes: 21 additions & 21 deletions Sources/SWBCore/SpecImplementations/Tools/SwiftCompiler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2947,7 +2947,7 @@ public final class SwiftCompilerSpec : CompilerSpec, SpecIdentifierType, SwiftDi
return (isEnabled, isExplicitlyEnabled)
}

private func staticallyLinkSwiftStdlib(_ producer: any CommandProducer, scope: MacroEvaluationScope) -> Bool {
private func staticallyLinkSwiftStdlib(_ producer: any CommandProducer, scope: MacroEvaluationScope, lookup: @escaping ((MacroDeclaration) -> MacroStringExpression?)) -> Bool {
// Determine whether we should statically link the Swift stdlib, and determined
// by the following logic in the following order:
//
Expand All @@ -2960,17 +2960,17 @@ public final class SwiftCompilerSpec : CompilerSpec, SpecIdentifierType, SwiftDi
//
// NOTE: With Swift in the OS, static libs aren't being supplied by the toolchains
// so users of this flag will need to provide their own.
if scope.evaluate(BuiltinMacros.SWIFT_FORCE_STATIC_LINK_STDLIB) {
if scope.evaluate(BuiltinMacros.SWIFT_FORCE_STATIC_LINK_STDLIB, lookup: lookup) {
return true
}
return false
}

public override func computeAdditionalLinkerArgs(_ producer: any CommandProducer, scope: MacroEvaluationScope, inputFileTypes: [FileTypeSpec], optionContext: (any BuildOptionGenerationContext)?, delegate: any TaskGenerationDelegate) async -> (args: [[String]], inputPaths: [Path]) {
return await computeAdditionalLinkerArgs(producer, scope: scope, inputFileTypes: inputFileTypes, optionContext: optionContext, forTAPI: false, delegate: delegate)
public override func computeAdditionalLinkerArgs(_ producer: any CommandProducer, scope: MacroEvaluationScope, lookup: @escaping ((MacroDeclaration) -> MacroStringExpression?), inputFileTypes: [FileTypeSpec], optionContext: (any BuildOptionGenerationContext)?, delegate: any TaskGenerationDelegate) async -> (args: [[String]], inputPaths: [Path]) {
return await computeAdditionalLinkerArgs(producer, scope: scope, lookup: lookup, inputFileTypes: inputFileTypes, optionContext: optionContext, forTAPI: false, delegate: delegate)
}

func computeAdditionalLinkerArgs(_ producer: any CommandProducer, scope: MacroEvaluationScope, inputFileTypes: [FileTypeSpec], optionContext: (any BuildOptionGenerationContext)?, forTAPI: Bool = false, delegate: any TaskGenerationDelegate) async -> (args: [[String]], inputPaths: [Path]) {
func computeAdditionalLinkerArgs(_ producer: any CommandProducer, scope: MacroEvaluationScope, lookup: @escaping ((MacroDeclaration) -> MacroStringExpression?), inputFileTypes: [FileTypeSpec], optionContext: (any BuildOptionGenerationContext)?, forTAPI: Bool = false, delegate: any TaskGenerationDelegate) async -> (args: [[String]], inputPaths: [Path]) {
guard let swiftToolSpec = optionContext as? DiscoveredSwiftCompilerToolSpecInfo else {
// An error message would have already been emitted by this point
return (args: [[]], inputPaths: [])
Expand All @@ -2983,21 +2983,21 @@ public final class SwiftCompilerSpec : CompilerSpec, SpecIdentifierType, SwiftDi
var inputPaths: [Path] = []
if !forTAPI {
// TAPI can't use all of the additional linker options, and its spec has all of the build setting/option arguments that it can use.
args = producer.effectiveFlattenedOrderedBuildOptions(self).map { $0.getAdditionalLinkerArgs(producer, scope: scope, inputFileTypes: inputFileTypes) }.filter { !$0.isEmpty }
args = producer.effectiveFlattenedOrderedBuildOptions(self).map { $0.getAdditionalLinkerArgs(producer, scope: scope, lookup: lookup, inputFileTypes: inputFileTypes) }.filter { !$0.isEmpty }
}

// Determine if we are forced to use the standard system location; this is currently only for OS adopters of Swift, not any client.
let useSystemSwift = scope.evaluate(BuiltinMacros.SWIFT_FORCE_SYSTEM_LINK_STDLIB)
let useSystemSwift = scope.evaluate(BuiltinMacros.SWIFT_FORCE_SYSTEM_LINK_STDLIB, lookup: lookup)

// Determine whether we should statically link the Swift stdlib.
let shouldStaticLinkStdlib = staticallyLinkSwiftStdlib(producer, scope: scope)
let shouldStaticLinkStdlib = staticallyLinkSwiftStdlib(producer, scope: scope, lookup: lookup)

let swiftStdlibName = scope.evaluate(BuiltinMacros.SWIFT_STDLIB)
var swiftLibraryPath = scope.evaluate(BuiltinMacros.SWIFT_LIBRARY_PATH)
let dynamicLibraryExtension = scope.evaluate(BuiltinMacros.DYNAMIC_LIBRARY_EXTENSION)
let swiftStdlibName = scope.evaluate(BuiltinMacros.SWIFT_STDLIB, lookup: lookup)
var swiftLibraryPath = scope.evaluate(BuiltinMacros.SWIFT_LIBRARY_PATH, lookup: lookup)
let dynamicLibraryExtension = scope.evaluate(BuiltinMacros.DYNAMIC_LIBRARY_EXTENSION, lookup: lookup)

// If we weren't given an explicit library path, compute one
let platformName = scope.evaluate(BuiltinMacros.PLATFORM_NAME)
let platformName = scope.evaluate(BuiltinMacros.PLATFORM_NAME, lookup: lookup)
if swiftLibraryPath.isEmpty {
// Look next to the compiler and in the toolchains for one.
if shouldStaticLinkStdlib {
Expand All @@ -3015,13 +3015,13 @@ public final class SwiftCompilerSpec : CompilerSpec, SpecIdentifierType, SwiftDi
}
}

let isMacCatalystUnzippered = producer.sdkVariant?.isMacCatalyst == true && !scope.evaluate(BuiltinMacros.IS_ZIPPERED)
let isMacCatalystUnzippered = producer.sdkVariant?.isMacCatalyst == true && !scope.evaluate(BuiltinMacros.IS_ZIPPERED, lookup: lookup)

var sdkPathArgument: [String] = []
var unzipperedSDKPathArgument: [String] = []
if forTAPI {
// TAPI requires absolute paths.
let sdkroot = scope.evaluate(BuiltinMacros.SDKROOT)
let sdkroot = scope.evaluate(BuiltinMacros.SDKROOT, lookup: lookup)
if !sdkroot.isEmpty {
sdkPathArgument = ["-L" + sdkroot.join("usr/lib/swift").str]
unzipperedSDKPathArgument = ["-L" + sdkroot.join("System/iOSSupport/usr/lib/swift").str]
Expand Down Expand Up @@ -3072,24 +3072,24 @@ public final class SwiftCompilerSpec : CompilerSpec, SpecIdentifierType, SwiftDi
// be a source-less target which just contains object files in it's framework phase.
let currentPlatformFilter = PlatformFilter(scope)
let containsSources = (producer.configuredTarget?.target as? StandardTarget)?.sourcesBuildPhase?.buildFiles.filter { currentPlatformFilter.matches($0.platformFilters) }.isEmpty == false
if containsSources && inputFileTypes.contains(where: { $0.conformsTo(identifier: "sourcecode.swift") }) && scope.evaluate(BuiltinMacros.GCC_GENERATE_DEBUGGING_SYMBOLS) && !scope.evaluate(BuiltinMacros.PLATFORM_REQUIRES_SWIFT_MODULEWRAP) {
let moduleName = scope.evaluate(BuiltinMacros.SWIFT_MODULE_NAME)
let moduleFileDir = scope.evaluate(BuiltinMacros.PER_ARCH_MODULE_FILE_DIR)
if containsSources && inputFileTypes.contains(where: { $0.conformsTo(identifier: "sourcecode.swift") }) && scope.evaluate(BuiltinMacros.GCC_GENERATE_DEBUGGING_SYMBOLS, lookup: lookup) && !scope.evaluate(BuiltinMacros.PLATFORM_REQUIRES_SWIFT_MODULEWRAP, lookup: lookup) {
let moduleName = scope.evaluate(BuiltinMacros.SWIFT_MODULE_NAME, lookup: lookup)
let moduleFileDir = scope.evaluate(BuiltinMacros.PER_ARCH_MODULE_FILE_DIR, lookup: lookup)
let moduleFilePath = moduleFileDir.join(moduleName + ".swiftmodule")
args += [["-Xlinker", "-add_ast_path", "-Xlinker", moduleFilePath.str]]
if scope.evaluate(BuiltinMacros.SWIFT_GENERATE_ADDITIONAL_LINKER_ARGS) {
if scope.evaluate(BuiltinMacros.SWIFT_GENERATE_ADDITIONAL_LINKER_ARGS, lookup: lookup) {
args += [["@\(Path(moduleFilePath.appendingFileNameSuffix("-linker-args").withoutSuffix + ".resp").str)"]]
}
}
}

if scope.evaluate(BuiltinMacros.SWIFT_ADD_TOOLCHAIN_SWIFTSYNTAX_SEARCH_PATHS) {
if scope.evaluate(BuiltinMacros.SWIFT_ADD_TOOLCHAIN_SWIFTSYNTAX_SEARCH_PATHS, lookup: lookup) {
args += [["-L\(swiftToolSpec.hostLibraryDirectory.str)"]]
}

let containsSwiftSources = (producer.configuredTarget?.target as? StandardTarget)?.sourcesBuildPhase?.containsSwiftSources(producer, producer, scope, producer.filePathResolver) == true
if scope.evaluate(BuiltinMacros.PLATFORM_REQUIRES_SWIFT_AUTOLINK_EXTRACT) && containsSwiftSources {
let inputPath = scope.evaluate(BuiltinMacros.SWIFT_AUTOLINK_EXTRACT_OUTPUT_PATH)
if scope.evaluate(BuiltinMacros.PLATFORM_REQUIRES_SWIFT_AUTOLINK_EXTRACT, lookup: lookup) && containsSwiftSources {
let inputPath = scope.evaluate(BuiltinMacros.SWIFT_AUTOLINK_EXTRACT_OUTPUT_PATH, lookup: lookup)
args += [["@\(inputPath.str)"]]
inputPaths.append(inputPath)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public final class TAPIToolSpec : GenericCommandLineToolSpec, GCCCompatibleCompi
let producer = cbc.producer
let swiftCompilerSpec = producer.swiftCompilerSpec
let optionContext = await swiftCompilerSpec.discoveredCommandLineToolSpecInfo(producer, scope, delegate)
commandLine += await swiftCompilerSpec.computeAdditionalLinkerArgs(producer, scope: scope, inputFileTypes: [], optionContext: optionContext, forTAPI: true, delegate: delegate).args.flatMap({ $0 })
commandLine += await swiftCompilerSpec.computeAdditionalLinkerArgs(producer, scope: scope, lookup: { _ in nil }, inputFileTypes: [], optionContext: optionContext, forTAPI: true, delegate: delegate).args.flatMap({ $0 })

if !scope.evaluate(BuiltinMacros.SWIFT_OBJC_INTERFACE_HEADER_NAME).isEmpty && scope.evaluate(BuiltinMacros.SWIFT_INSTALL_OBJC_HEADER) {
let generatedHeaderPath = SwiftCompilerSpec.generatedObjectiveCHeaderOutputPath(scope).str
Expand Down
20 changes: 20 additions & 0 deletions Sources/SWBUniversalPlatform/Specs/Clang.xcspec
Original file line number Diff line number Diff line change
Expand Up @@ -2850,6 +2850,26 @@
Name = "CLANG_COVERAGE_MAPPING_LINKER_ARGS";
Type = Boolean;
DefaultValue = "$(CLANG_COVERAGE_MAPPING)";
},

{
Name = "SWIFTC_CLANG_COVERAGE_MAPPING_LINKER_ARGS";
Type = Boolean;
DefaultValue = "$(CLANG_COVERAGE_MAPPING_LINKER_ARGS)";
Condition = "$(LINKER_DRIVER) == swiftc";
AdditionalLinkerArgs = {
NO = ();
YES = (
"-Xclang-linker", "-fprofile-instr-generate",
);
};
},

{
Name = "CLANG_CLANG_COVERAGE_MAPPING_LINKER_ARGS";
Type = Boolean;
DefaultValue = "$(CLANG_COVERAGE_MAPPING_LINKER_ARGS)";
Condition = "$(LINKER_DRIVER) == clang";
AdditionalLinkerArgs = {
NO = ();
YES = (
Expand Down
20 changes: 20 additions & 0 deletions Sources/SWBUniversalPlatform/Specs/Swift.xcspec
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,26 @@
Name = "CLANG_COVERAGE_MAPPING_LINKER_ARGS";
Type = Boolean;
DefaultValue = "$(CLANG_COVERAGE_MAPPING)";
},

{
Name = "SWIFTC_CLANG_COVERAGE_MAPPING_LINKER_ARGS";
Type = Boolean;
DefaultValue = "$(CLANG_COVERAGE_MAPPING_LINKER_ARGS)";
Condition = "$(LINKER_DRIVER) == swiftc";
AdditionalLinkerArgs = {
NO = ();
YES = (
"-Xclang-linker", "-fprofile-instr-generate",
);
};
},

{
Name = "CLANG_CLANG_COVERAGE_MAPPING_LINKER_ARGS";
Type = Boolean;
DefaultValue = "$(CLANG_COVERAGE_MAPPING_LINKER_ARGS)";
Condition = "$(LINKER_DRIVER) == clang";
AdditionalLinkerArgs = {
NO = ();
YES = (
Expand Down
Loading