NOTE: This bug report is the culmination of a tag-team effort between @Brett-Best and myself, with helpful guidance in Slack from @bkhouri.
PR #1424 exposed an issue with the way framework type sub-dependencies are copied if and when they are identified as shared leaves in the dependency tree. By the time such a dependency is copied by CopyFilesTaskProducer, it has been identified by its $(EXECUTABLE_NAME) instead of its $(WRAPPER_NAME), causing a dependency like Some.framework to be identified as Some. When it attempts the copy it fails, because the dependency is properly named with the .framework extension.
The practical result of this is that when building a product with SPM dependencies where any leaf node is a framework type library that is promoted, it breaks the build.
To reproduce, open DiamondRepro.zip, and build it against swift-build that was built after 73bfc08, where PR #1424 was merged:
XCBBUILDSERVICE_PATH=/path/to/recent/SWBBuildServiceBundle xcodebuild build-for-testing -scheme DiamondRepro-Package -destination "generic/platform=macOS"
Expected: the build should succeed.
Actual: the build fails with errors like:
error: /Users/daniel/Library/Developer/Xcode/DerivedData/DiamondRepro-etcxnaxkentskdfhftanfxppyfhd/Build/Products/Debug/PackageFrameworks/_NumericsShims: No such file or directory (in target 'AppTests-product' from project 'DiamondRepro')
A comment by @Brett-Best in PR #1424 (#1424 (comment)) suggested a fix that would rewrite the copy file name if it's a framework type and doesn't end in ".framework". I have tested this in my local builds and it seems to address the problem.
Another option would be to have SwiftBuildSupport's buildSourceModule (source link) do something similar to buildLibraryProduct by special casing frameworks and using the $(WRAPPER_NAME) when creating the ProjectModel.Target (source link). This is probably a more consistent fix if you want to continue keeping the special casing at the SPM level. There's a reference here that might be pertinent as well :)
// FIXME: Cleanup this mess with <rdar://56889224>
NOTE: This bug report is the culmination of a tag-team effort between @Brett-Best and myself, with helpful guidance in Slack from @bkhouri.
PR #1424 exposed an issue with the way framework type sub-dependencies are copied if and when they are identified as shared leaves in the dependency tree. By the time such a dependency is copied by
CopyFilesTaskProducer, it has been identified by its$(EXECUTABLE_NAME)instead of its$(WRAPPER_NAME), causing a dependency likeSome.frameworkto be identified asSome. When it attempts the copy it fails, because the dependency is properly named with the .framework extension.The practical result of this is that when building a product with SPM dependencies where any leaf node is a framework type library that is promoted, it breaks the build.
To reproduce, open DiamondRepro.zip, and build it against swift-build that was built after 73bfc08, where PR #1424 was merged:
Expected: the build should succeed.
Actual: the build fails with errors like:
A comment by @Brett-Best in PR #1424 (#1424 (comment)) suggested a fix that would rewrite the copy file name if it's a framework type and doesn't end in ".framework". I have tested this in my local builds and it seems to address the problem.
Another option would be to have SwiftBuildSupport's
buildSourceModule(source link) do something similar tobuildLibraryProductby special casing frameworks and using the$(WRAPPER_NAME)when creating theProjectModel.Target(source link). This is probably a more consistent fix if you want to continue keeping the special casing at the SPM level. There's a reference here that might be pertinent as well :)