Congrats supporting multithreading!
It works fine, but binary creation seems to fail with multithreaded and statically linked.
Anything.
p 1
$ docker run -it -u `id -u` -v `pwd`:/mnt -w /mnt --rm crystallang/crystal:0.32.1 bash
$ crystal build test.cr --link-flags "-static" -Dpreview_mt
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libevent.a(evutil.o): In function `test_for_getaddrinfo_hacks':
(.text+0x2e4): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libevent.a(evutil.o): In function `evutil_getaddrinfo_common_':
(.text+0x1beb): warning: Using 'getprotobynumber' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
(.text+0x1cc3): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libevent_pthreads.a(evthread_pthread.o): In function `evthread_posix_cond_free':
(.text+0x55): undefined reference to `pthread_cond_destroy'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libevent_pthreads.a(evthread_pthread.o): In function `evthread_posix_cond_alloc':
(.text+0x89): undefined reference to `pthread_cond_init'
collect2: error: ld returned 1 exit status
Error: execution of command failed with code: 1: `cc "${@}" -o '/mnt/test' -static -rdynamic -lpcre -lm /usr/bin/../lib/crystal/lib/libgc.a -lpthread /usr/share/crystal/src/ext/libcrystal.a -levent_pthreads -levent -lrt -ldl -L/usr/bin/../lib/crystal/lib -L/usr/lib -L/usr/local/lib`
It works fine in following cases.
$ crystal build test.cr -Dpreview_mt # only multithreaded
$ crystal build test.cr --link-flags "-static" # only statically linked
$ crystal --version
Crystal 0.32.1 [41bd18fbe] (2019-12-18)
LLVM: 8.0.0
Default target: x86_64-unknown-linux-gnu
Best regards,
Not really related to MT. This is glibc warning that despite being compiled statically it still still dynamically load some libraries at runtime (sigh).
@ysbaddaden
Yeah, I know it. I put the log as it was, but I had to cut off the first half. 馃槄
The essential problem is this part of the second half. Compilation was not successful.
undefined reference to `pthread_cond_destroy'
undefined reference to `pthread_cond_init'
collect2: error: ld returned 1 exit status
Oh, sorry! I reproduced. This is a CC or LD trickery.
It fails to compile when -lpthread is _before_ -levent_pthreads. If we move it after, or declare it a second time, like -lpthread ... -levent_pthreads -lpthread then it compiles fine...
@ysbaddaden
worked! You have prevented me from wasting time. Thank you very much. 馃挴 馃槏
$ crystal build test.cr --link-flags "-static -levent_pthreads -lpthread" -Dpreview_mt
$ ldd test
not a dynamic executable
$ ./test
1
Can we make this work without manual configuration?
@straight-shoota yes:
diff --git a/src/crystal/system/unix/lib_event2.cr b/src/crystal/system/unix/lib_event2.cr
index f898c528b..7d723754e 100644
--- a/src/crystal/system/unix/lib_event2.cr
+++ b/src/crystal/system/unix/lib_event2.cr
@@ -11,6 +11,7 @@ require "c/netdb"
@[Link("event")]
{% end %}
{% if flag?(:preview_mt) %}
+ @[Link("pthread")]
@[Link("event_pthreads")]
{% end %}
lib LibEvent2
Weirdly, I must declare @[Link("pthread")] before @[Link("event_pthreads")] for the -lpthread to be inserted after -levent_pthreads ?!
We do an explicit reverse in the compiler because the order you have to pass these to the linker seems counter-intuitive:
I can't remember how it is exactly... event_pthreads uses pthread so it would make sense for pthread to come before event_pthreads in the linker command. However, if I remember correctly, if you include a lib and no previous lib needed it, it's discarded or something like that.
We could probably revisit this ordering decision...
Weirdly, I must declare
@[Link("pthread")]before@[Link("event_pthreads")]for the-lpthreadto be inserted after-levent_pthreads?!
-levent_pthreads depends on -lpthread so the order in the sourcecode is correct.
Please submit a PR with this patch @ysbaddaden!
Most helpful comment
@straight-shoota yes:
Weirdly, I must declare
@[Link("pthread")]before@[Link("event_pthreads")]for the-lpthreadto be inserted after-levent_pthreads?!