Skip to content

Commit 603bda9

Browse files
Stop renaming main symbol for WASI (#3804)
* Don't rename main symbol for WASI For a long-term solution, this renaming feature should be supported on wasm-ld because it's not a limitation of WebAssembly. * Simplify linkerFlagsForRenamingMainFunction to simply return nil for other than linux and darwin platforms * Add unit tests for main renaming for each platforms The call of checkSupportedFrontendFlags is moved from BuildPlan to test it in file system independently. The check needs to access temp file, but the in-memory fs doesn't allow that. * Rename {should,can}RenameEntrypointFunctionName
1 parent ffaa852 commit 603bda9

File tree

4 files changed

+64
-6
lines changed

4 files changed

+64
-6
lines changed

Sources/Build/BuildPlan.swift

+9-6
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,16 @@ extension BuildParameters {
115115

116116
/// Computes the linker flags to use in order to rename a module-named main function to 'main' for the target platform, or nil if the linker doesn't support it for the platform.
117117
fileprivate func linkerFlagsForRenamingMainFunction(of target: ResolvedTarget) -> [String]? {
118-
var args: [String] = []
118+
let args: [String]
119119
if self.triple.isDarwin() {
120120
args = ["-alias", "_\(target.c99name)_main", "_main"]
121121
}
122122
else if self.triple.isLinux() {
123123
args = ["--defsym", "main=\(target.c99name)_main"]
124124
}
125+
else {
126+
return nil
127+
}
125128
return args.flatMap { ["-Xlinker", $0] }
126129
}
127130

@@ -745,10 +748,9 @@ public final class SwiftTargetBuildDescription {
745748
// we can rename the symbol unconditionally.
746749
// No `-` for these flags because the set of Strings in driver.supportedFrontendFlags do
747750
// not have a leading `-`
748-
if SwiftTargetBuildDescription.checkSupportedFrontendFlags(flags: ["entry-point-function-name"], fileSystem: self.fileSystem) {
749-
if buildParameters.linkerFlagsForRenamingMainFunction(of: target) != nil {
750-
args += ["-Xfrontend", "-entry-point-function-name", "-Xfrontend", "\(target.c99name)_main"]
751-
}
751+
if buildParameters.canRenameEntrypointFunctionName,
752+
buildParameters.linkerFlagsForRenamingMainFunction(of: target) != nil {
753+
args += ["-Xfrontend", "-entry-point-function-name", "-Xfrontend", "\(target.c99name)_main"]
752754
}
753755
}
754756

@@ -1228,7 +1230,8 @@ public final class ProductBuildDescription {
12281230
// we will instead have generated a source file containing the redirect.
12291231
// Support for linking tests againsts executables is conditional on the tools
12301232
// version of the package that defines the executable product.
1231-
if product.executableModule.underlyingTarget is SwiftTarget, toolsVersion >= .v5_5 {
1233+
if product.executableModule.underlyingTarget is SwiftTarget, toolsVersion >= .v5_5,
1234+
buildParameters.canRenameEntrypointFunctionName {
12321235
if let flags = buildParameters.linkerFlagsForRenamingMainFunction(of: product.executableModule) {
12331236
args += flags
12341237
}

Sources/Commands/SwiftTool.swift

+3
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,9 @@ public class SwiftTool {
869869
xcbuildFlags: options.xcbuildFlags,
870870
jobs: options.jobs ?? UInt32(ProcessInfo.processInfo.activeProcessorCount),
871871
shouldLinkStaticSwiftStdlib: options.shouldLinkStaticSwiftStdlib,
872+
canRenameEntrypointFunctionName: SwiftTargetBuildDescription.checkSupportedFrontendFlags(
873+
flags: ["entry-point-function-name"], fileSystem: localFileSystem
874+
),
872875
sanitizers: options.enabledSanitizers,
873876
enableCodeCoverage: options.shouldEnableCodeCoverage,
874877
indexStoreMode: options.indexStoreMode.indexStoreMode,

Sources/SPMBuildCore/BuildParameters.swift

+5
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ public struct BuildParameters: Encodable {
133133
/// Whether to create dylibs for dynamic library products.
134134
public var shouldCreateDylibForDynamicProducts: Bool
135135

136+
/// Whether to enable the entry-point-function-name feature.
137+
public var canRenameEntrypointFunctionName: Bool
138+
136139
/// The current build environment.
137140
public var buildEnvironment: BuildEnvironment {
138141
BuildEnvironment(platform: currentPlatform, configuration: configuration)
@@ -182,6 +185,7 @@ public struct BuildParameters: Encodable {
182185
jobs: UInt32 = UInt32(ProcessInfo.processInfo.activeProcessorCount),
183186
shouldLinkStaticSwiftStdlib: Bool = false,
184187
shouldEnableManifestCaching: Bool = false,
188+
canRenameEntrypointFunctionName: Bool = false,
185189
shouldCreateDylibForDynamicProducts: Bool = true,
186190
sanitizers: EnabledSanitizers = EnabledSanitizers(),
187191
enableCodeCoverage: Bool = false,
@@ -211,6 +215,7 @@ public struct BuildParameters: Encodable {
211215
self.shouldLinkStaticSwiftStdlib = shouldLinkStaticSwiftStdlib
212216
self.shouldEnableManifestCaching = shouldEnableManifestCaching
213217
self.shouldCreateDylibForDynamicProducts = shouldCreateDylibForDynamicProducts
218+
self.canRenameEntrypointFunctionName = canRenameEntrypointFunctionName
214219
self.sanitizers = sanitizers
215220
self.enableCodeCoverage = enableCodeCoverage
216221
self.indexStoreMode = indexStoreMode

Tests/BuildTests/BuildPlanTests.swift

+47
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ final class BuildPlanTests: XCTestCase {
6363
toolchain: SPMBuildCore.Toolchain = MockToolchain(),
6464
flags: BuildFlags = BuildFlags(),
6565
shouldLinkStaticSwiftStdlib: Bool = false,
66+
canRenameEntrypointFunctionName: Bool = false,
6667
destinationTriple: TSCUtility.Triple = hostTriple,
6768
indexStoreMode: BuildParameters.IndexStoreMode = .off,
6869
useExplicitModuleBuild: Bool = false
@@ -76,6 +77,7 @@ final class BuildPlanTests: XCTestCase {
7677
flags: flags,
7778
jobs: 3,
7879
shouldLinkStaticSwiftStdlib: shouldLinkStaticSwiftStdlib,
80+
canRenameEntrypointFunctionName: canRenameEntrypointFunctionName,
7981
indexStoreMode: indexStoreMode,
8082
useExplicitModuleBuild: useExplicitModuleBuild
8183
)
@@ -1826,6 +1828,51 @@ final class BuildPlanTests: XCTestCase {
18261828
XCTAssertEqual(testPathExtension, "wasm")
18271829
}
18281830

1831+
func testEntrypointRenaming() throws {
1832+
let fs = InMemoryFileSystem(emptyFiles:
1833+
"/Pkg/Sources/exe/main.swift"
1834+
)
1835+
1836+
let observability = ObservabilitySystem.makeForTesting()
1837+
let graph = try loadPackageGraph(
1838+
fs: fs,
1839+
manifests: [
1840+
Manifest.createRootManifest(
1841+
name: "Pkg",
1842+
path: .init("/Pkg"),
1843+
toolsVersion: .v5_5,
1844+
targets: [
1845+
TargetDescription(name: "exe", type: .executable),
1846+
]),
1847+
],
1848+
observabilityScope: observability.topScope
1849+
)
1850+
1851+
func createResult(for triple: TSCUtility.Triple) throws -> BuildPlanResult {
1852+
BuildPlanResult(plan: try BuildPlan(
1853+
buildParameters: mockBuildParameters(canRenameEntrypointFunctionName: true, destinationTriple: triple),
1854+
graph: graph,
1855+
fileSystem: fs,
1856+
observabilityScope: observability.topScope
1857+
))
1858+
}
1859+
let supportingTriples: [TSCUtility.Triple] = [.x86_64Linux, .macOS]
1860+
for triple in supportingTriples {
1861+
let result = try createResult(for: triple)
1862+
let exe = try result.target(for: "exe").swiftTarget().compileArguments()
1863+
XCTAssertMatch(exe, ["-Xfrontend", "-entry-point-function-name", "-Xfrontend", "exe_main"])
1864+
let linkExe = try result.buildProduct(for: "exe").linkArguments()
1865+
XCTAssertMatch(linkExe, [.contains("exe_main")])
1866+
}
1867+
1868+
let unsupportingTriples: [TSCUtility.Triple] = [.wasi, .windows]
1869+
for triple in unsupportingTriples {
1870+
let result = try createResult(for: triple)
1871+
let exe = try result.target(for: "exe").swiftTarget().compileArguments()
1872+
XCTAssertNoMatch(exe, ["-entry-point-function-name"])
1873+
}
1874+
}
1875+
18291876
func testIndexStore() throws {
18301877
let fs = InMemoryFileSystem(emptyFiles:
18311878
"/Pkg/Sources/exe/main.swift",

0 commit comments

Comments
 (0)