简体   繁体   English

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

[英]g++ Linking Error on Mac while compiling FFMPEG

g++ on Snow Leopard is throwing linking errors on the following piece of code Snow Leopard上的g ++会在下面的代码中抛出链接错误

test.cpp 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;
}

When I try to compile this using the following command 当我尝试使用以下命令编译它时

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

I get the error Undefined symbols: "av_register_all()", referenced from: _main in ccUD1ueX.o ld: symbol(s) not found collect2: ld returned 1 exit status 我收到错误未定义的符号:“av_register_all()”,引自:ccUD1ueX中的_main.l ld:未找到符号collect2:ld返回1退出状态

Interestingly, if I have an equivalent c code, test.c 有趣的是,如果我有一个等效的c代码,test.c

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

gcc compiles it just fine gcc编译得很好

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

I am using Mac OS X 10.6.5 我使用的是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's libavcodec, libavformat etc. are C libraries and I have built them on my machine like thus: FFMPEG的libavcodec,libavformat等是C库,我已经在我的机器上构建它们,如下所示:

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

As one would expect, libavformat indeed contains the symbol av_register_all 正如人们所料,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

I am inclined to believe g++ and gcc have different views of the libraries on my machine. 我倾向于相信g ++和gcc对我机器上的库有不同的看法。 g++ is not able to pick up the right libraries. g ++无法选择合适的库。 Any clue? 任何线索?

This is probably because the av_register_all function is not in an extern "C" block and thus when the forward declaration is interpreted by the C++ compiler, it's name is mangled. 这可能是因为av_register_all函数不在extern "C"块中,因此当C ++编译器解释前向声明时,它的名称会被破坏。 Try to change your code to: 尝试将您的代码更改为:

#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;
}

The name mangling is used by the C++ compilers to allow override of the same function with differents arguments, but is not performed by C compilers (which do not offer function overriding). C ++编译器使用名称修改来允许使用不同的参数覆盖相同的函数,但不是由C编译器执行(不提供函数覆盖)。

Generally, the headers that are written in C and can be included in C++ file should have the following structure to prevent such bugs to occurs. 通常,用C编写并且可以包含在C ++文件中的头应具有以下结构以防止发生此类错误。 You should probably inform the ffmpeg developpers to have their code modified: 您应该通知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

[Edit]: I just found out that this is mentioned on FFmpeg wiki . [编辑]:我刚刚发现这是在FFmpeg wiki上提到的。

If your goal is to install ffmpeg , you can always do so using MacPorts . 如果你的目标是安装ffmpeg ,你可以随时使用MacPorts The following works for me: 以下适用于我:

 sudo port install ffmpeg

You will find that a lot of open source projects targetting UNIX make Linux-specific assumptions that require patches to properly configure and install on the Mac. 您会发现许多针对UNIX的开源项目都会针对特定于Linux的假设,这些假设需要在Mac上正确配置和安装补丁。 It is generally a waste of time to replicate the work of determining and creating such patches, which is why it makes more sense to use MacPorts. 复制确定和创建此类补丁的工作通常是浪费时间,这就是使用MacPorts更有意义的原因。 If you care to know what the specific fix needed is, you can examine the portfile to find out both what source code patches were applied as well as any modifications to the build commands. 如果您想知道所需的具体修复是什么,您可以检查portfile以找出应用了哪些源代码补丁以及对构建命令的任何修改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM