Skip to content

Begin adding support for using swiftc as a linker driver #236

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
Apr 2, 2025
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
9 changes: 9 additions & 0 deletions Sources/SWBCore/Settings/BuiltinMacros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,7 @@ public final class BuiltinMacros {
public static let LIBTOOL_DEPENDENCY_INFO_FILE = BuiltinMacros.declarePathMacro("LIBTOOL_DEPENDENCY_INFO_FILE")
public static let LIBTOOL_USE_RESPONSE_FILE = BuiltinMacros.declareBooleanMacro("LIBTOOL_USE_RESPONSE_FILE")
public static let LINKER = BuiltinMacros.declareStringMacro("LINKER")
public static let LINKER_DRIVER = BuiltinMacros.declareEnumMacro("LINKER_DRIVER") as EnumMacroDeclaration<LinkerDriverChoice>
public static let ALTERNATE_LINKER = BuiltinMacros.declareStringMacro("ALTERNATE_LINKER")
public static let LINK_OBJC_RUNTIME = BuiltinMacros.declareBooleanMacro("LINK_OBJC_RUNTIME")
public static let LINK_WITH_STANDARD_LIBRARIES = BuiltinMacros.declareBooleanMacro("LINK_WITH_STANDARD_LIBRARIES")
Expand Down Expand Up @@ -1371,6 +1372,7 @@ public final class BuiltinMacros {
ALL_OTHER_LDFLAGS,
ALL_SETTINGS,
ALTERNATE_GROUP,
LINKER_DRIVER,
ALTERNATE_LINKER,
ALTERNATE_MODE,
ALTERNATE_OWNER,
Expand Down Expand Up @@ -2662,6 +2664,13 @@ public enum ModuleVerifierKind: String, Equatable, Hashable, EnumerationMacroTyp
case both
}

public enum LinkerDriverChoice: String, Equatable, Hashable, EnumerationMacroType {
public static let defaultValue: LinkerDriverChoice = .clang

case clang
case swiftc
}

/// Enumeration macro type for the value of the `INFOPLIST_KEY_LSApplicationCategoryType` build setting.
public enum ApplicationCategory: String, Equatable, Hashable, EnumerationMacroType {
public static let defaultValue = ApplicationCategory.none
Expand Down
14 changes: 12 additions & 2 deletions Sources/SWBCore/SpecImplementations/ProductTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,22 @@ public class ProductTypeSpec : Spec, SpecType, @unchecked Sendable {
if producer.isApplePlatform {
let compatibilityVersion = scope.evaluate(BuiltinMacros.DYLIB_COMPATIBILITY_VERSION)
if !compatibilityVersion.isEmpty {
args += ["-compatibility_version", compatibilityVersion]
switch scope.evaluate(BuiltinMacros.LINKER_DRIVER) {
case .clang:
args += ["-compatibility_version", compatibilityVersion]
case .swiftc:
args += ["-Xlinker", "-compatibility_version", "-Xlinker", compatibilityVersion]
}
}

let currentVersion = scope.evaluate(BuiltinMacros.DYLIB_CURRENT_VERSION)
if !currentVersion.isEmpty {
args += ["-current_version", currentVersion]
switch scope.evaluate(BuiltinMacros.LINKER_DRIVER) {
case .clang:
args += ["-current_version", currentVersion]
case .swiftc:
args += ["-Xlinker", "-current_version", "-Xlinker", currentVersion]
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ private final class EnumBuildOptionType : BuildOptionType {
return try namespace.declareEnumMacro(name) as EnumMacroDeclaration<SwiftEnableExplicitModulesSetting>
case "SWIFT_ENABLE_EXPLICIT_MODULES":
return try namespace.declareEnumMacro(name) as EnumMacroDeclaration<SwiftEnableExplicitModulesSetting>
case "LINKER_DRIVER":
return try namespace.declareEnumMacro(name) as EnumMacroDeclaration<LinkerDriverChoice>
default:
return try namespace.declareStringMacro(name)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,13 @@ public final class LdLinkerSpec : GenericLinkerSpec, SpecIdentifierType, @unchec
public static let identifier = "com.apple.pbx.linkers.ld"

public override func computeExecutablePath(_ cbc: CommandBuildContext) -> String {
return cbc.producer.hostOperatingSystem.imageFormat.executableName(basename: "clang")
// TODO: We should also provide an "auto" option which chooses based on the source files in the target
Copy link
Collaborator

Choose a reason for hiding this comment

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

I do remember there being some subtle differences between linker drivers for C sources as well, so "auto" could result in surprises.

switch cbc.scope.evaluate(BuiltinMacros.LINKER_DRIVER) {
case .clang:
return cbc.producer.hostOperatingSystem.imageFormat.executableName(basename: "clang")
case .swiftc:
return cbc.producer.hostOperatingSystem.imageFormat.executableName(basename: "swiftc")
}
}

override public var toolBasenameAliases: [String] {
Expand Down
39 changes: 37 additions & 2 deletions Sources/SWBGenericUnixPlatform/Specs/UnixLd.xcspec
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
};
Options = (
{
Name = "MACH_O_TYPE";
Name = "CLANG_MACH_O_TYPE";
Type = Enumeration;
Values = (
{
Expand All @@ -46,13 +46,26 @@
CommandLineFlag = "-r";
},
);
Condition = "$(LINKER_DRIVER) == clang";
DefaultValue = "$(MACH_O_TYPE)";
},
// We can inherit SWIFTC_MACHO_TYPE from the universal platform Ld.xcspec
{
Name = SDKROOT;
Name = CLANG_SDKROOT_LINKER_INPUT;
Type = Path;
DefaultValue = "$(SDKROOT)";
Condition = "$(LINKER_DRIVER) == clang";
CommandLineFlag = "--sysroot";
IsInputDependency = Yes;
},
{
Name = SWIFTC_SDKROOT_LINKER_INPUT;
Type = Path;
DefaultValue = "$(SDKROOT)";
Condition = "$(LINKER_DRIVER) == swiftc";
CommandLineFlag = "-sysroot";
IsInputDependency = Yes;
},
{
Name = "LD_DYLIB_INSTALL_NAME";
Type = String;
Expand All @@ -65,6 +78,17 @@
);
Condition = "$(MACH_O_TYPE) == mh_dylib";
},
// Override the differentiated settings to no-ops, both linker drivers use the same flags.
{
Name = "CLANG_LD_DYLIB_INSTALL_NAME";
Type = String;
Condition = "NO";
},
{
Name = "SWIFTC_LD_DYLIB_INSTALL_NAME";
Type = String;
Condition = "NO";
},
{
Name = GOLD_BUILDID;
Type = Boolean;
Expand Down Expand Up @@ -130,6 +154,17 @@
);
IsInputDependency = Yes;
},
// Override the differentiated settings to no-ops, both linker drivers use the same flags.
{
Name = "CLANG__INPUT_FILE_LIST_PATH__";
Type = Path;
Condition = "NO";
},
{
Name = "SWIFTC__INPUT_FILE_LIST_PATH__";
Type = Path;
Condition = "NO";
}
);
},
)
2 changes: 1 addition & 1 deletion Sources/SWBUniversalPlatform/Specs/Clang LLVM 1.0.xcspec
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@
// that the ObjC runtime must be linked in (with possible
// backwards compatibility libraries linked in).
AdditionalLinkerArgs = {
YES = ( "-fobjc-link-runtime" );
YES = ( "$(LD_OBJC_RUNTIME_ARGS)" );
NO = ();
};
FileTypes = (
Expand Down
Loading