I'm using two third party frameworks, one Swift and one Objective C inside my Xamarin iOS project. I was asked to add following Linker Flags for those frameworks.
-lz -lc++ -lstdc++ -ObjC
Once I add those flags, I'm getting build error
MTOUCH: Error MT5216: Native linking failed
My questions are,
What are the meanings of those Linker Flags ?
Is there a place that I can find the Linker Flags with their descriptions?
How can I know which Linker flags would need for a third party framework?
Related
In Linux I have a shared library somelib.so, which could be optionally compiled against several other shared libs, say, dep1 and dep2. Now I'm writing a client application which uses somelib, but I don't now in advance if somelib was compiled with dep1 and dep2 or not until I get a linker error.
Is there a way to find this out using CMake? I need something like
IF somelib DEPEND ON dep1 THEN...
... client application which uses somelib, but I don't now in advance
if somelib was compiled with dep1 and dep2 ... I need something like
IF somelib DEPEND ON dep1 THEN...
On Linux I believe the way to solve it is using LD linker options -Wl,--exclude-libs,ALL and -Wl,--as-needed.
Always include -ldep1 and -ldep2 as library options. Then use -Wl,--as-needed to exclude the libraries if unneeded.
If I recall correctly, this trick dates back 20 or 30 years or so for the math library -lm. Sometimes math symbols were included in glibc and other times they were included in -lm. So you always linked against -lm and allowed the linker to discard the -lm library with -Wl,--as-needed.
In fact the ld(1) man page says to push and pop state when using the trick:
One target for this option are specifications for pkg-config.
When used with the --libs option all possibly needed libraries
are listed and then possibly linked with all the time. It is
better to return something as follows:
-Wl,--push-state,--as-needed -libone -libtwo -Wl,--pop-state
-Wl,--exclude-libs,ALL is an option to keep you from re-exporting symbols from -ldep1 and -ldep2. If the libraries are not used then you should not need -Wl,--exclude-libs,ALL.
I believe the two CMake settings for a static library and shared object when building somelib.so are:
set(OUR_LINKER_FLAGS "-Wl,--exclude-libs,ALL -Wl,--as-needed -ldep1 -ldep2")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${OUR_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${OUR_LINKER_FLAGS}")
Also see ld(1) man page, CMAKE_MODULE_LINKER_FLAGS and CMAKE_SHARED_LINKER_FLAGS in the CMake docs. You might also be interested in CMAKE_EXE_LINKER_FLAGS if you are building executables.
Say I have an address acquired by __builtin_return_address(0).
Sometime later I want to translate it to a coreesponding function name.
There's dladdr(3) which works only for dynamic libraries.
Is there any way to receive function of any symbol (maybe by libunwind, backrace_symbol() etc.)?
Compile all your code (and perhaps even some shared libraries that you use) with debug info (-g). Notice that GCC enables to use both -g and some optimization flag like -O2 (of course, in that case, the debug info is "approximate"). So you can compile code with gcc -Wall -g -O2 etc....
Then use perhaps Ian Taylor's libbacktrace which is included in recent versions of GCC.
BTW, dladdr or backtrace_symbol might also work (but I recommend using libbacktrace because it is parsing DWARF info). And dladdr(3) does work on symbols from the executable itself. You may need to link your executable with -rdynamic flag.
Notice also that static symbols (notably static functions) "don't really exist" in the ELF executable (only global symbols are kept in it) so dladdr cannot give them. Be also aware of the visibility function attribute and pragma.
I'm trying to build my application with MSVC 2010 instead of GCC. With GCC everything works fine. My app uses boost_system and boost_thread libraries.
I built boost with VC2010 in "system" layout, that means the libraries are named just libboost_system.lib (and not libboost_system_compiler_threading_version_wtf_snafu.lib)
The libs reside in C:\Boost\lib,
the Makefile specifies
LFLAGS = /NOLOGO /INCREMENTAL:NO /SUBSYSTEM:CONSOLE
LIBS = /LIBPATH:C:/Boost/lib libboost_system.lib libboost_thread.lib Ws2_32.lib
when invoking nmake it compiles, but when trying to link it quits with
LINK : fatal error LNK1104: cannot open file 'libboost_date_time-vc100-mt-1_43.lib
I mean seriously, WTF? I told it to link libboost_systen.lib and libboost_thread.lib how come it tries to link libboost_data_time and why does it assume I built the libs in "tagged" layout??
How can I stop MSVC trying to be smart and guess what I might have wanted to link?
Thanks,
Philipp
This is a feature of the Boost libs with compatible compilers for automatic linking.
(Those convoluted library names cover the myriad of threading and linking options that are available on the platform; there are good reasons to use that convention on Windows...)
More information here:
http://www.boost.org/doc/libs/1_33_1/more/getting_started.html#auto-link
I can't find a page for a more recent version, but I believe the BOOST_ALL_NO_LIB and related options are all still valid in 1.43.
Assuming you are auto-linking (i.e. you've defined BOOST_ALL_DYN_LINK or library specific equivalents).
For layout 'system' you have to define the preprocessor macro:
BOOST_AUTO_LINK_NOMANGLE
to link to the correct library names.
For layout 'tagged' you have to define the preprocessor macro:
BOOST_AUTO_LINK_TAGGED
to link to the correct library names.
I don't know if you could do this override for some libraries and keep the default for others. That would be a very cumbersome setup I'd imagine.
Can anyone please suggest some way we can restrict exporting of our symbols to global symbol table?
Thanks in advance
Hi,
Thanks for replying...
Actually I have an executable which is statically linked to a third party library say "ver1.a" and also uses a third party ".so" file which is again linked with same library but different version say "ver2.a". Problem is implementation of both these versions is different. At the beginning, when executable is loaded, symbols from "ver1.a" will get exported to global symbol table. Now whenever ".so" is loaded it will try to refer to symbols from ver2.a, it will end up referring to symbols from "ver1.a" which were previously loaded.Thus crashing our binary.
we thought of a solution that we wont be exporting the symbols for executable to Global symbol table, thus when ".so" gets loaded and will try to use symbols from ver2.a it wont find it in global symbol table and it will use its own symbols i.e symbols from ver2.a
I cant find any way by which i can restrict exporting of symbols to global symbol table. I tried with --version-script and retain-symbol-file, but it didn't work. For -fvisibility=hidden option, its giving an error that " -f option may only be used with -shared". So I guess, this too like "--version-script" works only for shared libraries not for executable binaries.
code is in c++, OS-Linux, gcc version-3.2. It may not be possible to recompile any of the third party libraries and ".so"s. So option of recompiling "so' file with bsymbolic flag is ruled out.
Any help would be appreciated.
Pull in the 3rd party library with dlopen.
You might be able to avoid that by creating your own shared lib that hides all the third party symbols and only exposes your own API to them, but if all else fails dlopen gives you complete control.
I had, what sounds like, a similar issue/question: Segfault on C++ Plugin Library with Duplicate Symbols
If you can rebuild the 3rd party library, you could try adding the linker flag -Bsymbolic (the flag to gcc/g++ would be -Wl,-Bsymbolic). That might solve your issue. It all depends on the organization of your code and stuff, as there are caveats to using it:
http://www.technovelty.org/code/c/bsymbolic.html
http://software.intel.com/en-us/articles/performance-tools-for-software-developers-bsymbolic-can-cause-dangerous-side-effects/
If you can't rebuild it, according to the first caveat link:
In fact, the only thing the -Bsymbolic
flag does when building a shared
library is add a flag in the dynamic
section of the binary called
DT_SYMBOLIC.
So maybe there's a way to add the DT_SYMBOLIC flag to the dynamic section post-linking?
The simplest solution is to rename the symbols (by changing source code) in your executable so they don't conflict with the shared library in the first place.
The next simplest thing is to localize the "problem" symbols with 'objcopy -L problem_symbol'.
Finally, if you don't link directly with the third party library (but dlopen it instead, as bmargulies suggests), and none of your other shared libraries use of define the "problem" symbol, and you don't link with -rdynamic or one of its equivalents, then the symbol should not be exported to the dynamic symbol table of the executable, and thus you shouldn't have a conflict.
Note: 'nm a.out' will still, show the symbol as globally defined, but that doesn't matter for dynamic linking. You want to look at the dynamic symbol table of a.out with 'nm -D a.out'.
I'm writing some code that uses dynamic shared libraries as plugins.
My command line for building the shared libraries looks like:
cc -shared -fPIC -o module.so -g -Wall module.c
Within the module, I can call functions that are in any other shared library that has been loaded within the main executable.
However I cannot access (exported) functions that are in the executable itself (I get undefined symbol errors).
My call to dlopen looks like this:
void *handle = dlopen(plugin, RTLD_NOW);
Can anyone please advise how my module can call back to my executable, without having to put all of the executable's utility functions into yet another shared library?
Correct solution is to add -rdynamic to the link command of the main executable. This will add appropriate option to ld (which, when using GNU ld, happens to be --export-dynamic).
Adding --export-dynamic directly is technically incorrect: it's a linker option, and so should be added as -Wl,--export-dynamic, or -Wl,-E. This is also less portable than -rdynamic (other linkers have an equivalent, but the option itself is different).
I've found the answer myself.
I had to add the --export-dynamic flags to the link options for the main executable.
When creating a dynamically linked
executable, add all symbols to the
dynamic symbol table. The dynamic
symbol table is the set of symbols
which are visible from dynamic objects
at run time.
If you do not use this option, the
dynamic symbol table will normally
contain only those symbols which are
referenced by some dynamic object
mentioned in the link.
If you use "dlopen" to load a dynamic
object which needs to refer back to
the symbols defined by the program,
rather than some other dynamic object,
then you will probably need to use
this option when linking the program
itself.
When I encountered the same problem, I just used the following solution. Before loading any plugin, just load the program itself, bringing its symbols to dynamic tables:
dlopen(NULL,RTLD_NOW|RTLD_GLOBAL);
I think the solution is better. The reason is that, it also solves the same problem if you
a) your program (or a trird-party module) is linked (not in runtime) against the shared library, which symbols need to be in dynamic table;
b) can not recompile that module with -rdynamic flag.