编译错误:未定义引用 '__atomic_fetch_add_4'

6
#include <opencv2/opencv.hpp>
using namespace cv;

int main()
{
  Mat img=imread("cornea.jpg");
  imshow("src",img);
  waitKey(0);
  return 0;
}

我使用以下命令进行编译:

g++ main.cpp -o main `pkg-config opencv --cflags --libs`

或者

g++ main.cpp -o main -I/usr/local/opencv-3.1.0/include/opencv -I/usr/local/opencv-3.1.0/include -L/usr/local/opencv-3.1.0/lib -lopencv_shape -lopencv_stitching -lopencv_objdetect -lopencv_superres -lopencv_videostab -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_ml -lopencv_imgproc -lopencv_flann -lopencv_core -lpng -lz -ltiff -ljasper -ljpeg -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgio-2.0 -lpangoft2-1.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo -lpango-1.0 -lfontconfig -lgobject-2.0 -lfreetype -lgthread-2.0 -lglib-2.0 -ldc1394 -lv4l1 -lv4l2 -lavcodec -lavformat -lavutil -lswscale -ldl -lm -lpthread -lrt

这给了我以下错误:

/tmp/ccoZCMRO.o:在函数 ‘cv::Mat::release()’ 中:main.cpp:(.text._ZN2cv3Mat7releaseEv[_ZN2cv3Mat7releaseEv]+0x22):对‘__atomic_fetch_add_4’的引用未定义
collect2: error: ld returned 1 exit status

我正在使用虚拟机中Ubuntu 14.04终端中的opencv 3.1.0!


2
也许还有更有趣的根本原因需要挖掘,但你尝试过使用-march=native-latomic吗? - Marc Glisse
非常感谢你,我的朋友!-march=native-latomic都很有用!你能告诉我它们的根本原因吗? - Little Tooth
1
你需要一些原子操作的实现。i386 没有合适的原子指令,所以在这些情况下,你需要一个库实现(在 libatomic 中)。如果你让编译器知道你实际上对比 i386 更高版本的机器(比如 i686)感兴趣,那么它可以直接使用适当的指令,而不需要库。 - Marc Glisse
3个回答

3
在i386上,由于GCC无法使用汇编指令而必须回退到libatomic库实现,因此需要添加-latomic。从i586开始,原子指令可用,不再需要链接到libatomic。这意味着-latomic的替代方法是使用-march=i586

0

您似乎混合使用了OpenCV库的Debug和Release版本。https://github.com/Itseez/opencv/issues/5581 您应该只包含和链接正常的Release库,或者自己构建的Debug库。

在您的情况下,这可能来自于双重包含-cflags -I /usr/local/include/opencv。我建议尝试删除所有手动路径,只写pkg-config --cflags --libs opencv(使用打包的Release版本)。

请注意,/usr/local/include是一个标准的包含路径,将始终被搜索。您可以尝试使用-nostdinc排除标准路径https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html

另一种选择是卸载其中一个版本,或将一个版本从标准路径中移除。


我的朋友,当我使用 g++ -o main main.cpp pkg-config opencv --cflags --libs opencv`` 命令时,出现了相同的错误!我的 PKG_CONFIG_PATH 链接到一个名为 opencv.pc 的文件。opencv.pc 包含版本信息、编译和链接参数。 - Little Tooth
你可能仍然会链接错误的库,因为/usr/local/lib/usr/lib总是被搜索到,前者优先级更高。我认为值得尝试将你自己编译的版本(即/usr/local)移动到一个非索引文件夹中或卸载打包的版本,以确保你包含和链接的是同一个版本。 - SpamBot
我认为你说的很有道理。当我安装OpenCV 3.0.0时,我只是参考了官方网站而没有关注安装路径“/usr/local”。当然,根本原因是我并不真正理解它。你能告诉我如何卸载OpenCV吗?我担心会错误地删除其他东西。 - Little Tooth
你好,这次我安装了OpenCV 3.1.0,但是问题中提到的错误仍然存在!你知道如何解决吗? - Little Tooth
@LittleTooth,我编辑了我的答案。此外,从 /usr/local 中删除库文件意味着要么运行 make uninstall,要么手动查看所有文件并手动删除它们(因为你没有记录它们属于哪个库)。 - SpamBot
但是如果我在/usr/local中使用make uninstall,我担心会错误地删除其他一些默认安装的软件。到目前为止,我已经将带有*opencv*的文件从/usr/local移动到了我的个人文件夹,并在/usr/local/opencv-3.1.0中安装了一个新的opencv 3.1.0。 - Little Tooth

-1
你可能需要链接原子库。在GCC编译命令行中尝试使用
-latomic
注意:我不得不在ARMv7设备(Android)上使用CLang 8进行编译。

对于那些添加了“-1”的人,请为其他人提供反馈。 - Arcadien

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接