Repository navigation
Compile Swift sources of extensions on macOS and iOS - #1135
Draft
ekharkunov wants to merge 5 commits into
Draft
ekharkunov wants to merge 5 commits into
ekharkunov wants to merge 5 commits into
Conversation
An extension can now keep .swift files in its src folder next to the Objective-C++ files. All of them are compiled as one module with a single swiftc call that emits the object file, the .swiftmodule and the <Module>-Swift.h header, which the .mm sources import. The module is named after the extension, and an optional <Module>-Bridging-Header.h in src is imported into it. The ext.manifest gets a swiftFlags context key. It is validated against the allowedSwiftFlags patterns of the platform in build.yml, and the -I and -F paths are resolved inside the extension folder. Defines reach the Swift code as conditional compilation names. Swift files outside of src are refused, and an SDK without the new build.yml keys answers with an explicit error. The Swift code can use the Swift packages and the Objective-C headers that SwiftPM resolved for the build. The server has to be deployed before the SDK that carries the new build.yml keys, as older servers refuse to load them.
This was referenced Nov 4, 2026
Summary - Extender code coverage reportSummary
Coveragecom/defold/extender - 45.8%
com/defold/extender/builders - 60.8%
com/defold/extender/cache - 32.8%
com/defold/extender/cache/info - 100%
com/defold/extender/jetty - 82.6%
com/defold/extender/log - 63.7%
com/defold/extender/metrics - 37.5%
com/defold/extender/process - 88%
com/defold/extender/progress - 90.6%
com/defold/extender/remote - 88.9%
com/defold/extender/services - 54.5%
com/defold/extender/services/cocoapods - 51.9%
com/defold/extender/services/data - 80.7%
com/defold/extender/services/spm - 37.6%
com/defold/extender/tracing - 21.2%
com/defold/extender/utils - 51.1%
|
The -I and -F options no longer go into swiftFlags, where they needed token pairs to be parsed and rewritten. The extension manifest gets the context keys additionalSwiftIncludePaths and additionalFrameworkSearchPaths instead. They are lists of paths that are validated to stay inside the extension folder and are passed to the Swift compiler as -I and -F. swiftFlags is now a plain allow list of flags.
The key is not Swift specific, so it is checked on every SDK and passed as -F to the existing compile and link templates through ext.frameworkPaths. Pod sources keep their own framework paths.
…the engine archive After linking an engine with Swift code, scan it with swift-stdlib-tool --print and add the libraries that the SDK settings of the platform mark as back-deployed for the minimum OS version, as Xcode does. Fail the build when the minimum OS version has no Swift runtime at all.
|
|
||
| SwiftRuntimeLibraries support = SwiftRuntimeLibraries.fromSdkSettings(new File(sdkSettings), target); | ||
| if (support == null) { | ||
| LOGGER.warn("Not checking the Swift runtime libraries: {} has no Swift support information for {}", sdkSettings, target); |
|
|
||
| SwiftRuntimeLibraries support = SwiftRuntimeLibraries.fromSdkSettings(new File(sdkSettings), target); | ||
| if (support == null) { | ||
| LOGGER.warn("Not checking the Swift runtime libraries: {} has no Swift support information for {}", sdkSettings, target); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Native extensions can now include Swift source files for macOS and iOS (devices and simulator). Put the
.swiftfiles into thesrcfolder of the extension and call them from the Objective-C++ code through the generated<Module>-Swift.hheader. The Swift code can import the Swift packages declared inSwiftPackages.json, and an optional<Module>-Bridging-Header.hinsrcgives it access to Objective-C and C declarations.Compiler options are set with the new
swiftFlagskey of the extension manifest, and the extra header and module folders withadditionalSwiftIncludePaths. Only flags that the SDK allows are accepted, and the paths must stay inside the extension folder. The newadditionalFrameworkSearchPathskey adds framework folders and is not tied to Swift: it applies to the Swift compile, to the compile of the extension's C++ and Objective-C++ sources, and to the link.The Swift runtime is part of iOS 12.2 and macOS 10.14.4 and later. Parts of it, such as Swift concurrency before iOS 15 and macOS 12, are not, and the application then needs extra dynamic libraries. The build server now finds them and adds them to the engine archive, as Xcode does, so nothing has to be configured for it. A build whose minimum OS version is older than the runtime of the OS fails with a clear error.
Technical changes
swiftc -wmo -parse-as-library -ccall per extension, which emits the object file, the.swiftmoduleand the-Swift.hheader. It runs before the C/C++/Objective-C sources, which import the header. The call goes through the existing process sandbox launcher.namewith every character outside[A-Za-z0-9_]replaced by_. The header and module are written to a per-extension folder in the build directory..swiftfiles are collected only fromsrcon Apple platforms. Swift files incommonsrcorpluginsrcfail the build, because the editor plugin build reads those folders.sourceReis not changed.PlatformConfiggets the platform keysswiftSourceRe,allowedSwiftFlagsandcompileSwiftModuleCmd. An SDK without them fails a build that has Swift sources with an explicit "not supported by this Defold SDK version" error, and ignoresswiftFlags.ExtensionManifestValidatorvalidatesswiftFlagsagainstallowedSwiftFlags; everything else, including-Iand-F, is rejected.additionalSwiftIncludePathsandadditionalFrameworkSearchPathsare lists of paths that are checked and resolved withSandboxedPath, then passed to the compiler as-Iand-Frelative to the job directory.additionalSwiftIncludePathsis ignored on an SDK without Swift support.additionalFrameworkSearchPathsis checked on every SDK and is also passed as-Fto the existingcompileCmdandlinkCmdtemplates throughext.frameworkPaths, so no SDK change is needed for it. It is not applied to the sources of pods.definesfrom the manifest context are passed to Swift as bare-Dnames, as Swift does not accept values.swiftc, so Swift code canimporta package module and the bridging header can import the Objective-C headers of a package. Importing a module requires the Xcode that builds the packages to match the toolchain of the platform SDK.listSwiftRuntimeLibsCmd,linkEngineruns it after the link:swift-stdlib-tool --printlists the Swift libraries that the engine references. The result is filtered by the table inSDKSettings.jsonof the platform SDK (SupportedTargets.<target>.SwiftCompatibilityLibraryNotNeededStartingIn): a library is added only if it is in the table and its threshold is above the minimum OS version.libswiftCoreand the other libraries that the OS always provides are never added. The libraries are copied from the toolchain to the build result, next to the engine, and are collected with the other dynamic libraries.SwiftRuntimeLibrariesholds the table, the parsing of the tool output and the check of the minimum version againstSwiftOSRuntimeMinimumDeploymentTarget. Below it the build fails with "Swift sources are not supported for this minimum OS version".JobFiles.copyFilegets an overload with a trusted source root, as the libraries come from the platform SDK and not from the job directory. The destination is still checked against the job directory.swiftToolchain,swiftSdkSettingsandswiftSdkTargetselect the toolchain, the settings file and the target. An SDK without them or withoutlistSwiftRuntimeLibsCmdskips the step.