1
votes

I have massive cross compilation of omxplayer whcih I am trying to debug. The file is downloaded from here. Unfortunately there are over 5000 files so I can not upload the directory tree. Here is the make command that gets issued:

/path/to/cross/compiler/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++ --sysroot=/mnt/root -Wall -L/mnt/root/lib -L/mnt/root/lib -L/mnt/root/usr/lib -L/mnt/root/usr/lib/omxplayer -L/mnt/root/opt/vc/lib -L/mnt/root/usr/lib/arm-linux-gnueabihf -L./ -ldbus-1 -lc -lWFC -lGLESv2 -lEGL -lbcm_host -lopenmaxil -lfreetype -lz -Lffmpeg_compiled/usr/local/lib/ -o omxplayer.bin linux/XMemUtils.o utils/log.o DynamicDll.o utils/PCMRemap.o utils/RegExp.o OMXSubtitleTagSami.o OMXOverlayCodecText.o BitstreamConverter.o linux/RBP.o OMXThread.o OMXReader.o OMXStreamInfo.o OMXAudioCodecOMX.o OMXCore.o OMXVideo.o OMXAudio.o OMXClock.o File.o OMXPlayerVideo.o OMXPlayerAudio.o OMXPlayerSubtitles.o SubtitleRenderer.o Unicode.o Srt.o KeyConfig.o OMXControl.o Keyboard.o omxplayer.o -lvchiq_arm -lvcos -lrt -lpthread -lavutil -lavcodec -lavformat -lavdevice -lavfilter -lswscale -lswresample -lpcre ./arm-linux-gnueabihf-pkg-config --libs dbus-1 -lrt

But then I get the following errors:

/path/to/cross/compiler/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc/arm-linux-gnueabihf/4.7.2/../../../../arm-linux-gnueabihf/bin/ld: warning: libavutil.so.51, needed by /mnt/root/usr/lib/arm-linux-gnueabihf/libpostproc.so.52, may conflict with libavutil.so.52
BitstreamConverter.o: In function `DllAvUtilBase::av_frame_move_ref(AVFrame*, AVFrame*)':
BitstreamConverter.cpp:(.text._ZN13DllAvUtilBase17av_frame_move_refEP7AVFrameS1_[_ZN13DllAvUtilBase17av_frame_move_refEP7AVFrameS1_]+0x8): undefined reference to `av_frame_move_ref'
BitstreamConverter.o: In function `DllAvUtilBase::av_frame_unref(AVFrame*)':
BitstreamConverter.cpp:(.text._ZN13DllAvUtilBase14av_frame_unrefEP7AVFrame[_ZN13DllAvUtilBase14av_frame_unrefEP7AVFrame]+0x4): undefined reference to `av_frame_unref'
BitstreamConverter.o: In function `DllAvUtilBase::av_frame_alloc()':
BitstreamConverter.cpp:(.text._ZN13DllAvUtilBase14av_frame_allocEv[_ZN13DllAvUtilBase14av_frame_allocEv]+0x0): undefined reference to `av_frame_alloc'
BitstreamConverter.o: In function `DllAvUtilBase::av_frame_free(AVFrame**)':
BitstreamConverter.cpp:(.text._ZN13DllAvUtilBase13av_frame_freeEPP7AVFrame[_ZN13DllAvUtilBase13av_frame_freeEPP7AVFrame]+0x4): undefined reference to `av_frame_free'
collect2: error: ld returned 1 exit status
make: *** [omxplayer.bin] Error 1

I traced the av_frame_unref function and the others to frame.h which is in both ffmpeg_compiled/usr/local/include/libavutil/frame.h and ffmpeg/libavutil/frame.h. Normally I would link to the .so library with -lframe or -Lffmpeg/libavutil/ -lframe, however, this is not a shared library (.so file) but an object file (.o file). I am pretty sure I do not have to link these manually, that's what the make file is for. Anyone shed some light on what is going on. Also, I will include my Makefile below (I also have a Makefile.include showing the cross compile options, I can post that as well if necessary)

