nitc :: AModule :: compile_foreign_lib
.so
fileReturns true
on success.
# Compile user FFI code and a standardized API into a `.so` file
#
# Returns `true` on success.
fun compile_foreign_lib(v: NaiveInterpreter): Bool
do
var mmodule = mmodule
assert mmodule != null
var compile_dir = v.compile_dir
var foreign_code_lib_path = v.foreign_code_lib_path(mmodule)
if not compile_dir.file_exists then compile_dir.mkdir(0o700)
# Compile the common FFI part
ensure_compile_ffi_wrapper
for mclassdef in mmodule.mclassdefs do for mpropdef in mclassdef.mpropdefs do
var anode = v.modelbuilder.mpropdef2node(mpropdef)
if mpropdef isa MMethodDef and anode isa AMethPropdef and anode.supported_by_dynamic_ffi then
anode.compile_ffi_method(mmodule)
end
end
mmodule.finalize_ffi_wrapper(compile_dir, mmodule)
# Compile the standard API and its implementation for the .so file
var ccu = compile_foreign_lib_api(compile_dir)
var srcs = [for file in ccu.files do new ExternCFile(file, ""): ExternFile]
srcs.add_all mmodule.ffi_files
# Compiler options specific to this module
var ldflags_array = mmodule.ldflags[""]
if ldflags_array.has("-lrt") and system("sh -c 'uname -s 2>/dev/null || echo not' | grep Darwin >/dev/null") == 0 then
# Remove -lrt on OS X
ldflags_array.remove "-lrt"
end
var ldflags = ldflags_array.join(" ")
# Protect pkg-config
var pkgconfigs = mmodule.pkgconfigs
var pkg_cflags = ""
if not pkgconfigs.is_empty then
# Check if the pkgconfig packages are available
v.modelbuilder.toolcontext.check_pkgconfig_packages pkgconfigs
if not v.modelbuilder.toolcontext.check_errors then return false
pkg_cflags = "`pkg-config --cflags {pkgconfigs.join(" ")}`"
ldflags += " `pkg-config --libs {pkgconfigs.join(" ")}`"
end
# Compile each source file to an object file (or equivalent)
var object_files = new Array[String]
for f in srcs do
f.compile(v, mmodule, object_files, pkg_cflags)
end
# Link everything in a shared library
var cmd = "{v.c_compiler} -Wall -shared -o {foreign_code_lib_path} {object_files.join(" ")} {ldflags}"
if system(cmd) != 0 then
v.fatal "FFI Error: Failed to link native code using `{cmd}`"
return false
end
return true
end
src/interpreter/dynamic_loading_ffi/on_demand_compiler.nit:100,2--164,4