2
2
# # 1. gcc / x86_64-w64-mingw32-gcc is available and is in path
3
3
# # 2. Package ArgParse is installed
4
4
5
+ # TODO : remove once Julia v0.7 is released
6
+ julia_v07 = VERSION > v " 0.7-"
7
+
5
8
using ArgParse
9
+ julia_v07 && using Libdl
6
10
7
11
function main (args)
8
12
9
- s = ArgParseSettings (" Julia AOT compiler" *
10
- " \n\n helper script to build libraries and executables from Julia code" ,
11
- version = " $(basename (@__FILE__ )) version 0.6" ,
13
+ s = ArgParseSettings (" Static Julia Compiler" ,
14
+ version = " $(basename (@__FILE__ )) version 0.7-DEV" ,
12
15
add_version = true )
13
16
14
17
@add_arg_table s begin
@@ -19,7 +22,7 @@ function main(args)
19
22
" cprog"
20
23
arg_type = String
21
24
default = nothing
22
- help = " C program to compile (required only when building an executable; if not provided a minimal standard program is used)"
25
+ help = " C program to compile (required only when building an executable; if not provided a minimal driver program is used)"
23
26
" builddir"
24
27
arg_type = String
25
28
default = " builddir"
@@ -86,7 +89,7 @@ function main(args)
86
89
metavar = " {yes|no|error}"
87
90
range_tester = (x -> x == " yes" || x == " no" || x == " error" )
88
91
help = " set syntax and method deprecation warnings"
89
- " --auto " , " -a"
92
+ " --autodeps " , " -a"
90
93
action = :store_true
91
94
help = " automatically build required dependencies"
92
95
" --object" , " -o"
@@ -105,15 +108,16 @@ function main(args)
105
108
106
109
s. epilog = """
107
110
examples:\n
108
- \u a0\u a0juliac.jl -vae hello.jl # verbose, auto, build executable\n
109
- \u a0\u a0juliac.jl -vae hello.jl myprog .c # embed into user defined C program\n
110
- \u a0\u a0juliac.jl -qo hello.jl # quiet, build object file only\n
111
- \u a0\u a0juliac.jl -vosej hello.jl # build all and sync Julia libs\n
111
+ \u a0\u a0juliac.jl -vae hello.jl # verbose, build executable and deps \n
112
+ \u a0\u a0juliac.jl -vae hello.jl prog .c # embed into user defined C program\n
113
+ \u a0\u a0juliac.jl -qo hello.jl # quiet, build object file only\n
114
+ \u a0\u a0juliac.jl -vosej hello.jl # build all and sync Julia libs\n
112
115
"""
113
116
114
117
parsed_args = parse_args (args, s)
115
118
116
- if ! any ([parsed_args[" clean" ], parsed_args[" object" ], parsed_args[" shared" ], parsed_args[" executable" ], parsed_args[" julialibs" ]])
119
+ # TODO : in future it may be possible to broadcast dictionary indexing, see: https://discourse.julialang.org/t/accessing-multiple-values-of-a-dictionary/8648
120
+ if ! any (getindex .(parsed_args, [" clean" , " object" , " shared" , " executable" , " julialibs" ]))
117
121
parsed_args[" quiet" ] || println (" Nothing to do, exiting\n Try \" $(basename (@__FILE__ )) -h\" for more information" )
118
122
exit (0 )
119
123
end
@@ -134,7 +138,7 @@ function main(args)
134
138
parsed_args[" check-bounds" ],
135
139
parsed_args[" math-mode" ],
136
140
parsed_args[" depwarn" ],
137
- parsed_args[" auto " ],
141
+ parsed_args[" autodeps " ],
138
142
parsed_args[" object" ],
139
143
parsed_args[" shared" ],
140
144
parsed_args[" executable" ],
@@ -145,11 +149,11 @@ end
145
149
function julia_compile (julia_program, c_program= nothing , build_dir= " builddir" , verbose= false , quiet= false ,
146
150
clean= false , sysimage = nothing , compile= nothing , cpu_target= nothing , optimize= nothing ,
147
151
debug= nothing , inline= nothing , check_bounds= nothing , math_mode= nothing , depwarn= nothing ,
148
- auto = false , object= false , shared= false , executable= true , julialibs= true )
152
+ autodeps = false , object= false , shared= false , executable= true , julialibs= true )
149
153
150
- verbose && quiet && (verbose = false )
154
+ verbose && quiet && (quiet = false )
151
155
152
- if auto
156
+ if autodeps
153
157
executable && (shared = true )
154
158
shared && (object = true )
155
159
end
@@ -193,12 +197,21 @@ function julia_compile(julia_program, c_program=nothing, build_dir="builddir", v
193
197
julia_program_basename = splitext (basename (julia_program))[1 ]
194
198
o_file = julia_program_basename * " .o"
195
199
s_file = " lib" * julia_program_basename * " .$(Libdl. dlext) "
196
- e_file = julia_program_basename * (is_windows () ? " .exe" : " " )
200
+ if julia_v07
201
+ e_file = julia_program_basename * (Sys. iswindows () ? " .exe" : " " )
202
+ else
203
+ e_file = julia_program_basename * (is_windows () ? " .exe" : " " )
204
+ end
197
205
tmp_dir = " tmp_v$VERSION "
198
206
199
207
# TODO : these should probably be emitted from julia-config also:
200
- shlibdir = is_windows () ? JULIA_HOME : abspath (JULIA_HOME, Base. LIBDIR)
201
- private_shlibdir = abspath (JULIA_HOME, Base. PRIVATE_LIBDIR)
208
+ if julia_v07
209
+ shlibdir = Sys. iswindows () ? Sys. BINDIR : abspath (Sys. BINDIR, Base. LIBDIR)
210
+ private_shlibdir = abspath (Sys. BINDIR, Base. PRIVATE_LIBDIR)
211
+ else
212
+ shlibdir = is_windows () ? JULIA_HOME : abspath (JULIA_HOME, Base. LIBDIR)
213
+ private_shlibdir = abspath (JULIA_HOME, Base. PRIVATE_LIBDIR)
214
+ end
202
215
203
216
if object
204
217
julia_cmd = ` $(Base. julia_cmd ()) `
@@ -215,66 +228,111 @@ function julia_compile(julia_program, c_program=nothing, build_dir="builddir", v
215
228
check_bounds == nothing || push! (julia_cmd. exec, " --check-bounds=$check_bounds " )
216
229
math_mode == nothing || push! (julia_cmd. exec, " --math-mode=$math_mode " )
217
230
depwarn == nothing || (julia_cmd. exec[5 ] = " --depwarn=$depwarn " )
218
- is_windows () && (julia_program = replace (julia_program, " \\ " , " \\\\ " ))
219
- expr = "
220
- VERSION >= v\" 0.7+\" && Base.init_load_path($(repr (JULIA_HOME)) ) # initialize location of site-packages
231
+ if julia_v07
232
+ Sys. iswindows () && (julia_program = replace (julia_program, " \\ " , " \\\\ " ))
233
+ expr = "
234
+ Base.init_depot_path() # initialize package depots
235
+ Base.init_load_path() # initialize location of site-packages
221
236
empty!(Base.LOAD_CACHE_PATH) # reset / remove any builtin paths
222
237
push!(Base.LOAD_CACHE_PATH, abspath(\" $tmp_dir \" )) # enable usage of precompiled files
223
- include($( repr ( julia_program)) ) # include \" julia_program\" file
238
+ include(\" $ julia_program\" ) # include \" julia_program\" file
224
239
empty!(Base.LOAD_CACHE_PATH) # reset / remove build-system-relative paths"
240
+ else
241
+ is_windows () && (julia_program = replace (julia_program, " \\ " , " \\\\ " ))
242
+ expr = "
243
+ empty!(Base.LOAD_CACHE_PATH) # reset / remove any builtin paths
244
+ push!(Base.LOAD_CACHE_PATH, abspath(\" $tmp_dir \" )) # enable usage of precompiled files
245
+ include(\" $julia_program \" ) # include \" julia_program\" file
246
+ empty!(Base.LOAD_CACHE_PATH) # reset / remove build-system-relative paths"
247
+ end
248
+ isdir (tmp_dir) || mkpath (tmp_dir)
225
249
command = ` $julia_cmd -e $expr `
226
- verbose && println (" Build \" .ji\" files :\n $command " )
250
+ verbose && println (" Build module image files \" .ji\" in subdirectory \" $tmp_dir \" :\n $command " )
227
251
run (command)
228
252
command = ` $julia_cmd --output-o $(joinpath (tmp_dir, o_file)) -e $expr `
229
- verbose && println (" Build object file \" $o_file \" :\n $command " )
253
+ verbose && println (" Build object file \" $o_file \" in subdirectory \" $tmp_dir \" :\n $command " )
230
254
run (command)
231
255
end
232
256
233
257
if shared || executable
234
- command = ` $(Base. julia_cmd ()) --startup-file=no $(joinpath (dirname (JULIA_HOME), " share" , " julia" , " julia-config.jl" )) `
235
- cflags = Base. shell_split (readstring (` $command --cflags` ))
236
- ldflags = Base. shell_split (readstring (` $command --ldflags` ))
237
- ldlibs = Base. shell_split (readstring (` $command --ldlibs` ))
238
- cc = is_windows () ? " x86_64-w64-mingw32-gcc" : " gcc"
258
+ if julia_v07
259
+ cc = Sys. iswindows () ? " x86_64-w64-mingw32-gcc" : " gcc"
260
+ command = ` $(Base. julia_cmd ()) --startup-file=no $(joinpath (dirname (Sys. BINDIR), " share" , " julia" , " julia-config.jl" )) `
261
+ flags = ` $(Base. shell_split (read (\ ` $command --allflags\` , String)))`
262
+ else
263
+ cc = is_windows () ? " x86_64-w64-mingw32-gcc" : " gcc"
264
+ command = ` $(Base. julia_cmd ()) --startup-file=no $(joinpath (dirname (JULIA_HOME), " share" , " julia" , " julia-config.jl" )) `
265
+ cflags = ` $(Base. shell_split (readstring (\ ` $command --cflags\` )))`
266
+ ldflags = ` $(Base. shell_split (readstring (\ ` $command --ldflags\` )))`
267
+ ldlibs = ` $(Base. shell_split (readstring (\ ` $command --ldlibs\` )))`
268
+ flags = ` $cflags $ldflags $ldlibs `
269
+ end
239
270
end
240
271
241
272
if shared
242
- command = ` $cc -m64 -shared -o $s_file $(joinpath (tmp_dir, o_file)) $cflags $ldflags $ldlibs `
243
- if is_apple ()
244
- command = ` $command -Wl,-install_name,@rpath/lib$julia_program_basename .dylib`
245
- elseif is_windows ()
246
- command = ` $command -Wl,--export-all-symbols`
273
+ command = ` $cc -m64 -shared -o $s_file $(joinpath (tmp_dir, o_file)) $flags `
274
+ if julia_v07
275
+ if Sys. isapple ()
276
+ command = ` $command -Wl,-install_name,@rpath/\" $s_file \" `
277
+ elseif Sys. iswindows ()
278
+ command = ` $command -Wl,--export-all-symbols`
279
+ end
280
+ else
281
+ if is_apple ()
282
+ command = ` $command -Wl,-install_name,@rpath/\" $s_file \" `
283
+ elseif is_windows ()
284
+ command = ` $command -Wl,--export-all-symbols`
285
+ end
247
286
end
248
- verbose && println (" Build shared library \" $s_file \" :\n $command " )
287
+ verbose && println (" Build shared library \" $s_file \" in build directory :\n $command " )
249
288
run (command)
250
289
end
251
290
252
291
if executable
253
- push! (cflags, " -DJULIAC_PROGRAM_LIBNAME=\" lib$julia_program_basename \" " )
254
- command = ` $cc -m64 -o $e_file $c_program $s_file $cflags $ldflags $ldlibs `
255
- if is_apple ()
256
- command = ` $command -Wl,-rpath,@executable_path`
257
- elseif is_unix ()
258
- command = ` $command -Wl,-rpath,\$ ORIGIN`
292
+ command = ` $cc -m64 -DJULIAC_PROGRAM_LIBNAME=\" lib$julia_program_basename \" -o $e_file $c_program $s_file $flags `
293
+ if julia_v07
294
+ if Sys. isapple ()
295
+ command = ` $command -Wl,-rpath,@executable_path`
296
+ elseif Sys. isunix ()
297
+ command = ` $command -Wl,-rpath,\$ ORIGIN`
298
+ end
299
+ else
300
+ if is_apple ()
301
+ command = ` $command -Wl,-rpath,@executable_path`
302
+ elseif is_unix ()
303
+ command = ` $command -Wl,-rpath,\$ ORIGIN`
304
+ end
259
305
end
260
- verbose && println (" Build executable file \" $e_file \" :\n $command " )
306
+ verbose && println (" Build executable file \" $e_file \" in build directory :\n $command " )
261
307
run (command)
262
308
end
263
309
264
310
if julialibs
265
- verbose && println (" Sync Julia libraries:" )
311
+ verbose && println (" Sync Julia libraries to build directory :" )
266
312
libfiles = String[]
267
313
dlext = " ." * Libdl. dlext
268
314
for dir in (shlibdir, private_shlibdir)
269
- if is_windows () || is_apple ()
270
- append! (libfiles, joinpath .(dir, filter (x -> endswith (x, dlext), readdir (dir))))
315
+ if julia_v07
316
+ if Sys. iswindows () || Sys. isapple ()
317
+ append! (libfiles, joinpath .(dir, filter (x -> endswith (x, dlext), readdir (dir))))
318
+ else
319
+ append! (libfiles, joinpath .(dir, filter (x -> contains (x, r" ^lib.+\. so(?:\.\d +)*$" ), readdir (dir))))
320
+ end
271
321
else
272
- append! (libfiles, joinpath .(dir, filter (x -> ismatch (r" ^lib.+\. so(?:\.\d +)*$" , x), readdir (dir))))
322
+ if is_windows () || is_apple ()
323
+ append! (libfiles, joinpath .(dir, filter (x -> endswith (x, dlext), readdir (dir))))
324
+ else
325
+ append! (libfiles, joinpath .(dir, filter (x -> ismatch (r" ^lib.+\. so(?:\.\d +)*$" , x), readdir (dir))))
326
+ end
273
327
end
274
328
end
275
329
sync = false
276
330
for src in libfiles
277
- ismatch (r" debug" , src) && continue
331
+ if julia_v07
332
+ contains (src, r" debug" ) && continue
333
+ else
334
+ ismatch (r" debug" , src) && continue
335
+ end
278
336
dst = basename (src)
279
337
if filesize (src) != filesize (dst) || ctime (src) > ctime (dst) || mtime (src) > mtime (dst)
280
338
verbose && println (" $dst " )
0 commit comments