From 18fcc44220b96b035ec09572ffeef1ea6bc95884 Mon Sep 17 00:00:00 2001 From: Owen Voorhees Date: Wed, 11 Jun 2025 13:47:10 -0700 Subject: [PATCH] Fixup cross platform specs handling of DEAD_CODE_STRIPPING --- .../Specs/UnixLd.xcspec | 10 ++++ Sources/SWBQNXPlatform/Specs/QNXLd.xcspec | 5 ++ Sources/SWBUniversalPlatform/Specs/Ld.xcspec | 5 +- .../Specs/WasmLd.xcspec | 10 ++++ .../SWBWindowsPlatform/Specs/WindowsLd.xcspec | 10 ++++ .../TaskConstructionTests.swift | 60 ++++++++++++++++++- 6 files changed, 98 insertions(+), 2 deletions(-) diff --git a/Sources/SWBGenericUnixPlatform/Specs/UnixLd.xcspec b/Sources/SWBGenericUnixPlatform/Specs/UnixLd.xcspec index e773b048..97316ed8 100644 --- a/Sources/SWBGenericUnixPlatform/Specs/UnixLd.xcspec +++ b/Sources/SWBGenericUnixPlatform/Specs/UnixLd.xcspec @@ -102,6 +102,16 @@ }; Condition = "$(ALTERNATE_LINKER) == gold"; }, + { + Name = "DEAD_CODE_STRIPPING"; + Type = Boolean; + DefaultValue = NO; + Condition = "$(MACH_O_TYPE) != mh_object"; + CommandLineArgs = { + YES = ("-Xlinker", "--gc-sections"); + NO = (); + }; + }, { // Frameworks are Mac specific Name = "SYSTEM_FRAMEWORK_SEARCH_PATHS"; diff --git a/Sources/SWBQNXPlatform/Specs/QNXLd.xcspec b/Sources/SWBQNXPlatform/Specs/QNXLd.xcspec index 30f9c24b..6c66a1ca 100644 --- a/Sources/SWBQNXPlatform/Specs/QNXLd.xcspec +++ b/Sources/SWBQNXPlatform/Specs/QNXLd.xcspec @@ -96,6 +96,11 @@ }; Condition = "$(ALTERNATE_LINKER) == gold"; }, + { + Name = "DEAD_CODE_STRIPPING"; + Type = Boolean; + Condition = "NO"; + }, { // Frameworks are Mac specific Name = "SYSTEM_FRAMEWORK_SEARCH_PATHS"; diff --git a/Sources/SWBUniversalPlatform/Specs/Ld.xcspec b/Sources/SWBUniversalPlatform/Specs/Ld.xcspec index d30e08ad..657c22b1 100644 --- a/Sources/SWBUniversalPlatform/Specs/Ld.xcspec +++ b/Sources/SWBUniversalPlatform/Specs/Ld.xcspec @@ -459,7 +459,10 @@ Type = Boolean; DefaultValue = NO; Condition = "$(MACH_O_TYPE) != mh_object"; - CommandLineFlag = "-dead_strip"; + CommandLineArgs = { + YES = ("-dead_strip"); + NO = (); + }; }, { Name = "BUNDLE_LOADER"; diff --git a/Sources/SWBWebAssemblyPlatform/Specs/WasmLd.xcspec b/Sources/SWBWebAssemblyPlatform/Specs/WasmLd.xcspec index 4b246b98..ba106172 100644 --- a/Sources/SWBWebAssemblyPlatform/Specs/WasmLd.xcspec +++ b/Sources/SWBWebAssemblyPlatform/Specs/WasmLd.xcspec @@ -64,6 +64,16 @@ NO = (); }; }, + { + Name = "DEAD_CODE_STRIPPING"; + Type = Boolean; + DefaultValue = NO; + Condition = "$(MACH_O_TYPE) != mh_object"; + CommandLineArgs = { + YES = ("-Xlinker", "--gc-sections"); + NO = (); + }; + }, { // Frameworks are Mac specific Name = "SYSTEM_FRAMEWORK_SEARCH_PATHS"; diff --git a/Sources/SWBWindowsPlatform/Specs/WindowsLd.xcspec b/Sources/SWBWindowsPlatform/Specs/WindowsLd.xcspec index 39f50000..fe66cb3f 100644 --- a/Sources/SWBWindowsPlatform/Specs/WindowsLd.xcspec +++ b/Sources/SWBWindowsPlatform/Specs/WindowsLd.xcspec @@ -102,6 +102,16 @@ Type = String; Condition = "NO"; }, + { + Name = "DEAD_CODE_STRIPPING"; + Type = Boolean; + DefaultValue = NO; + Condition = "$(MACH_O_TYPE) != mh_object"; + CommandLineArgs = { + YES = ("-Xlinker", "/OPT:REF"); + NO = (); + }; + }, { // No such concept Name = "LD_RUNPATH_SEARCH_PATHS"; diff --git a/Tests/SWBTaskConstructionTests/TaskConstructionTests.swift b/Tests/SWBTaskConstructionTests/TaskConstructionTests.swift index a0edbbe6..3c55f3d9 100644 --- a/Tests/SWBTaskConstructionTests/TaskConstructionTests.swift +++ b/Tests/SWBTaskConstructionTests/TaskConstructionTests.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import struct Foundation.Data +import Foundation import Testing @@ -8657,6 +8657,64 @@ fileprivate struct TaskConstructionTests: CoreBasedTests { } } + @Test(.requireSDKs(.host)) + func crossPlatformDeadCodeStripping() async throws { + try await withTemporaryDirectory { tmpDir in + let testProject = TestProject( + "aProject", + sourceRoot: tmpDir, + groupTree: TestGroup( + "SomeFiles", path: "Sources", + children: [ + TestFile("SourceFile.c"), + ]), + buildConfigurations: [ + TestBuildConfiguration("Debug", buildSettings: [ + "DEAD_CODE_STRIPPING": "YES", + "ONLY_ACTIVE_ARCH": "YES" + ]) + ], + targets: [ + TestStandardTarget( + "Library", + type: .dynamicLibrary, + buildConfigurations: [ + TestBuildConfiguration("Debug") + ], + buildPhases: [ + TestSourcesBuildPhase([ + "SourceFile.c", + ]) + ] + )] + ) + + let fs = PseudoFS() + + let core = try await getCore() + let tester = try TaskConstructionTester(core, testProject) + + try await tester.checkBuild(BuildParameters(configuration: "Debug", overrides: [:]), runDestination: .host, fs: fs) { results in + try results.checkTask(.matchRuleType("Ld")) { task in + switch try ProcessInfo.processInfo.hostOperatingSystem() { + case .macOS: + task.checkCommandLineContains(["-dead_strip"]) + task.checkCommandLineDoesNotContain("--gc-sections") + task.checkCommandLineDoesNotContain("/OPT:REF") + case .windows: + task.checkCommandLineDoesNotContain("-dead_strip") + task.checkCommandLineDoesNotContain("--gc-sections") + task.checkCommandLineContains(["/OPT:REF"]) + default: + task.checkCommandLineDoesNotContain("-dead_strip") + task.checkCommandLineContains(["--gc-sections"]) + task.checkCommandLineDoesNotContain("/OPT:REF") + } + } + } + } + } + @Test(.requireSDKs(.macOS)) func warningSuppression() async throws { try await withTemporaryDirectory { tmpDir in