1414
1515def getoptions ():
1616 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" )
2119 parser .add_argument (f"--swift-source-tree" , required = True , type = resolve ,
2220 metavar = "DIR" , help = f"path to Swift source tree" )
2321
@@ -34,9 +32,9 @@ def getoptions():
3432 return opts
3533
3634
37- Libs = namedtuple ( "Libs " , ( "archive " , "static " , "shared" , "linker_flags" ))
35+ REQUIRED_CMAKE_PACKAGES = [ "LLVM " , "Clang " , "Swift " , "SwiftSyntax" ]
3836
39- EXPORTED_LIB = "CodeQLSwiftFrontendTool"
37+ Libs = namedtuple ( "Libs" , ( "static" , "shared" , "linker_flags" ))
4038
4139
4240def resolve (p ):
@@ -50,35 +48,46 @@ def run(prog, *, cwd, env=None, input=None):
5048 runenv .update (env )
5149 else :
5250 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+ }
5460
5561
5662def get_platform ():
5763 return "linux" if platform .system () == "Linux" else "macos"
5864
5965
60- def configure_dummy_project (tmp , * , llvm = None , swift = None ):
66+ def configure_dummy_project (tmp , package_locations ):
6167 print ("configuring dummy cmake project" )
6268 script_dir = pathlib .Path (os .path .realpath (__file__ )).parent
6369 print (script_dir )
6470 shutil .copy (script_dir / "CMakeLists.txt" , tmp / "CMakeLists.txt" )
6571 shutil .copy (script_dir / "empty.cpp" , tmp / "empty.cpp" )
6672 tgt = tmp / "build"
6773 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 )
7079 return tgt
7180
7281
7382def get_libs (configured ):
7483 print ("extracting linking information from dummy project" )
7584 with open (configured / "CMakeFiles" / "codeql-swift-artifacts.dir" / "link.txt" ) as link :
7685 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 ([], [], [])
7988 for l in libs :
8089 if l .endswith (".a" ):
81- ret .static .append (str (( configured / l ).resolve () ))
90+ ret .static .append (( configured / l ).resolve ())
8291 elif l .endswith (".so" ) or l .endswith (".tbd" ) or l .endswith (".dylib" ):
8392 l = pathlib .Path (l ).stem
8493 ret .shared .append (f"-l{ l [3 :]} " ) # drop 'lib' prefix and '.so' suffix
@@ -97,55 +106,6 @@ def get_tgt(tgt, filename):
97106 return tgt .resolve ()
98107
99108
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-
149109def copy_includes (src , tgt ):
150110 print ("copying includes" )
151111 for dir , exts in (("include" , ("h" , "def" , "inc" )), ("stdlib" , ("h" ,))):
@@ -159,7 +119,7 @@ def copy_includes(src, tgt):
159119
160120def export_sdk (tgt , swift_source_tree , swift_build_tree ):
161121 print ("assembling sdk" )
162- srcdir = swift_build_tree / "lib" / "swift"
122+ srcdir = swift_build_tree / "lib" / "swift"
163123 tgtdir = tgt / "usr" / "lib" / "swift"
164124 if get_platform () == "linux" :
165125 srcdir /= "linux"
@@ -181,11 +141,11 @@ def export_stdlibs(exported_dir, swift_build_tree):
181141 ext = 'so'
182142 lib_dir = swift_build_tree / 'lib/swift' / platform
183143 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' ]
189149 for stdlib in stdlibs :
190150 lib_path = lib_dir / stdlib
191151 if lib_path .exists ():
@@ -197,13 +157,10 @@ def export_stdlibs(exported_dir, swift_build_tree):
197157
198158def export_libs (exported_dir , libs , swift_build_tree ):
199159 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 :]} ' )
207164 export_stdlibs (exported_dir , swift_build_tree )
208165
209166
@@ -213,7 +170,8 @@ def export_headers(exported_dir, swift_source_tree, llvm_build_tree, swift_build
213170 llvm_source_tree = swift_source_tree .parent / 'llvm-project/llvm'
214171 clang_source_tree = swift_source_tree .parent / 'llvm-project/clang'
215172 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 ]
217175 for h in header_dirs :
218176 copy_includes (h , exported_dir )
219177
@@ -230,18 +188,19 @@ def main(opts):
230188 if os .path .exists (tmp ):
231189 shutil .rmtree (tmp )
232190 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 ) )
234192 libs = get_libs (configured )
235193
236194 exported = tmp / "exported"
237195 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 )
241201
242202 zip_dir (exported , opts .output )
243203
244204
245205if __name__ == "__main__" :
246206 main (getoptions ())
247-
0 commit comments