Hi there!<br><br>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.<br>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.<br>
Either way, this might be useful for others that might be thinking of taking the same path... :)<br><br>My setup: Windows XP, OTP_R13B (I started off with OTP_R13A so paths will vary), MSYS + MinGW.<br><br>I started off following the erl_interface tutorial (<a href="http://erlang.org/doc/tutorial/erl_interface.html">http://erlang.org/doc/tutorial/erl_interface.html</a>) and things broke when I tried to compile:<br>
Davide@LAPTOP /c/Projectos/eNotify/src/native/port<br> $ 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<br> Warning: .drectve `/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" ' unrecognized<br>
Warning: .drectve `/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" ' unrecognized<br> Warning: .drectve `/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" ' unrecognized<br>
Warning: .drectve `/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" ' unrecognized<br> Warning: .drectve `/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" ' unrecognized<br>
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/<a href="http://obj.mt/win32/erl_malloc.o):(.text+0x47">obj.mt/win32/erl_malloc.o):(.text+0x47</a>): undefined reference to `ei_malloc'<br>
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/<a href="http://obj.mt/win32/erl_malloc.o):(.text+0x7c">obj.mt/win32/erl_malloc.o):(.text+0x7c</a>): undefined reference to `ei_realloc'<br>
(...)<br> <br> 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/<a href="http://obj.mt/win32/erl_error.o):(.text+0xa2">obj.mt/win32/erl_error.o):(.text+0xa2</a>): more undefined references to `__iob_func' follow<br>
collect2: ld returned 1 exit status<br><br>??? :|<br>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. :\<br><br>A little online research (<a href="http://erlang.org/pipermail/erlang-questions/2003-September/009854.html">http://erlang.org/pipermail/erlang-questions/2003-September/009854.html</a>) lead me think that the .lib files weren't GCC-compliant (and what I needed were .a files).<br>
So it would be a simple matter of getting the source and compiling erl_interface again (famous last words).<br><br>This is were someone can come in and say "No! No! No! You just had to do XPTO."<br>Considering no XPTO existed I went along to try and build erl_interface.<br>
<br>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/<a href="http://target.mk">target.mk</a>.<br>So I:<br><ul><li>got the otp_src_R13A sourcecode</li>
<li>did a ./configure</li><li>exported ERL_TOP=c:/otp_src_R13A</li><li>IIRC</li><ul><li>got something about a missing c:/otp_src_R13A/make/i686-pc-mingw32/<a href="http://otp.mk">otp.mk</a> folder</li><li>which I copied and renamed from c:/otp_src_R13A/make/<a href="http://otp.mk.in">otp.mk.in</a> (I'm guessing something is responsible for this step)<br>
</li></ul><li>added the necessary LIBS = -lwsock32 to c:/otp_src_R13A/lib/erl_interface/src/i686-pc-mingw32/Makefile</li><li>did a successful build</li><ul><li>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/</li>
<li>I created a folder c:/otp_src_R13A/lib/erl_interface/lib</li><li>and copied the two files there</li></ul></ul>I then tried using those two files to build the erl_interface tutorial program with this result:<br> Davide@LAPTOP /c/Projectos/eNotify/src/native/port<br>
$ 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<br> c:/otp_src_R13A/lib/erl_interface/lib/liberl_interface.a(erl_malloc.o): In function `erl_malloc':<br>
c:/otp_src_R13A/lib/erl_interface/src/legacy/erl_malloc.c:221: undefined reference to `ei_malloc'<br> c:/otp_src_R13A/lib/erl_interface/lib/liberl_interface.a(erl_malloc.o): In function `erl_realloc':<br>
c:/otp_src_R13A/lib/erl_interface/src/legacy/erl_malloc.c:231: undefined reference to `ei_realloc'<br> c:/otp_src_R13A/lib/erl_interface/lib/liberl_interface.a(erl_malloc.o): In function `erl_free':<br>
c:/otp_src_R13A/lib/erl_interface/src/legacy/erl_malloc.c:238: undefined reference to `ei_free'<br> ...<br> c:/otp_src_R13A/lib/erl_interface/lib/liberl_interface.a(erl_fix_alloc.o): In function `erl_eterm_alloc':<br>
c:/otp_src_R13A/lib/erl_interface/src/legacy/erl_fix_alloc.c:111: undefined reference to `__erl_errno_place'<br> collect2: ld returned 1 exit status<br><br>Which (other than the initial warnings) is exactly the same problem as the one I got with the original compilation.<br>
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:<br>c:/erl5.7/lib/erl_interface/obj.st.debug/i686-pc-mingw32/<br><br>Since the compiler was nagging me about missing .o files I just included them all in:<br>
Davide@LAPTOP /c/Projectos/eNotify/src/native/port<br> $ 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<br>
c:/otp_src_R13A/lib/erl_interface/include/erl_resolve.o: In function `erl_gethostbyname_r':<br> c:/otp_src_R13A/lib/erl_interface/src/legacy/erl_resolve.c:58: undefined reference to `ei_gethostbyname_r'<br>
c:/otp_src_R13A/lib/erl_interface/include/erl_resolve.o: In function `erl_gethostbyaddr_r':<br> c:/otp_src_R13A/lib/erl_interface/src/legacy/erl_resolve.c:70: undefined reference to `ei_gethostbyaddr_r'<br>
collect2: ld returned 1 exit status<br><br>:| This is another struggle.<br>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.<br>
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 (<a href="http://daniel.haxx.se/projects/portability/">http://daniel.haxx.se/projects/portability/</a>), 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. :)<br>
Of course that worked (to shut the compiler up at least). :P<br> Davide@LAPTOP /c/Projectos/eNotify/src/native/port<br> $ 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<br>
<br>Finally that got me a working extprg.exe that I was able to complete the tutorial with!<br><br><sleep break + upgrade to R13B><br><br>I picked up were I left off: being able to compile IF including all of the .o files.<br>
Some [n00b] research -> <a href="http://en.wikipedia.org/wiki/Ar_(Unix)">http://en.wikipedia.org/wiki/Ar_(Unix)</a> & <a href="http://linux.die.net/man/1/ar">http://linux.die.net/man/1/ar</a><br>Got me to check if all the .o files the linker was complaining about were getting archived in the two .a files.<br>
And indeed, all of them were on libei.a.<br><br>I unpacked the .o files from libeia.a and replaced it with a call to those .o:<br> Davide@LAPTOP /c/Projectos/eNotify/src/native/port<br> $ 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<br>
<br>And guess what... It worked! :)<br><br>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? :)<br>Any(!!!) clues are more than welcome! :)<br><br>
Cheers,<br>Davide :)<br>