Compilation error using ffmpeg library - gcc

I have downloaded and installed the ffmpeg library. I want to use it for reading the separate frames of different videos and manipulate them. For that I tried to follow some tutorial from here: http://dranger.com/ffmpeg/tutorial01.html
But I can't compile my cpp file since I get the following compilation:
Undefined symbols for architecture x86_64:
"av_register_all()", referenced from:
_main in cc9zyUBe.o
_main in ccRz35d4.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
When I was installing ffmpeg library, I used arch=x86_64 option in ./configure step.
I use OS X Mountain Lion 10.8.2 and gcc 4.2 compiler.
Does somebody have any clue what can be the reason of this error?
Thanks in advance.
UPDATE:
I've already tried many different install options, with static libraries, shared libraries, with/without --arch=x86_64 option. Also installed it with homebrew, result remains the same. Library isn't recognized. But ffmpeg binary works pretty well, when I use it as a command-line tool.

Finally I have managed to compile my program which uses ffmpeg library.
For some reason I still couldn't compile it using gcc compiler, but I could do it with g++ compiler.
When the static libraries are installed, all the dependencies must be specified explicitly, and the order of linking of these libraries is also important. So here is the compilation code which finally compiled my program:
g++ readVideo.cc -o readVideo $(pkg-config --libs --cflags libavformat)
pkg-config here is a utility which prints all the flags and libraries that are needed to properly link the specified libavformat library.
Also it's worth of mentioning, that the source file was renamed from readVideo.C to readVideo.cc, and that #include statements have been encompassed using extern "C" as follows:
extern "C" {
#include <libavformat/avformat.h>
}
It is needed because ffmpeg is a C project and program will not compile with C++ compiler if you don't explicitly state that it is C library.
And if you don't want to bother with pkg-config to include all dependencies for ffmpeg libraries, you can install ffmpeg with shared libraries instead of static ones. Then it will compile by simpler call:
g++ readVideo.cc -o readVideo -lavformat
To install shared libraries, you need to add these 2 options to ./configure program when installing ffmpeg:
--disable-static --enable-shared
Hope it helps somebody some time ...

The error means that you aren't linking to the ffmpeg libraries. Simply including the header files is not enough. You need to also link to the actual library files. On Windows they have .lib extension, on Linux usually .a extension, not sure about Mac.

Related

ld: building for macOS-x86_64 but attempting to link with file built for macOS-x86_64

