编译FFMPEG时Mac上的g ++链接错误

Posted

技术标签:

【中文标题】编译FFMPEG时Mac上的g ++链接错误【英文标题】:g++ Linking Error on Mac while compiling FFMPEG 【发布时间】:2011-01-03 15:43:56 【问题描述】:

Snow Leopard 上的 g++ 在以下代码中引发链接错误

test.cpp

#include <iostream>
using namespace std;
#include <libavcodec/avcodec.h>    // required headers
#include <libavformat/avformat.h>
int main(int argc, char**argv) 
    av_register_all();             // offending library call
    return 0;

当我尝试使用以下命令编译时

g++ test.cpp -I/usr/local/include -L/usr/local/lib \
-lavcodec -lavformat -lavutil -lz -lm -o test

我得到了错误 未定义的符号: “av_register_all()”,引用自: ccUD1ueX.o 中的 _main ld:未找到符号 collect2: ld 返回 1 个退出状态

有趣的是,如果我有一个等效的 c 代码, 测试.c

#include <stdio.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
int main(int argc, char**argv) 
    av_register_all();
    return 0;

gcc 编译得很好

gcc test.c -I/usr/local/include -L/usr/local/lib \
-lavcodec -lavformat -lavutil -lz -lm -o test

我使用的是 Mac OS X 10.6.5

$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)
$ gcc --version
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)

FFMPEG 的 libavcodec、libavformat 等是 C 库,我在我的机器上构建了它们,如下所示:

./configure --enable-gpl --enable-pthreads --enable-shared \
--disable-doc --enable-libx264
make && sudo make install

正如所料,libavformat 确实包含符号 av_register_all

$ nm /usr/local/lib/libavformat.a | grep av_register_all
0000000000000000 T _av_register_all
00000000000089b0 S _av_register_all.eh

我倾向于相信 g++ 和 gcc 对我机器上的库有不同的看法。 g++ 无法选择正确的库。有什么线索吗?

【问题讨论】:

【参考方案1】:

这可能是因为 av_register_all 函数不在 extern "C" 块中,因此当 C++ 编译器解释前向声明时,它的名称被破坏了。尝试将您的代码更改为:

#include <iostream>
using namespace std;
extern "C" 
#include <libavcodec/avcodec.h>    // required headers
#include <libavformat/avformat.h>

int main(int argc, char**argv) 
    av_register_all();             // offending library call
    return 0;

C++ 编译器使用名称 mangling 来允许使用不同参数覆盖同一函数,但 C 编译器不执行此操作(不提供函数覆盖)。

一般情况下,用 C 语言编写并且可以包含在 C++ 文件中的头文件应具有以下结构,以防止发生此类错误。您可能应该通知 ffmpeg 开发人员修改他们的代码:

// Standard includes guards
#ifndef INCLUDED_AVCODEC_H
#define INCLUDED_AVCODEC_H

// Protection against inclusion by a C++ file
#ifdef __cplusplus
extern "C" 
#endif

// C code
// ....

// Closing the protection against inclusion by a C++ file
#ifdef __cplusplus

#endif
#endif

[编辑]:我刚刚发现FFmpeg wiki 上提到了这一点。

【讨论】:

谢谢,成功了。也许这应该是分布在库中的 .h 文件的一部分 是的,它应该在分发的.h文件中。【参考方案2】:

如果您的目标是安装ffmpeg,您始终可以使用MacPorts 进行安装。以下对我有用:

 sudo port install ffmpeg

您会发现许多针对 UNIX 的开源项目都做出了特定于 Linux 的假设,这些假设需要补丁才能在 Mac 上正确配置和安装。重复确定和创建此类补丁的工作通常是浪费时间,这就是使用 MacPorts 更有意义的原因。如果您想知道所需的具体修复是什么,您可以检查 portfile 以找出应用了哪些源代码补丁以及对构建命令的任何修改。

【讨论】:

目标不是安装ffmpeg(我猜你的意思是ffmpeg-devel),而是写一个程序使用 ffmpeg库 好的,但是安装 ffmpeg-devel 将为您提供在程序中使用它所需的库。 即使我使用了 ffmpeg-devel,同样的 gcc 与 g++ 问题仍然存在,因为 ffmpeg 和 ffmpeg-devel 都是 C 库。 Sylvain 的回答很到位。不过还是感谢您的努力。

以上是关于编译FFMPEG时Mac上的g ++链接错误的主要内容,如果未能解决你的问题,请参考以下文章

C ++静态库未在mac上的xcode中编译[重复]

编译时与 Boost.python 链接错误

OpenCV3.2 编译错误 MAC OS X

C语言使用第三方库编译报错错误排查

使用 g++ 链接对象时的问题

C++编译链接错误