lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Coroutines once stated:
> 
> ANYWAY: Because the REPL is an example of how to embed Lua, my biggest
> suggestion would be to turn it into a dynamic liblua.so/liblua.dll
> with a defined main() -- so you could link to it and execute the
> library directly.  

  I've often wondered why more applications aren't themselves linkable
libraries [1].  It is possible:

GenericUnixLibary> /lib/tls/libc.so.6 
GNU C Library stable release version 2.3.4, by Roland McGrath et al.
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 3.4.6 20060404 (Red Hat 3.4.6-11).
Compiled on a Linux 2.4.20 system on 2010-04-18.
Available extensions:
        GNU libio by Per Bothner
        crypt add-on version 2.1 by Michael Glad and others
        Native POSIX Threads Library by Ulrich Drepper et al
        RT using linux kernel aio
        The C stubs add-on version 2.1.2.
        BIND-8.2.3-T5B
        NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk
        Glibc-2.0 compatibility add-on by Cristian Gafton 
        GNU Libidn by Simon Josefsson
Thread-local storage support included.
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.

but as I've learned---it's not quite as straightforward as you might think. 
As an example, I've add my own luaL_newstate() function to a project and
attempted to link it:

[spc]lucy:~/source/boston>make
gcc -std=c99 -pedantic -Wall -Wextra -g -c -o build/globals.o src/globals.c
gcc -std=c99 -pedantic -Wall -Wextra -g -rdynamic -o build/boston ...
/usr/local/lib/liblua.a(lauxlib.o)(.text+0x1184): In function `luaL_newstate':
: multiple definition of uaL_newstate'
build/globals.o(.text+0x0):src/globals.c:112: first defined here
/usr/bin/ld: Warning: size of symbol uaL_newstate' changed from 10 in build/globals.o to 52 in /usr/local/lib/liblua.a(lauxlib.o)
collect2: ld returned 1 exit status
make: *** [build/boston] Error 1

The in the GNU toolchain, you need to mark (in the library) that a symbol is
"weak"---that is, for a given symbol in a library, if you don't find it
defined anywhere else, use the definition in the library [3] (and for Lua,
none of the functions there are marked as "weak").  Marking a symbol as
"weak" uses a GCC extension as:

	int foo(int bar) __attribute__((weak))
	{
	}

and the GCC manual states:

	weak 
		The weak attribute causes the declaration to be emitted as a
		weak symbol rather than a global.  This is primarily useful
		in defining library functions that cna be overridden in user
		code, though it can also be used with non-function
		declarations.  Weak symbols are supported for ELF targets,
		and also for a.out targets when usign the GNU assembler and
		linker.

  The upshot is that for the GNU tool chain on a system using ELF, what you
want is possible as long as you make main() a weak symbol.  The issue now
becomes what to do on systems that don't use the GNU tool chain, or don't
use ELF (Windows, I'm looking at you).

  I'm not saying this isn't a worthy goal---I'm just pointing out how
convoluted it can get.

  -spc

[1]	I've though this since 1991 when I got my Amiga and realized that
	the object file format and the executable format were identical [2]

[2]	Unlike MS-DOS/Windows.  The object format is distinct from the
	executable format.  I think the same was true for Unix until the ELF
	standard came about.

[3]	I think the C standard mandates that user-defined symbols have
	precedence over library symbols such that a user can define a
	function called realloc() without it being an error [4].  Whether
	this extends to main() is another story.  

	And again, I'm not sure if this is actually IN the standard, or just
	somethign that POSIX allows, or even if it just happens to be the
	case on most Unix systems.

[4]	It doesn't have to even have the same semantics as the standard C
	library version, and as long as you don't call a Standard C function
	that calls realloc(), you should be okay.