Separate Package.swift for Embedded Swift?

Is it possible to have different Package.swift for Embedded Swift and normal Swift?

There are so many settings in my Package.swift for Embedded Swift that are not needed for normal Swift.

Like these:

let embeddedSwiftSettings: [SwiftSetting] = [
    .enableExperimentalFeature("Embedded"),
    .interoperabilityMode(.Cxx),
    .unsafeFlags(["-wmo", "-disable-cmo", "-Xfrontend", "-gnone", "-Xfrontend", "-disable-stack-protector"])
]

let embeddedCSettings: [CSetting] = [
    .unsafeFlags(["-fdeclspec"])
]

let linkerSettings: [LinkerSetting] = [
    .unsafeFlags([
        "-Xclang-linker", "-nostdlib",
        "-Xlinker", "--no-entry"
    ])
]

let libcSettings: [CSetting] = [
    .define("LACKS_TIME_H"),
    .define("LACKS_SYS_TYPES_H"),
    .define("LACKS_STDLIB_H"),
    .define("LACKS_STRING_H"),
    .define("LACKS_SYS_MMAN_H"),
    .define("LACKS_FCNTL_H"),
    .define("NO_MALLOC_STATS", to: "1"),
    .define("__wasilibc_unmodified_upstream"),
]

Or is it possible to apply these settings only for Embedded Swift? I haven't found how...

Before jumping in, we dont have a fully fleshed out design for how Embedded Swift will interact with SwiftPM.

To make use of Embedded Swift easier with SwiftPM @kubamracek @Max_Desiatov @bnbarham and I discussed the following short term changes:

Nope, maybe an interesting direction.

One option is passing them as -Xswiftc and -Xcc flags to swift build manually


Edit: I've updated the above list with links to SwiftPM issues.

2 Likes

I wonder if it could make sense to have a build settings conditional for embedded? Not sure if it makes sense as a platform, but if not, a new axis could be added.

This could avoid having to declare a whole new manifest while still being able to distinguish settings, dependencies, etc between embedded and general purpose Swift.

Thank you, I successfully started using symlinks for each embedded target which points to the original code e.g.

Sources/JavaScriptKit - normal folder with source code
Sources/JavaScriptKitEmbedded - symlink which points to Sources/JavaScriptKit

It gives an ability to declare two targets for the same code with different settings in Package.swift e.g.

.target(
    name: "JavaScriptKit",
    dependencies: ["_CJavaScriptKit"],
    resources: [.copy("Runtime")]
),
// Embedded
.target(
    name: "JavaScriptKitEmbedded",
    dependencies: [
        "_CJavaScriptKitEmbedded",
        .product(name: "U16String", package: "U16String")
    ],
//  resources: [.copy("Runtime")], // FIXME: doesn't work because trying to import Foundation
    cSettings: embeddedCSettings,
    swiftSettings: embeddedSwiftSettings,
    linkerSettings: linkerSettings
),
2 Likes

Embedded as a platform is something @Douglas_Gregor mentioned in a different context (availability) and is a direction to explore.

I know it’s not a long-term solution but if you want a temporary workaround you can create a module called Foundation yourself. Then, provide the Bundle API used by SPM and tell SPM to not look for system libraries for that target. This should get rid off compiler errors allowing you to build the project with a copy of whatever resource your trying to include. Of course, a more flexible Foundation framework that is lightweight and supports embedded mode will always be welcome.

1 Like

This new pitch could help with some of this: [Pitch] Package traits

1 Like