I tried refactoring in this direction, with the following (simplified) setup:
// Package.swift
import PackageDescription
let package = Package(
name: "…",
products: [
.plugin(name: "Plugin", targets: ["Plugin"]]
],
targets: [
.executableTarget(name: "Executable"),
.plugin(
name: "Plugin",
capability: .buildTool(),
dependencies: ["Executable"]
)
]
)
The file hierarchy:
.
├── Package.swift
├── Plugins
│ └── Plugin
│ └── plugin.swift
├── README.md
└── Sources
└── Executable
└── main.swift
The plugin is set up to return a .prebuildCommand which dispatches to Executable — and I can confirm that the plugin runs. However: the path to Executable that's found is not an absolute path; unlike the path that I get when trying to look up a .binaryTarget, the path I get back from context.tool(named:) is /${BUILD_DIR}/${CONFIGURATION}/Executable.
When this path is returned to .prebuildCommand, these variables aren't expanded as expected (as far as I can tell), and the invocation that's run is
/usr/bin/sandbox-exec -p "(version 1)
(deny default)
(import \"system.sb\")
(allow file-read*)
(allow process*)
(allow file-write*
(subpath \"/private/tmp\")
(subpath \"/private/var/folders/…\")
)
(deny file-write*
(subpath \"…\")
)
(allow file-write*
(subpath \"…\")
)
" "/${BUILD_DIR}/${CONFIGURATION}/Executable" <arguments>
The result of this invocation is The file “Executable” doesn’t exist.
I do see that an Executable binary has been built in ~/Library/Developer/Xcode/DerivedData/<project dir>/Build/Products/Develop Debug/Executable, as well as in a few places in Intermediates.noindex/<package name>.build/Develop Debug/Executable.build, so my guess is that BUILD_DIR and CONFIGURATION may not be getting set or expanded in executing this.
Is there anything explicit I should be doing to get this invocation to work? On the face of it, it doesn't appear that there's enough info in PluginContext to expand these variables myself if I wanted.