What should Package.swift see when using the static linux SDK?

Hi!

I was trying to modify a package that's using C dependencies so I (probably quite naively) tried to catch whether Glibc or Musl would be available in Package.swift, but at that level it seems that there is no way to capture the fact you're using the static linux SDK. Is this expected? what would be the reasoning, if that's the case?

The following code piece in Package.swift will always exit with an error "Glibc" whether using --swift-sdk or not in the command line for swift build

#if canImport(Glibc)
#error("Glibc")
#endif
#if canImport(Musl)
#error("Musl")
#endif

the result is always

/home/marcelo/repo/aws-crt-swift/Package.swift:4:8: error: Glibc
  2 | // swift-tools-version:5.7
  3 | #if canImport(Glibc)
  4 | #error("Glibc")
    |        `- error: Glibc
  5 | #endif
  6 | #if canImport(Musl)

Can you suggest another way of detecting the package is being built with the swift linux sdk other than passing something like -Xcc -DUSE_MUSL in the swift build command line?

Yes, the package manifest is a separately compiled executable for the host, it is not cross-compiled for the target. You can see this for yourself by deleting your prior SwiftPM caches and running SwiftPM in very verbose mode:

> rm -rf .build/ ~/.cache/org.swift.swiftpm/
> ~/swift-6.0.1-RELEASE-fedora39/usr/bin/swift build --vv

That shows you that the package manifest is compiled first for the host, then run on the host to determine what files and commands to run when compiling the package source itself.

As such, conditional compilation like #if os(macOS) is only useful in the manifest if you know the package will only be natively compiled on macOS for macOS and natively compiled on linux for linux. The moment you start cross-compiling from macOS to linux, such compile-time conditionals break.

For cross-compilation, you have to use target dependency conditions where available, but it appears platform support was never added for Musl.

It depends what you're trying to do.

In the package source, obviously you're supposed to use #if canImport(Musl), as you know. If you're trying to tailor the package manifest used by SwiftPM, I don't think there's a way to do that yet.

I think the idea was that Musl is pretty much a drop-in replacement for Glibc and wouldn't require changes to package manifests, only a few source customizations.

1 Like

Use -Xswiftc -DUSE_MUSL in swift build or detect Musl via environment in a script.