2
2
import Foundation
3
3
4
4
#if os(Linux)
5
- let libCPP = " -L/usr/lib -lc++ "
5
+ let libCPP = " -L/usr/lib -lc++ "
6
6
#elseif os(macOS)
7
- let libCPP = " -lc++ "
7
+ let libCPP = " -lc++ "
8
8
#endif
9
9
10
10
/// Runs the specified program at the provided path.
@@ -25,110 +25,118 @@ func run(_ path: String, args: [String] = []) -> String? {
25
25
26
26
let data = pipe. fileHandleForReading. readDataToEndOfFile ( )
27
27
guard let result = String ( data: data, encoding: . utf8) ?
28
- . trimmingCharacters ( in: . whitespacesAndNewlines) ,
29
- !result. isEmpty else { return nil }
28
+ . trimmingCharacters ( in: . whitespacesAndNewlines) ,
29
+ !result. isEmpty else { return nil }
30
30
return result
31
31
}
32
32
33
33
/// Finds the location of the provided binary on your system.
34
34
func which( _ name: String ) -> String ? {
35
- return run ( " /usr/bin/which " , args: [ name] )
35
+ run ( " /usr/bin/which " , args: [ name] )
36
36
}
37
37
38
- extension String : Error {
39
- /// Replaces all occurrences of characters in the provided set with
40
- /// the provided string.
41
- func replacing( charactersIn characterSet: CharacterSet ,
42
- with separator: String ) -> String {
43
- let components = self . components ( separatedBy: characterSet)
44
- return components. joined ( separator: separator)
45
- }
38
+ extension String {
39
+ /// Replaces all occurrences of characters in the provided set with
40
+ /// the provided string.
41
+ func replacing( charactersIn characterSet: CharacterSet ,
42
+ with separator: String ) -> String
43
+ {
44
+ let components = components ( separatedBy: characterSet)
45
+ return components. joined ( separator: separator)
46
+ }
47
+ }
48
+
49
+ struct MakeFileError : Error {
50
+ let message : String
51
+
52
+ init ( _ message: String ) {
53
+ self . message = message
54
+ }
46
55
}
47
56
48
57
func makeFile( ) throws {
49
- let brewPrefix = {
50
- guard let brew = which ( " brew " ) else { return nil }
51
- return run ( brew, args: [ " --prefix " ] )
52
- } ( ) ?? " /usr/local "
53
-
54
- let pkgConfigPath = " \( brewPrefix) /lib/pkgconfig "
55
- let pkgConfigDir = URL ( fileURLWithPath: pkgConfigPath)
56
-
57
- // Make <brew-prefix>/lib/pkgconfig if it doesn't already exist
58
- if !FileManager. default. fileExists ( atPath: pkgConfigPath) {
59
- try FileManager . default. createDirectory ( at: pkgConfigDir,
60
- withIntermediateDirectories: true )
61
- }
62
- let cllvmPath = pkgConfigDir. appendingPathComponent ( " llvm.pc " )
63
- let brewLLVMConfig = { which ( " \( brewPrefix) /opt/llvm/bin/llvm-config " ) }
64
-
65
- /// Ensure we have llvm-config in the PATH
66
- guard let llvmConfig = which ( " llvm-config-15 " ) ?? which ( " llvm-config " ) ?? brewLLVMConfig ( ) else {
67
- throw " Failed to find llvm-config. Ensure llvm-config is installed and " +
68
- " in your PATH "
69
- }
70
-
71
- /// Extract the info we need from llvm-config
72
-
73
- print ( " Found llvm-config at \( llvmConfig) ... " )
74
-
75
- let versionStr = run ( llvmConfig, args: [ " --version " ] ) !
76
- . replacing ( charactersIn: . newlines, with: " " )
77
- . replacingOccurrences ( of: " svn " , with: " " )
78
- let components = versionStr. components ( separatedBy: " . " )
79
- . compactMap { Int ( $0) }
80
-
81
- guard components. count == 3 else {
82
- throw " Invalid version number \( versionStr) "
83
- }
84
-
85
- let version = ( components [ 0 ] , components [ 1 ] , components [ 2 ] )
86
-
87
- guard version >= ( 15 , 0 , 0 ) else {
88
- throw " LLVMSwift requires LLVM version >=15.0.0, but you have \( versionStr) "
89
- }
90
-
91
- print ( " LLVM version is \( versionStr) " )
92
-
93
- let ldFlags = run ( llvmConfig, args: [ " --ldflags " , " --libs " , " all " ,
94
- " --system-libs " ] ) !
95
- . replacing ( charactersIn: . newlines, with: " " )
96
- . components ( separatedBy: " " )
97
- . filter { !$0. hasPrefix ( " -W " ) }
98
- . joined ( separator: " " )
99
-
100
- // SwiftPM has a whitelisted set of cflags that it understands, and
101
- // unfortunately that includes almost everything but the include dir.
102
-
103
- let cFlags = run ( llvmConfig, args: [ " --cflags " ] ) !
104
- . replacing ( charactersIn: . newlines, with: " " )
105
- . components ( separatedBy: " " )
106
- . filter { $0. hasPrefix ( " -I " ) }
107
- . joined ( separator: " " )
108
-
109
- /// Emit the pkg-config file to the path
110
-
111
- let s = [
112
- " Name: cllvm " ,
113
- " Description: The llvm library " ,
114
- " Version: \( versionStr) " ,
115
- " Libs: \( ldFlags) \( libCPP) " ,
116
- " Requires.private: " ,
117
- " Cflags: \( cFlags) " ,
118
- ] . joined ( separator: " \n " )
119
-
120
- print ( " Writing pkg-config file to \( cllvmPath. path) ... " )
121
-
122
- try s. write ( toFile: cllvmPath. path, atomically: true , encoding: . utf8)
123
-
124
- print ( " \n Successfully wrote pkg-config file! " )
125
- print ( " Make sure to re-run this script when you update LLVM. " )
58
+ let brewPrefix = {
59
+ guard let brew = which ( " brew " ) else { return nil }
60
+ return run ( brew, args: [ " --prefix " ] )
61
+ } ( ) ?? " /usr/local "
62
+
63
+ let pkgConfigPath = " \( brewPrefix) /lib/pkgconfig "
64
+ let pkgConfigDir = URL ( fileURLWithPath: pkgConfigPath)
65
+
66
+ // Make <brew-prefix>/lib/pkgconfig if it doesn't already exist
67
+ if !FileManager. default. fileExists ( atPath: pkgConfigPath) {
68
+ try FileManager . default. createDirectory ( at: pkgConfigDir,
69
+ withIntermediateDirectories: true )
70
+ }
71
+ let cllvmPath = pkgConfigDir. appendingPathComponent ( " llvm.pc " )
72
+ let brewLLVMConfig = { which ( " \( brewPrefix) /opt/llvm/bin/llvm-config " ) }
73
+
74
+ /// Ensure we have llvm-config in the PATH
75
+ guard let llvmConfig = which ( " llvm-config-15 " ) ?? which ( " llvm-config " ) ?? brewLLVMConfig ( ) else {
76
+ throw MakeFileError ( " Failed to find llvm-config. Ensure llvm-config is installed and " +
77
+ " in your PATH " )
78
+ }
79
+
80
+ /// Extract the info we need from llvm-config
81
+
82
+ print ( " Found llvm-config at \( llvmConfig) ... " )
83
+
84
+ let versionStr = run ( llvmConfig, args: [ " --version " ] ) !
85
+ . replacing ( charactersIn: . newlines, with: " " )
86
+ . replacingOccurrences ( of: " svn " , with: " " )
87
+ let components = versionStr. components ( separatedBy: " . " )
88
+ . compactMap { Int ( $0) }
89
+
90
+ guard components. count == 3 else {
91
+ throw MakeFileError ( " Invalid version number \( versionStr) " )
92
+ }
93
+
94
+ let version = ( components [ 0 ] , components [ 1 ] , components [ 2 ] )
95
+
96
+ guard version >= ( 15 , 0 , 0 ) else {
97
+ throw MakeFileError ( " LLVMSwift requires LLVM version >=15.0.0, but you have \( versionStr) " )
98
+ }
99
+
100
+ print ( " LLVM version is \( versionStr) " )
101
+
102
+ let ldFlags = run ( llvmConfig, args: [ " --ldflags " , " --libs " , " all " ,
103
+ " --system-libs " ] ) !
104
+ . replacing ( charactersIn: . newlines, with: " " )
105
+ . components ( separatedBy: " " )
106
+ . filter { !$0. hasPrefix ( " -W " ) }
107
+ . joined ( separator: " " )
108
+
109
+ // SwiftPM has a whitelisted set of cflags that it understands, and
110
+ // unfortunately that includes almost everything but the include dir.
111
+
112
+ let cFlags = run ( llvmConfig, args: [ " --cflags " ] ) !
113
+ . replacing ( charactersIn: . newlines, with: " " )
114
+ . components ( separatedBy: " " )
115
+ . filter { $0. hasPrefix ( " -I " ) }
116
+ . joined ( separator: " " )
117
+
118
+ /// Emit the pkg-config file to the path
119
+
120
+ let s = [
121
+ " Name: cllvm " ,
122
+ " Description: The llvm library " ,
123
+ " Version: \( versionStr) " ,
124
+ " Libs: \( ldFlags) \( libCPP) " ,
125
+ " Requires.private: " ,
126
+ " Cflags: \( cFlags) " ,
127
+ ] . joined ( separator: " \n " )
128
+
129
+ print ( " Writing pkg-config file to \( cllvmPath. path) ... " )
130
+
131
+ try s. write ( toFile: cllvmPath. path, atomically: true , encoding: . utf8)
132
+
133
+ print ( " \n Successfully wrote pkg-config file! " )
134
+ print ( " Make sure to re-run this script when you update LLVM. " )
126
135
}
127
136
128
137
do {
129
- try makeFile ( )
138
+ try makeFile ( )
130
139
} catch {
131
- print ( " error: \( error) " )
132
- exit ( - 1 )
140
+ print ( " error: \( error) " )
141
+ exit ( - 1 )
133
142
}
134
-
0 commit comments