Skip to content

[SwiftBuild] Keep macro implementation products as build-time dependencies in SwiftPM PIF generation #776

Description

@kateinoigakukun

Description

Follow-up from #773.

Swift macro implementation products are compile-time tools, but SwiftPM's generated PIF can treat a macro implementation target like a target-side dependency for WASI builds. In the minimum reproducer, ReproMacrosImpl is a macro implementation target and intentionally contains this guard:

#if os(WASI)
#error("ReproMacrosImpl must not be compiled for the WASI target")
#endif

ClientTests depends only on Client, which uses the macro declaration from ReproMacros. The macro implementation should be available as a host build tool for macro expansion, but it should not be compiled as a WASI target-side product.

Updated reproducer zip: https://gist.githubusercontent.com/kateinoigakukun/ba21c654a675032aa77906877c906e53/raw/b457bfba4389d1bacd730f0475020c0ee04844f0/updated-776-macro-build-dependency-linux-2026-06-12.zip

The updated zip preserves the original repro package and original repro.sh, and also includes repro-linux-2026-06-12.sh plus adaptation notes for running the same reproducer with the Linux June 12 snapshot toolchain and Swift SDK.

Expected behavior

Macro implementation targets should remain host/build-time dependencies. SwiftBuild should not build a WASI-side ReproMacrosImpl--...-testable variant for this transitive macro path, and macro implementation artifacts should not contaminate target-side WASI products.

The native and SwiftBuild backends should both build the package tests for the WASI Swift SDK. Macro-dependent tests should still get the direct macro testable variants they need, without pulling the macro implementation into the target-side WASI build.

Actual behavior

With the June 12, 2026 development snapshot and swift-DEVELOPMENT-SNAPSHOT-2026-06-12-a_wasm, the native backend succeeds and SwiftBuild still reproduces the original failure.

Observed in the latest verification:

native exit:     0
swiftbuild exit: 1
swiftbuild testable macro mentions:  24

SwiftBuild plans/compiles a WASI testable macro implementation variant:

ReproMacrosImpl--3E7BE6D87A4DC5F2-testable

and fails with:

Sources/ReproMacrosImpl/ReproMacrosImpl.swift:6:8: error: ReproMacrosImpl must not be compiled for the WASI target
 6 | #error("ReproMacrosImpl must not be compiled for the WASI target")

Steps to reproduce

  1. Download and unzip https://gist.githubusercontent.com/kateinoigakukun/ba21c654a675032aa77906877c906e53/raw/b457bfba4389d1bacd730f0475020c0ee04844f0/updated-776-macro-build-dependency-linux-2026-06-12.zip.

  2. Enter the package directory:

    cd 776-macro-build-dependency
  3. On this Linux verification machine, run the adapted script:

    ./repro-linux-2026-06-12.sh

    The adapted script uses:

    /home/ubuntu/.local/share/swiftly/toolchains/main-snapshot-2026-06-12/usr/bin/swift
    swift-DEVELOPMENT-SNAPSHOT-2026-06-12-a_wasm
    
  4. On a machine matching the original macOS-style repro assumptions, the original script is still available:

    ./repro.sh
  5. The script runs the same comparison for both build systems:

    swift build --package-path "$ROOT" --scratch-path "$WORK/native" --swift-sdk "$SWIFT_SDK_ID" --build-system native --build-tests -v
    swift build --package-path "$ROOT" --scratch-path "$WORK/swiftbuild" --swift-sdk "$SWIFT_SDK_ID" --build-system swiftbuild --build-tests -v
  6. Expected reproducer result for the current bug: native exits 0; SwiftBuild exits nonzero with the WASI-side ReproMacrosImpl #error.

Swift Package Manager version/commit hash

Swift Package Manager - Swift 6.5.0-dev

Swift & OS version (output of swift --version ; uname -a)

Swift version 6.5-dev (LLVM 18d2bfb70c14d89, Swift c13d82e5987aecb)
Target: x86_64-unknown-linux-gnu
Build config: +assertions
Linux swift-dev.fugu.katei.dev 6.8.0-94-generic #96-Ubuntu SMP PREEMPT_DYNAMIC Fri Jan  9 20:36:55 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions