Backport #7948

Can not compile pseudo static Ruby binary on OSX

Added by Michal Papis about 1 year ago. Updated 9 months ago.

[ruby-core:52845]
Status:Assigned
Priority:Normal
Assignee:Tomoyuki Chikanaga

Description

In ruby 1.9.x I was using LDFLAGS="-Bstatic $LDFLAGS" to force pseudo static compilation on OSX (full static is not possible).

This stopped to work with 2.0.0-p0, the binary is compiled but the static flag is not handled properly and the generated binary can not run:

$ ~/.sm/pkg/versions/tokaidoapp/2.0.0-p0/bin/ruby --version
dyld: Symbol not found: Initencinit
Referenced from: /Users/mpapis/.sm/pkg/versions/tokaidoapp/2.0.0-p0/bin/ruby
Expected in: flat namespace
in /Users/mpapis/.sm/pkg/versions/tokaidoapp/2.0.0-p0/bin/ruby
Trace/BPT trap

using otool -L ~/.sm/pkg/versions/tokaidoapp/2.0.0-p0/bin/ruby I can see the binary depends on a lot more external libraries:

/Users/mpapis/.sm/pkg/versions/tokaidoapp/2.0.0-p0/bin/ruby:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0)
/Users/mpapis/.sm/pkg/versions/openssl/0.9.8y/lib/libssl.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8)
/Users/mpapis/.sm/pkg/versions/openssl/0.9.8y/lib/libcrypto.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8)
/usr/lib/libncurses.5.4.dylib (compatibility version 5.4.0, current version 5.4.0)
/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk (compatibility version 8.5.0, current version 8.5.7)
/System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl (compatibility version 8.5.0, current version 8.5.7)
/usr/lib/libffi.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libutil.dylib (compatibility version 1.0.0, current version 1.0.0)

compared to otool -L ~/.sm/pkg/versions/tokaidoapp/1.9.3-p392/bin/ruby

/Users/mpapis/.sm/pkg/versions/tokaidoapp/1.9.3-p392/bin/ruby:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0)

What is the preferred way to compile static ruby (with minimal external dependencies) on systems like OSX which do not provide default package manager so no default library paths can be assumed.

History

#1 Updated by Nobuyoshi Nakada about 1 year ago

  • Status changed from Open to Feedback

If you want all extension libraries, including encodings and
transcoders, to be statically linked to ruby, then you can use
--with-static-linked-ext configure option.

What is the preferred way to compile static ruby (with minimal
external dependencies) on systems like OSX which do not provide
default package manager so no default library paths can be assumed.

Do you mean external libraries linked to ruby, by "external
dependencies"?

I couldn't get "no default library paths can be assumed", could you
ellaborate?

#2 Updated by Nobuyoshi Nakada about 1 year ago

=begin
Just tried:

$ ./configure -C --prefix $HOME/ruby/2.0.0-p0-static --disable-install-doc --with-out-ext=win32 LDFLAGS=-Bstatic
$ make -j4 install

succeeded, and statically linked ruby and extension library shared objects are installed.
=end

#3 Updated by Michal Papis about 1 year ago

in the output above you can see:

/Users/mpapis/.sm/pkg/versions/openssl/0.9.8y/lib/libssl.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8)
/Users/mpapis/.sm/pkg/versions/openssl/0.9.8y/lib/libcrypto.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8)

this are external dependencies that will not be available after moving this ruby to other machines.

#4 Updated by Luis Lavena about 1 year ago

mpapis (Michal Papis) wrote:

in the output above you can see:

/Users/mpapis/.sm/pkg/versions/openssl/0.9.8y/lib/libssl.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8)
/Users/mpapis/.sm/pkg/versions/openssl/0.9.8y/lib/libcrypto.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8)

this are external dependencies that will not be available after moving this ruby to other machines.

I deal with this in the past and solved by only building dependencies statically.

Can you turn off shared packages and only use static versions?

#5 Updated by Tomoyuki Chikanaga about 1 year ago

  • Tracker changed from Backport to Bug
  • Project changed from Backport200 to ruby-trunk

#6 Updated by Michal Papis 11 months ago

found it the problem:

dyld: Symbol not found: _Init_encinit
  Referenced from: /Users/mpapis/tmp/ruby-bin-static-ext/bin/ruby
  Expected in: flat namespace
 in /Users/mpapis/tmp/ruby-bin-static-ext/bin/ruby
Trace/BPT trap: 5

was conflicting --enable-load-relative with: --with-static-linked-ext can you add an error in case both are used together? or maybe just fix it?

#7 Updated by Michal Papis 9 months ago

confirmed it again - compiling with LDFLAGS=-Bstatic + --with-static-linked-ext and without: --enable-load-relative works as expected - this two flags can not be used together.

#8 Updated by Nobuyoshi Nakada 9 months ago

  • Status changed from Feedback to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r42213.
Michal, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


extmk.rb: static extensions

  • ext/extmk.rb (extmake): should make static libraries for extensions to be statically linked. [Bug #7948]

#9 Updated by Tomoyuki Chikanaga 9 months ago

  • Tracker changed from Bug to Backport
  • Project changed from ruby-trunk to Backport200
  • Status changed from Closed to Assigned
  • Assignee set to Tomoyuki Chikanaga

#10 Updated by Michal Papis 9 months ago

=begin
Is it possible that http://www.rubyist.net/~eban/goto/r42213 is reason of:

make[2]: *** No rule to make target `static'. Stop.
make[1]: *** [ext/-test-/win32/dln/static] Error 2

where (({/Users/mpapis/.rvm/src/ruby-2.0.0-p247/ext/-test-/win32/dln/mkmf.log})):

Failed to configure -test-/win32/dln. It will not be installed.

=end

#11 Updated by Michal Papis 9 months ago

=begin
confirming that for static extensions ((({--with-static-linked-ext}))) it is required to ignore extensions that fail, for me on OSX it was:

--with-out-ext=dl/win32,fiddle/win32,tk/tkutil,win32ole,-test-/win32/dln,-test-/win32/fd_setsize

which makes the static ruby compilation two step pass process:

make | grep "Failed to configure"
./configure --with-out-ext=...,...,...
make

this is related to the change http://www.rubyist.net/~eban/goto/r42213 - can we make the "Fail"s to be ignored from static compilation list?
=end

Also available in: Atom PDF