I have this strange issue where creating / using a static library works in my Ubuntu VM but not on macOS:
ld: warning: ignoring file ./dist/libXXXX.a, building for macOS-x86_64 but attempting to link with file built for macOS-x86_64
Command to create the static library is:
ar rcs libtest.a obj1.o obj2.o ...
Compiler invocation:
gcc -g -Wall -Wextra main.c -L./dist -lXXXX -o main
Searching on google didn't yield any usable results except for this (maybe) related question on SO:
Possible related question
I realize this is an old post and you found your fix, but let me post this here for anyone else who runs into this problem for whom these answers don't provide a solution.
You might be using two different toolchains unknowingly, one from Apple (installed via Xcode) and one from GNU (installed via Home-brew or MacPorts). If you type ranlib --version and see version info showing that ranlib is GNU, this is likely the case.
Make sure that /usr/bin comes in your $PATH before /usr/local/bin and /opt/local/bin. When you run which -a ranlib, the first result in the list should be /usr/bin/ranlib. Same for which -a ar-- the first result should be /usr/bin/ar. If it is not so, you need to fix your $PATH.
Once you fix your path and clean your project, try building again and things should work.
The issue was solved when I directly put those object files rather than gathering them into a static library, i.e.,
gcc -g -Wall -Wextra main.c obj1.o obj2.o -o main
After that, I got many warnings like ld: warning: object file (obj1.o) was built for newer macOS version (11.0) than being linked (10.14), but it is a warning, and the object is linked, so the problem is solved.
The root cause is that some library passes -mmacosx-version-min=10.14 to gcc, so the object file is built for 10.14, but my macos is now 11.0.
If you want to make things work, try directly using object files rather than creating a static library.
If you want to resolve all the warnings, find ``-mmacosx-version-min` and comment it.
After looking at my script that automatically creates the static library I've found the culprit:
For some reason my tool created object files for header files (resulting in files like header.h.o).
Removing those fixed the issue.

Link against shared library with SONAME

How can I force the gcc linker to link against a given version (soname) of a shared library on the system?
I need this to enforce that the version of openssl that is #include'ed matches the version that is linked, on any system, even if multiple versions of openssl are installed. To find the ABI version, my configure script first compiles and runs a program that extracts the SONAME from the headers:
#include <openssl/opensslv.h>
#include <stdio.h>
int main () {
printf(SHLIB_VERSION_NUMBER);
return 0;
}
The SHLIB_VERSION_NUMBER contains the so version string, e.g. 0.9.8 or 1.0.2k or 1.1.0. But how do I tell gcc to link against this version of libssl or libcrypto rather than just any -lssl?
I tried "in situ" linking, so that instead of linking with gcc main.c -lcrypto we use:
gcc main.c libcrypto.so.1.1.0
However it seems the linker libcrypto.so.1.1.0 cannot be found:
gcc: error: libcrypto.so.1.1.0: No such file or directory
I guess the system only searches in the standard locations when using the -l flag. Is there a better way to make my software link against libcrypto.so.1.1.0?
To select the correct version of the openssl shared libraries use:
gcc main.c -l:libssl.so.1.0.0 -l:libcrypto.so.1.0.0
The key to answering this question is "how do I control ld so that is links the correct version of a shared library?".
The correct way to pass a linker flag (a command line parameter to ld) using the gnu compilers (gcc, g++, gdc, etc...) is to use the normal ld parameter prefixed with "-l". For example -lssl or -L/usr/local/lib.
Edit: As per How to specify the library version to use at link time? you can read the manual for ld with:man ld.

Getting started with GCC plugins

So after searching the web for a while, Ive decided to try here as it seems to be a good forum for discussion. Im trying to create a simple gcc plugin. The program code is attached in the end of this mail, but in plain english it registers the plugin and makes sure that the pragma_init function is called when pragmas are registered. It is here that I use c_register_pragma to intercept some of the pragmas.
I compile it using the example in http://gcc.gnu.org/onlinedocs/gccint/Plugins-building.html#Plugins-building. The compilation and linking works fine. However, when I load the plug-in I get:
gcc -c -fplugin=plugin.so test.c -o test.o
cc1: error: cannot load plugin plugin.so
plugin.so: undefined symbol: warning
What am I doing wrong? In addition, when including some header files (that will be required later), I get a lot of errors. For example, including "tree.h" yields (amongst 50 other errors):
/machmode.h:262:1: error: unknown type name 'class'
class bit_field_mode_iterator
^
/machmode.h:263:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
{
^
/plugin/include/tree.h:27:0,
from conftest.c:63:
/vec.h:220:8: error: field 'register_overhead' declared as a function
Anyone have a clue on what I am doing wrong?
Thank you
There are two problems here :
The error : "cannot load plugin plugin.so" means that you should add to your LD_LIBRARY_PATH the directory where you store your new shared library plugin.
The hundreds of errors you got with all the files in the include are resolved in my computer if you compile with g++ instead of gcc (not sure to understand why thought)
Which version of GCC are you using, both to compile your plugin, and to use the plugin? Run simply
gcc -v
without any other program argument to find out!
Did you install the appropriate package for GCC plugin development (on Debian or Ubuntu, it might be gcc-4.7-plugin-dev, but adapt the 4.7 version to your particular version of GCC)?
Did you install all the dependencies needed to build your GCC (on Debian or Ubuntu, apt-get build-dep gcc-4.7 gcc-4.7-plugin-dev)?
Recent versions of GCC (notably many GCC 4.7 shipped by distributions, and all GCC 4.8) are compiled by a C++ compiler, not a C compiler.
You may check how was your GCC built (in C or in C++) by running
nm -D -C $(gcc -print-file-name=cc1)
If that command shows typed C++ manged names, e.g. execute_ipa_pass_list(opt_pass*) instead of just execute_ipa_pass_list your GCC has been compiled with a C++ compiler (probably g++)
So you may need to use g++ (not gcc) to compile your GCC plugin.
As I commented, did you consider using MELT (a domain specific language to extend GCC) to extend or customize your gcc compiler?
I suggest downloading the very latest http://gcc-melt.org/melt-plugin-snapshot.tar.bz2 since I will release the next MELT in a few weeks for GCC 4.7 and 4.8
And don't expect to change the parsing behavior of your GCC with a plugin. That is not really possible (GCC provides only plugin hooks to add your builtins and pragmas, not to extend the parsed syntax).

undefined reference to `x264_encoder_open_125'

