13

Here's my problem:

  • I built ffmpeg from source (version 1.2), the libav* libraries are in /usr/local/lib and they're static
  • I'm compiling a ns3 (www.nsnam.org) module, so my only control over the linker is through the env variable LINKFLAGS
  • In the source the headers are in a "extern C" block, so it's not the usual g++ name mangling
  • I set LINKFLAGS="-I/usr/local/include/libavformat -I/usr/local/include/libavcodec -I/usr/local/include/libavutil -L/usr/local/lib -lavformat -lavcodec -lavutil", and the linker can't seem to find any of the libav* functions I call (I get a lot of "undefined reference" and then "collect2: error: ld returned status 1"

Can anyone help me? Thanks...

edit: here are a few of the undefined reference messages:

    ./libns3.14.1-qoe-monitor-debug.so: undefined reference to `av_guess_format'
    ./libns3.14.1-qoe-monitor-debug.so: undefined reference to `av_read_frame'
    ./libns3.14.1-qoe-monitor-debug.so: undefined reference to `avformat_write_header'
    ./libns3.14.1-qoe-monitor-debug.so: undefined reference to `av_interleaved_write_frame'
    ./libns3.14.1-qoe-monitor-debug.so: undefined reference to `av_find_stream_info'
    ./libns3.14.1-qoe-monitor-debug.so: undefined reference to `av_register_all'
    ./libns3.14.1-qoe-monitor-debug.so: undefined reference to `av_init_packet'
    ./libns3.14.1-qoe-monitor-debug.so: undefined reference to `avformat_alloc_context'
    ./libns3.14.1-qoe-monitor-debug.so: undefined reference to `av_dump_format'
    ./libns3.14.1-qoe-monitor-debug.so: undefined reference to `avio_close'

edit2: here is the message I get after "build failed":

