[erlang-questions] Building erl_interface with mingw (an unfinished tale)

Davide Marquês <>
Thu Apr 23 12:29:10 CEST 2009


Hi again!

Found the solution (and indeed... it was trivial)! :)
It was simply a matter of changing the order used to link the ei and
erl_interface libraries!! (didn't have a clue that mattered :))

This works perfectly:
$ gcc -o extprg.exe *.c -I/c/otp_src_R13B/lib/erl_interface/include/
-L/c/otp_src_R13B/lib/erl_interface/obj/i686-pc-mingw32/ -lei
-lerl_interface -lwsock32

Now... to determine if all this trouble was worth it I went back to the .lib
files included in the windows distribution to see if those worked.
  $ gcc -o extprg.exe *.c -I/c/erl5.7.1/lib/erl_interface-3.6.1/include/
-L/c/erl5.7.1/lib/erl_interface-3.6.1/lib/ -lerl_interface -lei -lwsock32

But (luckily for my mental health) it didn't work... some of dependencies
were indeed fixed but not all of then.
I got a bunch of these warnings:
  Warning: .drectve `/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib"
/DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" ' unrecognized
And these undefined references:

c:/erl5.7.1/lib/erl_interface-3.6.1/lib//erl_interface.lib(C:/cygwin/ldisk/daily_build/otp_build_win32_r13b.2009-04-20_20/otp_src_R13B/lib/erl_interface/
obj.mt/win32/erl_marshal.o):(.text+0xf4): undefined reference to
`__security_cookie'
(and: @, __security_cookie,
@, __iob_func, _tls_index, _tls_array)

While the .lib files aren't working, it's possible to build erl_interface
using mingw and get working libei.a and liberl_interface.a libraries. :)
Hope that's useful for someone out there.

Cheers,
Davide :)

2009/4/23 Davide Marquês <>

