Skip to content

Commit 3a5e369

Browse files
committed
Refactored Package LLVM config
1 parent 1c3523c commit 3a5e369

File tree

3 files changed

+74
-18
lines changed

3 files changed

+74
-18
lines changed

.github/workflows/swift.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
- name: Pre-install
1919
run: |
2020
brew update
21-
brew install llvm@18
21+
brew install llvm@18.1.8
2222
# Important: add empty string
2323
echo "" >> /Users/runner/.bash_profile
2424
echo 'export PATH="/opt/homebrew/opt/llvm/bin:$PATH"' >> /Users/runner/.bash_profile
@@ -27,7 +27,7 @@ jobs:
2727
source /Users/runner/.bash_profile
2828
clang --version
2929
swift --version
30-
swift utils/make-pkg-config.swift
30+
# swift utils/make-pkg-config.swift
3131

3232
- name: Build
3333
run: swift build -v

Package.swift

+70-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription
5+
import Foundation
6+
7+
let (cFlags, linkFlags) = try! getLLVMConfig()
58

69
let package = Package(
710
name: "llvm-api",
@@ -11,17 +14,76 @@ let package = Package(
1114
targets: [
1215
.systemLibrary(
1316
name: "CLLVM",
14-
path: "llvm-api/CLLVM",
15-
pkgConfig: "CLLVM",
16-
providers: [
17-
.brew(["llvm"]),
18-
]
17+
path: "llvm-api/CLLVM"
1918
),
2019
.target(
2120
name: "LLVM",
2221
dependencies: ["CLLVM"],
23-
path: "llvm-api/LLVM"
22+
path: "llvm-api/LLVM",
23+
cSettings: [
24+
.unsafeFlags(cFlags)
25+
],
26+
linkerSettings: [
27+
.unsafeFlags(linkFlags)
28+
]
2429
),
25-
],
26-
cxxLanguageStandard: .cxx20
30+
]
2731
)
32+
33+
/// Get LLVM config flags
34+
func getLLVMConfig() throws -> ([String], [String]) {
35+
let brewPrefix = {
36+
guard let brew = which("brew") else { return nil }
37+
return run(brew, args: ["--prefix"])
38+
}() ?? "/usr/local"
39+
/// Ensure we have llvm-config in the PATH
40+
guard let llvmConfig = which("llvm-config") ?? which("\(brewPrefix)/opt/llvm/bin/llvm-config") else {
41+
throw "Failed to find llvm-config. Ensure llvm-config is installed and in your PATH"
42+
}
43+
// Get linkage (LD) flags
44+
let ldFlags = run(llvmConfig, args: ["--ldflags", "--libs", "all", "--system-libs"])!
45+
.replacing(charactersIn: .newlines, with: " ")
46+
.components(separatedBy: " ")
47+
.filter { !$0.hasPrefix("-W") }
48+
// Get C flags
49+
let cFlags = run(llvmConfig, args: ["--cflags"])!
50+
.replacing(charactersIn: .newlines, with: "")
51+
.components(separatedBy: " ")
52+
.filter { $0.hasPrefix("-I") }
53+
return (cFlags, ldFlags)
54+
}
55+
56+
/// Runs the specified program at the provided path.
57+
/// - parameter path: The full path of the executable you wish to run.
58+
/// - parameter args: The arguments you wish to pass to the process.
59+
/// - returns: The standard output of the process, or nil if it was empty.
60+
func run(_ path: String, args: [String] = []) -> String? {
61+
let pipe = Pipe()
62+
let process = Process()
63+
process.executableURL = URL(fileURLWithPath: path)
64+
process.arguments = args
65+
process.standardOutput = pipe
66+
try? process.run()
67+
process.waitUntilExit()
68+
69+
let data = pipe.fileHandleForReading.readDataToEndOfFile()
70+
guard let result = String(data: data, encoding: .utf8)?
71+
.trimmingCharacters(in: .whitespacesAndNewlines),
72+
!result.isEmpty else { return nil }
73+
return result
74+
}
75+
76+
/// Finds the location of the provided binary on your system.
77+
func which(_ name: String) -> String? {
78+
run("/usr/bin/which", args: [name])
79+
}
80+
81+
extension String: Error {
82+
/// Replaces all occurrences of characters in the provided set with the provided string.
83+
func replacing(charactersIn characterSet: CharacterSet,
84+
with separator: String) -> String
85+
{
86+
let components = components(separatedBy: characterSet)
87+
return components.joined(separator: separator)
88+
}
89+
}

utils/make-pkg-config.swift

+2-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ let libCPP = "-lc++"
1010
/// process.
1111
/// - returns: The standard output of the process, or nil if it was empty.
1212
func run(_ path: String, args: [String] = []) -> String? {
13-
print("Running \(path) \(args.joined(separator: " "))...")
13+
print("Run: \(path) \(args.joined(separator: " "))")
1414
let pipe = Pipe()
1515
let process = Process()
1616
process.executableURL = URL(fileURLWithPath: path)
@@ -60,7 +60,7 @@ func makeFile() throws {
6060
let brewLLVMConfig = { which("\(brewPrefix)/opt/llvm/bin/llvm-config") }
6161

6262
/// Ensure we have llvm-config in the PATH
63-
guard let llvmConfig = which("llvm-config-15") ?? which("llvm-config") ?? brewLLVMConfig() else {
63+
guard let llvmConfig = which("llvm-config") ?? brewLLVMConfig() else {
6464
throw "Failed to find llvm-config. Ensure llvm-config is installed and " +
6565
"in your PATH"
6666
}
@@ -79,12 +79,6 @@ func makeFile() throws {
7979
throw "Invalid version number \(versionStr)"
8080
}
8181

82-
let version = (components[0], components[1], components[2])
83-
84-
guard version >= (11, 0, 0) else {
85-
throw "LLVMSwift requires LLVM version >=15.0.0, but you have \(versionStr)"
86-
}
87-
8882
print("LLVM version is \(versionStr)")
8983

9084
let ldFlags = run(llvmConfig, args: ["--ldflags", "--libs", "all",

0 commit comments

Comments
 (0)