【问题标题】:How to link libgomp statically when linking other libraries dynamically?动态链接其他库时如何静态链接libgomp?
【发布时间】:2015-02-25 15:12:56
【问题描述】:

我正在尝试使用我从 www.mingw.org/ 在 Windows 8 64 位计算机上下载的 MinGW + MSYS(使用 GCC4.8.1)构建一个用 C++ 编写的图像处理程序,该程序依赖于以下库

LibJPEG

BLAS 和 LAPACK

犰狳

OpenMP

我已经成功编译了所有的源代码文件(当然带有-fopenmp标志),然后我链接了以下语句:

g++ -o ./build/rspfitter {.o 文件列表} -L{库路径} -ljpeg -lopenblas -lgomp -lpthread

可执行文件已正确生成。但是,它要求以下 dll:

libgomp-1.dll

libpthread-2.dll

pthreadGC2.dll

我认为静态链接 libgomp 和 libpthread 可能更好,这样我就可以最大限度地减少部署程序所需的 dll 数量(上述三个 dll 并不是程序唯一依赖的)。所以我尝试使用以下命令仅静态链接 libgomp 和 libpthread:

g++ -o ./build/rspfitter {.o 文件列表} -L{库路径} -ljpeg -lopenblas -Wl,-static -lgomp -lpthread

但这一次它失败并显示以下错误消息:

d:/mingw/bin/../lib/gcc/mingw32/4.8.1\libgomp.a(env.o):(.text.startup+0xbfe): 对 `_imp__pthread_attr_init' 的未定义引用

d:/mingw/bin/../lib/gcc/mingw32/4.8.1\libgomp.a(env.o):(.text.startup+0xc13): 对 `_imp__pthread_attr_setdetachstate' 的未定义引用

d:/mingw/bin/../lib/gcc/mingw32/4.8.1\libgomp.a(env.o):(.text.startup+0x3c): 对 `_imp__pthread_attr_setstacksize' 的未定义引用

d:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe:

d:/mingw/bin/../lib/gcc/mingw32/4.8.1\libgomp.a(env.o):重定位错误 `.ctors' 部分中的地址 0x0

d:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe:

最终链接失败:无效操作

然后我尝试使用与 CodeLite 一起安装的 MinGW + GCC 4.8.1 环境执行完全相同的编译和链接命令。它再次失败并显示不同的错误消息:

./tmp/hshfitcmdline.o:hshfitcmdline.cpp:(.text.unlikely+0x105): 对 `_Unwind_Resume' 的未定义引用

./tmp/hshfitcmdline.o:hshfitcmdline.cpp:(.text$_ZN9NormalMapD1Ev[__ZN9NormalMapD1Ev]+0xb4): 对 `_Unwind_Resume' 的未定义引用

d:/mingw-4.8.1/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe:

./tmp/hshfitcmdline.o: 部分中的错误重定位地址 0xb4 `.text$_ZN9NormalMapD1Ev[__ZN9NormalMapD1Ev]'

d:/mingw-4.8.1/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe:

最终链接失败:collect2.exe 操作无效:错误:ld 返回

1 退出状态 make: *** [build/rspfitter] 错误 1

我确认对于 MinGW 的两个安装,文件“libgomp.a”/“libgomp.dll.a”都存在于 [MinGW 目录]/lib/gcc/mingw32/4.8.1/ 上。但是,它们的大小不同!从 MinGW.org 下载的安装中,'libgomp.a' 为 86kb,“libgomp.dll.a”为 87kb;但是,在 CodeLite 安装中,大小分别为 74kB 和 148Kb。

现在我想知道:

  1. 两个 MinGW 系统给出错误消息的原因可能是什么?会不会是我从 MinGW 下载的静态库损坏了?但是动态链接在两个系统上都非常好。

  2. 究竟如何才能正确静态链接 libgomp?

谢谢

【问题讨论】:

标签: c++ gcc mingw openmp static-linking


【解决方案1】:

要静态链接libgomp,你可以这样做

ln -s `g++ --print-file-name=libgomp.a` && \
g++ foo.o -static-libgcc -static-libstdc++ -L. -o foo -fopenmp -ljpeg -lopenblas

但是,您的可执行文件仍将依赖于 pthread dll。您收到错误的原因是 libc 仍在动态链接。要解决此问题,您还必须静态链接 libc

ln -s `g++ --print-file-name=libpthread.a` && \
ln -s `g++ --print-file-name=libc.a` && \
g++ foo.o -static-libgcc -static-libstdc++ -L. -o foo -fopenmp -ljpeg -lopenblas

但是,如果 openblasjpeg 库依赖于 libc,那么可能仍然存在未定义的引用。

【讨论】:

  • 非常感谢。问题解决了。很抱歉延迟接受。
  • @MingjingZhang,成功了!很高兴知道。我放弃了在 Linux 上的静态链接,但在 Windows 上似乎还可以。
  • @Boson,对不起,我必须更新我的回复。我观察到的是可执行文件的大小从 1.19MB 增加到大约 1.4MB,并且它在同一个文件夹中没有 dll 的情况下运行,所以我认为它有效。直到刚才我才意识到我在某个时候将 dll 的路径添加为环境变量,而 exec 实际上在那里调用了 dll。如果我删除该变量,它仍然会报告缺少 dll 错误。增加的大小可能是由于 -static-libstdc++。无论如何,我的主管认为可以使用 dll 发布它;我想我现在可以跳过这个问题。感谢您的帮助!
  • @MingjingZhang,下次使用Dependency Walker查找它所依赖的DLL。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-10
  • 1970-01-01
  • 2012-10-22
  • 2014-01-06
  • 2020-01-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多