-
-
Save godfat/548caf0d63f647c0fbe2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def compile_object(path, output) | |
base = File.basename(path, '.rb') | |
output ||= File.join(File.dirname(path), base + '.o') | |
# Generate init function (must be unique). | |
uuid = `uuidgen`.strip.gsub('-', '') | |
init_func = "MREP_#{uuid}" | |
tmp_objs = [] | |
@archs.each do |arch| | |
# Compile the file into LLVM bitcode. | |
bc = gen_tmpfile(base + arch, 'bc') | |
execute("arch -#{arch} #{@macruby} --emit-llvm \"#{bc}\" #{init_func} \"#{path}\"") | |
# Compile the bitcode as assembly. | |
asm = gen_tmpfile(base + arch, 's') | |
execute("#{@llc} -f \"#{bc}\" -o=\"#{asm}\" -march=#{llc_arch(arch)} -relocation-model=pic -enable-eh") | |
# Compile the assembly. | |
tmp_obj = gen_tmpfile(base + arch, 'o') | |
execute("#{@gcc} -c -arch #{arch} \"#{asm}\" -o \"#{tmp_obj}\"") | |
tmp_objs << tmp_obj | |
end | |
# Link the architecture objects. | |
cli_tmp_objs = tmp_objs.map do |obj| | |
'"' + obj + '"' | |
end | |
execute("#{@lipo} -create #{cli_tmp_objs.join(' ')} -output \"#{output}\"") | |
[output, init_func] | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def compile_executable(objs_data, output) | |
output ||= 'a.out' | |
raise if objs_data.empty? | |
die "first object file must be a Ruby source file or object" if objs_data[0][1] == nil | |
# Generate main file. | |
main_txt = <<EOS | |
extern "C" { | |
void ruby_sysinit(int *, char ***); | |
void ruby_init(void); | |
void ruby_init_loadpath(void); | |
void ruby_script(const char *); | |
void ruby_set_argv(int, char **); | |
void rb_vm_init_compiler(void); | |
void rb_vm_aot_feature_provide(const char *, void *); | |
void *rb_vm_top_self(void); | |
void rb_vm_print_current_exception(void); | |
void rb_exit(int); | |
EOS | |
objs_data.each do |obj, init_func| | |
next if init_func == nil | |
main_txt << "void *#{init_func}(void *, void *);\n" | |
end | |
main_txt << <<EOS | |
} | |
int main(int argc, char **argv) | |
{ | |
const char *progname = argv[0]; | |
ruby_sysinit(&argc, &argv); | |
if (argc > 0) { | |
argc--; | |
argv++; | |
} | |
ruby_init(); | |
ruby_init_loadpath(); | |
ruby_set_argv(argc, argv); | |
rb_vm_init_compiler(); | |
ruby_script(progname); | |
try { | |
EOS | |
objs_data[1..-1].each do |obj, init_func| | |
next if init_func == nil | |
main_txt << "rb_vm_aot_feature_provide(\"#{feature_name(obj)}\", (void *)#{init_func});\n" | |
end | |
main_txt << <<EOS | |
void *self = rb_vm_top_self(); | |
#{objs_data[0][1]}(self, 0); | |
} | |
catch (...) { | |
rb_vm_print_current_exception(); | |
rb_exit(1); | |
} | |
rb_exit(0); | |
} | |
EOS | |
# Prepare objects. | |
objs = [] | |
objs_data.each { |o, _| objs << o } | |
# Compile main file. | |
main = gen_tmpfile('main', 'mm') | |
File.open(main, 'w') { |io| io.write(main_txt) } | |
main_o = gen_tmpfile('main', 'o') | |
execute("#{@gcxx} \"#{main}\" -c #{arch_flags} -o \"#{main_o}\" -fobjc-gc") | |
objs.unshift(main_o) | |
# Link all objects into executable. | |
linkf = @static ? | |
"-L#{RbConfig::CONFIG['libdir']} #{RbConfig::CONFIG['LIBRUBYARG_STATIC_REALLY']}" : | |
"-framework MacRuby -lobjc" | |
line = "#{@gcxx} -o \"#{output}\" #{arch_flags} #{linkf} " | |
objs.each { |o| line << " \"#{o}\"" } | |
execute(line) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment