Package Manager Conditional Target Dependencies

Great proposal!

This may be deferred to other proposal but I think we should expand the BuildSettingCondition API:

  • Add platform families: for example, the Apple Platforms family .darwin/.apple
  • Add the equivalent to targetEnvironment on Swift code with similar options: .simulator/.macCatalyst.

Looks great! I wonder if we should also add ability to conditionalize based on the target triple. That will provide a lot of flexibility and an escape hatch for the platforms (and other information in the triple) SwiftPM doesn’t know about yet. This could also be proposed separately but we might as well consider it while we’re on the topic.

2 Likes

I think that will work, but it will require adding @_exported declarations in the Bluetooth module to avoid having to import BT-mac and BT-linux from client packages.

There are .macOS and .iOS platforms. Not sure about Catalyst. I might not be the best person to answer that question.

Yeah, we can chat about it, but I agree it should probably be discussed separately as it will then affect both build settings and target dependencies.

How would you see users configure that condition? With a string?

If you want to play with the implementation here are toolchains:

yep

It's not currently possible to distinguish Mac Catalyst from the other two -- it probably should be, though.

One thing I would like is to have optional system libraries, rather than listing out all of the individual platforms on every single target, and then to add a condition like .when(available: "CoreGraphics"). I really, really dislike the whole iOS, tvOS, watchOS dance. I don't expect that list to get shorter in future, either.

Anyway, the reason why it's relevant to this proposal is that it would possibly mean using a different kind of condition to BuildSettingCondition - more like a TargetAvailabilityCondition.

EDIT (aside): I'd love to test the toolchain, but apparently you can't be trusted, and there doesn't seem to be any way for me to overrule it. The button to not require notarisation in system preferences has gone :man_shrugging:. As a long-time Mac user - this is, to be completely honest, very sad.

1 Like

Perhaps I'm missing the point, but I don't think this is possible, because SwiftPM can't know at compile time which libraries are importable at runtime on different platforms.

Just move the toolchain into /Library/Developer/Toolchains/ and launch Xcode.

If you get the warning, you can always allow it from the Security & Privacy preferences, on the General tab, towards the bottom:

It would be based on what's available in the SDK you're building against.

Yeah that's what I tried first, but the new API requires tools version 5.3, which Xcode refuses to work with, even with the new toolchain selected ("/.../Package.swift: package at '...' is using Swift tools version 5.3.0 but the installed version is 5.1.0")

Tried that already, but thanks.

You might want to run swift build directly from the command line. To have the CLI select this toolchain, define the following environment variable. To check that it works, check the output of xcrub --find swift:

$ export TOOLCHAINS=org.swift.pr.28041.441
$ xcrun --find swift
/Library/Developer/Toolchains/swift-PR-28041-441.xctoolchain/usr/bin/swift

Then, when you run swift build, it should popup a different interface that WILL allow you to accept the consequences of trusting me ;)

Nice try - the export line does at least ensure the correct CLI tools are selected (switching in Xcode doesn't seem to do anything to the CLI anymore). I have no reason to doubt your trustworthiness, but apparently Apple does, so... who am I to argue?

I can't imagine this is the first time the issue pops up. Do you all run secret builds with the safety wheels off or something?

(Oh, and I already tried the standard method of opening the executables from the Finder's right-click menu. Seriously, Apple is pretty insistent something sketchy is going on - what did you do??)

Now, you should be able to bypass the restriction from the Security preference. I don't know why it's so difficult to run a custom toolchain :frowning: @mishal_shah Any ideas if we are doing something wrong?

I wish. Rebooted, did everything again, still no luck. I think I'm just going to spin up a Linux VM.

It's (frankly) completely ridiculous, but macOS absolutely refuses to allow me to run this program. Is anybody else (on Catalina 10.15.1) able to run the toolchain?

Have you tried remove the quarantine attribute from the toolchain?

$ xattr -d -r com.apple.quarantine /path/to.xctoolchain

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

3 Likes

:partying_face: Yeah, so after you do that, "it just works".

Thanks a lot :slight_smile:

Cool.

I’ve recently been helping a developer who’s shipping a custom toolchain (s. 723651342), so I’ve spent a bunch of time looking into this. The issue here is that Xcode toolchains kinda look like a bundle but aren’t really, and that causes them to slip through a crack between Gatekeeper and the notary service. This is something that Apple needs to investigate (I don’t yet have a bug number because I only just asked the developer to file one).

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

1 Like

Just to clarify — this will not allow me to declare an entire dependency only for debug, correct?

(I'm +1 either way, as I think it'll be useful)

Correct. You can't directly declare a dependency only for debug: it will just indirectly only be for debug if it is only depended on by targets with a conditional configuration of Debug.

Which only means nothing from it will be built when you do swift build --configuration debug.

Such a dependency will still be fetched and still participate in the resolution of the package graph; all its own version constraints will still be relevant. This is important so that Package.resolved plays nice, and so you cannot accidentally end up with a package graph that works in debug but is unsolvable in release.

2 Likes
Terms of Service

Privacy Policy

Cookie Policy