Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-11207] swiftSettings are not used when compiling target dependencies #4682

Open
daveanderson mannequin opened this issue Jul 25, 2019 · 6 comments
Open

[SR-11207] swiftSettings are not used when compiling target dependencies #4682

daveanderson mannequin opened this issue Jul 25, 2019 · 6 comments
Labels

Comments

@daveanderson
Copy link
Mannequin

daveanderson mannequin commented Jul 25, 2019

Previous ID SR-11207
Radar None
Original Reporter @daveanderson
Type Bug
Environment

See also FB6809427

Additional Detail from JIRA
Votes 0
Component/s Package Manager
Labels Bug
Assignee None
Priority Medium

md5: 9be0f0f148baa6f1d9d1f89ff7b1324f

Issue Description:

The SPM Package.swift supports swiftSettings per https://github.com/apple/swift-evolution/blob/master/proposals/0238-package-manager-build-settings.md
However it appears that the target-level swiftSettings are not inherited/defined when compiling dependencies.

e.g. I have a SPM-based library that responds to several Swift settings. When building an executable that leverages this library, I can build my executable via

swift build -c release -Xswiftc -DFLAG_ONE -Xswiftc -DFLAG_TWO

This causes the executable AND the library to both be built leveraging FLAG_ONE and FLAG_TWO

However if I attempt to set these same flags in Package.swift for the executable

        .target(
            name: “MyExecutable,
            dependencies: [“MyLibrary”],
            swiftSettings: [
                // These are needed by MyLibrary but I don't know how to define them so they are used when the dependency is compiled.
                .define("FLAG_ONE"),
                .define("FLAG_TWO)
            ]
        ),

And then

swift build -v -c release

I can only see that FLAG_ONE and FLAG_TWO are leveraged when building MyExecutable (they are NOT defined when the MyLibrary dependency is compiled)

Without resorting to -Xswiftc, how can I set flags in Package.swift for an executable that will also be set when compiling dependencies?

Note: I very much would like to avoid setting these flags at the Library’s Package.swift swiftSettings level because not all consumers of the Library to have these flags set. I only need them set in the Library when compiling this one executable.

@daveanderson
Copy link
Mannequin Author

daveanderson mannequin commented Jul 25, 2019

Yes, SE-0238 indicates that

> The build settings specified in these arguments will be used to compile a particular target and the settings will not affect any other target in the package or the package graph.

However it is unclear how (apart from -Xswiftc on the command line) I can define a setting that will affect dependencies of my target.

@ankitspd
Copy link
Member

Right, we don't have such a feature yet.

@daveanderson
Copy link
Mannequin Author

daveanderson mannequin commented Jul 25, 2019

Here's another example of where the scope of swiftSettings is deficient.

let package = Package(
    name: "Experimental",
    products: [.library(name: "Experimental", targets: ["Experimental"]),],
    dependencies: [],
    targets: [
        .target(
            name: "Experimental",
            dependencies: []),
        .testTarget(
            name: "ExperimentalTests",
            dependencies: ["Experimental"],
            swiftSettings: [
                // I want to trigger testing-specific code in the Experimental library, but if I set this flag here, it doesn't propagate to `Experimental` and my testing-specific code never gets enabled. 
                .define("TEST"),
        ]),
    ]
)

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 4, 2022
@ylorn
Copy link

ylorn commented May 25, 2022

Maybe we can come up with some 'versioned' or 'labeled' Target system?

Taking example from @daveanderson:

let package = Package(
    name: "Experimental",
    products: [
        .library(
            name: "Experimental", 
            targets: [
+                .targetItem("Experimental", label: "production")
            ]
        ),
    ],
    dependencies: [],
    targets: [
        .target(
            name: "Experimental",
            dependencies: [],
+           versions: [
+               "production": [],
+               "testable": [.swiftSettings([.define("TEST")])],
+           ] 
        ),
        .testTarget(
            name: "ExperimentalTests",
            dependencies: [
+                .targetItem("Experimental", label: "testable")
            ],
            swiftSettings: [
                // I want to trigger testing-specific code in the Experimental library, but if I set this flag here, it doesn't propagate to `Experimental` and my testing-specific code never gets enabled. 
                .define("TEST"),
        ]),
    ]
)

And we can extend this system to Package.Dependency as well to cover the #4368 (SR-15611).

@neonichu
Copy link
Member

I think it is desirable to have some kind of feature flag system like this. To me, the biggest design question is how does it compose if there end up being multiple clients of a target which have different opinions about the flags that should be applied.

@ylorn
Copy link

ylorn commented May 25, 2022

Can't the final opinion simply be the union of all opinions from multiple clients? I mean this could cause conflicts for sure, but the complier will throw an error if those conflicts cannot co-exist, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants