Skip to content

Commit f52dc50

Browse files
Merge pull request #319 from swiftwasm/katei/package-trait
Use package-trait to enable Embedded specific options
2 parents b006cf6 + 047e5a6 commit f52dc50

File tree

5 files changed

+140
-37
lines changed

5 files changed

+140
-37
lines changed

Examples/Embedded/Package.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
// swift-tools-version:6.0
1+
// swift-tools-version:6.1
22

33
import PackageDescription
44

55
let package = Package(
66
name: "Embedded",
77
dependencies: [
8-
.package(name: "JavaScriptKit", path: "../../"),
8+
.package(name: "JavaScriptKit", path: "../../", traits: ["Embedded"]),
99
.package(url: "https://github.com/swiftwasm/swift-dlmalloc", branch: "0.1.0"),
1010
],
1111
targets: [

Examples/Embedded/build.sh

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#!/bin/bash
22
package_dir="$(cd "$(dirname "$0")" && pwd)"
3-
JAVASCRIPTKIT_EXPERIMENTAL_EMBEDDED_WASM=true \
4-
swift package --package-path "$package_dir" \
3+
swift package --package-path "$package_dir" \
54
-c release --triple wasm32-unknown-none-wasm js

Package.swift

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
// swift-tools-version:6.0
1+
// swift-tools-version:6.1
22

33
import PackageDescription
44

55
// NOTE: needed for embedded customizations, ideally this will not be necessary at all in the future, or can be replaced with traits
6-
let shouldBuildForEmbedded = Context.environment["JAVASCRIPTKIT_EXPERIMENTAL_EMBEDDED_WASM"].flatMap(Bool.init) ?? false
76
let useLegacyResourceBundling =
87
Context.environment["JAVASCRIPTKIT_USE_LEGACY_RESOURCE_BUNDLING"].flatMap(Bool.init) ?? false
98

@@ -16,22 +15,23 @@ let package = Package(
1615
.library(name: "JavaScriptEventLoopTestSupport", targets: ["JavaScriptEventLoopTestSupport"]),
1716
.plugin(name: "PackageToJS", targets: ["PackageToJS"]),
1817
],
18+
traits: [
19+
"Embedded"
20+
],
1921
targets: [
2022
.target(
2123
name: "JavaScriptKit",
2224
dependencies: ["_CJavaScriptKit"],
2325
exclude: useLegacyResourceBundling ? [] : ["Runtime"],
2426
resources: useLegacyResourceBundling ? [.copy("Runtime")] : [],
25-
cSettings: shouldBuildForEmbedded
26-
? [
27-
.unsafeFlags(["-fdeclspec"])
28-
] : nil,
29-
swiftSettings: shouldBuildForEmbedded
30-
? [
31-
.enableExperimentalFeature("Embedded"),
32-
.enableExperimentalFeature("Extern"),
33-
.unsafeFlags(["-Xfrontend", "-emit-empty-object-file"]),
34-
] : nil
27+
cSettings: [
28+
.unsafeFlags(["-fdeclspec"], .when(traits: ["Embedded"]))
29+
],
30+
swiftSettings: [
31+
.enableExperimentalFeature("Embedded", .when(traits: ["Embedded"])),
32+
.enableExperimentalFeature("Extern", .when(traits: ["Embedded"])),
33+
.unsafeFlags(["-Xfrontend", "-emit-empty-object-file"], .when(traits: ["Embedded"])),
34+
]
3535
),
3636
.target(name: "_CJavaScriptKit"),
3737
.testTarget(

[email protected]

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// swift-tools-version:6.0
2+
3+
import PackageDescription
4+
5+
// NOTE: needed for embedded customizations, ideally this will not be necessary at all in the future, or can be replaced with traits
6+
let shouldBuildForEmbedded = Context.environment["JAVASCRIPTKIT_EXPERIMENTAL_EMBEDDED_WASM"].flatMap(Bool.init) ?? false
7+
let useLegacyResourceBundling =
8+
Context.environment["JAVASCRIPTKIT_USE_LEGACY_RESOURCE_BUNDLING"].flatMap(Bool.init) ?? false
9+
10+
let package = Package(
11+
name: "JavaScriptKit",
12+
products: [
13+
.library(name: "JavaScriptKit", targets: ["JavaScriptKit"]),
14+
.library(name: "JavaScriptEventLoop", targets: ["JavaScriptEventLoop"]),
15+
.library(name: "JavaScriptBigIntSupport", targets: ["JavaScriptBigIntSupport"]),
16+
.library(name: "JavaScriptEventLoopTestSupport", targets: ["JavaScriptEventLoopTestSupport"]),
17+
.plugin(name: "PackageToJS", targets: ["PackageToJS"]),
18+
],
19+
targets: [
20+
.target(
21+
name: "JavaScriptKit",
22+
dependencies: ["_CJavaScriptKit"],
23+
exclude: useLegacyResourceBundling ? [] : ["Runtime"],
24+
resources: useLegacyResourceBundling ? [.copy("Runtime")] : [],
25+
cSettings: shouldBuildForEmbedded
26+
? [
27+
.unsafeFlags(["-fdeclspec"])
28+
] : nil,
29+
swiftSettings: shouldBuildForEmbedded
30+
? [
31+
.enableExperimentalFeature("Embedded"),
32+
.enableExperimentalFeature("Extern"),
33+
.unsafeFlags(["-Xfrontend", "-emit-empty-object-file"]),
34+
] : nil
35+
),
36+
.target(name: "_CJavaScriptKit"),
37+
.testTarget(
38+
name: "JavaScriptKitTests",
39+
dependencies: ["JavaScriptKit"],
40+
swiftSettings: [
41+
.enableExperimentalFeature("Extern")
42+
]
43+
),
44+
45+
.target(
46+
name: "JavaScriptBigIntSupport",
47+
dependencies: ["_CJavaScriptBigIntSupport", "JavaScriptKit"]
48+
),
49+
.target(name: "_CJavaScriptBigIntSupport", dependencies: ["_CJavaScriptKit"]),
50+
.testTarget(
51+
name: "JavaScriptBigIntSupportTests",
52+
dependencies: ["JavaScriptBigIntSupport", "JavaScriptKit"]
53+
),
54+
55+
.target(
56+
name: "JavaScriptEventLoop",
57+
dependencies: ["JavaScriptKit", "_CJavaScriptEventLoop"]
58+
),
59+
.target(name: "_CJavaScriptEventLoop"),
60+
.testTarget(
61+
name: "JavaScriptEventLoopTests",
62+
dependencies: [
63+
"JavaScriptEventLoop",
64+
"JavaScriptKit",
65+
"JavaScriptEventLoopTestSupport",
66+
],
67+
swiftSettings: [
68+
.enableExperimentalFeature("Extern")
69+
]
70+
),
71+
.target(
72+
name: "JavaScriptEventLoopTestSupport",
73+
dependencies: [
74+
"_CJavaScriptEventLoopTestSupport",
75+
"JavaScriptEventLoop",
76+
]
77+
),
78+
.target(name: "_CJavaScriptEventLoopTestSupport"),
79+
.testTarget(
80+
name: "JavaScriptEventLoopTestSupportTests",
81+
dependencies: [
82+
"JavaScriptKit",
83+
"JavaScriptEventLoopTestSupport",
84+
]
85+
),
86+
.plugin(
87+
name: "PackageToJS",
88+
capability: .command(
89+
intent: .custom(verb: "js", description: "Convert a Swift package to a JavaScript package")
90+
),
91+
sources: ["Sources"]
92+
),
93+
]
94+
)

Plugins/PackageToJS/Sources/PackageToJSPlugin.swift

+31-21
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,11 @@ struct PackageToJSPlugin: CommandPlugin {
161161
}
162162

163163
// Build products
164+
let selfPackage = try findSelfPackage(in: context.package)
164165
let productName = try buildOptions.product ?? deriveDefaultProduct(package: context.package)
165166
let build = try buildWasm(
166167
productName: productName,
168+
selfPackage: selfPackage,
167169
context: context,
168170
options: buildOptions.packageOptions
169171
)
@@ -178,14 +180,6 @@ struct PackageToJSPlugin: CommandPlugin {
178180
} else {
179181
context.pluginWorkDirectoryURL.appending(path: "Package")
180182
}
181-
guard
182-
let selfPackage = findPackageInDependencies(
183-
package: context.package,
184-
id: Self.JAVASCRIPTKIT_PACKAGE_ID
185-
)
186-
else {
187-
throw PackageToJSError("Failed to find JavaScriptKit in dependencies!?")
188-
}
189183
var make = MiniMake(
190184
explain: buildOptions.packageOptions.explain,
191185
printProgress: self.printProgress
@@ -226,9 +220,11 @@ struct PackageToJSPlugin: CommandPlugin {
226220
exit(1)
227221
}
228222

223+
let selfPackage = try findSelfPackage(in: context.package)
229224
let productName = "\(context.package.displayName)PackageTests"
230225
let build = try buildWasm(
231226
productName: productName,
227+
selfPackage: selfPackage,
232228
context: context,
233229
options: testOptions.packageOptions
234230
)
@@ -264,14 +260,6 @@ struct PackageToJSPlugin: CommandPlugin {
264260
} else {
265261
context.pluginWorkDirectoryURL.appending(path: "PackageTests")
266262
}
267-
guard
268-
let selfPackage = findPackageInDependencies(
269-
package: context.package,
270-
id: Self.JAVASCRIPTKIT_PACKAGE_ID
271-
)
272-
else {
273-
throw PackageToJSError("Failed to find JavaScriptKit in dependencies!?")
274-
}
275263
var make = MiniMake(
276264
explain: testOptions.packageOptions.explain,
277265
printProgress: self.printProgress
@@ -311,6 +299,7 @@ struct PackageToJSPlugin: CommandPlugin {
311299

312300
private func buildWasm(
313301
productName: String,
302+
selfPackage: Package,
314303
context: PluginContext,
315304
options: PackageToJS.PackageOptions
316305
) throws
@@ -331,11 +320,7 @@ struct PackageToJSPlugin: CommandPlugin {
331320
)
332321
parameters.echoLogs = true
333322
parameters.otherSwiftcFlags = ["-color-diagnostics"]
334-
let buildingForEmbedded =
335-
ProcessInfo.processInfo.environment["JAVASCRIPTKIT_EXPERIMENTAL_EMBEDDED_WASM"].flatMap(
336-
Bool.init
337-
) ?? false
338-
if !buildingForEmbedded {
323+
if !isBuildingForEmbedded(selfPackage: selfPackage) {
339324
// NOTE: We only support static linking for now, and the new SwiftDriver
340325
// does not infer `-static-stdlib` for WebAssembly targets intentionally
341326
// for future dynamic linking support.
@@ -355,6 +340,31 @@ struct PackageToJSPlugin: CommandPlugin {
355340
return try self.packageManager.build(.product(productName), parameters: parameters)
356341
}
357342

343+
/// Check if the build is for embedded WebAssembly
344+
private func isBuildingForEmbedded(selfPackage: Package) -> Bool {
345+
let coreTarget = selfPackage.targets.first { $0.name == "JavaScriptKit" }
346+
guard let swiftTarget = coreTarget as? SwiftSourceModuleTarget else {
347+
return false
348+
}
349+
// SwiftPM defines "Embedded" compilation condition when `Embedded` experimental
350+
// feature is enabled.
351+
// TODO: This should be replaced with a proper trait-based solution in the future.
352+
return swiftTarget.compilationConditions.contains("Embedded")
353+
}
354+
355+
/// Find JavaScriptKit package in the dependencies of the given package recursively
356+
private func findSelfPackage(in package: Package) throws -> Package {
357+
guard
358+
let selfPackage = findPackageInDependencies(
359+
package: package,
360+
id: Self.JAVASCRIPTKIT_PACKAGE_ID
361+
)
362+
else {
363+
throw PackageToJSError("Failed to find JavaScriptKit in dependencies!?")
364+
}
365+
return selfPackage
366+
}
367+
358368
/// Clean if the build graph of the packaging process has changed
359369
///
360370
/// This is especially important to detect user changes debug/release

0 commit comments

Comments
 (0)