Per Hedeland per@REDACTED
Mon Mar 27 18:40:07 CEST 2000

Ljung Magnus <etxmljg@REDACTED> wrote:
>I want to add an Erlang programming language interface to a Tcl/Tk
>application. I'm using the erl_interface to C with the libraries libei.a
>and liberl_interface.a. Compiling and inking a stand-alone application
>C-Erlang works. When compiling a loadable package to Tcl/Tk adding a Tcl
>command using one of the Erlang C library function something goes wrong.
>Loading the shared library in tclsh I get the error:  relocation error:
>file /home/etxmljg/application/app.o: symbol erl_init_nothreads:
>referenced symbol not found
>I guess this means that the runtime linker cant find the function in the
>Erlang library. The result is the same for PTHREADS and STHREADS as
>well. Is there any environment variable that I have missed or does it
>depend on how the Erlang libraries have been compiled?
>Compiler flags used:
>gcc -O2 -shared -fPIC -R/EDUP/Otp/0/lib/erl_interface-3.2/lib
>-I/EDUP/Tcl/0/include/ -L/EDUP/Tcl/0/lib
>-L/EDUP/Otp/0/lib/erl_interface-3.2/lib  \
> -lerl_interface -lei -lm -ltcl app.c -o

Hm, you're doing some pretty complex stuff here, and I'm not sure your
problems have much if anything to do with Erlang... - however the
solution seems simple: Move the 'app.c' earlier in the commandline, such
that it is before at least the '-L/.../erl_interface-3.2/lib
-lerl_interface -lei' part - the linker needs to have processed the
object produced from your app.c before it searches liberl_interface, in
order to know that it should pull in from the library the object that
satisfies the erl_init_nothreads reference (repeat for lots of other
references in this case, but dlopen() only reports the first failure).

That's why you generally have the library specifications towards the end
of a linker commandline... - and if you weren't building a "shared
object", you would have gotten the error at link time instead
(presumably your successful build used a very different commandline),
but since the reference may be satisfied at runtime in a way that the
linker knows nothing about (e.g. through being defined in the binary
that loads the object), it can't flag this as an error.

Another solution (with different properties) would presumably be to
build shared versions of libei and liberl_interface - this is left as an
exercise for the reader...:-)

--Per Hedeland

PS If the -R option above means what I think it does (it's not in my gcc
man page:-), i.e. runtime library search path, it's a no-op unless you
have put some shared libraries of your own in that directory.

More information about the erlang-questions mailing list