0

Working on a large embedded linux codebase / SDK "Not Invented Here" - invented offshore by Elbonian Code Slaves nailing various things together.

Part of the codebase is Live555 WIS-Streamer. In order to (try to) fix a niggle relating to timestamps I have inserted a couple of calls to clock_gettime(CLOCK_MONOTONIC, &ts); which then caused the compilation to fail with several undefined reference to 'clock_gettime' errors.

I've had this before and it was solved by adding -lrt to the compiler options to include librealtime, however this time round it just isn't helping. I've done a lot of googling and reading SO but I can't see any definitive answer, and the makefiles for the project are a lot more complicated than the examples found across the web.

I need some help either pointing out the blindingly obvious mistake I've made in the makefile(s), or with tracing the compiler's expectations back through the chain to see where I need to make a change.

This project is cross-compiled using a set of libraries for the given hardware, so -lrt is still required (I see it's no longer necessary in later gcc libs) and we can't update or change that stuff easily.

Here's a snippet of failed compiler output, with much verbosity. I have shortened path names just to stay below the post size limit.

make[10]: Entering directory `/ipnc_rdk/ipnc_app/network/live/testProgs'
/ipnc_rdk/../dvsdk_ipnctools/linux-devkit//bin/arm-arago-linux-gnueabi-g++ -c -I../UsageEnvironment/include -I../groupsock/include -I../liveMedia/include -I../BasicUsageEnvironment/include -I. -O3 -v -DSOCKLEN_T=socklen_t -DNO_STRSTREAM=1 -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -Wl,--verbose -lrt -Wall -DBSD=1 testMP3Streamer.cpp
Using built-in specs.
Target: arm-arago-linux-gnueabi
Thread model: posix
gcc version 4.3.3 (GCC) 
COLLECT_GCC_OPTIONS='-c' '-I../UsageEnvironment/include' '-I../groupsock/include' '-I../liveMedia/include' '-I../BasicUsageEnvironment/include' '-I.' '-O3' '-v' '-DSOCKLEN_T=socklen_t' '-DNO_STRSTREAM=1' '-D_LARGEFILE_SOURCE=1' '-D_FILE_OFFSET_BITS=64' '-Wall' '-DBSD=1' '-shared-libgcc' '-mfloat-abi=soft'
 ../libexec/gcc/arm-arago-linux-gnueabi/4.3.3/cc1plus -quiet -v -I../UsageEnvironment/include -I../groupsock/include -I../liveMedia/include -I../BasicUsageEnvironment/include -I. -iprefix ../lib/gcc/arm-arago-linux-gnueabi/4.3.3/ -isysroot ../arm-arago-linux-gnueabi -D_GNU_SOURCE -DSOCKLEN_T=socklen_t -DNO_STRSTREAM=1 -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -DBSD=1 testMP3Streamer.cpp -quiet -dumpbase testMP3Streamer.cpp -mfloat-abi=soft -auxbase testMP3Streamer -O3 -Wall -version -o /tmp/cckqq421.s
ignoring duplicate directory "../lib/gcc/../../lib/gcc/arm-arago-linux-gnueabi/4.3.3/../../../../arm-arago-linux-gnueabi/include/c++/4.3.3"
ignoring duplicate directory "../lib/gcc/../../lib/gcc/arm-arago-linux-gnueabi/4.3.3/../../../../arm-arago-linux-gnueabi/include/c++/4.3.3/arm-arago-linux-gnueabi"
ignoring duplicate directory "../lib/gcc/../../lib/gcc/arm-arago-linux-gnueabi/4.3.3/../../../../arm-arago-linux-gnueabi/include/c++/4.3.3/backward"
ignoring nonexistent directory "../arm-arago-linux-gnueabi/usr/local/include"
ignoring duplicate directory "../lib/gcc/../../lib/gcc/arm-arago-linux-gnueabi/4.3.3/include"
ignoring duplicate directory "../lib/gcc/../../lib/gcc/arm-arago-linux-gnueabi/4.3.3/include-fixed"
ignoring duplicate directory "../lib/gcc/../../lib/gcc/arm-arago-linux-gnueabi/4.3.3/../../../../arm-arago-linux-gnueabi/include"
#include "..." search starts here:
#include <...> search starts here:
 ../UsageEnvironment/include
 ../groupsock/include
 ../liveMedia/include
 ../BasicUsageEnvironment/include
 .
 ../lib/gcc/arm-arago-linux-gnueabi/4.3.3/../../../../arm-arago-linux-gnueabi/include/c++/4.3.3
 ../lib/gcc/arm-arago-linux-gnueabi/4.3.3/../../../../arm-arago-linux-gnueabi/include/c++/4.3.3/arm-arago-linux-gnueabi
 ../lib/gcc/arm-arago-linux-gnueabi/4.3.3/../../../../arm-arago-linux-gnueabi/include/c++/4.3.3/backward
 ../lib/gcc/arm-arago-linux-gnueabi/4.3.3/include
 ../lib/gcc/arm-arago-linux-gnueabi/4.3.3/include-fixed
 ../lib/gcc/arm-arago-linux-gnueabi/4.3.3/../../../../arm-arago-linux-gnueabi/include
 ../arm-arago-linux-gnueabi/usr/include
End of search list.
GNU C++ (GCC) version 4.3.3 (arm-arago-linux-gnueabi)
    compiled by GNU C version 4.4.3, GMP version 4.2.4, MPFR version 3.0.0-p7.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 05177eff49440274f3899a250a52b5a7
COLLECT_GCC_OPTIONS='-c' '-I../UsageEnvironment/include' '-I../groupsock/include' '-I../liveMedia/include' '-I../BasicUsageEnvironment/include' '-I.' '-O3' '-v' '-DSOCKLEN_T=socklen_t' '-DNO_STRSTREAM=1' '-D_LARGEFILE_SOURCE=1' '-D_FILE_OFFSET_BITS=64' '-Wall' '-DBSD=1' '-shared-libgcc' '-mfloat-abi=soft'
 ../lib/gcc/arm-arago-linux-gnueabi/4.3.3/../../../../arm-arago-linux-gnueabi/bin/as -mfloat-abi=soft -meabi=4 -o testMP3Streamer.o /tmp/cckqq421.s
COMPILER_PATH=../libexec/gcc/arm-arago-linux-gnueabi/4.3.3/:../libexec/gcc/:../lib/gcc/arm-arago-linux-gnueabi/4.3.3/../../../../arm-arago-linux-gnueabi/bin/
LIBRARY_PATH=../lib/gcc/arm-arago-linux-gnueabi/4.3.3/:../lib/gcc/:../lib/gcc/arm-arago-linux-gnueabi/4.3.3/../../../../arm-arago-linux-gnueabi/lib/:../arm-arago-linux-gnueabi/lib/:../arm-arago-linux-gnueabi/usr/lib/
COLLECT_GCC_OPTIONS='-c' '-I../UsageEnvironment/include' '-I../groupsock/include' '-I../liveMedia/include' '-I../BasicUsageEnvironment/include' '-I.' '-O3' '-v' '-DSOCKLEN_T=socklen_t' '-DNO_STRSTREAM=1' '-D_LARGEFILE_SOURCE=1' '-D_FILE_OFFSET_BITS=64' '-Wall' '-DBSD=1' '-shared-libgcc' '-mfloat-abi=soft'
/ipnc_rdk/../dvsdk_ipnctools/linux-devkit//bin/arm-arago-linux-gnueabi-g++ -otestMP3Streamer -L. testMP3Streamer.o ../liveMedia/libliveMedia.a ../groupsock/libgroupsock.a ../BasicUsageEnvironment/libBasicUsageEnvironment.a ../UsageEnvironment/libUsageEnvironment.a 
../liveMedia/libliveMedia.a: In function `RTPSink::presetNextTimestamp()':
Locale.cpp:(.text+0x3232c): undefined reference to `clock_gettime'
../liveMedia/libliveMedia.a: In function `RTCPInstance::addSR()':
Locale.cpp:(.text+0x36dd8): undefined reference to `clock_gettime'
../BasicUsageEnvironment/libBasicUsageEnvironment.a: In function `TimeNow()':
BasicHashTable.cpp:(.text+0x1edc): undefined reference to `clock_gettime'
../BasicUsageEnvironment/libBasicUsageEnvironment.a: In function `DelayQueue::DelayQueue()':
BasicHashTable.cpp:(.text+0x2378): undefined reference to `clock_gettime'
../BasicUsageEnvironment/libBasicUsageEnvironment.a: In function `DelayQueue::DelayQueue()':
BasicHashTable.cpp:(.text+0x2414): undefined reference to `clock_gettime'
../BasicUsageEnvironment/libBasicUsageEnvironment.a:BasicHashTable.cpp:(.text+0x246c): more undefined references to `clock_gettime' follow
collect2: ld returned 1 exit status
make[10]: *** [testMP3Streamer] Error 1

Unfortunately I can't attach the full output or contents of the makefile as I seem to have hit the post length limit! Here is most of one of the makefiles, I have put ...snip... where I have cut out a lot of similar entries that you can probably guess what was going on:

INCLUDES = -Iinclude -I../UsageEnvironment/include -I../groupsock/include
PREFIX = /usr/local
LIBDIR = $(PREFIX)/lib
##### Change the following for your environment:
CROSS_COMPILE=      $(MVTOOL_PREFIX)
COMPILE_OPTS =      $(INCLUDES) -I. -v -Wall -O3 -DSOCKLEN_T=socklen_t -DNO_STRSTREAM=1 -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -Wl,--verbose -lrt
### JU - Added -lrt for MONOTONIC CLOCK in RTPSink.cpp
C =         c
C_COMPILER =        $(CROSS_COMPILE)gcc
C_FLAGS =       $(COMPILE_OPTS)
CPP =           cpp
CPLUSPLUS_COMPILER =    $(CROSS_COMPILE)g++
CPLUSPLUS_FLAGS =   $(COMPILE_OPTS) -DBSD=1
OBJ =           o
LINK =          $(CROSS_COMPILE)g++ -o
LINK_OPTS =     -L.
CONSOLE_LINK_OPTS = $(LINK_OPTS)
LIBRARY_LINK =      $(CROSS_COMPILE)ld -o
LIBRARY_LINK_OPTS = $(LINK_OPTS) -r -Bstatic
LIB_SUFFIX =            a
LIBS_FOR_CONSOLE_APPLICATION =
LIBS_FOR_GUI_APPLICATION =
EXE =
##### End of variables to change

NAME = libliveMedia
LIVEMEDIA_LIB = $(NAME).$(LIB_SUFFIX)
ALL = $(LIVEMEDIA_LIB)
all:    $(ALL)

.$(C).$(OBJ):
    $(C_COMPILER) -c $(C_FLAGS) $<       
.$(CPP).$(OBJ):
    $(CPLUSPLUS_COMPILER) -c $(CPLUSPLUS_FLAGS) $<

MP3_SOURCE_OBJS = MP3FileSource.$(OBJ)  ...snip...  MP3InternalsHuffman.$(OBJ) MP3InternalsHuffmanTable.$(OBJ) MP3ADURTPSource.$(OBJ)
MPEG_SOURCE_OBJS = MPEG1or2Demux.$(OBJ)  ...snip...  ADTSAudioFileSource.$(OBJ)
H263_SOURCE_OBJS = H263plusVideoRTPSource.$(OBJ) H263plusVideoStreamFramer.$(OBJ) H263plusVideoStreamParser.$(OBJ)
AC3_SOURCE_OBJS = AC3AudioStreamFramer.$(OBJ) AC3AudioRTPSource.$(OBJ)
DV_SOURCE_OBJS = DVVideoStreamFramer.$(OBJ) DVVideoRTPSource.$(OBJ)
MP3_SINK_OBJS = MP3ADURTPSink.$(OBJ)
MPEG_SINK_OBJS = MPEG1or2AudioRTPSink.$(OBJ) $(MP3_SINK_OBJS) MPEG1or2VideoRTPSink.$(OBJ) MPEG4LATMAudioRTPSink.$(OBJ) MPEG4GenericRTPSink.$(OBJ) MPEG4ESVideoRTPSink.$(OBJ)
H263_SINK_OBJS = H263plusVideoRTPSink.$(OBJ)
H264_OR_5_SINK_OBJS = H264or5VideoRTPSink.$(OBJ) H264VideoRTPSink.$(OBJ) H265VideoRTPSink.$(OBJ)
DV_SINK_OBJS = DVVideoRTPSink.$(OBJ)
AC3_SINK_OBJS = AC3AudioRTPSink.$(OBJ)

MISC_SOURCE_OBJS = MediaSource.$(OBJ)  ...snip... StreamReplicator.$(OBJ)
MISC_SINK_OBJS = MediaSink.$(OBJ)  ...snip...  OutputFile.$(OBJ)
MISC_FILTER_OBJS = uLawAudioFilter.$(OBJ)
TRANSPORT_STREAM_TRICK_PLAY_OBJS = MPEG2IndexFromTransportStream.$(OBJ) MPEG2TransportStreamIndexFile.$(OBJ) MPEG2TransportStreamTrickModeFilter.$(OBJ)

RTP_SOURCE_OBJS = RTPSource.$(OBJ)  ...snip...  VP9VideoRTPSource.$(OBJ)
RTP_SINK_OBJS = RTPSink.$(OBJ) MultiFramedRTPSink.$(OBJ) AudioRTPSink.$(OBJ) VideoRTPSink.$(OBJ) TextRTPSink.$(OBJ)
RTP_INTERFACE_OBJS = RTPInterface.$(OBJ)
RTP_OBJS = $(RTP_SOURCE_OBJS) $(RTP_SINK_OBJS) $(RTP_INTERFACE_OBJS)

RTCP_OBJS = RTCP.$(OBJ) rtcp_from_spec.$(OBJ)
GENERIC_MEDIA_SERVER_OBJS = GenericMediaServer.$(OBJ)
RTSP_OBJS = RTSPServer.$(OBJ) RTSPClient.$(OBJ) RTSPCommon.$(OBJ) RTSPServerSupportingHTTPStreaming.$(OBJ) RTSPRegisterSender.$(OBJ)
SIP_OBJS = SIPClient.$(OBJ)

SESSION_OBJS = MediaSession.$(OBJ)  ...snip...  ProxyServerMediaSession.$(OBJ)

QUICKTIME_OBJS = QuickTimeFileSink.$(OBJ) QuickTimeGenericRTPSource.$(OBJ)
AVI_OBJS = AVIFileSink.$(OBJ)

MATROSKA_FILE_OBJS = MatroskaFile.$(OBJ) MatroskaFileParser.$(OBJ) EBMLNumber.$(OBJ) MatroskaDemuxedTrack.$(OBJ)
MATROSKA_SERVER_MEDIA_SUBSESSION_OBJS = MatroskaFileServerMediaSubsession.$(OBJ) MP3AudioMatroskaFileServerMediaSubsession.$(OBJ)
MATROSKA_RTSP_SERVER_OBJS = MatroskaFileServerDemux.$(OBJ) $(MATROSKA_SERVER_MEDIA_SUBSESSION_OBJS)
MATROSKA_OBJS = $(MATROSKA_FILE_OBJS) $(MATROSKA_RTSP_SERVER_OBJS)

OGG_FILE_OBJS = OggFile.$(OBJ) OggFileParser.$(OBJ) OggDemuxedTrack.$(OBJ)
OGG_SERVER_MEDIA_SUBSESSION_OBJS = OggFileServerMediaSubsession.$(OBJ)
OGG_RTSP_SERVER_OBJS = OggFileServerDemux.$(OBJ) $(OGG_SERVER_MEDIA_SUBSESSION_OBJS)
OGG_OBJS = $(OGG_FILE_OBJS) $(OGG_RTSP_SERVER_OBJS)

MISC_OBJS = BitVector.$(OBJ) StreamParser.$(OBJ) DigestAuthentication.$(OBJ) ourMD5.$(OBJ) Base64.$(OBJ) Locale.$(OBJ)

LIVEMEDIA_LIB_OBJS = Media.$(OBJ) $(MISC_SOURCE_OBJS) $(MISC_SINK_OBJS) $(MISC_FILTER_OBJS) $(RTP_OBJS) $(RTCP_OBJS) $(GENERIC_MEDIA_SERVER_OBJS) $(RTSP_OBJS) $(SIP_OBJS) $(SESSION_OBJS) $(QUICKTIME_OBJS) $(AVI_OBJS) $(TRANSPORT_STREAM_TRICK_PLAY_OBJS) $(MATROSKA_OBJS) $(OGG_OBJS) $(MISC_OBJS)

$(LIVEMEDIA_LIB): $(LIVEMEDIA_LIB_OBJS) \
    $(PLATFORM_SPECIFIC_LIB_OBJS)
    $(LIBRARY_LINK)$@ $(LIBRARY_LINK_OPTS) \
        $(LIVEMEDIA_LIB_OBJS)

Media.$(CPP):       include/Media.hh
include/Media.hh:   include/liveMedia_version.hh
MediaSource.$(CPP): include/MediaSource.hh
include/MediaSource.hh:     include/Media.hh
FramedSource.$(CPP):    include/FramedSource.hh
include/FramedSource.hh:    include/MediaSource.hh

 ...snip... 

ourMD5.$(CPP):  include/ourMD5.hh
Base64.$(CPP):  include/Base64.hh
Locale.$(CPP):  include/Locale.hh

include/liveMedia.hh:: include/MPEG1or2AudioRTPSink.hh  ...snip...  include/VP9VideoRTPSource.hh

include/liveMedia.hh::  include/MPEG2TransportStreamFromPESSource.hh  ...snip...  include/RTSPRegisterSender.hh

include/liveMedia.hh:: include/RTSPServerSupportingHTTPStreaming.hh ...snip... include/ProxyServerMediaSession.hh

clean:
    -rm -rf *.$(OBJ) $(ALL) core *.core *~ include/*~

install: install1 $(INSTALL2)
install1: $(LIVEMEDIA_LIB)
     install -d $(DESTDIR)$(PREFIX)/include/liveMedia $(DESTDIR)$(LIBDIR)
     install -m 644 include/*.hh $(DESTDIR)$(PREFIX)/include/liveMedia
     install -m 644 $(LIVEMEDIA_LIB) $(DESTDIR)$(LIBDIR)
install_shared_libraries: $(LIVEMEDIA_LIB)
     ln -fs $(NAME).$(LIB_SUFFIX) $(DESTDIR)$(LIBDIR)/$(NAME).$(SHORT_LIB_SUFFIX)
     ln -fs $(NAME).$(LIB_SUFFIX) $(DESTDIR)$(LIBDIR)/$(NAME).so

##### Any additional, platform-specific rules come here:
John U
  • 2,886
  • 3
  • 27
  • 39
  • *Ten* levels of recursion? What happens when you try to compile that one source file from the command line (i.e. without Make)? What happens when you write a `HelloWorld` that calls `clock_gettime(...)` and does very little else? – Beta Apr 11 '16 at 16:12
  • I did warn you about the Elbonian Code Slaves... It's tricky, as compiling without all the options from lower layers means that GCC uses the native libraries on the PC, which don't require the `-lrt` flag. I can compile the entire livemedia codebase separately with no issue, just not when cross-compiling. My makefile kung-fu is not strong enough to work out the invocation to compile a single file but with the cross-compile options that would be passed down the chain. – John U Apr 11 '16 at 17:29
  • Can't you pick the invocation out of the output? How's your sed-fu? – Beta Apr 11 '16 at 18:08

1 Answers1

2

You have added -lrt - and apparently also -Wl,--verbose - to the definition of COMPILE_OPTS. That will not work, because the $(COMPILE_OPTS) are only passed to invocations of the compiler, and -lrt is a linker option, which you must pass to the invocation of the linker for it have any effect.

Remove -lrt from the definition of COMPILE_OPTS and add it to the definition of LIBRARY_LINK_OPTS.

(The same applies to -Wl,--verbose, though you have probably only introduced it for debugging. You clearly know that -Wl,option means pass option through to the linker. But this instruction is addressed to the gcc/g++ tool-driver and is effective when it is invoking the linker, not when it is invoking the compiler. Hence you have verbose compiler output, due to -v` option, but no verbose linker output).

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
  • I'm flattered you think I *clearly know* anything... Unfortunately having come to this profession sideways and always starting with existing codebases I have very little experience with the workings of makefiles, and this codebase is not a gentle introduction. I'll give your suggestions a go. – John U Apr 12 '16 at 09:38
  • Thanks for the help, your comments made it clearer what I should be looking at and ultimately I got the frickin' thing to compile. – John U Apr 12 '16 at 12:47