> Hi again!
>
> I just did a fresh R13B install on an linux box and came across
> the same problem while compiling the erl_interface tutorial example.
>
> If I try this:
>     :~/port$ gcc -o extprg erl_comm.c ei.c -lei
> -lerl_interface -I/usr/local/lib/erlang/lib/erl_interface-3.6.1/include/
> -L/usr/local/lib/erlang/lib/erl_interface-3.6.1/lib/
>
> I get a bunch of "undefined reference" warnings:
>
> /usr/local/lib/erlang/lib/erl_interface-3.6.1/lib//liberl_interface.a(erl_eterm.o):
> In function `erl_mk_var':
>
> /home/nonroot/otp_src_R13B/lib/erl_interface/src/legacy/erl_eterm.c:498:
> undefined reference to `__erl_errno_place'
>     ... the list continues ...
>
> (I did forgot -lpthread there.)
>
> But if I unpack the contents of libei.a and include the .o files instead of
> adding the -lei flag then the linking succeeds and the program works
> perfectly:
>
>     :~/port$ gcc -o extprg erl_comm.c ei.c
> lib_ei_extracted/*.o -lerl_interface -lpthread
> -I/usr/local/lib/erlang/lib/erl_interface-3.6.1/include/
> -L/usr/local/lib/erlang/lib/erl_interface-3.6.1/lib/
>     :~/port$ erl
>     Erlang R13B (erts-5.7.1) [source] [rq:1] [async-threads:0] [hipe]
> [kernel-poll:false]
>
>     Eshell V5.7.1  (abort with ^G)
>     1> complex:start("./extprg").
>     <0.35.0>
>     2> complex:foo(1).
>     1
>
> What am I missing here? :|
> It must be something really trivial but I'm fresh out of ideas on what it
> might be.
>
> Cheers,
> Davide :)
>
> 2009/4/22 Davide Marquês <>
>
> Hi there!
>>
>> I was (almost) able to compile erl_interface using mingw (with some
>> unhealthy hacks along the way) and I'd like to get your feedback on whether
>> this would be the correct way to go.
>> Actually, since I have no *useful* experience using gcc and related tools
>> I'm prepared to have someone telling me that I really didn't had to
>> recompile erl_interface.
>> Either way, this might be useful for others that might be thinking of
>> taking the same path... :)
>>
>> My setup: Windows XP, OTP_R13B (I started off with OTP_R13A so paths will
>> vary), MSYS + MinGW.
>>
>> I started off following the erl_interface tutorial (
>> http://erlang.org/doc/tutorial/erl_interface.html) and things broke when
>> I tried to compile:
>>      /c/Projectos/eNotify/src/native/port
>>     $ gcc.exe ei.c erl_comm.c -o extprg.exe
>> -Ic:/erl5.7/lib/erl_interface-3.6/include
>> -Lc:/erl5.7/lib/erl_interface-3.6/lib -lei -lerl_interface
>>     Warning: .drectve `/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib"
>> /DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" ' unrecognized
>>     Warning: .drectve `/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib"
>> /DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" ' unrecognized
>>     Warning: .drectve `/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib"
>> /DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" ' unrecognized
>>     Warning: .drectve `/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib"
>> /DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" ' unrecognized
>>     Warning: .drectve `/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib"
>> /DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" ' unrecognized
>>
>> c:/erl5.7/lib/erl_interface-3.6/lib/erl_interface.lib(C:/cygwin/ldisk/daily_build/otp_build_win32_r13a.2009-03-16_22/otp_src_R13A/lib/erl_interface/
>> obj.mt/win32/erl_malloc.o):(.text+0x47<http://obj.mt/win32/erl_malloc.o%29:%28.text+0x47>):
>> undefined reference to `ei_malloc'
>>
>> c:/erl5.7/lib/erl_interface-3.6/lib/erl_interface.lib(C:/cygwin/ldisk/daily_build/otp_build_win32_r13a.2009-03-16_22/otp_src_R13A/lib/erl_interface/
>> obj.mt/win32/erl_malloc.o):(.text+0x7c<http://obj.mt/win32/erl_malloc.o%29:%28.text+0x7c>):
>> undefined reference to `ei_realloc'
>>     (...)
>>
>>
>> c:/erl5.7/lib/erl_interface-3.6/lib/erl_interface.lib(C:/cygwin/ldisk/daily_build/otp_build_win32_r13a.2009-03-16_22/otp_src_R13A/lib/erl_interface/
>> obj.mt/win32/erl_error.o):(.text+0xa2<http://obj.mt/win32/erl_error.o%29:%28.text+0xa2>):
>> more undefined references to `__iob_func' follow
>>     collect2: ld returned 1 exit status
>>
>> ??? :|
>> The ei.lib and erl_interface.lib files were in
>> c:/erl5.7/lib/erl_interface-3.6/lib so I was expecting this to work. :\
>>
>> A little online research (
>> http://erlang.org/pipermail/erlang-questions/2003-September/009854.html)
>> lead me think that the .lib files weren't GCC-compliant (and what I needed
>> were .a files).
>> So it would be a simple matter of getting the source and compiling
>> erl_interface again (famous last words).
>>
>> This is were someone can come in and say "No! No! No! You just had to do
>> XPTO."
>> Considering no XPTO existed I went along to try and build erl_interface.
>>
>> First I tried to just build it using the files that were available on the
>> windows binary distribution but it failed complaining about a missing /make/
>> target.mk.
>> So I:
>>
>>    - got the otp_src_R13A sourcecode
>>    - did a ./configure
>>    - exported ERL_TOP=c:/otp_src_R13A
>>    - IIRC
>>       - got something about a missing
>>       c:/otp_src_R13A/make/i686-pc-mingw32/otp.mk folder
>>       - which I copied and renamed from c:/otp_src_R13A/make/otp.mk.in(I'm guessing something is responsible for this step)
>>       - added the necessary LIBS = -lwsock32 to
>>    c:/otp_src_R13A/lib/erl_interface/src/i686-pc-mingw32/Makefile
>>    - did a successful build
>>       - which resulted in two files: libei.a and liberl_interface.a
>>       getting placed in
>>       c:/otp_src_R13A/lib/erl_interface/obj.debug/i686-pc-mingw32/
>>       - I created a folder c:/otp_src_R13A/lib/erl_interface/lib
>>       - and copied the two files there
>>
>> I then tried using those two files to build the erl_interface tutorial
>> program with this result:
>>          /c/Projectos/eNotify/src/native/port
>>         $ gcc.exe ei.c erl_comm.c -o extprg.exe
>> -Ic:/otp_src_R13A/lib/erl_interface/include
>> -Lc:/otp_src_R13A/lib/erl_interface/lib -lei -lerl_interface
>>
>> c:/otp_src_R13A/lib/erl_interface/lib/liberl_interface.a(erl_malloc.o): In
>> function `erl_malloc':
>>         c:/otp_src_R13A/lib/erl_interface/src/legacy/erl_malloc.c:221:
>> undefined reference to `ei_malloc'
>>
>> c:/otp_src_R13A/lib/erl_interface/lib/liberl_interface.a(erl_malloc.o): In
>> function `erl_realloc':
>>         c:/otp_src_R13A/lib/erl_interface/src/legacy/erl_malloc.c:231:
>> undefined reference to `ei_realloc'
>>
>> c:/otp_src_R13A/lib/erl_interface/lib/liberl_interface.a(erl_malloc.o): In
>> function `erl_free':
>>         c:/otp_src_R13A/lib/erl_interface/src/legacy/erl_malloc.c:238:
>> undefined reference to `ei_free'
>>         ...
>>
>> c:/otp_src_R13A/lib/erl_interface/lib/liberl_interface.a(erl_fix_alloc.o):
>> In function `erl_eterm_alloc':
>>         c:/otp_src_R13A/lib/erl_interface/src/legacy/erl_fix_alloc.c:111:
>> undefined reference to `__erl_errno_place'
>>         collect2: ld returned 1 exit status
>>
>> Which (other than the initial warnings) is exactly the same problem as the
>> one I got with the original compilation.
>> Here I took a look at the build process and realized that the
>> erl_interface build process had also produced a bunch of .o files in another
>> folder:
>> c:/erl5.7/lib/erl_interface/obj.st.debug/i686-pc-mingw32/
>>
>> Since the compiler was nagging me about missing .o files I just included
>> them all in:
>>          /c/Projectos/eNotify/src/native/port
>>         $ gcc.exe ei.c erl_comm.c -o extprg.exe
>> c:/otp_src_R13A/lib/erl_interface/include/*.o
>> -Ic:/otp_src_R13A/lib/erl_interface/include
>> -Lc:/otp_src_R13A/lib/erl_interface/lib -lei -lerl_interface -lwsock32
>>         c:/otp_src_R13A/lib/erl_interface/include/erl_resolve.o: In
>> function `erl_gethostbyname_r':
>>         c:/otp_src_R13A/lib/erl_interface/src/legacy/erl_resolve.c:58:
>> undefined reference to `ei_gethostbyname_r'
>>         c:/otp_src_R13A/lib/erl_interface/include/erl_resolve.o: In
>> function `erl_gethostbyaddr_r':
>>         c:/otp_src_R13A/lib/erl_interface/src/legacy/erl_resolve.c:70:
>> undefined reference to `ei_gethostbyaddr_r'
>>         collect2: ld returned 1 exit status
>>
>> :| This is another struggle.
>> Under certain circumstances (mine) the functions ei_gethostbyname_r and
>> ei_gethostbyaddr_r aren't included in the compilation of the ei_resolve.c
>> file.
>> Being completely astray from my original goal, and after figuring out that
>> these were the reentrant versions of the same functions without the _r and
>> that on windows the original ones are already thread safe (
>> http://daniel.haxx.se/projects/portability/), I just went ahead and added
>> these *_r functions calling out to original ones (on the $ifdef __WIN32__
>> part ). This was the unhealthy hack part. :)
>> Of course that worked (to shut the compiler up at least). :P
>>      /c/Projectos/eNotify/src/native/port
>>     $ gcc.exe ei.c erl_comm.c -o extprg.exe
>> c:/otp_src_R13A/lib/erl_interface/include/*.o
>> -Ic:/otp_src_R13A/lib/erl_interface/include
>> -Lc:/otp_src_R13A/lib/erl_interface/lib -lei -lerl_interface -lwsock32
>>
>> Finally that got me a working extprg.exe that I was able to complete the
>> tutorial with!
>>
>> <sleep break + upgrade to R13B>
>>
>> I picked up were I left off: being able to compile IF including all of the
>> .o files.
>> Some [n00b] research -> http://en.wikipedia.org/wiki/Ar_(Unix)<http://en.wikipedia.org/wiki/Ar_%28Unix%29>&
>> http://linux.die.net/man/1/ar
>> Got me to check if all the .o files the linker was complaining about were
>> getting archived in the two .a files.
>> And indeed, all of them were on libei.a.
>>
>> I unpacked the .o files from libeia.a and replaced it with a call to those
>> .o:
>>      /c/Projectos/eNotify/src/native/port
>>     $ gcc.exe -o extprg.exe ei.c erl_comm.c
>> /c/otp_src_R13B/lib/erl_interface/obj/i686-pc-mingw32/*.o
>> /c/otp_src_R13B/lib/erl_interface/obj/i686-pc-mingw32/liberl_interface.a
>> -Ic:/otp_src_R13B/lib/erl_interface/include -lwsock32
>>
>> And guess what... It worked! :)
>>
>> So what am I missing here? Is it normal that "ar"ed files don't link
>> correctly? Is it mingw? Or is it just me? :)
>> Any(!!!) clues are more than welcome! :)
>>
>> Cheers,
>> Davide :)
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20090423/43a2bd05/attachment.html>


More information about the erlang-questions mailing list