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,9 +32,9 @@ def getoptions():
34
32
return opts
35
33
36
34
37
- Libs = namedtuple ( "Libs " , ( "archive " , "static " , "shared" , "linker_flags" ))
35
+ REQUIRED_CMAKE_PACKAGES = [ "LLVM " , "Clang " , "Swift " , "SwiftSyntax" ]
38
36
39
- EXPORTED_LIB = "CodeQLSwiftFrontendTool"
37
+ Libs = namedtuple ( "Libs" , ( "static" , "shared" , "linker_flags" ))
40
38
41
39
42
40
def resolve (p ):
@@ -50,35 +48,46 @@ def run(prog, *, cwd, env=None, input=None):
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 )
52
+
53
+
54
+ def get_cmake_package_locations (build_tree ):
55
+ build_tree = pathlib .Path (build_tree )
56
+ return {
57
+ package : next (build_tree .rglob (f"{ package } Config.cmake" ))
58
+ for package in REQUIRED_CMAKE_PACKAGES
59
+ }
54
60
55
61
56
62
def get_platform ():
57
63
return "linux" if platform .system () == "Linux" else "macos"
58
64
59
65
60
- def configure_dummy_project (tmp , * , llvm = None , swift = None ):
66
+ def configure_dummy_project (tmp , package_locations ):
61
67
print ("configuring dummy cmake project" )
62
68
script_dir = pathlib .Path (os .path .realpath (__file__ )).parent
63
69
print (script_dir )
64
70
shutil .copy (script_dir / "CMakeLists.txt" , tmp / "CMakeLists.txt" )
65
71
shutil .copy (script_dir / "empty.cpp" , tmp / "empty.cpp" )
66
72
tgt = tmp / "build"
67
73
tgt .mkdir ()
68
- run (["cmake" , f"-DCMAKE_PREFIX_PATH={ llvm } ;{ swift } " , "-DBUILD_SHARED_LIBS=OFF" , ".." ],
69
- cwd = tgt )
74
+ cmd = ["cmake" , ".." , "-DBUILD_SHARED_LIBS=OFF" ]
75
+ cmd += [
76
+ f"-D{ package } _DIR={ ___location .parent } " for package , ___location in package_locations .items ()
77
+ ]
78
+ run (cmd , cwd = tgt )
70
79
return tgt
71
80
72
81
73
82
def get_libs (configured ):
74
83
print ("extracting linking information from dummy project" )
75
84
with open (configured / "CMakeFiles" / "codeql-swift-artifacts.dir" / "link.txt" ) as link :
76
85
libs = link .read ().split ()
77
- libs = libs [libs .index ('codeql-swift-artifacts' )+ 1 :] # skip up to -o dummy
78
- ret = Libs ([], [], [], [] )
86
+ libs = libs [libs .index ('codeql-swift-artifacts' ) + 1 :] # skip up to -o dummy
87
+ ret = Libs ([], [], [])
79
88
for l in libs :
80
89
if l .endswith (".a" ):
81
- ret .static .append (str (( configured / l ).resolve () ))
90
+ ret .static .append (( configured / l ).resolve ())
82
91
elif l .endswith (".so" ) or l .endswith (".tbd" ) or l .endswith (".dylib" ):
83
92
l = pathlib .Path (l ).stem
84
93
ret .shared .append (f"-l{ l [3 :]} " ) # drop 'lib' prefix and '.so' suffix
@@ -97,55 +106,6 @@ def get_tgt(tgt, filename):
97
106
return tgt .resolve ()
98
107
99
108
100
- def create_static_lib (tgt , libs ):
101
- tgt = get_tgt (tgt , f"lib{ EXPORTED_LIB } .a" )
102
- print (f"packaging { tgt .name } " )
103
- if sys .platform == 'linux' :
104
- includedlibs = "\n " .join (f"addlib { l } " for l in libs .archive + libs .static )
105
- mriscript = f"create { tgt } \n { includedlibs } \n save\n end"
106
- run (["ar" , "-M" ], cwd = tgt .parent , input = mriscript )
107
- else :
108
- libtool_args = ["libtool" , "-static" ]
109
- libtool_args .extend (libs .archive )
110
- libtool_args .extend (libs .static )
111
- libtool_args .append ("-o" )
112
- libtool_args .append (str (tgt ))
113
- run (libtool_args , cwd = tgt .parent )
114
- return tgt
115
-
116
-
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
109
def copy_includes (src , tgt ):
150
110
print ("copying includes" )
151
111
for dir , exts in (("include" , ("h" , "def" , "inc" )), ("stdlib" , ("h" ,))):
@@ -159,7 +119,7 @@ def copy_includes(src, tgt):
159
119
160
120
def export_sdk (tgt , swift_source_tree , swift_build_tree ):
161
121
print ("assembling sdk" )
162
- srcdir = swift_build_tree / "lib" / "swift"
122
+ srcdir = swift_build_tree / "lib" / "swift"
163
123
tgtdir = tgt / "usr" / "lib" / "swift"
164
124
if get_platform () == "linux" :
165
125
srcdir /= "linux"
@@ -181,11 +141,11 @@ def export_stdlibs(exported_dir, swift_build_tree):
181
141
ext = 'so'
182
142
lib_dir = swift_build_tree / 'lib/swift' / platform
183
143
stdlibs = [
184
- f'libswiftCore.{ ext } ' ,
185
- 'libswiftCompatibility50.a' ,
186
- 'libswiftCompatibility51.a' ,
187
- 'libswiftCompatibilityConcurrency.a' ,
188
- 'libswiftCompatibilityDynamicReplacements.a' ]
144
+ f'libswiftCore.{ ext } ' ,
145
+ 'libswiftCompatibility50.a' ,
146
+ 'libswiftCompatibility51.a' ,
147
+ 'libswiftCompatibilityConcurrency.a' ,
148
+ 'libswiftCompatibilityDynamicReplacements.a' ]
189
149
for stdlib in stdlibs :
190
150
lib_path = lib_dir / stdlib
191
151
if lib_path .exists ():
@@ -197,13 +157,10 @@ def export_stdlibs(exported_dir, swift_build_tree):
197
157
198
158
def export_libs (exported_dir , libs , swift_build_tree ):
199
159
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 )
160
+ # index libraries to preserve linking order
161
+ for i , lib in enumerate (libs .static ):
162
+ assert lib .name .startswith ("lib" )
163
+ shutil .copy (lib , exported_dir / f'lib{ i :03} { lib .name [3 :]} ' )
207
164
export_stdlibs (exported_dir , swift_build_tree )
208
165
209
166
@@ -213,7 +170,8 @@ def export_headers(exported_dir, swift_source_tree, llvm_build_tree, swift_build
213
170
llvm_source_tree = swift_source_tree .parent / 'llvm-project/llvm'
214
171
clang_source_tree = swift_source_tree .parent / 'llvm-project/clang'
215
172
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 ]
173
+ header_dirs = [llvm_source_tree , clang_source_tree , swift_source_tree , llvm_build_tree , swift_build_tree ,
174
+ clang_tools_build_tree ]
217
175
for h in header_dirs :
218
176
copy_includes (h , exported_dir )
219
177
@@ -230,18 +188,19 @@ def main(opts):
230
188
if os .path .exists (tmp ):
231
189
shutil .rmtree (tmp )
232
190
os .mkdir (tmp )
233
- configured = configure_dummy_project (tmp , llvm = opts .llvm_build_tree , swift = opts . swift_build_tree )
191
+ configured = configure_dummy_project (tmp , get_cmake_package_locations ( opts .build_tree ) )
234
192
libs = get_libs (configured )
235
193
236
194
exported = tmp / "exported"
237
195
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 )
196
+ llvm_build_tree = next (pathlib .Path (opts .build_tree ).glob ("llvm-*" ))
197
+ swift_build_tree = next (pathlib .Path (opts .build_tree ).glob ("swift-*" ))
198
+ export_libs (exported , libs , swift_build_tree )
199
+ export_headers (exported , opts .swift_source_tree , llvm_build_tree , swift_build_tree )
200
+ export_sdk (exported / "sdk" , opts .swift_source_tree , swift_build_tree )
241
201
242
202
zip_dir (exported , opts .output )
243
203
244
204
245
205
if __name__ == "__main__" :
246
206
main (getoptions ())
247
-
0 commit comments