c++:从静态库创建共享对象

标签 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) 内部,所以这个问题有点令人费解。

最佳答案

-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 是一个编译 选项并且这是一个链接 命令。没有源文件 是输入。编译已经完成。此命令行中的其他编译选项:

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), 即文件 libpsmile.MPI1.a 的成员 mod_oasis_auxiliary_routines.o,不是 使用 -fPIC 编译。你说:

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

但更有可能的是 -fPIC 没有被用于编译 libpsmile.MPI1.a 中的目标文件比链接器错误。

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

关于c++:从静态库创建共享对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54195559/

相关文章:

c++ - 带有 push_back 的 libstdc++ 错误可复制 vecor 元素

generics - Fortran 泛型接口(interface)的警告,其中包含虚拟参数是无限多态指针的过程

c++ - Fortran 77 代码到 C++ 的转换

C_F_POINTER 导致未定义的数组

c - 使用 __attribute__ ((section "STACK")) 将变量准确地放在 ("STACK"部分中可能有什么意义?

c++ - 从基类虚拟继承

c++ - 我可以使用 QBS 创建用户定义的运行配置文件吗?

c++ - 二维 vector 排序算法

c - 尝试将 fmemopen 文件描述符与 stdin 相关联时出现错误的文件描述符错误

gcc - 想要很好地理解内存级别的共享库