14
14
15
15
def getoptions ():
16
16
parser = argparse .ArgumentParser (description = "package swift for codeql compilation" )
17
- parser .add_argument (f"--llvm-build-tree" , required = True , type = resolve ,
18
- metavar = "DIR" , help = f"path to LLVM build tree" )
19
- parser .add_argument (f"--swift-build-tree" , required = True , type = resolve ,
20
- metavar = "DIR" , help = f"path to Swift build tree" )
17
+ parser .add_argument (f"--build-tree" , required = True , type = resolve ,
18
+ metavar = "DIR" , help = f"path to the build tree" )
21
19
parser .add_argument (f"--swift-source-tree" , required = True , type = resolve ,
22
20
metavar = "DIR" , help = f"path to Swift source tree" )
23
21
@@ -34,57 +32,54 @@ def getoptions():
34
32
return opts
35
33
36
34
37
- Libs = namedtuple ("Libs" , ("archive" , "static" , "shared" , "linker_flags" ))
38
-
39
35
EXPORTED_LIB = "CodeQLSwiftFrontendTool"
40
36
37
+ Libs = namedtuple ("Libs" , ("static" , "shared" , "linker_flags" ))
38
+
41
39
42
40
def resolve (p ):
43
41
return pathlib .Path (p ).resolve ()
44
42
45
43
46
44
def run (prog , * , cwd , env = None , input = None ):
47
- print ("running" , " " . join ( prog ) , f"(cwd={ cwd } )" )
45
+ print ("running" , * prog , f"(cwd={ cwd } )" )
48
46
if env is not None :
49
47
runenv = dict (os .environ )
50
48
runenv .update (env )
51
49
else :
52
50
runenv = None
53
- subprocess .run (prog , cwd = cwd , env = runenv , input = input , text = True )
51
+ subprocess .run (prog , cwd = cwd , env = runenv , input = input , text = True , check = True )
54
52
55
53
56
54
def get_platform ():
57
55
return "linux" if platform .system () == "Linux" else "macos"
58
56
59
57
60
- def configure_dummy_project (tmp , * , llvm = None , swift = None ):
58
+ def configure_dummy_project (tmp , prefixes ):
61
59
print ("configuring dummy cmake project" )
62
60
script_dir = pathlib .Path (os .path .realpath (__file__ )).parent
63
61
print (script_dir )
64
62
shutil .copy (script_dir / "CMakeLists.txt" , tmp / "CMakeLists.txt" )
65
63
shutil .copy (script_dir / "empty.cpp" , tmp / "empty.cpp" )
66
64
tgt = tmp / "build"
67
65
tgt .mkdir ()
68
- run ([ "cmake" , f"-DCMAKE_PREFIX_PATH= { llvm } ; { swift } " , "-DBUILD_SHARED_LIBS=OFF" , ".." ],
69
- cwd = tgt )
66
+ prefixes = ';' . join ( str ( p ) for p in prefixes )
67
+ run ([ "cmake" , f"-DCMAKE_PREFIX_PATH= { prefixes } " , "-DBUILD_SHARED_LIBS=OFF" , ".." ], cwd = tgt )
70
68
return tgt
71
69
72
70
73
71
def get_libs (configured ):
74
72
print ("extracting linking information from dummy project" )
75
73
with open (configured / "CMakeFiles" / "codeql-swift-artifacts.dir" / "link.txt" ) as link :
76
74
libs = link .read ().split ()
77
- libs = libs [libs .index ('codeql-swift-artifacts' )+ 1 :] # skip up to -o dummy
78
- ret = Libs ([], [], [], [] )
75
+ libs = libs [libs .index ('codeql-swift-artifacts' ) + 1 :] # skip up to -o dummy
76
+ ret = Libs ([], [], [])
79
77
for l in libs :
80
78
if l .endswith (".a" ):
81
- ret .static .append (str (( configured / l ).resolve () ))
79
+ ret .static .append (( configured / l ).absolute ( ))
82
80
elif l .endswith (".so" ) or l .endswith (".tbd" ) or l .endswith (".dylib" ):
83
- l = pathlib .Path (l ).stem
84
- ret .shared .append (f"-l{ l [3 :]} " ) # drop 'lib' prefix and '.so' suffix
85
- elif l .startswith ("-l" ):
86
- ret .shared .append (l )
87
- elif l .startswith ("-L" ) or l .startswith ("-Wl" ):
81
+ ret .shared .append ((configured / l ).absolute ())
82
+ elif l .startswith (("-L" , "-Wl" , "-l" )):
88
83
ret .linker_flags .append (l )
89
84
else :
90
85
raise ValueError (f"cannot understand link.txt: " + l )
@@ -94,60 +89,27 @@ def get_libs(configured):
94
89
def get_tgt (tgt , filename ):
95
90
if tgt .is_dir ():
96
91
tgt /= filename
97
- return tgt .resolve ()
92
+ return tgt .absolute ()
98
93
99
94
100
95
def create_static_lib (tgt , libs ):
101
96
tgt = get_tgt (tgt , f"lib{ EXPORTED_LIB } .a" )
102
97
print (f"packaging { tgt .name } " )
103
98
if sys .platform == 'linux' :
104
- includedlibs = "\n " .join (f"addlib { l } " for l in libs .archive + libs . static )
99
+ includedlibs = "\n " .join (f"addlib { l } " for l in libs .static )
105
100
mriscript = f"create { tgt } \n { includedlibs } \n save\n end"
106
101
run (["ar" , "-M" ], cwd = tgt .parent , input = mriscript )
107
102
else :
108
103
libtool_args = ["libtool" , "-static" ]
109
- libtool_args .extend (libs .archive )
110
104
libtool_args .extend (libs .static )
111
105
libtool_args .append ("-o" )
112
106
libtool_args .append (str (tgt ))
113
107
run (libtool_args , cwd = tgt .parent )
114
108
return tgt
115
109
116
110
117
- def create_shared_lib (tgt , libs ):
118
- ext = "so"
119
- if sys .platform != 'linux' :
120
- ext = "dylib"
121
- libname = f"lib{ EXPORTED_LIB } .{ ext } "
122
- tgt = get_tgt (tgt , libname )
123
- print (f"packaging { libname } " )
124
- compiler = os .environ .get ("CC" , "clang" )
125
- cmd = [compiler , "-shared" ]
126
- cmd .extend (libs .linker_flags )
127
-
128
- if sys .platform == 'linux' :
129
- cmd .append ("-Wl,--whole-archive" )
130
- else :
131
- cmd .append ("-Wl,-all_load" )
132
-
133
- cmd .append (f"-o{ tgt } " )
134
- cmd .extend (libs .archive )
135
-
136
- if sys .platform == 'linux' :
137
- cmd .append ("-Wl,--no-whole-archive" )
138
- else :
139
- cmd .append ("-lc++" )
140
-
141
- cmd .extend (libs .static )
142
- cmd .extend (libs .shared )
143
- run (cmd , cwd = tgt .parent )
144
- if sys .platform != "linux" :
145
- run (["install_name_tool" , "-id" , f"@executable_path/{ libname } " , libname ], cwd = tgt .parent )
146
- return tgt
147
-
148
-
149
111
def copy_includes (src , tgt ):
150
- print ("copying includes" )
112
+ print (f "copying includes from { src } " )
151
113
for dir , exts in (("include" , ("h" , "def" , "inc" )), ("stdlib" , ("h" ,))):
152
114
srcdir = src / dir
153
115
for ext in exts :
@@ -159,7 +121,7 @@ def copy_includes(src, tgt):
159
121
160
122
def export_sdk (tgt , swift_source_tree , swift_build_tree ):
161
123
print ("assembling sdk" )
162
- srcdir = swift_build_tree / "lib" / "swift"
124
+ srcdir = swift_build_tree / "lib" / "swift"
163
125
tgtdir = tgt / "usr" / "lib" / "swift"
164
126
if get_platform () == "linux" :
165
127
srcdir /= "linux"
@@ -168,8 +130,8 @@ def export_sdk(tgt, swift_source_tree, swift_build_tree):
168
130
srcdir /= "macosx"
169
131
for mod in srcdir .glob ("*.swiftmodule" ):
170
132
shutil .copytree (mod , tgtdir / mod .name )
171
- shutil .copytree (swift_source_tree / "stdlib" / "public" / "SwiftShims" ,
172
- tgt / "usr" / "include " / "SwiftShims " ,
133
+ shutil .copytree (swift_source_tree / "stdlib" / "public" / "SwiftShims" / "swift" / "shims" ,
134
+ tgt / "usr" / "lib " / "swift" / "shims " ,
173
135
ignore = shutil .ignore_patterns ('CMakeLists.txt' ))
174
136
175
137
@@ -181,11 +143,11 @@ def export_stdlibs(exported_dir, swift_build_tree):
181
143
ext = 'so'
182
144
lib_dir = swift_build_tree / 'lib/swift' / platform
183
145
stdlibs = [
184
- f'libswiftCore.{ ext } ' ,
185
- 'libswiftCompatibility50.a' ,
186
- 'libswiftCompatibility51.a' ,
187
- 'libswiftCompatibilityConcurrency.a' ,
188
- 'libswiftCompatibilityDynamicReplacements.a' ]
146
+ f'libswiftCore.{ ext } ' ,
147
+ 'libswiftCompatibility50.a' ,
148
+ 'libswiftCompatibility51.a' ,
149
+ 'libswiftCompatibilityConcurrency.a' ,
150
+ 'libswiftCompatibilityDynamicReplacements.a' ]
189
151
for stdlib in stdlibs :
190
152
lib_path = lib_dir / stdlib
191
153
if lib_path .exists ():
@@ -197,13 +159,11 @@ def export_stdlibs(exported_dir, swift_build_tree):
197
159
198
160
def export_libs (exported_dir , libs , swift_build_tree ):
199
161
print ("exporting libraries" )
200
- exportedlibs = [
201
- create_static_lib (exported_dir , libs ),
202
- create_shared_lib (exported_dir , libs )
203
- ]
204
-
205
- for l in exportedlibs :
206
- l .rename (exported_dir / l .name )
162
+ create_static_lib (exported_dir , libs )
163
+ for lib in libs .shared :
164
+ # export libraries under the build tree (e.g. libSwiftSyntax.so)
165
+ if lib .is_relative_to (swift_build_tree .parent ):
166
+ shutil .copy (lib , exported_dir )
207
167
export_stdlibs (exported_dir , swift_build_tree )
208
168
209
169
@@ -213,7 +173,8 @@ def export_headers(exported_dir, swift_source_tree, llvm_build_tree, swift_build
213
173
llvm_source_tree = swift_source_tree .parent / 'llvm-project/llvm'
214
174
clang_source_tree = swift_source_tree .parent / 'llvm-project/clang'
215
175
clang_tools_build_tree = llvm_build_tree / 'tools/clang'
216
- header_dirs = [ llvm_source_tree , clang_source_tree , swift_source_tree , llvm_build_tree , swift_build_tree , clang_tools_build_tree ]
176
+ header_dirs = [llvm_source_tree , clang_source_tree , swift_source_tree , llvm_build_tree , swift_build_tree ,
177
+ clang_tools_build_tree ]
217
178
for h in header_dirs :
218
179
copy_includes (h , exported_dir )
219
180
@@ -230,18 +191,21 @@ def main(opts):
230
191
if os .path .exists (tmp ):
231
192
shutil .rmtree (tmp )
232
193
os .mkdir (tmp )
233
- configured = configure_dummy_project (tmp , llvm = opts .llvm_build_tree , swift = opts .swift_build_tree )
194
+ llvm_build_tree = next (opts .build_tree .glob ("llvm-*" ))
195
+ swift_build_tree = next (opts .build_tree .glob ("swift-*" ))
196
+ earlyswiftsyntax_build_tree = next (opts .build_tree .glob ("earlyswiftsyntax-*" ))
197
+ configured = configure_dummy_project (tmp , prefixes = [llvm_build_tree , swift_build_tree ,
198
+ earlyswiftsyntax_build_tree / "cmake" / "modules" ])
234
199
libs = get_libs (configured )
235
200
236
201
exported = tmp / "exported"
237
202
exported .mkdir ()
238
- export_libs (exported , libs , opts . swift_build_tree )
239
- export_headers (exported , opts .swift_source_tree , opts . llvm_build_tree , opts . swift_build_tree )
240
- export_sdk (exported / "sdk" , opts .swift_source_tree , opts . swift_build_tree )
203
+ export_libs (exported , libs , swift_build_tree )
204
+ export_headers (exported , opts .swift_source_tree , llvm_build_tree , swift_build_tree )
205
+ export_sdk (exported / "sdk" , opts .swift_source_tree , swift_build_tree )
241
206
242
207
zip_dir (exported , opts .output )
243
208
244
209
245
210
if __name__ == "__main__" :
246
211
main (getoptions ())
247
-
0 commit comments