swiftlang / swift-package-manager

The Package Manager for the Swift Programming Language
Apache License 2.0
9.76k stars 1.35k forks source link

Build command doesn't get executed on Windows #6962

Open tishin opened 1 year ago

tishin commented 1 year ago

Description

I have a trivial setup of a package at tishin/BuildCommandIssue -Generator target generates a source file -GeneratorPlugin plugin emits a buildCommand to execute Generator -Consumer target uses the result of the code generation

Building this package on Windows fails since Generator.exe doesn't get executed during the build:

Building for debugging...
[5/5] Linking C:\Projects\BuildCommandIssue\.build\plugins\tools\debug\Generator.exe
Build complete! (11.29s)
Building for debugging...
error: couldn't build C:\Projects\BuildCommandIssue\.build\x86_64-unknown-windows-msvc\debug\Consumer.build\Consumer.swift.o because of missing inputs: C:\Projects\BuildCommandIssue\.build\plugins\outputs\buildcommandissue\Consumer\GeneratorPlugin\GeneratedScources\Product.swift

What's weird is that I managed to work around this issue by using prebuildCommand instead of buildCommand: tishin/BuildCommandIssue#1 Which I think I was not even supposed to use like that, since on macOS I get the following error trying to use prebuildCommand-based setup: a prebuild command cannot use executables built from source, including executable target 'Generator' But on Windows prebuildCommand works perfectly fine, and building succeeds.

If I put a fatalError in the beginning of Generator, I see the exception when using prebuildCommand on Windows. But with buildCommand it does not fail with the error I put, it just fails not being able to find the source file expected to be generated by the plugin. Which means that the executable is not being called at all.

I've found a couple of similar issues here, but both #6859 and #6851 go deep into Path-related issues, and I don't think it has anything to do with paths in my case since prebuildCommand works fine as is.

Expected behavior

  1. Generator.exe gets executed during build as a buildCommand
  2. Windows and macOS have the same way of handling buildCommand and prebuildCommand

Actual behavior

  1. Generator is being ignored as buildCommand, wokrs fine as prebuildCommand
  2. Various quirks and differences between the platforms

Steps to reproduce

  1. Prepare Windows environment
  2. Clone tishin/BuildCommandIssue
  3. run swift build

Swift Package Manager version/commit hash

5.9 release

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

compnerd.org Swift version 5.9 (swift-5.9-RELEASE) Target: x86_64-unknown-windows-msvc OS Version: 10.0.19045 N/A Build 19045

neonichu commented 1 year ago

Probably same issue as https://github.com/apple/swift-package-manager/issues/6859

The prebuild command issue is odd, but probably also related to incorrect treatment of .exe, so that

if builtToolNames.contains(executable.basename)

ends up not being true on Windows, bypassing the diagnostic. If you're not doing clean builds, prebuild commands will be able to use built products from previous iteration, so maybe that's why it was working.