【问题标题】:linking 3rd party static libs in cgo library在 cgo 库中链接 3rd 方静态库
【发布时间】:2014-09-02 18:47:49
【问题描述】:

我有一个为 C++ OpenImageIO 库 (OpenImageiGO) 提供绑定的 Go 库。我一直很高兴通过标准动态链接到 libOpenImageIO 来构建我的绑定,但现在我正在尝试静态链接。我遇到了一个问题,无论我尝试哪种标志组合,外部链接器都会失败并出现大量“未定义引用”错误。我似乎记得在过去看到过这个问题,说链接器看到符号的顺序存在问题。但我似乎再也找不到这个信息了。

这是我最近一次构建尝试的简短示例,试图让它链接到 boost、OpenColorIO 和 OpenImageIO 的静态构建:

$ export CGO_CPPFLAGS="\
-I/path/to/boost/include \
-I/path/to/OpenColorIO/include \
-I/path/to/OpenImageIO/include"

$ export CGO_LDFLAGS="\
-L/path/to/boost/lib -lboost_thread_static -lboost_system_static \
-L/path/to/OpenColorIO/lib -lopencolorio \
-L/path/to/OpenImageIO/lib -lOpenImageIO"

$ go build -v -x --ldflags '-extldflags "-static"'  github.com/justinfx/openimageigo
...
CGO_LDFLAGS="/path/to/boost/lib/libboost_system_static.a" "/path/to/boost/lib/libboost_thread_static.a" "/path/to/OpenColorIO/lib/libopencolorio.a" "/path/to/OpenImageIO/lib/libOpenImageIO.a" "-lstdc++" /vol/apps/go/1.3.0/pkg/tool/linux_amd64/cgo -objdir $WORK/github.com/justinfx/openimageigo/_obj/ -- -I/path/to/boost/include -I/path/to/OpenColorIO/include -I/path/to/OpenImageIO/include -I./cpp -I $WORK/github.com/justinfx/openimageigo/_obj/ -I/path/to/boost/include -I/path/to/OpenColorIO/include -I/path/to/OpenImageIO/include color.go imagebuf.go imagebufalgo.go imagecache.go imageinput.go imageoutput.go imagespec.go oiio.go roi.go
...
/usr/bin/g++ -I . -fPIC -m64 -pthread -fmessage-length=0 -I/path/to/boost/include -I/path/to/OpenColorIO/include -I/path/to/OpenImageIO/include -I./cpp -I $WORK/github.com/justinfx/openimageigo/_obj/ -g -O2 -o $WORK/github.com/justinfx/openimageigo/_obj/all.cpp.o -c ./all.cpp

/usr/bin/g++ -I . -fPIC -m64 -pthread -fmessage-length=0 -o $WORK/github.com/justinfx/openimageigo/_obj/_cgo_.o $WORK/github.com/justinfx/openimageigo/_obj/_cgo_main.o $WORK/github.com/justinfx/openimageigo/_obj/_cgo_export.o $WORK/github.com/justinfx/openimageigo/_obj/color.cgo2.o $WORK/github.com/justinfx/openimageigo/_obj/imagebuf.cgo2.o $WORK/github.com/justinfx/openimageigo/_obj/imagebufalgo.cgo2.o $WORK/github.com/justinfx/openimageigo/_obj/imagecache.cgo2.o $WORK/github.com/justinfx/openimageigo/_obj/imageinput.cgo2.o $WORK/github.com/justinfx/openimageigo/_obj/imageoutput.cgo2.o $WORK/github.com/justinfx/openimageigo/_obj/imagespec.cgo2.o $WORK/github.com/justinfx/openimageigo/_obj/oiio.cgo2.o $WORK/github.com/justinfx/openimageigo/_obj/roi.cgo2.o $WORK/github.com/justinfx/openimageigo/_obj/all.cpp.o /path/to/boost/lib/libboost_system_static.a /path/to/boost/lib/libboost_thread_static.a /path/to/OpenColorIO/lib/libopencolorio.a /path/to/OpenImageIO/lib/libOpenImageIO.a -lstdc++

这里有一些精心挑选的错误,因为它是一个很长的输出:

