背景信息:我正在交叉编译一个名为cpr的库。它可以很好地编译和链接。当我去使用它时,我得到了 C++ 版本不匹配的信息:
/tmp/[project name]: /usr/lib/libstdc++.so.6: version 'CXXABI_1.3.11' not found (required by /tmp/[project name]
/tmp/[project name]: /usr/lib/libstdc++.so.6: version 'GLIBCXX_3.4.26' not found (required by /tmp/[project name]
我不知道什么或为什么有些东西试图使用 /usr/lib 中的任何东西。我也尝试过 VisualGDB 中的详细模式,但我无法追踪导致此问题的原因。
cpr 取决于旋度。由于我的构建架构与目标架构不同,我发现我还必须交叉编译curl,这可能是导致此问题的原因。按照交叉编译的指示,它工作得很好。我可以执行网站上的示例。为了简单起见,我禁用了 SSL、ZLIB 以及大多数功能。我试图消除对任何依赖项的需要,因此完整的链应该是项目需要cpr需要curl。我专门构建并链接到静态curl,以避免依赖.so 库的问题。我怀疑这就是正在发生的事情,但我不确定。
我尝试了许多不同的配置,但这最终是让我走得最远的。 虽然curl工作得很好,但为了完整起见,这里是curl配置:
sudo ./configure --host=arm-linux-gnueabihf --build=x86_64-linux-gnu --without-ssl --disable-ipv6 --without-brotli --without-libpsl --without-nghttp2 --without-ngtcp2 --without-zstd --without-libidn2 --without-librtmp --without-zlib --disable-shared --enable-static --disable-threaded-resolver --disable-pthreads --prefix=/usr/arm-linux-gnueabihf AR=arm-linux-gnueabihf-gcc-ar-9 RANLIB=arm-linux-gnueabihf-gcc-ranlib-9 CC=/usr/bin/arm-linux-gnueabihf-gcc-9 CXX=/usr/bin/arm-linux-gnueabihf-g++ LD=arm-linux-gnueabihf-ld AS=arm-linux-gnueabihf-gcc-as CROSS_COMPILE=arm-linux-gnueabihf CFLAGS=-I/usr/arm-linux-gnueabihf/include LDFLAGS=-L/usr/arm-linux-gnueabihf/lib PATH=$PATH:/usr/arm-linux-gnueabihf/bin
相关env
参数:LDFLAGS=-L/usr/arm-linux-gnueabihf/lib
,CPPFLAGS=-I/usr/arm-linux-gnueabihf/include','PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/arm-linux-gnueabihf/bin:/usr/arm-linux-gnueabihf/bin
构建后我直接链接到/usr/arm-linux-gnueabihf/lib/libcurl.a
现在,这是 cpr 配置:
sudo cmake -DCURL_LIBRARY=/usr/arm-linux-gnueabihf/lib -DCURL_INCLUDE_DIR=/usr/arm-linux-gnueabihf/include -DCMAKE_INSTALL_PREFIX=/usr/arm-linux-gnueabihf -DCMAKE_TOOLCHAIN_FILE=/home/[username]/include/toolchain.cmake -DCPR_ENABLE_SSL=OFF -DCURL_ZLIB=OFF -DCPR_USE_SYSTEM_CURL=ON -DBUILD_SHARED_LIBS:BOOL=OFF --debug-output ..
工具链文件很简单:
set(CMAKE)SYSTEM)NAME Linux)
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc-9)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
set(CMAKE_FIND_ROOT_PATH /usr/bin)
我还尝试了 cpr 版本 1.9.7,因为它对 C++ 的要求较低,但没有骰子。它具有完全相同的错误消息。 我也尝试了curl版本7.68.0。
编译器位于 /usr/bin 中,这是我的 VisualGDB 工具链指向的位置。链接器目录是
/usr/arm-linux/gnueabihf/lib
,我链接到 pthread curl cpr
。 CFLAGS 为 -ggdb -ffunction-sections -O0 -DCURL_STATICLIB -I/usr/arm-linux-gnueabihf/include
,CXXFLAGS 为 std=gnu++2a -ggdb -ffunction-sections -O0 -DCURL_STATICLIB -I/usr/arm-linux-gnueabihf/include
。我尝试了许多不同的std
版本,包括17、14和11。所有结果都相同。
一个简单的
Post
就会导致错误。只要该行未被注释,代码就不会运行到该点。它会编译和链接得很好,但是当我去调试它时,它启动但不执行任何代码,而是吐出上面提到的错误。
const std::string role;
cpr::Response response = cpr::Post(cpr::Url{"192.168.1.2/login"},cpr::Payload{{role, "password"}});
更多可能混乱的信息:
我还尝试在标志的开头使用
-static
和 -Bstatic
以及 -static-libc++.
它们都没有改变结果。不过,libcstd++.a
中好像没有/usr/arm-linux-gnueabihf/lib
。我用apt install g++-arm-linux-gnueabihf
得到了它。
此外,我尝试显式链接
pthread.a
,但失败了(不会详细说明,除非您认为它相关,已经足够长了)。
显式链接到
libcurl.a
反而会导致类似的问题:
/tmp/[project name]: /usr/lib/libstdc++.so.6: version 'CXXABI_1.3.11' not found (required by /tmp/[project name]
/tmp/[project name]: /usr/lib/libstdc++.so.6: version 'GLIBCXX_3.4.26' not found (required by /tmp/[project name]
/tmp/[project name]: /lib/libc.so.6: version 'GLIBC2_28' not found (required by /tmp/[project name]
值得注意的是,这次包括
GLIBC
,并且该目录位于稍微不同的引导目录中。
显式链接到
libcpr.a
会导致相同的两个错误,尤其是这次,即使 cpr
函数仍然被注释掉。
编辑:我在cpr代码下面有一些curl代码,所以当cpr代码被注释掉时,curl代码仍然存在。
显式链接到
libcurl.a
和 libcpr.a
也会产生相同的三个错误,无论是否注释掉 cpr 代码
现在对于通配符,我做了一个
locate libstdc++.a
并在/usr/lib/gcc-cross/arm-linux-gnueabihf/9/libstdc++.a
中找到了一个。它编译和链接,我在调试时遇到的唯一错误是 /tmp/[project name]: symbol lookup error: /tmp/[project name]: undefined symbol: curl_mime_type
,只有当我 not 链接到 libcurl.a
而只是将“curl”添加到库名称时(实际上是 -lcurl
),才会发生这种情况。这感觉像是进步,但是这感觉不对,因为我应该链接到静态库。我认为最正确的应该是-lpthread
、libcurl.a
和libcpr.a
。逻辑是,pthread 是一个系统库,当我apt install
它时,它会随工具链一起提供,而另外两个是我自己构建的,应该需要链接到静态版本。
这里可能出现一些问题,我不确定问题到底是什么。
cpr 看起来正是我所需要的,但我就是无法让它工作。任何帮助将不胜感激。
最后,我不愿意将其发布到 cpr github 问题跟踪器上,因为我觉得这是我的构建过程的问题,而不是库的问题,但请让我知道我是否应该在那里发布。
提前致谢
当然问了之后我就明白了。事情就是这样进行的。无论如何,答案是我使用
-static
作为编译器标志而不是链接器标志。卷曲问题和心肺复苏问题是转移注意力的问题。真正的罪魁祸首其实是pthread
。这花费了我比我愿意承认的更多的时间。