Wednesday, September 7, 2011

Installing Ruby 1.8.7p352 under rvm

I was recently trying to install Ruby under RVM on OS X, 10.6.8, running in 32-bit mode.

For Ruby 1.9.2 p290, it was no problem. rvm installed it without issue (using x86_64).

However, Ruby 1.8.7 p352 would fail constantly, with:

making ruby
/usr/bin/gcc-4.2 -arch i386 -arch x86_64 -g -Os -pipe -no-cpp-precomp -fno-common -pipe -fno-common -DRUBY_EXPORT -L. -arch i386 -arch x86_64 -bind_at_load main.o -lruby -ldl -lobjc -o ruby
ld: warning: ignoring file ./libruby.dylib, file was built for unsupported file format which is not the architecture being linked (i386)
Undefined symbols for architecture i386:
"_ruby_init_stack", referenced from:
_main in main.o
"_ruby_init", referenced from:
_main in main.o
"_ruby_options", referenced from:
_main in main.o
"_ruby_run", referenced from:
_main in main.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status
lipo: can't open input file: /var/folders/rp/rprVpkCiGbKvS3sirOXX9k+++TI/-Tmp-//ccoGzQBh.out (No such file or directory)
make[1]: *** [ruby] Error 1
make: *** [all] Error 2


You can see above that files are getting correctly compiled with both the -i386 and -x86_64 -arch flags. That was confusing. I verified that the Makefile included the arch flags on both the CFLAGS and LDFLAGS variable.

I traced the problem to the following line of output:

cc -dynamiclib -undefined suppress -flat_namespace -install_name
/Users/wwilliam/.rvm/rubies/ruby-1.8.7-p352/lib/libruby.dylib
-current_version 1.8.7 -compatibility_version 1.8 array.o bignum.o
class.o compar.o dir.o dln.o enum.o enumerator.o error.o eval.o file.o
gc.o hash.o inits.o io.o marshal.o math.o numeric.o object.o pack.o
parse.o process.o prec.o random.o range.o re.o regex.o ruby.o signal.o
sprintf.o st.o string.o struct.o time.o util.o variable.o version.o
dmyext.o -o libruby.1.8.7.dylib


As you can see, the dynamic library is being linked here without any architecture flags. What needed to be set is the LDSHARED variable.

My first attempt was to modify the Makefile by hand, adding the -arch flags to LDSHARED. That worked - somewhat. I was able to run make and get everything compiled. However, that didn't solve the problem completely, because whenever I tried to install via rvm again, my changes were overwritten since rvm ran configure again.

Naturally, for my next attempt, I did a "export LDSHARED="-arch i386 -arch x86_64" in the terminal in which I was running rvm install. That also did not work. I checked and config.log DID show my additions to LDSHARED. Hmmm...WTH?

It turns out that the configure.in defines LDSHARED explicity for each machine type and does not use the value that configure picks up.

For darwin, it was:

        darwin*)        : ${LDSHARED='cc -dynamic -bundle -undefined suppress -flat_namespace'}


So the fix in this case, was to change it to:
        darwin*)        : ${LDSHARED='cc -arch i386 -arch x86_64 -dynamic -bundle -undefined suppress -flat_namespace'}


I did submit bug #5295 against Ruby 1.8 for this issue. Whether it will get fixed or not, I don't know.

6 comments:

  1. I hit this today as well. Looks like a change in rvm, rolling back to 1.8.0 made it work again:

    curl -s https://rvm.beginrescueend.com/install/rvm -o rvm-installer ; chmod +x rvm-installer ; ./rvm-installer --version 1.8.0

    ReplyDelete
  2. I had the same issue, thanks for posting your solutions. Exceptionally helpful, cheers!

    ReplyDelete
  3. Confirm that 1.8.0 worked for me as well.

    ReplyDelete
  4. Solved my issue, been looking around for ages! Thanks!

    ReplyDelete