Build for linux
C extension and glue files compiled without any issues, but I was not able to compile crystal code to dynamic library.
Samle file in question sample.cr
:
class CrystalModule
class SomeThing
def some_method
69.0
end
end
class CrystalClass
def crystal_method
return 42
end
def return_object
SomeThing.new
end
def recv_arg(arg : Int64) : Void
puts "Received #{arg}"
end
end
end
puts CrystalModule::CrystalClass.new.return_object.some_method
crystal build sample.cr --link-flags -shared
produces
/usr/bin/ld: /home/crystal/sample: version node not found for symbol *Slice(UInt8)@Slice(T)#initialize:read_only<Pointer(UInt8), (Int32 | UInt32 | UInt64), Bool>:Int32
/usr/bin/ld: failed to set dynamic section sizes: bad value
collect2: error: ld returned 1 exit status
The same for code with Anyolite, just the name of the symbol in error message is different
crystal build sample.cr -o sample --cross-compile --target "x86_64-unknown-linux-gnu"
# next command is the output from the first command + `-shared`
cc sample.o -o sample.so -rdynamic -L/usr/bin/../lib/crystal -lpcre -lm -lgc -lpthread -levent -lrt -lpthread -ldl -shared
It produces some *.so
file, but I’m not sure it is valid. Because, when I try to do the same with Anyolite code it fails
Entrypoint file (polycrystal_module.cr):
require "anyolite/anyolite"
require "sample"
FAKE_ARG = "polycrystal"
fun __polycrystal_init
GC.init
ptr = FAKE_ARG.to_unsafe
LibCrystalMain.__crystal_main(1, pointerof(ptr))
puts "Polycrystal init"
end
fun __polycrystal_module_run
puts "Polycrystal module run"
rbi = Anyolite::RbInterpreter.new
Anyolite::HelperClasses.load_all(rbi)
Anyolite.wrap rbi, CrystalModule
end
# compile
CRYSTAL_PATH=lib:/usr/bin/../share/crystal/src:/home/sample_project/build/deps:/home/sample_project/crystal ANYOLITE_LINK_GLUE="" crystal build /home/sample_project/build/polycrystal_module.cr -o /home/sample_project/build/polycrystal_module --release -Danyolite_implementation_ruby_3 -Duse_general_object_format_chars -Dexternal_ruby --cross-compile --target "x86_64-unknown-linux-gnu"
# link
cc /home/sample_project/build/polycrystal_module.o /home/ext/polycrystal/data_helper.o /home/ext/polycrystal/error_helper.o /home/ext/polycrystal/return_functions.o /home/ext/polycrystal/script_helper.o -o /home/sample_project/build/polycrystal_module -rdynamic -L/usr/bin/../lib/crystal -lpcre -lm -lgc -lpthread -levent -lrt -lpthread -ldl -lruby
Produces valid executable, it runs. But with -shared
it fails during linking with
/usr/bin/ld: /home/sample_project/build/polycrystal_module: version node not found for symbol ~proc9Proc(Int64, Pointer(Anyolite::RbCore::RbValue), Anyolite::RbCore::RbValue, Anyolite::RbCore::RbValue)@build/polycrystal_module.cr:17
/usr/bin/ld: failed to set dynamic section sizes: bad value
collect2: error: ld returned 1 exit status
I tried a lot of things, but I have no clues.
I thought, it requires ruby to be compiled with clang, but it shows the same error even when -lruby
is removed.
Google is not helpfull either. node(js), version, symbol, link is too frequently used elsewhere
Last random attempt, and seems like it works with
--link-flag "-shared -Wl,--version-script=#{mapfile}"
, where mapfile is
VERS_1.1 {
global:
*;
};