In a directory I have a C file and its header
/home/test/c_pro
f.c
f.h
libf.so
I have compiled the f.c into a dll called libf.so using the following command
gcc -c -fPIC f.c -o f.o
gcc f.o -shared -o f.so
I want to use this in my Rust project.
So in Rust project I have a build.rs
println!("cargo:rustc-link-search=/home/test/c_pro");
println!("cargo:rustc-link-lib=dylib=f")
When I run a cargo build the build fails with the following errors
/home/test/c_pro/f.so: undefined reference to `EC_KEY_new_by_curve_name'
collect2: error: ld returned 1 exit status
In my f.c I do some imports from openssl
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
and use symbols from these libraries.
Any ideas as to why the build fails? I am following the official doc and am relying on 2 build parameters
cargo:rustc-link-search so that cargo can know that he has to do a look up in this directory as well.
cargo:rustc-link-lib=dylib to tell what dynamic library to link to.
What am I missing here folks?
Thanks in advance.
EDIT+UPDATE:
I did as pointed out by #Uli Schlachter and it compiles but I get a runtime error stating that libf.so is not found.
ldd ./target/debug/test_f
libf.so => not found.
Any ideas?
Compile your shared object with
gcc -c -fPIC f.c -o f.o
gcc f.o -shared -o f.so -lssl
Related
When I am trying to compile the source code by 'make', the first steps that creating the '.o' files are running fine, and all '.o' files could be compiled normally. However, when compiling the executable file:
mpifort -fopenmp -O3 -o MyEXE sth.o main.o -L/usr/local/share/fftw-3.3.8/lib -lfftw3_mpi -lfftw3 -lm -L/usr/local/share/mpich-3.2/lib -lmpi -lz -L/usr/local/share/hdf5-1.8.18/lib -lhdf5_fortran -lhdf5hl_fortran -lhdf5_hl -lhdf5 -fPIC
it gots the following error:
/usr/bin/ld: /usr/local/share/hdf5-1.8.18/lib/libhdf5.a(H5PL.o): undefined reference to symbol 'dlclose##GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libdl.so.2: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
How could I solve this problem? Some pages suggest that it is due to the '-ldl- flag when calling c++ compiler, but I couldn't find a way to make it suitable for my cases.
The pages were right. Your HDF5 library libhdf5.a uses the function dlclose, which is defined in the library libdl. To use it, you need to simply add -ldl at the end of your mpifort command line.
I am trying to get OpenSSL to work, but it seems to have a problem with linking. Here is what I did:
I downloaded OpenSSL for Linux from https://www.openssl.org/source/ I tried versions 0.9.8zc, 1.0.0o and 1.0.1j, all with the same result.
I installed each OpenSSL version using ./config, make and sudo make install.
For debugging purposes, I went to /usr/lib/ssl and used sudo chmod -R 777 * to remove any restrictions that could have caused the error.
I created the following program:
main.c:
#include <errno.h>
#include <malloc.h>
#include <resolv.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
int main(void) {
SSL_load_error_strings();
return EXIT_SUCCESS;
}
I created the following makefile in the same directory as my .c file:
makefile:
all: main.o
cc -o main main.o -L/usr/local/ssl/lib/ -lcrypto -lssl
main.o: main.c
cc -c -Wall main.c -I/usr/local/ssl/include/ -o main.o
When I run the makefile, I get the following error:
cc -o main main.o -L/usr/local/ssl/lib/ -lcrypto -lssl
/usr/local/ssl/lib//libssl.a(ssl_err2.o): In function SSL_load_error_strings':
ssl_err2.c:(.text+0x4): undefined reference toERR_load_crypto_strings'
/usr/local/ssl/lib//libssl.a(ssl_err.o): In function ERR_load_SSL_strings':
ssl_err.c:(.text+0xc): undefined reference toERR_func_error_string'
ssl_err.c:(.text+0x28): undefined reference to ERR_load_strings'
ssl_err.c:(.text+0x3c): undefined reference toERR_load_strings'
collect2: ld returned 1 exit status
make: *** [all] Error 1
What am I doing wrong?
Cheers
Alex
As answered on the maillist by scott_n but for the record here, swap the order to -lssl -lcrypto.
Explanation: for static C libraries in general on nearly all systems, members of library files like libxxx.a are only pulled in by the linker if they define things referenced from translation units already linked i.e. to the left in the command line. OpenSSL libssl has (numerous) references to libcrypto. If you link -lcrypto first, those references haven't been seen, so the libcrypto files aren't linked; then you link -lssl and create the unsatisfied references. In cases of mutual dependency also called recursive dependency you may need to repeat a library like -lcrypto -lssl -lcrypto but OpenSSL has no such "backward" references.
Currently i'm working on a project to log data out of a Siemens PLC. To achieve this i'm using Snap7. Snap7 (http://snap7.sourceforge.net/) is a communication library.
I've managed to get it work on my linux desktop but when i try to cross-compile the snap7 library i get some errors
The error is generated when linking all of the object files.
g++ -shared -fPIC -o ../bin/mips-openwrt-linux-g++/libsnap7.so #"filelist.txt" -L. -lpthread -lrt -O3
/usr/bin/ld: ../temp/mips-openwrt-linux/sys_snap_msgsock.o: Relocations in generic ELF (EM: 8)
./temp/mips-openwrt-linux/sys_snap_msgsock.o: could not read symbols: File in wrong format
collect2: error: ld returned 1 exit status
make: *** [../bin/mips-openwrt-linux-g++/libsnap7.so] Error 1
If i'm correct i think it's using the wrong linker, it should use the linker of the toolchain located at: openwrt/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/
I've also tried to compile the software with mips-openwrt-linux-g++.
Now another error is given:
mips-openwrt-linux-g++ -shared -fPIC -o ../bin/mips-openwrt-linux-g++/libsnap7.so #"filelist.txt" -L. -lpthread -lrt -O3
openwrt/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/lib/gcc/mips-openwrt-linux-uclibc/4.8.3/../../../../mips-openwrt-linux-uclibc/bin/ld: ../temp/mips-openwrt-linux/sys_snap_msgsock.o: relocation R_MIPS_26 against `close' can not be used when making a shared object; recompile with -fPIC
../temp/mips-openwrt-linux/sys_snap_msgsock.o: could not read symbols: Bad value
collect2: error: ld returned 1 exit status
make: *** [../bin/mips-openwrt-linux-g++/libsnap7.so] Error 1
I hope someone is familiar with this error and can help me out.
Thanks in advance.
edit1:
There are some pre-compiled binaries. In the makefiles i changed the CC to my g++ directory. There is no LD flag so i cannot set my linker over there.
Can you cross compile and run a "hello world" program?
What is the output of file ../temp/mips-openwrt-linux/sys_snap_msgsock.o?
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 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