DingoTim
DingoTim

Reputation: 97

c++: making a shared object from a static library

we are trying to make a c++ shared object library to interface with a static fortran library (compiled with mpif90). There is one fortran wrapper file compiled with gfortran or mpif90 (both fail) and one c++ wrapper file compiled with g++

The compilation command is

g++ -std=c++11 -ftemplate-depth-256 -Wno-inline -fPIC -O3 -pthread -fopenmp -v  -I /usr/lib/x86_64-linux-gnu/openmpi/include/ -I /opt/local/nextsim/modules/oasis/include -o /opt/local/nextsim/lib/liboasis.so.1.0 /opt/local/nextsim/objs/./oasis_cpp_interface.o /opt/local/nextsim/objs/./oasis_cpp_interface_ftn.o /docker_io/compile_oa3-mct/lib/libpsmile.MPI1.a /docker_io/compile_oa3-mct/lib/libmct.a /docker_io/compile_oa3-mct/lib/libmpeu.a /docker_io/compile_oa3-mct/lib/libscrip.a -fopenmp -Wl,-rpath,/usr/lib/x86_64-linux-gnu/openmpi/lib/ -L /usr/lib/x86_64-linux-gnu/openmpi/lib/ -lmpi_cxx -lmpi -ldl -lstdc++ -lpthread -L /docker_io/compile_oa3-mct/lib -Wl,-rpath,/usr/lib/x86_64-linux-gnu -L /usr/lib/x86_64-linux-gnu -lnetcdff -shared -Wl,-soname,liboasis.so.1

The error it gives is:

/usr/bin/x86_64-linux-gnu-ld: /docker_io/compile_oa3-mct/lib/libpsmile.MPI1.a(mod_oasis_auxiliary_routines.o): relocation R_X86_64_PC32 against symbol `__mod_oasis_data_MOD_mpi_comm_local' can not be used when making a shared object; recompile with -fPIC
/usr/bin/x86_64-linux-gnu-ld: final link failed: Bad value

As you can see we already compiled with -fPIC (as was the fortran library and the c++ objects). I also tried linking the fortran objects instead of the libraries, but they were also using some other static libraries which gave the same error.

Actually for some reason, our code compiles on one particular server, but not another, and not inside docker (ubuntu) so the problem is a little puzzling.

Upvotes: 0

Views: 253

Answers (1)

Mike Kinghan
Mike Kinghan

Reputation: 61610

The -fPIC option is ineffective in your commandline:

g++ -std=c++11 -ftemplate-depth-256 -Wno-inline -fPIC -O3 -pthread -fopenmp -v \
-I /usr/lib/x86_64-linux-gnu/openmpi/include/ -I /opt/local/nextsim/modules/oasis/include \
-o /opt/local/nextsim/lib/liboasis.so.1.0 \
/opt/local/nextsim/objs/./oasis_cpp_interface.o \
/opt/local/nextsim/objs/./oasis_cpp_interface_ftn.o \
/docker_io/compile_oa3-mct/lib/libpsmile.MPI1.a \
/docker_io/compile_oa3-mct/lib/libmct.a \
/docker_io/compile_oa3-mct/lib/libmpeu.a \
/docker_io/compile_oa3-mct/lib/libscrip.a \
-fopenmp -Wl,-rpath,/usr/lib/x86_64-linux-gnu/openmpi/lib/ \
-L /usr/lib/x86_64-linux-gnu/openmpi/lib/ \
-lmpi_cxx -lmpi -ldl -lstdc++ -lpthread -L /docker_io/compile_oa3-mct/lib \
-Wl,-rpath,/usr/lib/x86_64-linux-gnu \
-L /usr/lib/x86_64-linux-gnu -lnetcdff \
-shared -Wl,-soname,liboasis.so.1

because -fPIC is a compilation option and this is a linkage command. No source files are input. Compilation has already been done. The other compilation options in this commandline:

std=c++11 -ftemplate-depth-256 -Wno-inline -fopenmp
-I /usr/lib/x86_64-linux-gnu/openmpi/include/ -I /opt/local/nextsim/modules/oasis/include \

are also redundant.

The linker says that the object file libpsmile.MPI1.a(mod_oasis_auxiliary_routines.o), i.e. member mod_oasis_auxiliary_routines.o of the archive libpsmile.MPI1.a, was not compiled with -fPIC. You say that:

we already compiled with -fPIC (as was the fortran library and the c++ objects).

but it's more likely that -fPIC was not used in the compilation of the object files in libpsmile.MPI1.a than that the linker is mistaken.

Recompile all the object files input to the linkage, including those within static libraries, ensuring that -fPIC is enabled. All object files that are linked into a shared library must be Position-Independent-Code.

Upvotes: 1

Related Questions