Little question about Package Manager flags

I build my project with the next line

swift build -Xswiftc "-target" -Xswiftc "x86_64-apple-macosx10.13" -Xswiftc "-DEWTEST"

And when I try to run app with
swift run MyApp

It writes the next error:
**'PHAsset' is only available on OS X 10.13 or newer**

But my OS is 10.13.6.
And I have some other flag -Xswiftc "-DEWTEST".
How to make line swift run MyApp right?

You will need to enclose your uses of PHAsset in @available [#available]. If you generate an Xcode project from your package, it will provide you with the relevant Fix‐It suggestions:

swift package generate-xcodeproj

Once the source builds successfully in Xcode (with unmodified project settings), it will build directly in the package manager too.

SE‐0238 will allow you to restrict the platform versions a package supports, so you could then specify 10.13 in your manifest and all this would go away. SE‐0238 was accepted and is already implemented, but it is more recent than the latest stable release (i.e. it is not in Swift 4.2.1).

I forget to write, than I generate Xcode project with the Config file.
swift package generate-xcodeproj --xcconfig-overrides Package.xcconfig

In that file all flags is include.


And in Xcode it compile and run normally. But from terminal it does not run.

In a nutshell: Nothing in .xcconfig has any effect on the package itself; it only affects Xcode.

The first line of your .xcconfig tells Xcode to use a different deployment target from the package manager.


(Enabling the same sort of thing for the package manager is what SE‐0238 is all about.)

I apologize for mis‐typing earlier: For now you will have to wrap your 10.13‐only code inside #available. (Not @available; that is something else.) Your package will then be able to “support” older versions of the operating system, at least at the source level. If you cannot actually support the proper implementation for older versions, you will have to make clear in external documentation that behaviour is undefined when run on something less than 10.13. You can put a fatalError() right at the beginning so that it is immediately obvious if someone tries to use it on an incompatible OS:

if #available(macOS 10.13, *) {
} else {
    fatalError("Only macOS 10.13 and higher are supported.")

If you temporarily generate the Xcode project without the .xcconfig, Xcode will behave just like the package manager. Its ensuing warnings and Fix‐Its will help you find all the problem points quickly. Once you’ve fixed them all with #available, you can restore the .xcconfig.

You should also be aware that your custom flag (-DEWTEST) is also only available to Xcode and not present in your package.

Thanks. But my build was successful in terminal via
swift build -Xswiftc "-target" -Xswiftc "x86_64-apple-macosx10.13" -Xswiftc "-DEWTEST"
Do I send these flags through swift run command? And my os is higher than 10.13, why does it crash anyway?

You can, but you will have to do that every time you do any build/test/run command, and no one can depend on your package without manually using the same unorthodox flags. (Even that only works since such flags currently happen to affect all dependencies the same, but that behaviour is undefined and about to be shuffled around.)

A package compiles a single binary for 10.10 and higher (or 10.13 and higher with your flag). That means everything must successfully compile for 10.10. #available performs a run‐time check of which OS API is available, and chooses its execution path according to what the OS has around for it to work with.

Alex is correct: the minimum deployment OS version (set via -target) is taken into account when evaluating whether #available is needed. The thing that's failing here is that swift run is really more like swift build-and-run, so you have to provide all the -Xswiftc flags there too.

So it works finally after little shaman dance.

swift run MyApp -Xswiftc "-target" -Xswiftc "x86_64-apple-macosx10.13" -Xswiftc "-DEWTEST"
Does not works.

swift run -Xswiftc "-target" -Xswiftc "x86_64-apple-macosx10.13" -Xswiftc "-DEWTEST"

Great thanks.

More specifically, any flags (such as --configuration release) need to be between the run subcommand and the name of the executable. Everything after the executable name will be interpreted as something to be passed to the executable itself.

# This executes “MyApp --help” in the release configuration:
swift run --configuration release MyApp --help
1 Like

...and if you only have one executable in the package and you do not need to send it arguments, you can leave out its name. That is why your second one worked.

I completely do not understand the concept of command and subcommands.

This is a concise description of shell terms, including “command” and “subcommand”:

1 Like
Terms of Service

Privacy Policy

Cookie Policy