[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Using Lua in dynamic modules with static linking
- From: Andrew Gierth <andrew@...>
- Date: Wed, 27 Feb 2019 00:47:34 +0000
>>>>> "William" == William Ahern <email@example.com> writes:
William> There are at least two (maybe three) ways to hide the symbols:
This is an issue we've had to deal with in PostgreSQL, so we have
working examples of methods to deal with it on a fairly wide range of
platforms. (In our case, we have some functions that have "frontend" and
"backend" versions with the same name, where the "backend" version is
linked into the postgres server binary, but that binary sometimes needs
to load dynamic modules that contain frontend code and which have been
linked against the frontend version.)
We actually went so far as to include an explicit "link canary" file
that we can test to ensure that functions have not been mis-linked to
the wrong versions.
You can see the compiler options PostgreSQL uses for building shared
libraries (including dynamically loaded modules) for all our platforms
except Windows here:
(for Windows there's a bunch of scripts under src/tools/msvc)
William> 1.a) #include the Lua source into the same C (or C++) source
William> file as the extension module and set LUA_API to "static". This
William> is the obvious, standard's compliant approach. However, this
William> can be unwieldy (especially for C++) and not great for
William> incremental builds.
This would have been impractical for us.
William> 1.b) Use GCC's or clang's -fvisibility=hidden flag when
William> building Lua. (Or try setting LUA_API to
William> '__attribute__((visibility ("hudden")))'). This has the same
William> effect as 1.a (truly "static" linking) but you can still build
William> and cross-link separate .o object files.
A better variation on this is to link your dynamic libraries with an
explicit exports / version-script file that defines an exported symbol
API (optionally with a version) and hides all other symbols.
We currently use export files on AIX , MacOS, *BSD, Linux, and Windows.
(On Windows, and I believe also on AIX, the export file is required.) We
would likely use it on Solaris(-derivatives) and other ELF platforms if
anyone cared enough about them to contribute a tested makefile patch.
For Linux and *BSD the version script can just look something like:
and link with -Wl,--version-script=filename
For MacOS it's a plain list of symbols with _ prepended, and the compile
option is -exported_symbols_list filename
William> 1.c) I think Mach-O has the ability to tweak symbol precedence
William> to favor symbols defined in same shared object. I haven't
William> explored this, though.
I don't know about MacOS, but a fair range of platforms support the
-Bsymbolic linker option, which means (when linking a shared library)
"resolve symbols within the library to their definitions now, rather
than at runtime". This is the option we use on HP-UX and Solaris.
William> I'm not very familiar with Visual Studio so don't know how to
William> do things there. If Visual Studio doesn't support something
William> like -fvisibility=hidden you could try clang.
Windows DLL symbol resolution is not like ELF; one of the big
differences is that DLLs export only the symbols you explicitly tell
them to export (in the .DEF file) and nothing else.