Hello everyone,
I recently created a peer macro to generate mock code for my protocols. My project is configured as:
- Main Target
- Local Packages (Common, Network...)
The local packages are linked into the main target. But I also use SPM to link a local package with one another. (e.g.: Network has Common as dependency). And they are all in the same workspace.
When I use the Macro on a code in the Main Target, it works fine when running the app and running the target's unit tests.
The problem starts when I use the macro on a local package
and try to run the unit tests. I get the following error:
External macro implementation type 'Macros.Spy' could not be found for macro 'Spy()'
The Macro can be extended on the local package and can be used when running the app. As shown in the image bellow. But as aforementioned, the unit tests starts failing.
This is the implementation I have for it
Package.swift for Network package
// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "Network",
platforms: [.iOS(.v15)],
products: [
.library(
name: "NetworkKit",
targets: ["NetworkKit"]),
],
dependencies: [
.package(name: "Common", path: "../Common"),
.package(name: "Macros", path: "../Macros"),
],
targets: [
.target(
name: "NetworkKit",
dependencies: [
.product(name: "Common", package: "Common"),
.product(name: "Macros", package: "Macros"),
]),
.testTarget(
name: "NetworkTests",
dependencies: ["NetworkKit"]),
])
Package.swift for Macros package
// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.
import CompilerPluginSupport
import PackageDescription
let package = Package(
name: "Macros",
platforms: [
.macOS(.v14),
.iOS(.v15),
.tvOS(.v13),
.watchOS(.v6),
.macCatalyst(.v13),
],
products: [
.library(
name: "Macros",
targets: ["Macros"]),
.executable(
name: "MacrosClient",
targets: ["MacrosClient"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-syntax.git", from: "509.0.0"),
],
targets: [
.macro(
name: "MacrosImpl",
dependencies: [
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
.product(name: "SwiftCompilerPlugin", package: "swift-syntax"),
]),
// Library that exposes a macro as part of its API, which is used in client programs.
.target(name: "Macros", dependencies: ["MacrosImpl"]),
// A client of the library, which is able to use the macro in its own code.
.executableTarget(name: "MacrosClient", dependencies: ["Macros"]),
// A test target used to develop the macro implementation.
.testTarget(
name: "MacrosTests",
dependencies: [
"MacrosImpl",
.product(name: "SwiftSyntaxMacrosTestSupport", package: "swift-syntax"),
]),
])
@attached(peer, names: suffixed(Spy))
public macro Spy() = #externalMacro(
module: "MacrosImpl",
type: "SpyMacro")
I wonder if this is a limitation. Or if there might be something I might be missing to make it work.
Any suggestion would be really appreciated!
Thanks