While installing ffmpeg on Ubuntu 12.04
I am getting following error
libavcodec/libavcodec.a(libx264.o): In function `X264_init':
/root/ffmpeg/libavcodec/libx264.c:492: undefined reference to `x264_encoder_open_125'
collect2: ld returned 1 exit status
make: *** [ffmpeg_g] Error 1
I am following the instructions given at
http://ffmpeg.org/trac/ffmpeg/wiki/UbuntuCompilationGuide
Do anyone have idea about this error?
This is a typical problem for people who already have x264 installed through the package management system. You can solve this in at least 2 ways:
Uninstall the already existing x264 from your system, through the package management system:
# apt-get remove x264
and compile your new x264 from source
Don't uninstall the x264 package, but compile your new x264 and then compile your ffmpeg, telling it to use that newly compiled x264 library, by specifying that directory where your compiled x264 library is, using the mentioned LD_LIBRARY_PATH environment variable:
LD_LIBRARY_PATH=/path/to/my/compiled/x264/library ./configure --enable-libx264 ...
More info can be found on these links:
problem with --enable-libx264 option in ffmpeg
Compiling FFmpeg
add the header and lib path
gcc x264_test1.c -o x264_encoder -I/usr/local/include -L/usr/local/lib -lpthread -lm -lx264
Generally the error means that the library binary libx264.so picked up by the linker does not match the version in the header file x264.h. See the following lines of code in this header file:
/* Force a link error in the case of linking against an incompatible API version.
* Glue #defines exist to force correct macro expansion; the final output of the macro
* is x264_encoder_open_##X264_BUILD (for purposes of dlopen). */
#define x264_encoder_glue1(x,y) x##y
#define x264_encoder_glue2(x,y) x264_encoder_glue1(x,y)
#define x264_encoder_open x264_encoder_glue2(x264_encoder_open_,X264_BUILD)
The solution usually does not require building libx264 yourself,
just make sure that you installed libx264-dev properly without interference with other versions, which may also be in /usr/local/lib or the like.
I had the same issue with version 155:
undefined reference to 'x264_encoder_open_155'.
In my case this was because I had in /usr/lib/x86_64-linux-gnu and unsuitable copy of libx264.so (which I had produced myself and uncleanly copied there).
So all I had to do was sudo apt-get install --reinstall libx264-dev.

GCC 4.7, including <stdatomic.h>

I've just compiled GCC 4.7 to work with stdatomic.h, but I can't seem to -I it. stdatomic.h seems to live in /usr/include/c++/4.4.3, but then the linker tells me it needs a bunch of other files in dirs nearby. If I -I all of them, I still get the error undefined reference to atomic_flag_clear_explicit. Any ideas how I'm supposed to link this right?
First, if you are compiling with GCC 4.7 you should not be including or linking anything from a directory from GCC 4.4.
Second, -I only affects the search path for header files. "undefined reference" is a linker error and usually means it hasn't found the right library. You change the library search path with -L. The linker didn't say it didn't find a library with the right name, it says it didn't find a symbol, so clearly the library it did find didn't have that symbol. I'd suggest you have a versioning problem, perhaps caused by a installation problem.
The <stdatomic.h> header in GCC 4.4 and 4.5 was from an early draft of C++0x atomics, but is not part of the final standard, so it was removed from libstdc++.
The C++ compiler supports C++11 atomics via the C++11 <atomic> header, so you should use that header in C++ code.
When the C compiler supports C11 atomics, the <stdatomic.h> header will be provided again.
Using this command solved the problem for me:
$ scl enable devtoolset-7 bash
I got the same error as you when entering sudo make altinstall for installing Python 3.8.5 on CentOS 7.

Resources