g++ Linking Error on Mac while compiling FFMPEG

跟風遠走 提交于 2019-12-12 13:24:09

问题


g++ on Snow Leopard is throwing linking errors on the following piece of code

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

Interestingly, if I have an equivalent c code, 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 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

$ 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:

./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

$ 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++ is not able to pick up the right libraries. Any clue?


回答1:


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. 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).

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. You should probably inform the ffmpeg developpers to have their code modified:

// 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.




回答2:


If your goal is to install ffmpeg, you can always do so using 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. 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. 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.



来源:https://stackoverflow.com/questions/4585847/g-linking-error-on-mac-while-compiling-ffmpeg

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!