我们正在尝试创建一个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)内部编译,因此问题有点令人困惑。
答案 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
。链接到共享库的所有 对象文件必须是“位置无关代码”。