Do you know how can I design the same concept that gsl is using to permit users to switch between various cblas implementation?
AFAIK, cblas dependency that gsl depends on should have been hard-coded into gsl library when gsl itself built.
2.2.2 Linking with an alternative BLAS library
The following command line shows how you would link the same
application with an alternative CBLAS library libcblas.a,
$ gcc example.o -lgsl -lcblas -lm
For the best performance an optimized platform-specific CBLAS library
should be used for -lcblas. The library must conform to the CBLAS
standard. The ATLAS package provides a portable high-performance BLAS
library with a CBLAS interface. It is free software and should be
installed for any work requiring fast vector and matrix operations.
The following command line will link with the ATLAS library and its
CBLAS interface,
$ gcc example.o -lgsl -lcblas -latlas -lm
If the ATLAS library is installed in a non-standard directory use the
-L option to add it to the search path, as described above.
For more information about BLAS functions see BLAS Support.
There's no special concept here – just multiple libraries implementing the same API and having the same ABI.
In other words, you write a program that uses function int do_stuff(char*) from #include foo.h. Libfoo.so is a shared library object that exports the symbol int do_stuff(char*), because it was generated off a program that contains an implementation of int do_stuff(char*).
If you now write a second library that implements all the same symbols that libfoo has, then you've got something that you could use in libfoo's place.
That's all that's happpening here. GSL uses BLAS symbols. BLAS defines what these symbols exactly are (read: their C function signature), so you can use whatever BLAS implementation you want. (assuming all was built with compatible compilers/linkers)
Blas library
gcc -c -Wall -Werror -fpic blas.cpp
gcc -shared -o libblas.so blas.o
GSL library, that is actually using blas but we don't link to it
gcc -c -Wall -Werror -fpic gsl.cpp
gcc -shared -o libgsl.so gsl.o
Example application that links against gsl and blas at the same time
gcc -Wall -o main main.cpp -L../mygsl -lgsl -L../mycblas -lblas
Related
In GCC, if I compile something into a shared library with GCC with g++ -shared func.cpp -o libfunc.so -fPIC, internal function calls to global symbols go through GOT in this generated shared library file. But if I compile with g++ func.cpp -o libfunc.so -mcmodel=large, it will not generate GOT but instead relocate by patching with R_X86_64_64 style relocation directly.
I want this behavior for executables as well. If I compile an executable with g++ main.cpp libfunc.so -o a.out, GCC will generate GOT for any function call from main.cpp to one defined in libfunc.so. I don't want this behavior. I want R_X86_64_64 style relocation. How can I achieve that?
Executables are compiled with -fPIE by default in modern distros for security reasons. To get old behavior add -no-pie to CFLAGS/CXXFLAGS.
I have a static libary mylib that depends on the math library.
If I first link mylib with math and then to my executable it works:
add_executable(myapp main.c)
target_link_libraries(mylib m)
target_link_libraries(myapp mylib)
But if I do the linking directly with the executable it fails when using gcc (with clang it works!)
add_executable(myapp main.c)
target_link_libraries(myapp m mylib)
Why does this make any difference?
I thought that it is anyway not possible to link libraries together?
When using cmake's target_link_libraries it does not mean you will link anything. It rather will create a dependency between a target and a library of type/action link.
I guess that the actually build line of the first example will result in something like that:
gcc -o myapp myapp.o -lmylib -lm
and the second one
gcc -o myapp myapp.o -lm -lmylib
. If mylib has references to m the second example (might) not link.
Try to run make VERBOSE=1 and study the command-line of the link-process to really understand what's happening. The linker of clang is maybe intelligent and waits for all calls to be linked before actually dropping a library during the link-process.
When using target_link_libraries it matters in which order you specify linked libraries.
This does not work when using gcc (at least in v4.6.3):
target_link_libraries(myapp m mylib)
while this works:
target_link_libraries(myapp mylib m)
So all libraries mylib depends on have to come after mylib.
If you track down the actual linker invocation with make VERBOSE=1 you will find this for the broken example:
gcc main.c.o -o luatest -rdynamic -lm mylib.a
and this for the working one:
gcc main.c.o -o luatest -rdynamic mylib.a -lm
Invoking clang with the exact same parameters works in both cases!
So #PatrickB seems to be right:
The linker of clang is maybe intelligent and waits for all calls to be
linked before actually dropping a library during the link-process.
how can I use pthread_spinlock_t in gcc 4.6.3?
Which flags do I have to specify at compile time?
I'm using Ubuntu 12.04!
Thanks
Just add the option -pthread or -lpthread when linking.
Options -std=c99/c11 will restrict the available library functions to those of C99/C11 standard library
For getting C99/C11 languages features/library and and POSIX (and some BSD and some GNU extension) APIs, one can use -std=gnu99 or -std=gnu11 option to GCC.
using gcc 4.5.1 in a 64bit x86 machine,I first create a.o as following:
g++ -fPIC -c a.cc -o a.o
then try to create liba.so as following:
g++ -static-libstdc++ -shared -W1,-soname,liba.so -o liba.so.1.0.0 a.o
but failed, with the following information:
relocation R_X86_64_32S against `vtable for __gnu_cxx::stdio_filebuf >' can not be used when making a shared object; recompile with -fPIC
I try to recompile libstdc++ library,with -fPIC added,but it failed anyway
I would expect that the static libstdc++ library was not build with -fPIC, and therefore can't be linked into a shared library.
Theoretically you could put non-PIC compiled code into a dynamic library, but it wouldn't be sharable (each program using it would have to have its own copy) so it's often not implemented.
You're going to need to link against the shared C++ library, make your own library a static library, or else rebuild libstdc++ yourself and grab the .o files from the build directory.
There is a similar question about this topic on stackoverflow, which refers to an external site about static linking of libstdc++.
If I run
gcc a.c -L /usr/lib -lexpat
and both libexpat.a and libexpat.so are in /usr lib which one is used by the linker?
By default the shared library (.so) will be chosen.
If you want to change this behavior, -static gcc option may be used
-static
On systems that support dynamic linking, this prevents linking
with the shared libraries. On other
systems, this option has no effect.