[macruby-changes] [2796] MacRuby/trunk/bin/rubyc

source_changes at macosforge.org source_changes at macosforge.org
Wed Oct 14 15:32:34 PDT 2009


Revision: 2796
          http://trac.macosforge.org/projects/ruby/changeset/2796
Author:   lsansonetti at apple.com
Date:     2009-10-14 15:32:30 -0700 (Wed, 14 Oct 2009)
Log Message:
-----------
macrubyc is now able to build fat binaries

Modified Paths:
--------------
    MacRuby/trunk/bin/rubyc

Modified: MacRuby/trunk/bin/rubyc
===================================================================
--- MacRuby/trunk/bin/rubyc	2009-10-14 20:12:47 UTC (rev 2795)
+++ MacRuby/trunk/bin/rubyc	2009-10-14 22:32:30 UTC (rev 2796)
@@ -13,6 +13,7 @@
 
   def initialize(argv)
     @mode = :normal
+    @archs = []
     @frameworks = []
     @internal = argv.delete('--internal')
 
@@ -24,6 +25,7 @@
       opts.on('--mode [MODE]', "Select compilation mode (normal or full)") { |mode| @mode = mode.intern }
       #opts.on('--framework <framework>', 'Link against <framework>') { |path| @frameworks << path }
       opts.on('-C', 'Compile, assemble and link a loadable object file') { @bundle = true }
+      opts.on('-a', '--arch <ARCH>', 'Compile for specified CPU architecture') { |arch| @archs << arch }
       opts.on('-v', '--version', 'Display the version') { puts RUBY_DESCRIPTION; exit 1 }
       opts.on('-V', '--verbose', 'Print every command line executed') { @verbose = true }
       opts.on('-h', '--help', 'Display this information') { die opts }
@@ -37,14 +39,17 @@
       if @mode != :normal and @mode != :full
         die "invalid mode `#{@mode}' (possible choices are: normal, full)"
       end
+      @archs.uniq!
+      @archs << RUBY_ARCH if @archs.empty?
     end
 
     # Locate necessary programs.
     @macruby = locate(@internal ? './miniruby' : 'macruby')
-    @llc = locate('llc')    
+    @llc = locate('llc')
     @gcc = locate('gcc')
     @gcxx = locate('g++')
     @nm = locate('nm')
+    @lipo = locate('lipo')
 
     # Misc.
     @tmpdir = (ENV['TMPDIR'] or '/tmp')
@@ -98,17 +103,25 @@
     # Generate init function (must be unique).
     init_func = "MREP_#{File.read(path).hash.abs}"
 
-    # Compile the file into LLVM bitcode.
-    bc = gen_tmpfile(base, 'bc')
-    execute("#{@macruby} --emit-llvm \"#{bc}\" #{init_func} \"#{path}\"")
+    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, 's')
-    execute("#{@llc} -f #{bc} -o=#{asm} -march=x86-64 -enable-eh")
+      # Compile the bitcode as assembly.
+      asm = gen_tmpfile(base + arch, 's')
+      execute("#{@llc} -f #{bc} -o=#{asm} -march=#{llc_arch(arch)} -enable-eh")
 
-    # Finally compile the assembly.
-    execute("#{@gcc} -c -arch x86_64 #{asm} -o #{output}")
+      # 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.
+    execute("#{@lipo} -create #{tmp_objs.join(' ')} -output #{output}")
+
     [output, init_func]
   end
 
@@ -131,8 +144,9 @@
 
     main = gen_tmpfile('main', 'c')
     File.open(main, 'w') { |io| io.write(main_txt) }
-    link = @internal ? "-L. -lmacruby" : "-framework MacRuby"
-    execute("#{@gcxx} #{main} -dynamic -bundle -undefined suppress -flat_namespace -arch x86_64 #{link} #{obj} -o #{output}")
+    linkf = @internal ? "-L. -lmacruby" : "-framework MacRuby"
+    archf = @archs.map { |x| "-arch #{x}" }.join(' ')
+    execute("#{@gcxx} #{main} -dynamic -bundle -undefined suppress -flat_namespace #{archf} #{linkf} #{obj} -o #{output}")
   end
 
   def compile_executable(objs_data, output)
@@ -184,11 +198,12 @@
     main = gen_tmpfile('main', 'cpp')
     File.open(main, 'w') { |io| io.write(main_txt) }
     main_o = gen_tmpfile('main', 'o')
-    execute("#{@gcxx} #{main} -c -arch x86_64 -o #{main_o}")
+    archf = @archs.map { |x| "-arch #{x}" }.join(' ')
+    execute("#{@gcxx} #{main} -c #{archf} -o #{main_o}")
     objs.unshift(main_o)
 
     # Link all objects into executable.
-    line = "#{@gcxx} -o #{output} -L#{RbConfig::CONFIG['libdir']} -lmacruby-static -arch x86_64 -framework Foundation -lobjc -lauto -I/usr/include/libxml2 -lxml2 "
+    line = "#{@gcxx} -o #{output} -L#{RbConfig::CONFIG['libdir']} -lmacruby-static #{archf} -framework Foundation -lobjc -lauto -I/usr/include/libxml2 -lxml2 "
     @frameworks.each { |f| line << "-framework #{f} " }
     line << execute("llvm-config --ldflags --libs core jit nativecodegen interpreter bitwriter").gsub(/\n/, '')
     objs.each { |o| line << " #{o}" }
@@ -208,6 +223,15 @@
     path
   end
 
+  def llc_arch(arch)
+    # LLVM uses a different convention for architecture names.
+    case arch
+      when 'i386'; 'x86'
+      when 'x86_64'; 'x86-64'
+      else; arch
+    end
+  end
+
   def gen_tmpfile(base, ext)
     file = File.join(@tmpdir, "#{base}.#{ext}")
     @tmpfiles << file
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091014/ac351d63/attachment.html>


More information about the macruby-changes mailing list