msantos / procket

Erlang interface to low level socket operations
http://blog.listincomprehension.com/search/label/procket
BSD 3-Clause "New" or "Revised" License
283 stars 80 forks source link

Compiling with 32 bit Erlang on x86_64 doesn't work #13

Closed NAR closed 10 years ago

NAR commented 10 years ago

Hello!

When I run 32 bit Erlang OTP R15B03 on x86_64, the compilation fails, because the fd_send.o and fd_recv.o objects are 32 bit files, while the procket.o is 64 bit, so the link phase returns with an error. The full output: ==> procket (compile) make: Entering directory /home/ethanl/titansimvolte/deps/procket/c_src' gcc -c -Wall -fPIC -g -O2 -m32 -DNDEBUG -DSPARE_SEND_FDS -DSPARE_RECV_FDS fd_send.c gcc -c -Wall -fPIC -g -O2 -m32 -DNDEBUG -DSPARE_SEND_FDS -DSPARE_RECV_FDS fd_recv.c ar cr libancillary.a fd_send.o fd_recv.o ranlib libancillary.a gcc -m32 -g -Wall -o ../priv/procket -L. procket_cmd.c -lancillary make: Leaving directory/home/ethanl/titansimvolte/deps/procket/c_src' Compiled src/procket_ioctl.erl Compiled src/procket_msg.erl Compiled src/procket_mktmp.erl Compiled src/packet.erl Compiled src/bpf.erl Compiled src/procket.erl Compiling c_src/procket.c /usr/lib64/gcc/x86_64-suse-linux/4.3/../../../../x86_64-suse-linux/bin/ld: skipping incompatible c_src/libancillary.a when searching for -lancillary /usr/lib64/gcc/x86_64-suse-linux/4.3/../../../../x86_64-suse-linux/bin/ld: cannot find -lancillary collect2: ld returned 1 exit status ERROR: cc c_src/procket.o -Lc_src -lancillary -shared -L/app/erlang/otp_R15B03/LMWP3/lib/erlang/lib/erl_interface-3.7.9/lib -lerl_interface -lei -o priv/procket.so failed with error: 1 and output: /usr/lib64/gcc/x86_64-suse-linux/4.3/../../../../x86_64-suse-linux/bin/ld: skipping incompatible c_src/libancillary.a when searching for -lancillary /usr/lib64/gcc/x86_64-suse-linux/4.3/../../../../x86_64-suse-linux/bin/ld: cannot find -lancillary collect2: ld returned 1 exit status

The following patch fixes the compilation on this platform: diff --git a/rebar.config b/rebar.config index 20f8470..f2a0dc3 100644 --- a/rebar.config +++ b/rebar.config @@ -1,5 +1,5 @@ {port_specs, [

But breaks when 64 bit Erlang OTP R16B03 is used on x86_64.Something more clever is needed.

msantos commented 10 years ago

Thanks for tracking this down and the patch!

I used to run a 32-bit VM on Mac OS X and I remember this used to work. I think it worked because rebar sets a default environment on darwin but not on linux, like this:

     %% OS X Leopard flags for 64-bit
     {"darwin9.*-64$", "CFLAGS", "-m64 $CFLAGS"},
     {"darwin9.*-64$", "CXXFLAGS", "-m64 $CXXFLAGS"},
     {"darwin9.*-64$", "LDFLAGS", "-arch x86_64 $LDFLAGS"},

     %% OS X Snow Leopard, Lion, and Mountain Lion flags for 32-bit
     {"darwin1[0-2].*-32", "CFLAGS", "-m32 $CFLAGS"},
     {"darwin1[0-2].*-32", "CXXFLAGS", "-m32 $CXXFLAGS"},
     {"darwin1[0-2].*-32", "LDFLAGS", "-arch i386 $LDFLAGS"},

The first element of the tuple is a regex against the ERLANG_TARGET env var that rebar sets. You can see what is going on by running rebar -vvv compile. In my case, I have:

{"ERLANG_TARGET","R17A-x86_64-unknown-linux-gnu-64"}

I don't have a 32-bit VM installed at the moment. I'm compiling one now but I think something like this should work:

diff --git a/rebar.config b/rebar.config
index 20f8470..a389083 100644
--- a/rebar.config
+++ b/rebar.config
@@ -4,9 +4,10 @@

 {port_env, [
     {"LDFLAGS", "$LDFLAGS -Lc_src -lancillary"},
-    {"x86_64", "PROCKET_CFLAGS", "-m$(ERLANG_ARCH)"},
-    {"i686", "PROCKET_CFLAGS", "-m$(ERLANG_ARCH)"},
-    {"i386", "PROCKET_CFLAGS", "-m$(ERLANG_ARCH)"}
+    {"x86_64", "PROCKET_CFLAGS", "-m$ERLANG_ARCH"},
+    {"x86_64", "CFLAGS", "$CFLAGS -m$ERLANG_ARCH"},
+    {"i686", "PROCKET_CFLAGS", "-m$ERLANG_ARCH"},
+    {"i386", "PROCKET_CFLAGS", "-m$ERLANG_ARCH"}
     ]}.

 {pre_hooks, [

Some extra line noise in that patch because I removed the parentheses so the variable would expand on the command line.

msantos commented 10 years ago

So the 32-bit VM on x86_64 identifies itself as:

{"ERLANG_ARCH","32"},
{"ERLANG_TARGET","R16B03-1-i686-pc-linux-gnu-32"},

This should fix it:

diff --git a/rebar.config b/rebar.config
index 20f8470..b182707 100644
--- a/rebar.config
+++ b/rebar.config
@@ -4,9 +4,11 @@

 {port_env, [
     {"LDFLAGS", "$LDFLAGS -Lc_src -lancillary"},
-    {"x86_64", "PROCKET_CFLAGS", "-m$(ERLANG_ARCH)"},
-    {"i686", "PROCKET_CFLAGS", "-m$(ERLANG_ARCH)"},
-    {"i386", "PROCKET_CFLAGS", "-m$(ERLANG_ARCH)"}
+    {"x86_64", "PROCKET_CFLAGS", "-m$ERLANG_ARCH"},
+    {"i686", "PROCKET_CFLAGS", "-m$ERLANG_ARCH"},
+    {"i686", "CFLAGS", "$CFLAGS -m$ERLANG_ARCH"},
+    {"i686", "LDFLAGS", "-m$ERLANG_ARCH $LDFLAGS"},
+    {"i386", "PROCKET_CFLAGS", "-m$ERLANG_ARCH"}
     ]}.

 {pre_hooks, [
msantos commented 10 years ago

@NAR I pushed a change that should fix this issue. If you have still have problems, please re-open this issue. And if you have any other problems or questions, please feel free to let me know!

NAR commented 10 years ago

Thanks, the patch solved the problem for me, the compilation works with 32 and 64 OTPs.