diff --git a/Sources/SWBCore/Settings/BuiltinMacros.swift b/Sources/SWBCore/Settings/BuiltinMacros.swift index 1f67c0ea..cf890daf 100644 --- a/Sources/SWBCore/Settings/BuiltinMacros.swift +++ b/Sources/SWBCore/Settings/BuiltinMacros.swift @@ -420,6 +420,7 @@ public final class BuiltinMacros { // MARK: Mergeable libraries macros + public static let ADD_MERGEABLE_DEBUG_HOOK = BuiltinMacros.declareBooleanMacro("ADD_MERGEABLE_DEBUG_HOOK") public static let AUTOMATICALLY_MERGE_DEPENDENCIES = BuiltinMacros.declareBooleanMacro("AUTOMATICALLY_MERGE_DEPENDENCIES") public static let MERGEABLE_LIBRARY = BuiltinMacros.declareBooleanMacro("MERGEABLE_LIBRARY") public static let DONT_EMBED_REEXPORTED_MERGEABLE_LIBRARIES = BuiltinMacros.declareBooleanMacro("DONT_EMBED_REEXPORTED_MERGEABLE_LIBRARIES") @@ -1369,6 +1370,7 @@ public final class BuiltinMacros { ADDITIONAL_SDK_DIRS, AD_HOC_CODE_SIGNING_ALLOWED, __AD_HOC_CODE_SIGNING_NOT_ALLOWED_SUPPLEMENTAL_MESSAGE, + ADD_MERGEABLE_DEBUG_HOOK, AGGREGATE_TRACKED_DOMAINS, ALLOW_BUILD_REQUEST_OVERRIDES, ALLOW_DISJOINTED_DIRECTORIES_AS_DEPENDENCIES, diff --git a/Sources/SWBCore/Settings/Settings.swift b/Sources/SWBCore/Settings/Settings.swift index 356b04f8..c9d99bd0 100644 --- a/Sources/SWBCore/Settings/Settings.swift +++ b/Sources/SWBCore/Settings/Settings.swift @@ -2164,9 +2164,14 @@ private class SettingsBuilder { table.push(BuiltinMacros.MERGE_LINKED_LIBRARIES, literal: true) } - // If this is a mergeable library, then build it as mergeable if this is a release build. - if scope.evaluate(BuiltinMacros.MERGEABLE_LIBRARY), !scope.evaluate(BuiltinMacros.IS_UNOPTIMIZED_BUILD) { - table.push(BuiltinMacros.MAKE_MERGEABLE, literal: true) + // If this is a mergeable library, for a release build we want to build it as mergeable, whereas for a debug build we want to add the mergeable debug hook. + if scope.evaluate(BuiltinMacros.MERGEABLE_LIBRARY) { + if scope.evaluate(BuiltinMacros.IS_UNOPTIMIZED_BUILD) { + table.push(BuiltinMacros.ADD_MERGEABLE_DEBUG_HOOK, literal: true) + } + else { + table.push(BuiltinMacros.MAKE_MERGEABLE, literal: true) + } } push(table, .exportedForNative) diff --git a/Sources/SWBTestSupport/CoreBasedTests.swift b/Sources/SWBTestSupport/CoreBasedTests.swift index 7c3e6f42..ff76cf5a 100644 --- a/Sources/SWBTestSupport/CoreBasedTests.swift +++ b/Sources/SWBTestSupport/CoreBasedTests.swift @@ -379,6 +379,13 @@ extension CoreBasedTests { try await SWBCore.discoveredSwiftCompilerInfo(MockCommandProducer(core: getCore(), productTypeIdentifier: "com.apple.product-type.framework", platform: nil, useStandardExecutableSearchPaths: true, toolchain: nil, fs: PseudoFS()), AlwaysDeferredCoreClientDelegate(), at: toolPath, blocklistsPathOverride: nil) } + package func discoveredLdLinkerInfo(at toolPath: Path) async throws -> DiscoveredLdLinkerToolSpecInfo { + guard let info = try await SWBCore.discoveredLinkerToolsInfo(MockCommandProducer(core: getCore(), productTypeIdentifier: "com.apple.product-type.framework", platform: nil, useStandardExecutableSearchPaths: true, toolchain: nil, fs: PseudoFS()), AlwaysDeferredCoreClientDelegate(), at: toolPath) as? DiscoveredLdLinkerToolSpecInfo else { + throw StubError.error("Could not get tool spec info for LdLinkerSpec") + } + return info + } + package func discoveredTAPIToolInfo(at toolPath: Path) async throws -> DiscoveredTAPIToolSpecInfo { try await SWBCore.discoveredTAPIToolInfo(MockCommandProducer(core: getCore(), productTypeIdentifier: "com.apple.product-type.framework", platform: nil, useStandardExecutableSearchPaths: true, toolchain: nil, fs: PseudoFS()), AlwaysDeferredCoreClientDelegate(), at: toolPath) } diff --git a/Sources/SWBUniversalPlatform/Specs/Ld.xcspec b/Sources/SWBUniversalPlatform/Specs/Ld.xcspec index d30e08ad..b39abe90 100644 --- a/Sources/SWBUniversalPlatform/Specs/Ld.xcspec +++ b/Sources/SWBUniversalPlatform/Specs/Ld.xcspec @@ -665,6 +665,19 @@ }; }, + { Name = LD_ADD_MERGEABLE_DEBUG_HOOK; + Type = Boolean; + DefaultValue = "$(ADD_MERGEABLE_DEBUG_HOOK)"; + CommandLineArgs = { + YES = ( + "-Xlinker", + "-add_mergeable_debug_hook", + ); + NO = (); + }; + SupportedVersionRanges = ( "1217" ); + }, + { Name = "LD_SHARED_CACHE_ELIGIBLE"; Type = Enumeration; diff --git a/Tests/SWBBuildSystemTests/MergeableLibrariesBuildOperationTests.swift b/Tests/SWBBuildSystemTests/MergeableLibrariesBuildOperationTests.swift index ce5ed097..2c9cdc01 100644 --- a/Tests/SWBBuildSystemTests/MergeableLibrariesBuildOperationTests.swift +++ b/Tests/SWBBuildSystemTests/MergeableLibrariesBuildOperationTests.swift @@ -26,6 +26,18 @@ import MachO @Suite(.requireXcode16()) fileprivate struct MergeableLibrariesBuildOperationTests: CoreBasedTests { + + private func linkerSupportsMergeableDebugHook() async throws -> Bool { + guard let ldPath = try await ldPath else { + throw StubError.error("Could not get path for ld linker.") + } + let info = try await discoveredLdLinkerInfo(at: ldPath) + guard let version = info.toolVersion else { + throw StubError.error("Could not get version for ld linker at '\(ldPath.str).") + } + return version >= Version(1217) + } + @Test(.requireSDKs(.iOS)) func automaticMergedFrameworkCreation() async throws { try await testAutomaticMergedFrameworkCreation(useAppStoreCodelessFrameworksWorkaround: true) @@ -164,6 +176,7 @@ fileprivate struct MergeableLibrariesBuildOperationTests: CoreBasedTests { let tester = try await BuildOperationTester(getCore(), testWorkspace, simulated: false) let SRCROOT = testWorkspace.sourceRoot.join("aProject") let signableTargets: Set = Set(tester.workspace.projects[0].targets.map({ $0.name })) + let supportsMergeableDebugHook = try await linkerSupportsMergeableDebugHook() // Write the source files. try await tester.fs.writeFileContents(SRCROOT.join("Sources/Application.swift")) { contents in @@ -216,6 +229,9 @@ fileprivate struct MergeableLibrariesBuildOperationTests: CoreBasedTests { results.checkTask(.matchTargetName(targetName), .matchRuleType("SwiftCompile")) { _ in } results.checkTask(.matchTargetName(targetName), .matchRuleType("Ld")) { task in task.checkCommandLineDoesNotContain("-make_mergeable") + if supportsMergeableDebugHook { + task.checkCommandLineContains("-add_mergeable_debug_hook") + } task.checkCommandLineContains(["-o", "\(SYMROOT)/Debug-iphoneos/\(targetName).framework/\(targetName)"]) } results.checkTasks(.matchTargetName(targetName), .matchRuleType("Copy")) { _ in /* likely Swift-related */ } @@ -234,6 +250,7 @@ fileprivate struct MergeableLibrariesBuildOperationTests: CoreBasedTests { task.checkCommandLineContains(["-o", "\(SYMROOT)/Debug-iphoneos/\(targetName).framework/\(targetName)"]) task.checkCommandLineDoesNotContain("-merge_framework") task.checkCommandLineDoesNotContain("-make_mergeable") + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") } results.checkTask(.matchTargetName(targetName), .matchRuleType("CodeSign"), .matchRuleItemBasename("\(targetName).framework")) { _ in } // Check that the mergeable frameworks' binaries were copied in and re-signed. @@ -396,6 +413,7 @@ fileprivate struct MergeableLibrariesBuildOperationTests: CoreBasedTests { results.checkTask(.matchTargetName(targetName), .matchRuleType("SwiftCompile")) { _ in } results.checkTask(.matchTargetName(targetName), .matchRuleType("Ld")) { task in task.checkCommandLineContains("-make_mergeable") + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") task.checkCommandLineContains(["-o", "\(OBJROOT)/UninstalledProducts/iphoneos/\(targetName).framework/\(targetName)"]) } results.checkTasks(.matchTargetName(targetName), .matchRuleType("Copy")) { _ in /* likely Swift-related */ } @@ -415,6 +433,7 @@ fileprivate struct MergeableLibrariesBuildOperationTests: CoreBasedTests { task.checkCommandLineContains(["-Xlinker", "-merge_framework", "-Xlinker", "FwkTarget2"]) task.checkCommandLineContains(["-o", "\(OBJROOT)/UninstalledProducts/iphoneos/\(targetName).framework/\(targetName)"]) task.checkCommandLineDoesNotContain("-make_mergeable") + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") task.checkCommandLineDoesNotContain("-no_merge_framework") } results.checkTask(.matchTargetName(targetName), .matchRuleType("Strip")) { _ in } @@ -649,6 +668,7 @@ fileprivate struct MergeableLibrariesBuildOperationTests: CoreBasedTests { let SRCROOT_App = testWorkspace.sourceRoot.join("AppProject") let SRCROOT_Fwk = testWorkspace.sourceRoot.join("FwkProject") let signableTargets: Set = Set(tester.workspace.projects.flatMap({$0.targets}).map({ $0.name })) + let supportsMergeableDebugHook = try await linkerSupportsMergeableDebugHook() // Write the source files. try await tester.fs.writeFileContents(SRCROOT_App.join("Sources/Application.swift")) { contents in @@ -698,6 +718,9 @@ fileprivate struct MergeableLibrariesBuildOperationTests: CoreBasedTests { results.checkTask(.matchTargetName(targetName), .matchRuleType("SwiftCompile")) { _ in } results.checkTask(.matchTargetName(targetName), .matchRuleType("Ld")) { task in task.checkCommandLineDoesNotContain("-make_mergeable") + if supportsMergeableDebugHook { + task.checkCommandLineContains("-add_mergeable_debug_hook") + } task.checkCommandLineContains(["-o", "\(SYMROOT)/Config-iphoneos/\(targetName).framework/\(targetName)"]) } results.checkTasks(.matchTargetName(targetName), .matchRuleType("Copy")) { _ in /* likely Swift-related */ } @@ -855,6 +878,7 @@ fileprivate struct MergeableLibrariesBuildOperationTests: CoreBasedTests { results.checkTask(.matchTargetName(targetName), .matchRuleType("SwiftCompile")) { _ in } results.checkTask(.matchTargetName(targetName), .matchRuleType("Ld")) { task in task.checkCommandLineContains("-make_mergeable") + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") task.checkCommandLineContains(["-o", "\(OBJROOT)/UninstalledProducts/iphoneos/\(targetName).framework/\(targetName)"]) } results.checkTasks(.matchTargetName(targetName), .matchRuleType("Copy")) { _ in /* likely Swift-related */ } @@ -876,6 +900,7 @@ fileprivate struct MergeableLibrariesBuildOperationTests: CoreBasedTests { task.checkCommandLineContains(["-Xlinker", "-merge_library", "-Xlinker", "\(OBJROOT)/UninstalledProducts/iphoneos/\(fwkTargetName).framework/\(fwkTargetName)"]) task.checkCommandLineContains(["-o", "\(DSTROOT)/Applications/\(targetName).app/\(targetName)"]) task.checkCommandLineDoesNotContain("-make_mergeable") + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") task.checkCommandLineDoesNotContain("-no_merge_framework") } // Check that we're excluding the binary when embedding the mergeable targets, but not the merged target. @@ -1512,6 +1537,7 @@ fileprivate struct MergeableLibrariesBuildOperationTests: CoreBasedTests { task.checkCommandLineContains(["-Xlinker", "-merge-l\(libBaseName)"]) task.checkCommandLineContains(["-o", "\(OBJROOT)/UninstalledProducts/iphoneos/\(targetName).framework/\(targetName)"]) task.checkCommandLineDoesNotContain("-make_mergeable") + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") task.checkCommandLineDoesNotContain("-no_merge_framework") } results.checkTasks(.matchTargetName(targetName), .matchRuleType("Copy")) { _ in /* likely Swift-related */ } diff --git a/Tests/SWBTaskConstructionTests/MergeableLibraryTests.swift b/Tests/SWBTaskConstructionTests/MergeableLibraryTests.swift index 84342e95..a93e3696 100644 --- a/Tests/SWBTaskConstructionTests/MergeableLibraryTests.swift +++ b/Tests/SWBTaskConstructionTests/MergeableLibraryTests.swift @@ -20,6 +20,18 @@ import SWBTestSupport @Suite fileprivate struct MergeableLibraryTests: CoreBasedTests { + + private func linkerSupportsMergeableDebugHook() async throws -> Bool { + guard let ldPath = try await ldPath else { + throw StubError.error("Could not get path for ld linker.") + } + let info = try await discoveredLdLinkerInfo(at: ldPath) + guard let version = info.toolVersion else { + throw StubError.error("Could not get version for ld linker at '\(ldPath.str).") + } + return version >= Version(1217) + } + /// Test automatically creating a merged framework via `MERGED_BINARY_TYPE = automatic` causing its immediate dependencies to be mergeable libraries. /// /// - remark: This is the main test to exercise a broad spectrum of automatic merged framework behavior, since it was originally written for iOS. `testAutomaticMergedFrameworkCreation_macOS()` tests some differences specific to macOS. @@ -158,6 +170,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { let FWK_CONTENTS_DIR_SUBPATH = runDestination == .macOS ? "Versions/A/" : "" let APP_CONTENTS_DIR_SUBPATH = runDestination == .macOS ? "Contents/" : "" let APP_EXEC_DIR_SUBPATH = runDestination == .macOS ? "\(APP_CONTENTS_DIR_SUBPATH)MacOS/" : "" + let supportsMergeableDebugHook = try await linkerSupportsMergeableDebugHook() // Test a debug build. This will just build the merged framework to reexport the frameworks it links against. do { @@ -178,13 +191,14 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { await tester.checkBuild(parameters, runDestination: runDestination, buildRequest: request) { results in results.consumeTasksMatchingRuleTypes() - // Check that the mergeable targets were *not* build to be mergeable. + // Check that the mergeable targets were *not* built to be mergeable. for targetName in ["FwkTarget1", "FwkTarget2"] { let FULL_PRODUCT_NAME = "\(targetName).framework" results.checkTarget(targetName) { target in results.checkTask(.matchTarget(target), .matchRuleType("Ld")) { task in task.checkCommandLineContains([ ["clang"], + supportsMergeableDebugHook ? ["-add_mergeable_debug_hook"] : [], // Only passed in debug builds ["-o", "\(BUILT_PRODUCTS_DIR)/\(FULL_PRODUCT_NAME)/\(FWK_CONTENTS_DIR_SUBPATH)\(targetName)"], ].reduce([], +)) task.checkCommandLineDoesNotContain("-make_mergeable") // Not passed in debug builds @@ -200,6 +214,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { results.checkTask(.matchTarget(target), .matchRuleType("Ld")) { task in task.checkCommandLineContains([ ["clang"], + supportsMergeableDebugHook ? ["-add_mergeable_debug_hook"] : [], // Only passed in debug builds ["-o", "\(BUILT_PRODUCTS_DIR)/\(FULL_PRODUCT_NAME)"], ].reduce([], +)) task.checkCommandLineDoesNotContain("-make_mergeable") // Not passed in debug builds @@ -357,6 +372,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { ["-Xlinker", "-make_mergeable"], ["-o", "\(DSTROOT)\(INSTALL_PATH)/\(FULL_PRODUCT_NAME)/\(FWK_CONTENTS_DIR_SUBPATH)\(targetName)"], ].reduce([], +)) + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") // Only passed in debug builds } // Don't generate an intermediate .tbd file for eager linking when we're making the binary mergeable. results.checkNoTask(.matchTarget(target), .matchRuleType("GenerateTAPI")) @@ -376,6 +392,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { ["-Xlinker", "-make_mergeable"], ["-o", "\(DSTROOT)\(INSTALL_PATH)/\(FULL_PRODUCT_NAME)"], ].reduce([], +)) + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") // Only passed in debug builds task.checkCommandLineDoesNotContain(reexportedBinariesDirectoryName) } // Mergeable products should not be stripped. @@ -574,6 +591,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { let FWK_CONTENTS_DIR_SUBPATH = runDestination == .macOS ? "Versions/A/" : "" let APP_CONTENTS_DIR_SUBPATH = runDestination == .macOS ? "Contents/" : "" let APP_EXEC_DIR_SUBPATH = runDestination == .macOS ? "\(APP_CONTENTS_DIR_SUBPATH)MacOS/" : "" + let supportsMergeableDebugHook = try await linkerSupportsMergeableDebugHook() // Test a debug build. This will just build the merged framework to reexport the frameworks it links against. do { @@ -594,7 +612,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { await tester.checkBuild(parameters, runDestination: runDestination, buildRequest: request) { results in results.consumeTasksMatchingRuleTypes() - // Check that the mergeable target was *not* build to be mergeable. + // Check that the mergeable target was *not* built to be mergeable. do { let targetName = "FwkTarget1" let FULL_PRODUCT_NAME = "\(targetName).framework" @@ -602,6 +620,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { results.checkTask(.matchTarget(target), .matchRuleType("Ld")) { task in task.checkCommandLineContains([ ["clang"], + supportsMergeableDebugHook ? ["-add_mergeable_debug_hook"] : [], // Only passed in debug builds ["-o", "\(BUILT_PRODUCTS_DIR)/\(FULL_PRODUCT_NAME)/\(FWK_CONTENTS_DIR_SUBPATH)\(targetName)"], ].reduce([], +)) task.checkCommandLineDoesNotContain("-make_mergeable") // Not passed in debug builds @@ -745,6 +764,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { ["-Xlinker", "-make_mergeable"], ["-o", "\(DSTROOT)\(INSTALL_PATH)/\(FULL_PRODUCT_NAME)/\(FWK_CONTENTS_DIR_SUBPATH)\(targetName)"], ].reduce([], +)) + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") // Only passed in debug builds } // Don't generate an intermediate .tbd file for eager linking when we're making the binary mergeable. results.checkNoTask(.matchTarget(target), .matchRuleType("GenerateTAPI")) @@ -965,6 +985,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { ]) let core = try await getCore() let tester = try TaskConstructionTester(core, testWorkspace) + let supportsMergeableDebugHook = try await linkerSupportsMergeableDebugHook() // Test a debug build. This will build the merged framework to reexport the frameworks it links against. do { @@ -991,6 +1012,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { task.checkRuleInfo(["Ld", "\(SYMROOT)/Config-iphoneos/\(targetName).framework/\(targetName)", "normal"]) task.checkCommandLineContains([ ["clang"], + supportsMergeableDebugHook ? ["-add_mergeable_debug_hook"] : [], // Only passed in debug builds ["-o", "\(SYMROOT)/Config-iphoneos/\(targetName).framework/\(targetName)"], ].reduce([], +)) task.checkCommandLineDoesNotContain("-make_mergeable") // Not passed in debug builds @@ -1113,6 +1135,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { ["-Xlinker", "-make_mergeable"], ["-o", "\(OBJROOT)/UninstalledProducts/iphoneos/\(targetName).framework/\(targetName)"], ].reduce([], +)) + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") // Only passed in debug builds } // Don't generate an intermediate .tbd file for eager linking when we're making the binary mergeable. results.checkNoTask(.matchTarget(target), .matchRuleType("GenerateTAPI")) @@ -2017,6 +2040,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { ]) let core = try await getCore() let tester = try TaskConstructionTester(core, testProject) + let supportsMergeableDebugHook = try await linkerSupportsMergeableDebugHook() // Test a debug build. This will reexport the mergeable framework and not the normal framework. do { @@ -2036,21 +2060,36 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { await tester.checkBuild(parameters, runDestination: .iOS, buildRequest: request) { results in results.consumeTasksMatchingRuleTypes() - // Check that the framework targets were *not* build to be mergeable. - for targetName in ["MergeableFwkTarget", "NormalFwkTarget"] { - results.checkTarget(targetName) { target in - results.checkTask(.matchTarget(target), .matchRuleType("Ld")) { task in - task.checkRuleInfo(["Ld", "\(SYMROOT)/Config-iphoneos/\(targetName).framework/\(targetName)", "normal"]) - task.checkCommandLineContains([ - ["clang"], - ["-o", "\(SYMROOT)/Config-iphoneos/\(targetName).framework/\(targetName)"], - ].reduce([], +)) - task.checkCommandLineDoesNotContain("-make_mergeable") // Not passed in debug builds - } - results.checkTask(.matchTarget(target), .matchRuleType("GenerateTAPI")) { _ in } + // Check that the framework targets were *not* built to be mergeable. + results.checkTarget("MergeableFwkTarget") { target in + let targetName = target.target.name + results.checkTask(.matchTarget(target), .matchRuleType("Ld")) { task in + task.checkRuleInfo(["Ld", "\(SYMROOT)/Config-iphoneos/\(targetName).framework/\(targetName)", "normal"]) + task.checkCommandLineContains([ + ["clang"], + supportsMergeableDebugHook ? ["-add_mergeable_debug_hook"] : [], // Only passed in debug builds + ["-o", "\(SYMROOT)/Config-iphoneos/\(targetName).framework/\(targetName)"], + ].reduce([], +)) + task.checkCommandLineDoesNotContain("-make_mergeable") // Not passed in debug builds + } + results.checkTask(.matchTarget(target), .matchRuleType("GenerateTAPI")) { _ in } - results.checkTasks(.matchTarget(target), body: { (tasks) -> Void in #expect(tasks.count > 0) }) + results.checkTasks(.matchTarget(target), body: { (tasks) -> Void in #expect(tasks.count > 0) }) + } + results.checkTarget("NormalFwkTarget") { target in + let targetName = target.target.name + results.checkTask(.matchTarget(target), .matchRuleType("Ld")) { task in + task.checkRuleInfo(["Ld", "\(SYMROOT)/Config-iphoneos/\(targetName).framework/\(targetName)", "normal"]) + task.checkCommandLineContains([ + ["clang"], + ["-o", "\(SYMROOT)/Config-iphoneos/\(targetName).framework/\(targetName)"], + ].reduce([], +)) + task.checkCommandLineDoesNotContain("-make_mergeable") // Not passed to this target + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") // Not passed to this target } + results.checkTask(.matchTarget(target), .matchRuleType("GenerateTAPI")) { _ in } + + results.checkTasks(.matchTarget(target), body: { (tasks) -> Void in #expect(tasks.count > 0) }) } // Check that the app target handled each framework appropriately. @@ -2159,6 +2198,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { ["-Xlinker", "-make_mergeable"], ["-o", "\(DSTROOT)/Library/Frameworks/\(targetName).framework/\(targetName)"], ].reduce([], +)) + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") // Only passed in debug builds } // Don't generate an intermediate .tbd file for eager linking when we're making the binary mergeable. results.checkNoTask(.matchTarget(target), .matchRuleType("GenerateTAPI")) @@ -2176,6 +2216,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { ["-o", "\(DSTROOT)/Library/Frameworks/\(targetName).framework/\(targetName)"], ].reduce([], +)) task.checkCommandLineDoesNotContain("-make_mergeable") + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") } // Check tasks are being run for this normal framework target. results.checkTask(.matchTarget(target), .matchRuleType("GenerateTAPI")) { _ in } @@ -2357,6 +2398,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { ["-Xlinker", "-make_mergeable"], ["-o", "\(DSTROOT)\(INSTALL_PATH)/\(FULL_PRODUCT_NAME)/\(targetName)\(variantSuffix)"], ].reduce([], +)) + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") // Only passed in debug builds } results.checkTask(.matchTarget(target), .matchRuleType("GenerateDSYMFile"), .matchRuleItemBasename("\(targetName)\(variantSuffix)")) { task in @@ -2536,6 +2578,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { ["-o", "\(DSTROOT)\(INSTALL_PATH)/\(FULL_PRODUCT_NAME)/\(targetName)"], ].reduce([], +)) task.checkCommandLineDoesNotContain("-make_mergeable") + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") } results.checkTasks(.matchTarget(target), body: { (tasks) -> Void in #expect(tasks.count > 0) }) @@ -2553,6 +2596,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { ["-framework", "NormalFwkTarget"], ["-o", "\(DSTROOT)\(INSTALL_PATH)/\(FULL_PRODUCT_NAME)/\(targetName)"], ].reduce([], +)) + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") // Only passed in debug builds } results.checkTasks(.matchTarget(target), body: { (tasks) -> Void in #expect(tasks.count > 0) }) @@ -2728,6 +2772,7 @@ fileprivate struct MergeableLibraryTests: CoreBasedTests { ["-Xlinker", "-make_mergeable"], ["-o", "\(DSTROOT)\(INSTALL_PATH)/\(FULL_PRODUCT_NAME)/\(FWK_CONTENTS_DIR_SUBPATH)\(targetName)"], ].reduce([], +)) + task.checkCommandLineDoesNotContain("-add_mergeable_debug_hook") // Only passed in debug builds } results.checkTasks(.matchTarget(target), body: { (tasks) -> Void in #expect(tasks.count > 0) })