Makefile:

SRC=linux/XMemUtils.cpp \
        utils/log.cpp \
        DynamicDll.cpp \
        utils/PCMRemap.cpp \
        utils/RegExp.cpp \
        OMXSubtitleTagSami.cpp \
        OMXOverlayCodecText.cpp \
        BitstreamConverter.cpp \
        linux/RBP.cpp \
        OMXThread.cpp \
        OMXReader.cpp \
        OMXStreamInfo.cpp \
        OMXAudioCodecOMX.cpp \
        OMXCore.cpp \
        OMXVideo.cpp \
        OMXAudio.cpp \
        OMXClock.cpp \
        File.cpp \
        OMXPlayerVideo.cpp \
        OMXPlayerAudio.cpp \
        OMXPlayerSubtitles.cpp \
        SubtitleRenderer.cpp \
        Unicode.cpp \
        Srt.cpp \
        KeyConfig.cpp \
        OMXControl.cpp \
        Keyboard.cpp \
        omxplayer.cpp \

OBJS+=$(filter %.o,$(SRC:.cpp=.o))

all: omxplayer.bin

%.o: %.cpp
    @rm -f $@ 
    $(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $@ -Wno-deprecated-declarations

version:
    bash gen_version.sh > version.h 

omxplayer.bin: version $(OBJS)
    $(CXX) $(LDFLAGS) -o omxplayer.bin $(OBJS) -lvchiq_arm -lvcos -lrt -lpthread -lavutil -lavcodec -lavformat -lavdevice -lavfilter -lswscale -lswresample -lpcre `./arm-linux-gnueabihf-pkg-config --libs dbus-1` -lrt
    #arm-unknown-linux-gnueabi-strip omxplayer.bin

clean:
    for i in $(OBJS); do (if test -e "$$i"; then ( rm $$i ); fi ); done
    @rm -f omxplayer.old.log omxplayer.log
    @rm -f omxplayer.bin
    @rm -rf $(DIST)
    @rm -f omxplayer-dist.tar.gz

ffmpeg:
    @rm -rf ffmpeg
    make -f Makefile.ffmpeg
    make -f Makefile.ffmpeg install

dist: omxplayer.bin
    mkdir -p $(DIST)/usr/lib/omxplayer
    mkdir -p $(DIST)/usr/bin
    mkdir -p $(DIST)/usr/share/doc
    cp omxplayer omxplayer.bin $(DIST)/usr/bin
    cp COPYING $(DIST)/usr/share/doc/
    cp README.md $(DIST)/usr/share/doc/README
    cp -a ffmpeg_compiled/usr/local/lib/*.so* $(DIST)/usr/lib/omxplayer/
    tar -czf omxplayer-dist.tar.gz $(DIST)
2
Which frame.cpp defines e.g. av_frame_move_ref? - Beta
@Beta both are identical, and both have the header file which has the signature for av_frame_move_ref but only ffmpeg/libavutil/ has frame.o and frame.c - puk

2 Answers

1
votes

It looks like you need to pull in the function definition from the .o files at compile time. I found this article very helpful in explaining the theory behind this:

http://eli.thegreenplace.net/2013/07/09/library-order-in-static-linking/

For more information on linking and compiling, I also highly recommend this book: http://www.network-theory.co.uk/docs/gccintro/index.html

0
votes

I went around and mule-headedly started adding foo/bar.o instructions after g++, luckily I only had to put two of these: ffmpeg/libavutil/frame.o and ffmpeg/libavutil/buffer.o. I finally got omxplayer to install. Note, if Linux has taught me anything it's that just because something compiles doesn't mean that it will work.

In hindsight, this makes perfect sense and I should have done it before, problem is that most websites either deal with insanely trivial situations, like g++ -o foo.o bar.o or insanely complex cases where you are redefining pkg-config to be cross compile capable and then setting up a dozen flags before even using that. I find these large Makefiles are always difficult to deal with for novice programmers.