Skip to content

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

Closed
NAR opened this Issue Jan 28, 2014 · 4 comments

2 participants

@NAR
NAR commented Jan 28, 2014

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, [

  • {"priv/procket.so", ["c_src/procket.c"]}
  • {"x86_64", "priv/procket.so", ["c_src/procket.c"], [{env, "$PROCKET_CFLAGS"}]}
    ]}.

    {port_env, [

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

@msantos
Owner
msantos commented Jan 28, 2014

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
Owner
msantos commented Jan 29, 2014

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 msantos added a commit that referenced this issue Jan 29, 2014
@msantos linux: fix compiling under a 32-bit VM/64-bit arch
Fix build failure:

#13

rebar designates 32-bit VM on x864_64 as
"R16B03-1-i686-pc-linux-gnu-32".

My guess is that a half-word emulator will be reported as
"x86_64.*-32", so try to accomodate this case as well.

Thanks @NAR!
94bd7bc
@msantos
Owner
msantos commented Jan 29, 2014

@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!

@msantos msantos closed this Jan 29, 2014
@NAR
NAR commented Feb 3, 2014

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.