crystal_ruby icon indicating copy to clipboard operation
crystal_ruby copied to clipboard

Cannot Run Sample on Arch Linux

Open jeremyjh opened this issue 8 years ago • 1 comments

The example has a couple of issues for me. I'm curious which compiler accepts an argument -bundle and what it means. Both GCC and Clang complain about it - on GCC its fatal. Clang just warns that its unused. With either compiler, linking fails due to ruby symbols unfound. If I add -lruby to the args, then it builds test_ruby.bundle but ruby is unable to load this file. If I rename test_ruby.bundle to test_ruby.so then I get a spectacular seg fault and stack trace.

Summary of relevant versions/info:

 crystal --version
Crystal 0.23.1 (2017-09-10) LLVM 5.0.0

[] ~/play/crystal/crystal_ruby <master> ✗ gcc --version
gcc (GCC) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[] ~/play/crystal/crystal_ruby <master> ✗ clang --version
clang version 5.0.0 (tags/RELEASE_500/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
[] ~/play/crystal/crystal_ruby <master> ✗ 

[] ~/play/crystal/crystal_ruby <master> ✗ ruby --version
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]

[] ~/play/crystal/crystal_ruby <master> ✗ ldd test_ruby.bundle
        linux-vdso.so.1 (0x00007ffcbfbf3000)
        libruby.so.2.4 => /usr/lib/libruby.so.2.4 (0x00007fbaae086000)
        libpcre.so.1 => /usr/lib/libpcre.so.1 (0x00007fbaade13000)
        libgc.so.1 => /usr/lib/libgc.so.1 (0x00007fbaadba9000)
        libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fbaad98b000)
        libevent-2.1.so.6 => /usr/lib/libevent-2.1.so.6 (0x00007fbaad735000)
        librt.so.1 => /usr/lib/librt.so.1 (0x00007fbaad52d000)
        libdl.so.2 => /usr/lib/libdl.so.2 (0x00007fbaad329000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007fbaad112000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007fbaacd5b000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fbaae7bd000)
        libcrypt.so.1 => /usr/lib/libcrypt.so.1 (0x00007fbaacb23000)
        libm.so.6 => /usr/lib/libm.so.6 (0x00007fbaac7d7000)
        libatomic_ops.so.1 => /usr/lib/libatomic_ops.so.1 (0x00007fbaac5d4000)
        libcrypto.so.1.1 => /usr/lib/libcrypto.so.1.1 (0x00007fbaac154000)

Changes I had to make to Makefile to get it to even build:

diff --git a/Makefile b/Makefile
index a223fa1..332da44 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 test_ruby.bundle: sample/test_ruby.cr
-       crystal sample/test_ruby.cr --link-flags "-dynamic -bundle -Wl,-undefined,dynamic_lookup" -o test_ruby.bundle
+       crystal sample/test_ruby.cr --link-flags "-dynamic -Wl,-undefined,dynamic_lookup,-lruby" -o test_ruby.bundle
 
 irb: test_ruby.bundle
        irb -rtest_ruby -I.

Results of running make irb:

make irb
irb -rtest_ruby -I.
/usr/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require':LoadError: cannot load such file -- test_ruby
irb(main):001:0> 

jeremyjh avatar Nov 05 '17 23:11 jeremyjh

On macOS for me:

$ man ld | grep bundle
...others
-bundle     Produce a mach-o bundle that has file type MH_BUNDLE.
-dynamic    The default.  Implied by -dylib, -bundle, or -execute
...others

$ ld -v
@(#)PROGRAM:ld  PROJECT:ld64-609
BUILD 07:59:13 Aug 25 2020
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
LTO support using: LLVM version 12.0.0, (clang-1200.0.32.2) (static support for 27, runtime is 27)
TAPI support using: Apple TAPI version 12.0.0 (tapi-1200.0.23)

So maybe it might not be needed 🤷🏻 For me, I found it to have the same effect as using -shared; the plus side with -shared is that it seems to work for generating .so too. So what I found to work for me (for both macOS and Ubuntu) was along these lines:

CRYSTAL = crystal
PLATFORM = $(shell uname -s)

ifeq "$(PLATFORM)" "Darwin"
TARGET = ../../lib/gls.bundle
endif

ifeq "$(PLATFORM)" "Linux"
TARGET = ../../lib/gls.so
endif

build: ./src/gloss.cr
	$(CRYSTAL) build  --link-flags "-shared -dynamic -Wl,-undefined,dynamic_lookup" $< -o $(TARGET) --release

Note the release flag too - it works for me on macOS without it, but when I didn't include it in Ubuntu I got the lovely:

/usr/bin/ld: /my/file/path.cr: 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                                                              

My system specs: macOS:

Catalina, 10.15.6 crystal version 0.35.1 (via homebrew) llvm:

llvm: stable 10.0.1 (bottled), HEAD [keg-only]
Next-gen compiler infrastructure
https://llvm.org/
/usr/local/Cellar/llvm/10.0.1_1 (7,029 files, 1GB)
  Poured from bottle on 2020-12-17 at 13:56:53
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/llvm.rb
License: Apache-2.0

Linux:

Ubuntu 20.04.2 LTS, running with docker crystal

Crystal 0.36.1 [c3a3c1823] (2021-02-02) 
                                        
LLVM: 10.0.0                            
Default target: x86_64-unknown-linux-gnu

johansenja avatar Mar 06 '21 18:03 johansenja