Skip to content

Commit 0124e9c

Browse files
authored
Add Swift repo header checkout and SPM build tool plugin (#199)
1 parent 4f3a69e commit 0124e9c

24 files changed

Lines changed: 269 additions & 169 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Checkout Swift Headers
2+
description: |
3+
This action checks-out certain header files from the swiftlang/swift
4+
repository by running Scripts/clone-swift.sh.
5+
6+
inputs:
7+
path:
8+
description: Relative path under $GITHUB_WORKSPACE to place the repository
9+
required: true
10+
swift-version-major:
11+
description: The Swift toolchain major version.
12+
required: true
13+
swift-version-minor:
14+
description: The Swift toolchain minor version.
15+
required: true
16+
17+
runs:
18+
using: "composite"
19+
steps:
20+
- name: Checkout Swift headers
21+
run: ./Scripts/clone-swift.sh --path "${{ inputs.path }}" --swift-version "${{ inputs.swift-version-major }}.${{ inputs.swift-version-minor }}"
22+
shell: bash

‎.github/workflows/compatibility_tests.yml‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,19 @@ jobs:
3434
run: Scripts/CI/darwin_setup_build.sh
3535
shell: bash
3636
- name: Swift version
37-
run: swift --version
37+
id: swift-version
38+
run: |
39+
swift --version
40+
SWIFT_VERSION=$(swift --version 2>/dev/null | grep -oE 'Swift version [0-9]+\.[0-9]+' | grep -oE '[0-9]+\.[0-9]+')
41+
echo "major=$(echo $SWIFT_VERSION | cut -d. -f1)" >> $GITHUB_OUTPUT
42+
echo "minor=$(echo $SWIFT_VERSION | cut -d. -f2)" >> $GITHUB_OUTPUT
43+
shell: bash
44+
- name: Checkout Swift headers
45+
uses: ./.github/actions/checkout-swift-headers
46+
with:
47+
path: .build/checkouts/swift
48+
swift-version-major: ${{ steps.swift-version.outputs.major }}
49+
swift-version-minor: ${{ steps.swift-version.outputs.minor }}
3850
- name: Run tests against Apple's AttributeGraph on macOS via SwiftPM
3951
run: |
4052
swift test \

‎.github/workflows/ios.yml‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,22 @@ jobs:
3434
with:
3535
xcode-version: ${{ matrix.xcode-version }}
3636
- name: Swift version
37-
run: swift --version
37+
id: swift-version
38+
run: |
39+
swift --version
40+
SWIFT_VERSION=$(swift --version 2>/dev/null | grep -oE 'Swift version [0-9]+\.[0-9]+' | grep -oE '[0-9]+\.[0-9]+')
41+
echo "major=$(echo $SWIFT_VERSION | cut -d. -f1)" >> $GITHUB_OUTPUT
42+
echo "minor=$(echo $SWIFT_VERSION | cut -d. -f2)" >> $GITHUB_OUTPUT
43+
shell: bash
3844
- name: Set up build environment
3945
run: Scripts/CI/darwin_setup_build.sh
4046
shell: bash
47+
- name: Checkout Swift headers
48+
uses: ./.github/actions/checkout-swift-headers
49+
with:
50+
path: .build/checkouts/swift
51+
swift-version-major: ${{ steps.swift-version.outputs.major }}
52+
swift-version-minor: ${{ steps.swift-version.outputs.minor }}
4153
- name: Build in debug mode on iOS
4254
run: |
4355
xcodebuild build \

‎.github/workflows/macos.yml‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,19 @@ jobs:
3333
run: Scripts/CI/darwin_setup_build.sh
3434
shell: bash
3535
- name: Swift version
36-
run: swift --version
36+
id: swift-version
37+
run: |
38+
swift --version
39+
SWIFT_VERSION=$(swift --version 2>/dev/null | grep -oE 'Swift version [0-9]+\.[0-9]+' | grep -oE '[0-9]+\.[0-9]+')
40+
echo "major=$(echo $SWIFT_VERSION | cut -d. -f1)" >> $GITHUB_OUTPUT
41+
echo "minor=$(echo $SWIFT_VERSION | cut -d. -f2)" >> $GITHUB_OUTPUT
42+
shell: bash
43+
- name: Checkout Swift headers
44+
uses: ./.github/actions/checkout-swift-headers
45+
with:
46+
path: .build/checkouts/swift
47+
swift-version-major: ${{ steps.swift-version.outputs.major }}
48+
swift-version-minor: ${{ steps.swift-version.outputs.minor }}
3749
- name: Build and run tests in debug mode with coverage
3850
run: |
3951
swift test \

‎.github/workflows/ubuntu.yml‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,18 @@ jobs:
2222
steps:
2323
- uses: actions/checkout@v4
2424
- name: Swift version
25+
id: swift-version
2526
run: |
2627
which swift && swift --version
28+
echo "major=$(echo ${{ matrix.swift_version }} | cut -d. -f1)" >> $GITHUB_OUTPUT
29+
echo "minor=$(echo ${{ matrix.swift_version }} | cut -d. -f2)" >> $GITHUB_OUTPUT
30+
shell: bash
31+
- name: Checkout Swift headers
32+
uses: ./.github/actions/checkout-swift-headers
33+
with:
34+
path: .build/checkouts/swift
35+
swift-version-major: ${{ steps.swift-version.outputs.major }}
36+
swift-version-minor: ${{ steps.swift-version.outputs.minor }}
2737
- name: Building and running tests in debug mode with coverage
2838
run: |
2939
swift test \

‎Package.resolved‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Package.swift‎

Lines changed: 37 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,7 @@ let libSwiftPath = {
148148
return libSwiftPath
149149
}()
150150

151-
let swiftToolchainPath = envStringValue("SWIFT_TOOLCHAIN_PATH") ?? (development ? "/Volumes/BuildMachine/swift-project" : "")
152-
let swiftToolchainVersion = envStringValue("SWIFT_TOOLCHAIN_VERSION") ?? (development ? "6.0.2" : "")
153-
let swiftToolchainSupported = envBoolValue("SWIFT_TOOLCHAIN_SUPPORTED", default: !swiftToolchainVersion.isEmpty)
151+
let swiftCheckoutPath = "\(Context.packageDirectory)/.build/checkouts/swift"
154152

155153
let releaseVersion = envIntValue("TARGET_RELEASE", default: 2024)
156154

@@ -167,6 +165,11 @@ var sharedCSettings: [CSetting] = [
167165
.define("NDEBUG", .when(configuration: .release)),
168166
]
169167

168+
var sharedCXXSettings: [CXXSetting] = [
169+
.unsafeFlags(["-I", libSwiftPath], .when(platforms: .nonDarwinPlatforms)),
170+
.define("NDEBUG", .when(configuration: .release)),
171+
]
172+
170173
var sharedSwiftSettings: [SwiftSetting] = [
171174
.enableUpcomingFeature("InternalImportsByDefault"),
172175
.enableExperimentalFeature("Extern"),
@@ -175,48 +178,21 @@ var sharedSwiftSettings: [SwiftSetting] = [
175178
.define("OPENATTRIBUTEGRAPH_RELEASE_\(releaseVersion)"),
176179
]
177180

178-
// Modified from: https://github.com/swiftlang/swift/blob/main/SwiftCompilerSources/Package.swift
179-
//
180-
// Create a couple of symlinks to an existing Ninja build:
181-
//
182-
// ```shell
183-
// cd $OPENATTRIBUTEGRAPH_SWIFT_TOOLCHAIN_PATH
184-
// mkdir -p build/Default
185-
// ln -s build/<Ninja-Build>/llvm-<os+arch> build/Default/llvm
186-
// ln -s build/<Ninja-Build>/swift-<os+arch> build/Default/swift
187-
// ```
188-
//
189-
// where <$OPENATTRIBUTEGRAPH_SWIFT_TOOLCHAIN_PATH> is the parent directory of the swift repository.
190-
191-
if !swiftToolchainPath.isEmpty {
192-
sharedCSettings.append(
193-
.unsafeFlags(
194-
[
195-
"-static",
196-
"-DCOMPILED_WITH_SWIFT",
197-
"-DPURE_BRIDGING_MODE",
198-
"-UIBOutlet", "-UIBAction", "-UIBInspectable",
199-
"-I\(swiftToolchainPath)/swift/include",
200-
"-I\(swiftToolchainPath)/swift/stdlib/public/SwiftShims",
201-
"-I\(swiftToolchainPath)/llvm-project/llvm/include",
202-
"-I\(swiftToolchainPath)/llvm-project/clang/include",
203-
"-I\(swiftToolchainPath)/build/Default/swift/include",
204-
"-I\(swiftToolchainPath)/build/Default/llvm/include",
205-
"-I\(swiftToolchainPath)/build/Default/llvm/tools/clang/include",
206-
"-DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING", // Required to fix LLVM link issue
207-
]
208-
)
209-
)
210-
}
211-
if !swiftToolchainVersion.isEmpty {
212-
sharedCSettings.append(
213-
.define("OPENATTRIBUTEGRAPH_SWIFT_TOOLCHAIN_VERSION", to: swiftToolchainVersion)
214-
)
215-
}
216-
if swiftToolchainSupported {
217-
sharedCSettings.append(.define("OPENATTRIBUTEGRAPH_SWIFT_TOOLCHAIN_SUPPORTED"))
218-
sharedSwiftSettings.append(.define("OPENATTRIBUTEGRAPH_SWIFT_TOOLCHAIN_SUPPORTED"))
219-
}
181+
sharedCSettings.append(
182+
.unsafeFlags([
183+
"-isystem", "\(swiftCheckoutPath)/include",
184+
"-isystem", "\(swiftCheckoutPath)/stdlib/include",
185+
"-isystem", "\(swiftCheckoutPath)/stdlib/public/SwiftShims",
186+
])
187+
)
188+
sharedCXXSettings.append(
189+
.unsafeFlags([
190+
"-isystem", "\(swiftCheckoutPath)/include",
191+
"-isystem", "\(swiftCheckoutPath)/stdlib/include",
192+
"-isystem", "\(swiftCheckoutPath)/stdlib/public/SwiftShims",
193+
])
194+
)
195+
220196
if releaseVersion >= 2021 {
221197
for year in 2021 ... releaseVersion {
222198
sharedSwiftSettings.append(.define("OPENATTRIBUTEGRAPH_SUPPORT_\(year)_API"))
@@ -232,6 +208,7 @@ if libraryEvolutionCondition {
232208
}
233209
if !compatibilityTestCondition {
234210
sharedCSettings.append(.define("OPENATTRIBUTEGRAPH"))
211+
sharedCXXSettings.append(.define("OPENATTRIBUTEGRAPH"))
235212
sharedSwiftSettings.append(.define("OPENATTRIBUTEGRAPH"))
236213
}
237214

@@ -256,10 +233,16 @@ extension [Platform] {
256233

257234
// MARK: - Targets
258235

236+
let swiftClonePlugin = Target.plugin(
237+
name: "CloneSwiftPlugin",
238+
capability: .buildTool()
239+
)
240+
259241
let openAttributeGraphTarget = Target.target(
260242
name: "OpenAttributeGraph",
261243
dependencies: ["OpenAttributeGraphCxx"],
262244
cSettings: sharedCSettings,
245+
cxxSettings: sharedCXXSettings,
263246
swiftSettings: sharedSwiftSettings
264247
)
265248
// FIXME: Merge into one target
@@ -270,13 +253,16 @@ let openAttributeGraphSPITarget = Target.target(
270253
cSettings: sharedCSettings + [
271254
.define("__COREFOUNDATION_FORSWIFTFOUNDATIONONLY__", to: "1", .when(platforms: .nonDarwinPlatforms)),
272255
],
256+
cxxSettings: sharedCXXSettings,
273257
linkerSettings: [
274258
.linkedLibrary("z"),
275-
]
259+
],
260+
plugins: [.plugin(name: swiftClonePlugin.name)]
276261
)
277262
let openAttributeGraphShimsTarget = Target.target(
278263
name: "OpenAttributeGraphShims",
279264
cSettings: sharedCSettings,
265+
cxxSettings: sharedCXXSettings,
280266
swiftSettings: sharedSwiftSettings
281267
)
282268

@@ -289,6 +275,7 @@ let openAttributeGraphTestsTarget = Target.testTarget(
289275
],
290276
exclude: ["README.md"],
291277
cSettings: sharedCSettings,
278+
cxxSettings: sharedCXXSettings,
292279
swiftSettings: sharedSwiftSettings
293280
)
294281
let openAttributeGraphCxxTestsTarget = Target.testTarget(
@@ -298,6 +285,7 @@ let openAttributeGraphCxxTestsTarget = Target.testTarget(
298285
],
299286
exclude: ["README.md"],
300287
cSettings: sharedCSettings + [.define("SWIFT_TESTING")],
288+
cxxSettings: sharedCXXSettings,
301289
swiftSettings: sharedSwiftSettings + [.interoperabilityMode(.Cxx)]
302290
)
303291
let openAttributeGraphShimsTestsTarget = Target.testTarget(
@@ -307,6 +295,7 @@ let openAttributeGraphShimsTestsTarget = Target.testTarget(
307295
],
308296
exclude: ["README.md"],
309297
cSettings: sharedCSettings,
298+
cxxSettings: sharedCXXSettings,
310299
swiftSettings: sharedSwiftSettings
311300
)
312301
let openAttributeGraphCompatibilityTestsTarget = Target.testTarget(
@@ -316,6 +305,7 @@ let openAttributeGraphCompatibilityTestsTarget = Target.testTarget(
316305
] + (compatibilityTestCondition ? [] : ["OpenAttributeGraph"]),
317306
exclude: ["README.md"],
318307
cSettings: sharedCSettings,
308+
cxxSettings: sharedCXXSettings,
319309
swiftSettings: sharedSwiftSettings
320310
)
321311

@@ -331,6 +321,7 @@ let package = Package(
331321
.package(url: "https://github.com/apple/swift-numerics", from: "1.0.2"),
332322
],
333323
targets: [
324+
swiftClonePlugin,
334325
openAttributeGraphTarget,
335326
openAttributeGraphSPITarget,
336327
openAttributeGraphShimsTarget,
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import Foundation
2+
import PackagePlugin
3+
4+
@main
5+
struct CloneSwiftPlugin: BuildToolPlugin {
6+
func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] {
7+
let packageDir = context.package.directoryURL
8+
let checkoutPath = packageDir.appending(path: ".build/checkouts/swift")
9+
let script = packageDir.appending(path: "Scripts/clone-swift.sh")
10+
11+
let env = ProcessInfo.processInfo.environment
12+
13+
let effectivePath = env["SWIFT_TOOLCHAIN_PATH"] ?? checkoutPath.path()
14+
var scriptArgs = "\(script.path()) --path \(effectivePath)"
15+
16+
if let version = env["SWIFT_TOOLCHAIN_VERSION"],
17+
!version.isEmpty {
18+
scriptArgs += " --swift-version \(version)"
19+
}
20+
21+
return [
22+
.prebuildCommand(
23+
displayName: "Clone Swift repository headers",
24+
executable: URL(filePath: "/bin/bash"),
25+
arguments: [
26+
"-c",
27+
"\(scriptArgs) 2>&1 || echo 'warning: CloneSwiftPlugin: clone-swift.sh failed. Run Scripts/clone-swift.sh manually or use swift build --disable-sandbox.'",
28+
],
29+
outputFilesDirectory: context.pluginWorkDirectoryURL
30+
)
31+
]
32+
}
33+
}

‎Scripts/build.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/zsh
1+
#!/bin/bash
22

33
# A `realpath` alternative using the default C implementation.
44
filepath() {

‎Scripts/build_swiftinterface.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/zsh
1+
#!/bin/bash
22

33
# A `realpath` alternative using the default C implementation.
44
filepath() {

0 commit comments

Comments
 (0)