Skip to content

Commit

Permalink
rdar://105991217 (Make macros testable)
Browse files Browse the repository at this point in the history
Opt macros into testable executables if we're building them as executables.
  • Loading branch information
neonichu committed Mar 22, 2023
1 parent 98bfe78 commit 163639c
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 5 deletions.
9 changes: 8 additions & 1 deletion Sources/Build/BuildDescription/ProductBuildDescription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,13 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
args += ["-emit-executable"]
args += self.deadStripArguments

// Exclude macros from testable executables if they are built as dylibs.
#if BUILD_MACROS_AS_DYLIBS
let macroCondition = executableTarget.underlyingTarget.type != .macro
#else
let macroCondition = true
#endif

// If we're linking an executable whose main module is implemented in Swift,
// we rename the `_<modulename>_main` entry point symbol to `_main` again.
// This is because executable modules implemented in Swift are compiled with
Expand All @@ -235,7 +242,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
// version of the package that defines the executable product.
let executableTarget = try product.executableTarget
if executableTarget.underlyingTarget is SwiftTarget, self.toolsVersion >= .v5_5,
self.buildParameters.canRenameEntrypointFunctionName, executableTarget.underlyingTarget.type != .macro
self.buildParameters.canRenameEntrypointFunctionName, macroCondition
{
if let flags = buildParameters.linkerFlagsForRenamingMainFunction(of: executableTarget) {
args += flags
Expand Down
18 changes: 16 additions & 2 deletions Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,16 @@ public final class SwiftTargetBuildDescription {

/// The path to the swiftmodule file after compilation.
var moduleOutputPath: AbsolutePath {
// Exclude macros from testable executables if they are built as dylibs.
#if BUILD_MACROS_AS_DYLIBS
let macroCondition = executableTarget.underlyingTarget.type != .macro
#else
let macroCondition = true
#endif

// If we're an executable and we're not allowing test targets to link against us, we hide the module.
let allowLinkingAgainstExecutables = (buildParameters.triple.isDarwin() || self.buildParameters.triple
.isLinux() || self.buildParameters.triple.isWindows()) && self.toolsVersion >= .v5_5 && target.type != .macro
.isLinux() || self.buildParameters.triple.isWindows()) && self.toolsVersion >= .v5_5 && macroCondition
let dirPath = (target.type == .executable && !allowLinkingAgainstExecutables) ? self.tempsPath : self
.buildParameters.buildPath
return dirPath.appending(component: self.target.c99name + ".swiftmodule")
Expand Down Expand Up @@ -442,6 +449,13 @@ public final class SwiftTargetBuildDescription {
args += self.buildParameters.sanitizers.compileSwiftFlags()
args += ["-parseable-output"]

// Exclude macros from testable executables if they are built as dylibs.
#if BUILD_MACROS_AS_DYLIBS
let macroCondition = false
#else
let macroCondition = self.target.type == .macro
#endif

// If we're compiling the main module of an executable other than the one that
// implements a test suite, and if the package tools version indicates that we
// should, we rename the `_main` entry point to `_<modulename>_main`.
Expand All @@ -450,7 +464,7 @@ public final class SwiftTargetBuildDescription {
// when we link the executable, we will ask the linker to rename the entry point
// symbol to just `_main` again (or if the linker doesn't support it, we'll
// generate a source containing a redirect).
if (self.target.type == .executable || self.target.type == .snippet)
if (self.target.type == .executable || self.target.type == .snippet || macroCondition)
&& !self.isTestTarget && self.toolsVersion >= .v5_5
{
// We only do this if the linker supports it, as indicated by whether we
Expand Down
11 changes: 9 additions & 2 deletions Sources/Build/BuildPlan.swift
Original file line number Diff line number Diff line change
Expand Up @@ -725,16 +725,23 @@ public class BuildPlan: SPMBuildCore.BuildPlan {
for dependency in allTargets {
switch dependency {
case .target(let target, _):
// Exclude macros from testable executables if they are built as dylibs.
#if BUILD_MACROS_AS_DYLIBS
let macroCondition = target.underlyingTarget.type != .macro
#else
let macroCondition = true
#endif

switch target.type {
// Executable target have historically only been included if they are directly in the product's
// target list. Otherwise they have always been just build-time dependencies.
// In tool version .v5_5 or greater, we also include executable modules implemented in Swift in
// any test products... this is to allow testing of executables. Note that they are also still
// built as separate products that the test can invoke as subprocesses.
case .executable, .snippet:
case .executable, .snippet, .macro:
if product.targets.contains(target) {
staticTargets.append(target)
} else if product.type == .test && target.underlyingTarget is SwiftTarget {
} else if product.type == .test && macroCondition && target.underlyingTarget is SwiftTarget {
if let toolsVersion = graph.package(for: product)?.manifest.toolsVersion, toolsVersion >= .v5_5 {
staticTargets.append(target)
}
Expand Down

0 comments on commit 163639c

Please sign in to comment.