Confused by unsafe flags being disallowed in dependencies

It'd help somewhat, but not completely (see e.g. the swift-atomics use case, there could be other similar things like the compiler bug I pointed out as well where you definitely want to be able to work around it to support a new/old toolchain even after you've shipped 1.0). I think it might just push people to never do 1.0 in that case, which would be a bit sad.

I think that could go a long way to alleviate the issues, as some escape hatch for when the existing functionality of SwiftPM just not enough would be useful - just the word unsafe in unsafeFlags at least tells me that I need to be careful and consider the long term effects of using them, but if even more clarity is desired, it's fine by me - in this case I just want us to be able to be unblocked and use SwiftPM dependencies properly even if we need to use some unsafe flag.

That would be super nice of course, thanks a lot for offering to consider that.

I just did a quick canvassing of the types of unsafe flags we've used recently (some might be much more useful implemented as different SwiftPM first-class features for sure, but just to give some input and to provide some background context, in no order of priority:

  1. The ability to enable library evolution mode and module versioning, related to
    Dynamic library support on Linux with library evolution · Issue #5714 · apple/swift-package-manager · GitHub
    and
    Availability annotations for third party libraries when using Library evolution/ resilience · Issue #60458 · apple/swift · GitHub
            swiftSettings: [.unsafeFlags(["-enable-library-evolution",
                                         "-emit-module-interface",
                                          "-user-module-version", "1.0"
  1. Additional linker settings
  linkerSettings: [
                // for M1 based Macs
                .unsafeFlags(["-Xlinker", "-L/opt/homebrew/lib"], .when(platforms: [.macOS])),
                // for Intel based Macs
                .unsafeFlags(["-Xlinker", "-L/usr/local/lib"], .when(platforms: [.macOS])),
            ]
  1. Overriding optimization level by target
    This is very commonly desired. Several times we want to do this, e.g. for dependencies of a Command plugin so that the executable dependency will be built optimised always when used by consumers of the package (I view the command plugin and related dependencies as part of the toolchain, just as I want my swift compiler to have been built with optimization turned on, I want the helper tool for the command plugin that processes tons of json to be optimised for a 2-3x speedup of post processing) - we have run into this in various settings, not just in this case (sometimes a specific part of the code will make debug runs so slow to be unusable, so it makes sense to turn that target to optimized, and conversely, something might need debug stuff).
swiftSettings: [SwiftSetting.unsafeFlags(["-Osize"])]
  1. Enabling experimental features
    (as pointed out by @xwu this now will be in 5.8 thanks to yourself, @Douglas_Gregor and others)
                .unsafeFlags(["-Xfrontend", "-enable-experimental-distributed"]),
            ]
  1. Working around compiler issues
swiftSettings: [
   .unsafeFlags(["-Xfrontend", "-validate-tbd-against-ir=none"]), // due to https://bugs.swift.org/browse/SR-15629
 ]
1 Like