swiftSettings flags aren't being sent to dependencies

Based on the [SR-15611] swiftSettings flags aren't being sent to dependencies - Swift
I just would like to confirm if this is a bug.

I have been a lot of hours straggling trying to send a specific flag to one of the dependencies that I have in my project.

I have tried the following documentation from here:
[Package — Swift Package Manager]

I see how the flag that is defined in the Package file, it is being sent properly to the source files that belong to my Package.swift, however, it is not being sent to the local and remote dependencies.

Basically, if we have:

A dummy dependency Goodbye

public struct Goodbye {
    static public func say() {
    #if DUMMY_FLAG
        print("Goodbye with DUMMY FLAG! 😊")
    #else
        print("Sadly Goodbye 😢")
    #endif
    }
}

With the Package.swift:

let package = Package(
    name: "Goodbye",
    products: [
        .library(
            name: "Goodbye",
            targets: ["Goodbye"]),
    ],
    dependencies: [],
    targets: [
        .target(
            name: "Goodbye",
            dependencies: []),
    ]
)

As you can see based on whether the DUMMY_FLAG is being sent or not, it will print one message or the other.

Then on the main target, we are using the GoodBye dependency:

import Goodbye

#if DUMMY_FLAG
print("Hello World with DUMMY FLAG! 😊")
#else
print("Sadly Hello World 😢")
#endif

Goodbye.say()

And in the Package.swift we are defining the specific DUMMY_FLAG inside of the swiftSettings section:

let package = Package(
    name: "dummy-swiftSettings",
    platforms: [
        .macOS(.v10_12)
    ],
    products: [
        .executable(name: "dummy-swiftSettings", targets: ["dummy-swiftSettings"]),
    ],
    dependencies: [
        .package(path: "Goodbye"),
    ],
    targets: [
        .executableTarget(
            name: "dummy-swiftSettings",
            dependencies: ["Goodbye"],
            swiftSettings: [.define("DUMMY_FLAG")])
    ]
)

The expected behavior if I'm right it is:

Hello World with DUMMY FLAG! 😊
Goodbye with DUMMY FLAG! 😊

However, it shows:

Hello World with DUMMY FLAG! 😊
Sadly Goodbye 😢

I have attached a dummy project with this specific example, I have also created a repo in GitHub where I have implemented as well the CI/CD, I have double-checked that it wasn't an issue in my local computer.
Here you have the link:
[GitHub - fjtrujy/dummy-swiftSettings: A dummy project for testing if the Package.swift is passing flag variables to dependencies]

I have tried in:

  • Local computer, MacOS 12.0.1 (M1 Max), Xcode 13.2, Swift 5.5.2
  • Github CI/CD using MacOS 11.6.1, Xcode 13.1, Swift 5.5.1
  • Github CI/CD using Ubuntu 20.04.3 LTS, Swift 5.5.2

Thanks

1 Like

To add more information to the main post.

I have been investigating the code of the swift-package-manager repo, and over there I see clearly a unit test where that specific scenario is not being checked.

In this specific testBuildSettings test we can see how the flag .init(tool: .swift, kind: .define("FOO")), is being set to the specific exe target, however it is not sent to the bar dependencie.

This is intentional: you set the settings on the target, and they only apply to that target, not to its dependencies.

1 Like

So then how can I set a flag that apply also to the dependency?

There are dependencies that based on a flag work in one way or other, how can we solve that situation?

The Swift Package Manager doesn't enable doing this at this time. If you can do it using swift build then you can use swift build -Xswiftc -DYOURFLAG but otherwise this isn't possible.

1 Like

Yes, this is actually what I was doing.

So then is it a bug? a feature? or something that will never be implemented?

Thanks

I'd call it an unimplemented feature. The feature is "package configuration", allowing consumers to ask for optional or different functionality, as tools like Cargo can do.