I am learning to create shared libraries in Linux, subsequently to develop parallelised scientific computing programs. I took the toy example from here for shared library. I modified the Makefile from this question to suit the toy example. My Makefile now is
CC = mpicc
INCDIR = -I ./
CFLAGS = -Wall -rdynamic -g -fPIC $(INCDIR)
LIBADD = -L ./ -lcalc_mean
all: dyn_main.out
dyn_main.out: libcalc_mean.so
$(CC) -o $# main.c $(LIBADD)
libcalc_mean.so: calc_mean.o
$(CC) -shared --export-dynamic -o $# $<
calc_mean.o: calc_mean.c
$(CC) $(CFLAGS) -c $<
clean :
-rm *.o
-rm *.out
-rm *.so
.PHONY:
clean
When I make with CC = gcc in the Makefile, things run fine. I could run the binary even with mpirun.
When I have CC = mpicc in the Makefile, I get the following error.
mpicc -Wall -rdynamic -g -fPIC -I ./ -c calc_mean.c
mpicc -shared --export-dynamic -o libcalc_mean.so calc_mean.o
mpicc -o dyn_main.out main.c -L ./ -lcalc_mean
/home/elan/localinstalls/lib/libmpi.so: undefined reference to `pthread_key_create'
/home/elan/localinstalls/lib/libmpi.so: undefined reference to `pthread_getspecific'
/home/elan/localinstalls/lib/libmpi.so: undefined reference to `pthread_create'
/home/elan/localinstalls/lib/libmpi.so: undefined reference to `pthread_atfork'
/home/elan/localinstalls/lib/libmpi.so: undefined reference to `pthread_setspecific'
/home/elan/localinstalls/lib/libmpi.so: undefined reference to `pthread_join'
collect2: ld returned 1 exit status
make: *** [dyn_main.out] Error 1
I added the path to libpthread.so,.a to LD_LIBRARY_PATH, but no avail. I have a self compiled openmpi-1.5.4. If this were a openmpi dependency, shouldn't it have been resolved when I configured it?
Is this error familiar? I am using Ubuntu 11.04, with gcc 4.5.2. I already built and run some mpi parallel programs successfully. But they are large packages configured with autotools. One of the config.log s display the same error. But even that one runs fine.
References to / examples of creating static/shared libraries with mpi will also be appreciated (though Openmpi discourages fully static libraries.)
Thank you very much,
Elan.
You should be able to just add -lpthread.
Open MPI probably didn't add it because it found that adding -lpthread wasn't necessary (likely due to some other dependency implicitly pulling in the pthread library). But with the linker flags you're using, you might well have changed that implicit dependency, so the pthread library isn't being pulled in automatically anymore.
If adding -lpthread to the command line fixes the issue, then see this FAQ entry for how to update the wrapper compilers (E.g., add your own flags): http://www.open-mpi.org/faq/?category=mpi-apps#override-wrappers-after-v1.0
You can see what options the Open MPI compiler wrapper supplies to the underlying compiler and linker using the -showme option or one of its specific variants:
-showme:compile to just show the compiler flags
-showme:link to just show the linker flags
For example:
$ mpicc -showme
icc -I/opt/MPI/openmpi-1.5.3/linux/intel/include -I/opt/MPI/openmpi-1.5.3/linux/intel/include/openmpi -fexceptions -pthread -I/opt/MPI/openmpi-1.5.3/linux/intel/lib -Wl,-rpath,/opt/MPI/openmpi-1.5.3/linux/intel/lib -I/opt/MPI/openmpi-1.5.3/linux/intel/lib -L/opt/MPI/openmpi-1.5.3/linux/intel/lib -lmpi -ldl -Wl,--export-dynamic -lnsl -lutil
Related
I am compiling a C++ application on Ubuntu 18.04.
The linker is unable to pickup the required functions from the library or it is not locating the right library
I have libcurl.so located at /usr/local/lib
nm -D lists all the functions I need with T prefix. Yet when I compile as follows
g++ -std=c++17 -lcurl tz.o main.o
I get
/usr/bin/ld: tz.o: in function 'date::curl_global()':
tz.cpp:(.text+0x9aef): undefined reference to 'curl_global_init'
I tried installing openssl-dev. No joy. So I uninstalled it.
try
g++ -std=c++17 tz.o main.o -lcurl
instead... g++ is shit in some ways, like argument ordering. (all i did was to make -lcurl the last argument instead of argument #3)
Is it possible to build a shared object file on Linux without using libc? I tried building the shared object using -nostdlib, and it complains that there is a conflicting type for built-in function 'memset'(I have my own version of the function defined within the shared object I am trying to build).
I am not using any libc functions from within the shared object file. I am building the shared object as follows :-
CC = gcc
CFLAGS = -Wall -Wextra -Werror -nostdlib
OUTPUTDIR = ./build
test: outputdir
$(CC) $(CFLAGS) -c -fPIC test.c -o ${OUTPUTDIR}/test.o
$(CC) $(CFLAGS) ${OUTPUTDIR}/test.o -shared -o ${OUTPUTDIR}/libtest.so
outputdir:
mkdir -p ${OUTPUTDIR}
clean:
rm -rf ${OUTPUTDIR}
If you link with -nostdlib, you should also compile with -ffreestanding and/or -fno-builtin as well.
You also have to be careful that you do not reference a libc.so.6 symbol without linking against glibc. Things may appear to work superficially, but it tends to introduce breakage in certain environments, especially once additional IFUNCs are added to glibc. (Intel did that with the ICC 16 compiler library.)
I have an error making a code project because of what I believe is a missing routine from lapack:
HomographyInit.cc:(.text+0x385): undefined reference to `dgesvd_'
I think I need to add lapack library somehow to my Makefile. Here is part of my Makefile:
CC = g++
COMPILEFLAGS = -I MY_CUSTOM_INCLUDE_PATH -D_LINUX -D_REENTRANT -Wall -O3 -march=nocona -msse3
LINKFLAGS = -L MY_CUSTOM_LINK_PATH -lGVars3 -lcvd
I tried doing the following to no avail:
CC = g++
COMPILEFLAGS = -I MY_CUSTOM_INCLUDE_PATH -D_LINUX -D_REENTRANT -Wall -O3 -march=nocona -msse3
LINKFLAGS = -L MY_CUSTOM_LINK_PATH -lGVars3 -lcvd **-llapack**
Result:
make
...
/usr/bin/ld: cannot find -llapack
collect2: ld returned 1 exit status
How can I add lapack to my project? I am pretty sure I installed it correctly, though would be willing to double-check that somehow.
It looks like liblapack isn't in the path that ld can find. I would suggest two things:
Establish a symbolic link manually. It is possible (and sometimes common) that ld cannot recognize liblapack.so.3gf or liblapack.so.3.0.1 or so are essentially liblapack.so. You can set up a link by ln -s liblapack.so.3gf liblapack.so
Install liblapack-dev package instead if you're using ubuntu or debian repos. For some unclear reasons, liblapack3gf is not the same as liblapack-dev. I am not sure if in any circumstances, both will do or not do the same thing.
I think the first item should be able to resolve your problem (hopefully).
On my computer the dynamic library is in /usr/lib64/liblapack.so.3.4.1 and contains the requested symbol:
$ nm -D /usr/lib64/liblapack.so.3.4.1 | grep dgesvd
0000000000189200 T dgesvd_
So I would guess that the place where your lapack is installed is not in the linker search path. You should add the flag -L/path/to/the/lapackdir to LINKFLAGS
I want to use one program as a shared library for an other program.
I started as follows:
I have a application which I have compiled using:
/usr/bin/g++ -I/usr/include/libxml2 -Xlinker -zmuldefs -fPIC -c a.cpp
/usr/bin/g++ -I/usr/include/libxml2 -Xlinker -zmuldefs -fPIC -c b.cpp
/usr/bin/g++ -I/usr/include/libxml2 -Xlinker -zmuldefs -fPIC -c c.cpp
Then I have created a shared object library from the objects I get from this file using this command:
g++ -fPIC -Xlinker -zmuldefs -shared -o libabc.so a.o b.o c.o
After this I get the libabc.so file which I copy to the
sudo cp libabc.so /usr/local/lib/libabc.so
Now when I compile my orignal application which will use this newly created library libabc.so using this command:
/usr/local/lib/libabd.so: undefined reference to `xmlXPathNewContext'
I get errors for all the functions I used from the included library libxml2 in the first application and the function which has this undefined reference is actually the library I include in the first program I mean I have tested it.
So kindly anyone guide me where I need corrections.
You may have to pass the path also using -I/path/to/library, or alternatively export it to LD_LIBRARY_PATH.
I don't see the command line that you used to link your application against your library, but I suppose that adding -lxml2 to the flags passed to the linker should solve the problem.
I am facing below errors when trying to statically link libDuma, Can you tell me how to ask g++ to use malloc from libDuma?
sunny#sunny-laptop:~/CodeTest$ g++ ./testDuma.cpp -g -o testDuma -static -lduma -pthread
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libc.a(malloc.o): In function `free':
(.text+0x4b00): multiple definition of `free'
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libduma.a(duma.o):(.text+0x25f0): first defined here
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libc.a(malloc.o): In function `malloc':
(.text+0x4bc0): multiple definition of `malloc'
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libduma.a(duma.o):(.text+0x2730): first defined here
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libc.a(malloc.o): In function `realloc':
(.text+0x5950): multiple definition of `realloc'
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libduma.a(duma.o):(.text+0x23d0): first defined here
collect2: ld returned 1 exit status
Don't force a completely static link (don't use the -static flag) -- doing so on any modern UNIX system is an extremely bad idea(TM).
Instead, link just the libduma statically. Either of these commands should work:
g++ ./testDuma.cpp -g -pthread -o testDuma /path/to/libduma.a
g++ ./testDuma.cpp -g -pthread -o testDuma -Wl,-Bstatic -lduma -Wl,-Bdynamic
Add -nodefaultlibs flag to not link to libc. Or, remove -lduma and link it dynamically after compilation with:
LD_PRELOAD=/usr/lib/libduma.so ./testDuma