C ++:从静态库制作共享库

时间:2019-01-15 08:59:07

标签: c++ fortran shared-libraries static-libraries

我们正在尝试创建一个c ++共享对象库,以与静态的fortran库(与mpif90编译)对接。有一个用gfortran或mpif90编译的fortran包装器文件(均失败)和一个用g ++编译的c ++包装器文件

编译命令为

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

它给出的错误是:

/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

如您所见,我们已经使用-fPIC进行了编译(fortran库和c ++对象也是如此)。我还尝试了链接fortran对象而不是库,但是它们还使用了其他一些会产生相同错误的静态库。

实际上,由于某种原因,我们的代码在一个特定的服务器上编译,而不是在另一台服务器上,并且不在docker(ubuntu)内部编译,因此问题有点令人困惑。

1 个答案:

答案 0 :(得分:1)

-fPIC选项在您的命令行中无效:

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

因为-fPIC编译选项,而这是 linkage 命令。没有源文件 被输入。编译已经完成。此命令行中的其他编译选项:

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 \

也是多余的。

链接器说目标文件libpsmile.MPI1.a(mod_oasis_auxiliary_routines.o), 即档案mod_oasis_auxiliary_routines.o的成员libpsmile.MPI1.a不是 用-fPIC编译。你说:

  

我们已经使用-fPIC进行了编译(fortran库和c ++对象也是如此)。

,但很有可能在编译以下内容时未使用-fPIC libpsmile.MPI1.a中的目标文件比链接器错误。

重新编译输入到链接的所有对象文件,包括静态库中的对象文件,确保已启用-fPIC。链接到共享库的所有 对象文件必须是“位置无关代码”。