/path/to/OpenImageIO/lib/libOpenImageIO.a(OpenImageIO_dist^src^libOpenImageIO^color_ocio.cpp.o): In function `ColorConfig':
/path/to/OpenImageIO/OpenImageIO_dist/src/libOpenImageIO/color_ocio.cpp:141: undefined reference to `OpenColorIO::v1::SetLoggingLevel(OpenColorIO::v1::LoggingLevel)'
...
/path/to/OpenImageIO/lib/libOpenImageIO.a(OpenImageIO_dist^src^libOpenImageIO^imagebufalgo_copy.cpp.o): In function `boost::shared_mutex::lock()':
/path/to/boost/include/boost/thread/pthread/shared_mutex.hpp:138: undefined reference to `boost::this_thread::disable_interruption::~disable_interruption()'

OpenImageIO 似乎无法找到 OpenColorIO 的参考。而且,OpenImageIO 似乎无法找到提升的参考。似乎链接期间发生的事情的顺序并没有使 OpenColorIO 或增强符号对 OpenImageIO 可用,所以我得到了一堆符号错误。

我希望我正在做一些可以在我的构建过程中纠正的简单而愚蠢的事情。但是与外部库的 cgo 静态链接似乎比默认的动态链接方法更复杂。

更新 #1

@james-henstridge 给出的答案是正确的,我几乎完全建成,除了最后一次打嗝。 OpenColorIO 需要的 yaml-cpp 引用失败,即使我的顺序似乎正确。

这是我最新的环境,我已经完成了所有必须添加的显式静态库:

$ export CGO_CPPFLAGS="-I/usr/local/include -I/usr/include"

$ export CGO_LDFLAGS="\
-L/usr/local/lib \
-L/usr/lib \
-L/usr/lib/x86_64-linux-gnu \
-lOpenImageIO \
-lHalf -lIex -lfreetype -lIlmThread -lImath -lIlmImf -lIlmThread \
-lOpenColorIO \
-lyaml-cpp -ltinyxml \
-lboost_regex -lboost_filesystem -lboost_thread -lboost_system \
-ltiff -lgif -lpng -ljpeg -lz \
-lrt -ldl"

$ go test -v -x --ldflags '-extldflags "-static"' github.com/justinfx/openimageigo
...
/home/justin/src/OpenColorIO/src/core/OCIOYaml.cpp:329: undefined reference to `YAML::Node::begin() const'
...
/home/justin/src/OpenColorIO/build/ext/dist/include/yaml-cpp/nodereadimpl.h:79: undefined reference to `YAML::Node::GetScalar(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) const'
...
/usr/local/lib/libOpenColorIO.a(OCIOYaml.cpp.o): In function `_FindFromNodeAtIndex':
/home/justin/src/OpenColorIO/build/ext/dist/include/yaml-cpp/nodeutil.h:53: undefined reference to `YAML::Node::FindAtIndex(unsigned long) const'
collect2: ld returned 1 exit status

更新 #2

不要介意更新 #1。它专门与OpenColorIO 相关,而不是一般问题。

【问题讨论】:

    标签: c++ go static-linking cgo


    【解决方案1】:

    当您与静态库链接时,-l 标志的顺序很重要。如果您使用-lfoo -lbar -lbaz 链接,则libbar.a 所需的任何符号将仅在libbar.alibbaz.a 中搜索。即使libfoo.a 包含您要查找的符号,链接器也不会找到它们。

    正在发生的情况是,对于每个库,链接器都会解压缩存档并添加包含之前所引用的符号的目标文件。如果不需要存档中的特定目标文件,则将其忽略。

    修复方法是确保在链接器标志中列出每个库之前它所依赖的任何库。如果存在任何依赖循环(不应该存在),则可能需要列出两次库。

    【讨论】:

    • 哦,所以如果我先列出 OpenImageIO,然后列出 OpenColorIO(前者需要),然后是 boost(其他需要),这可能已经编译了吗?将测试并报告!
    • 非常感谢。这似乎是问题所在。如果您不介意最后看一下我对原始问题的更新?在成功链接之前,最后一个引用似乎仍然给我带来麻烦,但这一个有点不同,因为我认为我在这里有正确的顺序。
    • libyaml-cpp.a 是如何构建的? ranlib 是否作为构建过程的一部分在生成的存档上运行?否则,您可能会遇到解决存档中符号依赖关系的问题。
    • 你知道吗?可能无视我对yaml-cpp 的问题。显然OpenColorIO(依赖)有某种未导出的设置与yaml-cpptinyxml。我在工作中遇到与在家中相同的问题。最有可能与此相关:github.com/imageworks/OpenColorIO/issues/318
    • 老歌但好人。这也适用于 Visual Studio 库。
    猜你喜欢
    • 2013-12-30
    • 2015-09-11
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多