-> task in 'scratch-simulator' failed (exit status 1): 
{task 53952272: cxxprogram scratch-simulator.cc.1.o -> scratch-simulator}
['/usr/bin/g++', '-I/usr/local/include/libavcodec', '-I/usr/local/include/libavformat/',
 '-I/usr/local/include/libavutil/', '-L/usr/local/lib', '-I/usr/local
/include/libavcodec', '-I/usr/local/include/libavformat/', '-I/usr/local/include
/libavutil/', '-L/usr/local/lib', '-pthread', '-pthread', '-Wl,-z,relro', 
'scratch/scratch-simulator.cc.1.o', '-o', '/home/fede/Thesis/ns-allinone-3.14.1
/ns-3.14.1/build/scratch/scratch-simulator', '-Wl,-Bstatic', '-Wl,-Bdynamic', 
'-Wl,--no-as-needed', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.',
 '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.',
 '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', '-L.', 
'-L.', '-L.', '-L.', '-L.', '-L.', '-L/usr/lib', '-lns3.14.1-test-debug', '-lns3.14.1-
csma-layout-debug', '-lns3.14.1-point-to-point-layout-debug', '-lns3.14.1-netanim-
debug', '-lns3.14.1-lte-debug', '-lns3.14.1-spectrum-debug', '-lns3.14.1-antenna-
debug', '-lns3.14.1-aodv-debug', '-lns3.14.1-dsdv-debug', '-lns3.14.1-dsr-debug', 
'-lns3.14.1-mesh-debug', '-lns3.14.1-olsr-debug', '-lns3.14.1-csma-debug', '-lns3.14.1-
wimax-debug', '-lns3.14.1-applications-debug', '-lns3.14.1-virtual-net-device-debug', 
'-lns3.14.1-uan-debug', '-lns3.14.1-energy-debug', '-lns3.14.1-flow-monitor-debug', 
'-lns3.14.1-nix-vector-routing-debug', '-lns3.14.1-tap-bridge-debug', '-lns3.14.1-
visualizer-debug', '-lns3.14.1-internet-debug', '-lns3.14.1-bridge-debug', '-lns3.14.1-
point-to-point-debug', '-lns3.14.1-mpi-debug', '-lns3.14.1-wifi-debug', '-lns3.14.1-
buildings-debug', '-lns3.14.1-propagation-debug', '-lns3.14.1-mobility-debug', 
'-lns3.14.1-config-store-debug', '-lns3.14.1-tools-debug', '-lns3.14.1-stats-debug',
 '-lns3.14.1-emu-debug', '-lns3.14.1-topology-read-debug', '-lns3.14.1-network-debug', 
'-lns3.14.1-qoe-monitor-debug', '-lns3.14.1-core-debug', '-lrt', '-lgsl', 
'-lgslcblas', '-lm', '-ldl', '-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', '-lfreetype', '-lfontconfig', '-lgobject-2.0', '-lglib-2.0', '-lxml2', 
'-lpython2.7']
Fedech
  • 131
  • 1
  • 1
  • 4
  • What are a few of the undefined references? Can you verify that they live in the libav*.a? Also, the '-I' flags are applicable to compile time; you can leave them out of the LINKFLAGS variable. Another idea: verify that the linker is honoring LINKFLAGS by inserting something bogus like '-lblahblah'. Unless you really have a libblahblah.a on your system, the linker should complain that it can't find the library. – Multimedia Mike Mar 26 '13 at 06:45
  • The linker does complain if I add a bogus library in LINKFLAGS. When I called nm mux.o (mux.c is the source file some of the functions I call are in), I get functions with the T flag and functions with the U flag, but both types are "undefined references". For example, avformat_write_header appears with a T and av_guess_format appears with a U, but I get both a "undefined reference to avformat_write_header" and a "undefined reference to av_guess_format" – Fedech Mar 26 '13 at 18:36
  • Thanks for providing more data-- just doing due diligence to get a feel for your environment. When you perform 'nm /usr/local/lib/libavformat.a | grep avformat_write_header', does the function show up there with a 'T' and an address? That's the library where it should live (and the function appears in my local copy). – Multimedia Mike Mar 26 '13 at 23:30
  • I thought of something else-- do you have any visibility into where LINKFLAGS is applied in the final linking command line? It needs to come after the object files, not before. – Multimedia Mike Mar 26 '13 at 23:31
  • avformat_write_header appears with a T in libavformat. I added what I get after "build failed" in the original post, it should be the linker config by the look of it (sorry I didn't post all the data at the beginning, I'm kind of a total newb) – Fedech Mar 27 '13 at 09:55

3 Answers3

28

The libraries are C. The library headers don't include an extern "C" when compiled as C++. Do this in your C++ source:

extern "C" { 
#include <libavcodec/avcodec.h> 
#include <libavformat/avformat.h>
}

Or, more generically, for mixed C and C++ source:

#ifdef __cplusplus
extern "C" {
#endif
#include <libavcodec/avcodec.h> 
#include <libavformat/avformat.h>
#ifdef __cplusplus 
}
#endif

And you should be fine.

Community
  • 1
  • 1
Jason C
  • 38,729
  • 14
  • 126
  • 182
1

I had this problem with av_find_stream_info and the problem was this function was deprecated. The problem was I had two ffmpeg installation on the box, and it was reading header from one installation and was using libraries from different installation.

After removing system default library, the problem resolved.

UPDATE: For Ubuntu I did following:

$ sudo dpkg -r libavcodec53
$ sudo dpkg -r libavformat53
$ sudo dpkg -r libavutil51
$ sudo dpkg -r libswscale2
Roozbeh Zabihollahi
  • 7,207
  • 45
  • 39
1

Just came across this question in my own searching.

In waf building system, you should use STLIB and STLIBPATH to denote static library name and path, instead of using LINKFLAGS. Note that you should set STLIB to list of static library names to use without prefix or extension.

In wscript file, add

conf.env.append_value("STLIBPATH", ["/usr/local/lib"])
conf.env.append_value("STLIB", ["av*,av**"])
Eniaczz
  • 73
  • 2
  • 6