@@ -106,7 +106,7 @@ function compile(f, _tt, path::String = tempname();
106106 rt = last (only (native_code_typed (f, tt, mixtape = mixtape)))
107107 isconcretetype (rt) || error (" $f on $_tt did not infer to a concrete type. Got $rt " )
108108 f_wrap! (out:: Ref , args:: Ref{<:Tuple} ) = (out[] = f (args[]. .. ); nothing )
109- _, _, table = generate_obj (f_wrap!, Tuple{RefValue{rt}, RefValue{tt}}, false , path, name; mixtape = mixtape, opt_level, strip_llvm, strip_asm, filename, kwargs... )
109+ _, _, table = generate_obj_for_compile (f_wrap!, Tuple{RefValue{rt}, RefValue{tt}}, false , path, name; mixtape = mixtape, opt_level, strip_llvm, strip_asm, filename, kwargs... )
110110
111111 lf = LazyStaticCompiledFunction {rt, tt} (Symbol (f), path, name, filename, table)
112112 cjl_path = joinpath (path, " $filename .cjl" )
117117
118118"""
119119```julia
120- generate_obj (f, tt, path::String = tempname(), name = fix_name(repr(f)), filenamebase::String="obj";
120+ generate_obj_for_compile (f, tt, path::String = tempname(), name = fix_name(repr(f)), filenamebase::String="obj";
121121 \t mixtape = NoContext(),
122122 \t strip_llvm = false,
123123 \t strip_asm = true,
@@ -141,7 +141,7 @@ The defaults compile to the native target.
141141julia> fib(n) = n <= 1 ? n : fib(n - 1) + fib(n - 2)
142142fib (generic function with 1 method)
143143
144- julia> path, name, table = StaticCompiler.generate_obj (fib, Tuple{Int64}, "./test")
144+ julia> path, name, table = StaticCompiler.generate_obj_for_compile (fib, Tuple{Int64}, "./test")
145145("./test", "fib", IdDict{Any, String}())
146146
147147shell> tree \$ path
@@ -151,7 +151,7 @@ shell> tree \$path
1511510 directories, 1 file
152152```
153153"""
154- function generate_obj (f, tt, external = true , path:: String = tempname (), name = fix_name (repr (f)), filenamebase:: String = " obj" ;
154+ function generate_obj_for_compile (f, tt, external = true , path:: String = tempname (), name = fix_name (repr (f)), filenamebase:: String = " obj" ;
155155 mixtape = NoContext (),
156156 strip_llvm = false ,
157157 strip_asm = true ,
@@ -200,10 +200,13 @@ end
200200compile_executable(f::Function, types::Tuple, path::String, [name::String=repr(f)];
201201 filename::String=name,
202202 cflags=``, # Specify libraries you would like to link against, and other compiler options here
203+ also_expose=[],
203204 kwargs...
204205)
205206```
206207Attempt to compile a standalone executable that runs function `f` with a type signature given by the tuple of `types`.
208+ If there are extra methods you would like to protect from name mangling in the produced binary for whatever reason,
209+ you can provide them as a vector of tuples of functions and types, i.e. `[(f1, types1), (f2, types2), ...]`
207210
208211### Examples
209212```julia
@@ -261,11 +264,21 @@ Hello, world!
261264```
262265"""
263266function compile_executable (f:: Function , types= (), path:: String = " ./" , name= fix_name (repr (f));
267+ also_expose= [],
268+ filename= name,
269+ cflags= ` ` ,
270+ kwargs... )
271+ compile_executable (vcat ([(f, types)], also_expose), path, name; filename, cflags, kwargs... )
272+ end
273+
274+
275+ function compile_executable (funcs:: Array , path:: String = " ./" , name= fix_name (repr (funcs[1 ][1 ]));
264276 filename= name,
265277 cflags= ` ` ,
266278 kwargs...
267279 )
268280
281+ (f, types) = funcs[1 ]
269282 tt = Base. to_tuple_type (types)
270283 isexecutableargtype = tt == Tuple{} || tt == Tuple{Int, Ptr{Ptr{UInt8}}}
271284 isexecutableargtype || @warn " input type signature $types should be either `()` or `(Int, Ptr{Ptr{UInt8}})` for standard executables"
@@ -274,13 +287,11 @@ function compile_executable(f::Function, types=(), path::String="./", name=fix_n
274287 isconcretetype (rt) || error (" `$f$types ` did not infer to a concrete type. Got `$rt `" )
275288 nativetype = isprimitivetype (rt) || isa (rt, Ptr)
276289 nativetype || @warn " Return type `$rt ` of `$f$types ` does not appear to be a native type. Consider returning only a single value of a native machine type (i.e., a single float, int/uint, bool, or pointer). \n\n Ignoring this warning may result in Undefined Behavior!"
277-
278- generate_executable (f, tt, path, name, filename; cflags= cflags, kwargs... )
279-
290+
291+ generate_executable (funcs, path, name, filename; cflags= cflags, kwargs... )
280292 joinpath (abspath (path), filename)
281293end
282294
283-
284295"""
285296```julia
286297compile_shlib(f::Function, types::Tuple, [path::String="./"], [name::String=repr(f)]; filename::String=name, cflags=``, kwargs...)
@@ -377,7 +388,7 @@ function compile_wasm(f::Function, types=();
377388 kwargs...
378389 )
379390 tt = Base. to_tuple_type (types)
380- obj_path, name = generate_obj (f, tt, true , path, filename; target = (triple = " wasm32-unknown-wasi" , cpu = " " , features = " " ), remove_julia_addrspaces = true , kwargs... )
391+ obj_path, name = generate_obj_for_compile (f, tt, true , path, filename; target = (triple = " wasm32-unknown-wasi" , cpu = " " , features = " " ), remove_julia_addrspaces = true , kwargs... )
381392 run (` $(lld ()) -flavor wasm --no-entry --export-all $flags $obj_path /obj.o -o $path /$name .wasm` )
382393 joinpath (abspath (path), filename * " .wasm" )
383394end
@@ -471,21 +482,19 @@ shell> ./hello
471482Hello, world!
472483```
473484"""
474- function generate_executable (f, tt, path= tempname (), name= fix_name (repr (f)), filename= string (name);
475- cflags= ` ` ,
476- kwargs...
477- )
478- mkpath (path)
479- obj_path = joinpath (path, " $filename .o" )
480- exec_path = joinpath (path, filename)
481- job, kwargs = native_job (f, tt, true ; name, kwargs... )
482- obj, _ = GPUCompiler. codegen (:obj , job; strip= true , only_entry= false , validate= false )
483-
484- # Write to file
485- open (obj_path, " w" ) do io
486- write (io, obj)
487- end
485+ function generate_executable (f, tt, args... ; kwargs... )
486+ generate_executable ([(f, tt)], args... ; kwargs... )
487+ end
488488
489+ function generate_executable (funcs:: Array , path= tempname (), name= fix_name (repr (funcs[1 ][1 ])), filename= string (name);
490+ demangle= false ,
491+ cflags= ` ` ,
492+ kwargs...
493+ )
494+ lib_path = joinpath (path, " $filename .$(Libdl. dlext) " )
495+ exec_path = joinpath (path, filename)
496+ external = true
497+ _, obj_path = generate_obj (funcs, external, path, filename; demangle= demangle, kwargs... )
489498 # Pick a compiler
490499 cc = Sys. isapple () ? ` cc` : clang ()
491500 # Compile!
@@ -510,10 +519,10 @@ function generate_executable(f, tt, path=tempname(), name=fix_name(repr(f)), fil
510519 # Clean up
511520 run (` rm $wrapper_path ` )
512521 end
513-
514522 path, name
515523end
516524
525+
517526"""
518527```julia
519528generate_shlib(f::Function, tt, [external::Bool=true], [path::String], [name], [filename]; kwargs...)
@@ -553,23 +562,15 @@ julia> ccall(("julia_test", "example/test.dylib"), Float64, (Int64,), 100_000)
553562```
554563"""
555564function generate_shlib (f:: Function , tt, external:: Bool = true , path:: String = tempname (), name= fix_name (repr (f)), filename= name;
556- cflags= ` ` ,
565+ cflags= ` ` , demangle = false ,
557566 kwargs...
558567 )
559-
560- mkpath (path)
561- obj_path = joinpath (path, " $filename .o" )
562568 lib_path = joinpath (path, " $filename .$(Libdl. dlext) " )
563- job, kwargs = native_job (f, tt, external; name, kwargs... )
564- obj, _ = GPUCompiler. codegen (:obj , job; strip= true , only_entry= false , validate= false )
565-
566- open (obj_path, " w" ) do io
567- write (io, obj)
568- end
569-
569+ _, obj_path = generate_obj ([(f, tt)], external, path, filename; demangle= demangle, kwargs... )
570+
570571 # Pick a Clang
571572 cc = Sys. isapple () ? ` cc` : clang ()
572- # Compile!
573+ # Compile
573574 run (` $cc -shared $cflags $obj_path -o $lib_path ` )
574575
575576 path, name
@@ -583,7 +584,7 @@ function generate_shlib(funcs::Array, external::Bool=true, path::String=tempname
583584
584585 lib_path = joinpath (path, " $filename .$(Libdl. dlext) " )
585586
586- _,obj_path = generate_obj (funcs, external, path, filename; demangle= demangle, kwargs... )
587+ _, obj_path = generate_obj (funcs, external, path, filename; demangle= demangle, kwargs... )
587588 # Pick a Clang
588589 cc = Sys. isapple () ? ` cc` : clang ()
589590 # Compile!
@@ -642,6 +643,71 @@ function native_llvm_module(funcs::Array; demangle = false, kwargs...)
642643 return mod
643644end
644645
646+
647+ """
648+ ```julia
649+ generate_obj(f, tt, external::Bool, path::String = tempname(), filenamebase::String="obj";
650+ mixtape = NoContext(),
651+ target = (),
652+ demangle =false,
653+ strip_llvm = false,
654+ strip_asm = true,
655+ opt_level=3,
656+ kwargs...)
657+ ```
658+ Low level interface for compiling object code (`.o`) for for function `f` given
659+ a tuple type `tt` characterizing the types of the arguments for which the
660+ function will be compiled.
661+
662+ `mixtape` defines a context that can be used to transform IR prior to compilation using
663+ [Mixtape](https://github.com/JuliaCompilerPlugins/Mixtape.jl) features.
664+
665+ `target` can be used to change the output target. This is useful for compiling to WebAssembly and embedded targets.
666+ This is a named tuple with fields `triple`, `cpu`, and `features` (each of these are strings).
667+ The defaults compile to the native target.
668+
669+ ### Examples
670+ ```julia
671+ julia> fib(n) = n <= 1 ? n : fib(n - 1) + fib(n - 2)
672+ fib (generic function with 1 method)
673+
674+ julia> path, name, table = StaticCompiler.generate_obj_for_compile(fib, Tuple{Int64}, "./test")
675+ ("./test", "fib", IdDict{Any, String}())
676+
677+ shell> tree \$ path
678+ ./test
679+ └── obj.o
680+
681+ 0 directories, 1 file
682+ ```
683+ """
684+ function generate_obj (f, tt, args... ; kwargs... )
685+ generate_obj ([(f, tt)], args... ; kwargs... )
686+ end
687+
688+
689+ """
690+ ```julia
691+ generate_obj(funcs::Array, external::Bool, path::String = tempname(), filenamebase::String="obj";
692+ mixtape = NoContext(),
693+ target = (),
694+ demangle =false,
695+ strip_llvm = false,
696+ strip_asm = true,
697+ opt_level=3,
698+ kwargs...)
699+ ```
700+ Low level interface for compiling object code (`.o`) for an array of Tuples
701+ (f, tt) where each function `f` and tuple type `tt` determine the set of methods
702+ which will be compiled.
703+
704+ `mixtape` defines a context that can be used to transform IR prior to compilation using
705+ [Mixtape](https://github.com/JuliaCompilerPlugins/Mixtape.jl) features.
706+
707+ `target` can be used to change the output target. This is useful for compiling to WebAssembly and embedded targets.
708+ This is a named tuple with fields `triple`, `cpu`, and `features` (each of these are strings).
709+ The defaults compile to the native target.
710+ """
645711function generate_obj (funcs:: Array , external:: Bool , path:: String = tempname (), filenamebase:: String = " obj" ;
646712 demangle = false ,
647713 strip_llvm = false ,
0 commit comments