xiph / opus-tools

A set of tools to encode, inspect, and decode audio in the Opus format.
https://opus-codec.org/
Other
212 stars 78 forks source link

Opusdec needs libogg too #53

Closed eblanca closed 4 years ago

eblanca commented 4 years ago

ogg library was missing from Makefile.am, this fix is specially needed in systems without pkg-config.

rillian commented 4 years ago

Hi, thanks for the patch!

Can you share some information about where the missing -logg fails? I was recently told applications should only link directly to libraries they use symbols from, and while opusdec uses types from ogg.h it doesn't call into libogg directly, so the transitive dependency declared in the elf headers of libopusurl.so and libopusfile.so are sufficient to resolve their own dynamic symbols at runtime.

Do you have a platform where that doesn't work?

appveyor failures aren't related to this patch.

eblanca commented 4 years ago

Hi, my system is

$ uname -a
Linux debbieb1 4.19.0-8-amd64 #1 SMP Debian 4.19.98-1 (2020-01-26) x86_64 GNU/Linux

I'm currently building opus-tools statically and all the dependencies are already there, built from git master as well. I installed headers and libraries into '/home/topolinik/svn/encoders/build'. The configure script can find everything it needs (I added '--without-flac', NOTE: 'pkg-config' was NOT used for detection)

./configure --disable-shared --enable-static --without-flac --prefix=/home/topolinik/svn/encoders/build/

Now, running make causes this error message from the linker:

$ make -j4 V=1
[cut]
/bin/bash ./libtool  --tag=CC   --mode=link gcc -I/home/topolinik/svn/encoders/build/include/opus -I/home/topolinik/svn/encoders/build/include -O3 -fstack-protector-strong -W -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-sign-compare  -s -o opusrtp src/opusrtp.o -L/home/topolinik/svn/encoders/build/lib -lopus -L/home/topolinik/svn/encoders/build/lib -logg -lsndio  -lsndio 
libtool: link: gcc -I/home/topolinik/svn/encoders/build/include/opus -I/home/topolinik/svn/encoders/build/include -O3 -fstack-protector-strong -W -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-sign-compare -s -o opusinfo src/opusinfo-opus_header.o src/opusinfo-opusinfo.o src/opusinfo-info_opus.o src/opusinfo-picture.o win32/opusinfo-unicode_support.o  -L/home/topolinik/svn/encoders/build/lib /home/topolinik/svn/encoders/build/lib/libogg.a -lsndio
/bin/bash ./libtool  --tag=CC   --mode=link gcc -I/home/topolinik/svn/encoders/build/include/opus -I/home/topolinik/svn/encoders/build/include -I/home/topolinik/svn/encoders/build/include/opus  -O3 -fstack-protector-strong -W -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-sign-compare  -s -o opusenc src/opusenc-opus_header.o src/opusenc-opusenc.o src/opusenc-picture.o src/opusenc-audio-in.o src/opusenc-diag_range.o src/opusenc-flac.o win32/opusenc-unicode_support.o -L/home/topolinik/svn/encoders/build/lib -lopusenc -L/home/topolinik/svn/encoders/build/lib -lopus  -L/home/topolinik/svn/encoders/build/lib -logg -lm -lsndio 
libtool: link: gcc -I/home/topolinik/svn/encoders/build/include/opus -I/home/topolinik/svn/encoders/build/include -O3 -fstack-protector-strong -W -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-sign-compare -s -o opusrtp src/opusrtp.o  -L/home/topolinik/svn/encoders/build/lib /home/topolinik/svn/encoders/build/lib/libopus.a -lm /home/topolinik/svn/encoders/build/lib/libogg.a -lsndio
mv -f src/.deps/opusdec-opusdec.Tpo src/.deps/opusdec-opusdec.Po
libtool: link: gcc -I/home/topolinik/svn/encoders/build/include/opus -I/home/topolinik/svn/encoders/build/include -I/home/topolinik/svn/encoders/build/include/opus -O3 -fstack-protector-strong -W -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-sign-compare -s -o opusenc src/opusenc-opus_header.o src/opusenc-opusenc.o src/opusenc-picture.o src/opusenc-audio-in.o src/opusenc-diag_range.o src/opusenc-flac.o win32/opusenc-unicode_support.o  -L/home/topolinik/svn/encoders/build/lib /home/topolinik/svn/encoders/build/lib/libopusenc.a /home/topolinik/svn/encoders/build/lib/libopus.a /home/topolinik/svn/encoders/build/lib/libogg.a -lm -lsndio
mv -f src/.deps/opusdec-resample.Tpo src/.deps/opusdec-resample.Po
/bin/bash ./libtool  --tag=CC   --mode=link gcc -I/home/topolinik/svn/encoders/build/include/opus -I/home/topolinik/svn/encoders/build/include -I/home/topolinik/svn/encoders/build/include/opus -O3 -fstack-protector-strong -W -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-sign-compare  -s -o opusdec src/opusdec-opus_header.o src/opusdec-wav_io.o src/opusdec-wave_out.o src/opusdec-opusdec.o src/opusdec-resample.o src/opusdec-diag_range.o win32/opusdec-unicode_support.o -L/home/topolinik/svn/encoders/build/lib -lopusfile -lopusurl -L/home/topolinik/svn/encoders/build/lib -lopus -lm -lsndio 
libtool: link: gcc -I/home/topolinik/svn/encoders/build/include/opus -I/home/topolinik/svn/encoders/build/include -I/home/topolinik/svn/encoders/build/include/opus -O3 -fstack-protector-strong -W -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-sign-compare -s -o opusdec src/opusdec-opus_header.o src/opusdec-wav_io.o src/opusdec-wave_out.o src/opusdec-opusdec.o src/opusdec-resample.o src/opusdec-diag_range.o win32/opusdec-unicode_support.o  -L/home/topolinik/svn/encoders/build/lib /home/topolinik/svn/encoders/build/lib/libopusurl.a /home/topolinik/svn/encoders/build/lib/libopusfile.a /home/topolinik/svn/encoders/build/lib/libopus.a -lm -lsndio
/usr/bin/ld: /home/topolinik/svn/encoders/build/lib/libopusfile.a(opusfile.o): in function `op_get_next_page':
opusfile.c:(.text+0x2b): undefined reference to `ogg_sync_pageseek'
/usr/bin/ld: opusfile.c:(.text+0x7f): undefined reference to `ogg_sync_buffer'
/usr/bin/ld: opusfile.c:(.text+0x9a): undefined reference to `ogg_sync_wrote'
/usr/bin/ld: /home/topolinik/svn/encoders/build/lib/libopusfile.a(opusfile.o): in function `op_fetch_headers_impl':
opusfile.c:(.text+0x17a): undefined reference to `ogg_page_serialno'
/usr/bin/ld: opusfile.c:(.text+0x184): undefined reference to `ogg_stream_reset_serialno'
/usr/bin/ld: opusfile.c:(.text+0x18f): undefined reference to `ogg_stream_pagein'
/usr/bin/ld: opusfile.c:(.text+0x19c): undefined reference to `ogg_stream_packetout'
/usr/bin/ld: opusfile.c:(.text+0x1f2): undefined reference to `ogg_page_bos'
/usr/bin/ld: opusfile.c:(.text+0x21b): undefined reference to `ogg_page_serialno'
/usr/bin/ld: opusfile.c:(.text+0x25e): undefined reference to `ogg_page_serialno'
/usr/bin/ld: opusfile.c:(.text+0x2b3): undefined reference to `ogg_page_serialno'
/usr/bin/ld: opusfile.c:(.text+0x2d8): undefined reference to `ogg_stream_packetout'
/usr/bin/ld: opusfile.c:(.text+0x308): undefined reference to `ogg_stream_packetout'
/usr/bin/ld: opusfile.c:(.text+0x3fa): undefined reference to `ogg_page_serialno'
/usr/bin/ld: opusfile.c:(.text+0x409): undefined reference to `ogg_page_bos'
/usr/bin/ld: opusfile.c:(.text+0x41d): undefined reference to `ogg_stream_pagein'
/usr/bin/ld: opusfile.c:(.text+0x42d): undefined reference to `ogg_stream_pagein'
/usr/bin/ld: /home/topolinik/svn/encoders/build/lib/libopusfile.a(opusfile.o): in function `op_clear':
opusfile.c:(.text+0x4a3): undefined reference to `ogg_stream_clear'
/usr/bin/ld: opusfile.c:(.text+0x4ac): undefined reference to `ogg_sync_clear'
/usr/bin/ld: /home/topolinik/svn/encoders/build/lib/libopusfile.a(opusfile.o): in function `op_collect_audio_packets':
opusfile.c:(.text+0x7d7): undefined reference to `ogg_stream_packetout'
/usr/bin/ld: /home/topolinik/svn/encoders/build/lib/libopusfile.a(opusfile.o): in function `op_find_final_pcm_offset':
opusfile.c:(.text+0xa29): undefined reference to `ogg_sync_reset'
/usr/bin/ld: opusfile.c:(.text+0xa71): undefined reference to `ogg_page_serialno'
/usr/bin/ld: opusfile.c:(.text+0xac4): undefined reference to `ogg_page_granulepos'
/usr/bin/ld: /home/topolinik/svn/encoders/build/lib/libopusfile.a(opusfile.o): in function `op_find_initial_pcm_offset':
opusfile.c:(.text+0xc35): undefined reference to `ogg_page_bos'
/usr/bin/ld: opusfile.c:(.text+0xc48): undefined reference to `ogg_page_serialno'
/usr/bin/ld: opusfile.c:(.text+0xc5c): undefined reference to `ogg_stream_pagein'
/usr/bin/ld: /home/topolinik/svn/encoders/build/lib/libopusfile.a(opusfile.o): in function `op_fetch_and_process_page':
opusfile.c:(.text+0x10e7): undefined reference to `ogg_page_serialno'
/usr/bin/ld: opusfile.c:(.text+0x1126): undefined reference to `ogg_stream_pagein'
/usr/bin/ld: opusfile.c:(.text+0x12d4): undefined reference to `ogg_page_bos'
/usr/bin/ld: opusfile.c:(.text+0x14b3): undefined reference to `ogg_page_serialno'
/usr/bin/ld: opusfile.c:(.text+0x150d): undefined reference to `ogg_stream_reset_serialno'
/usr/bin/ld: /home/topolinik/svn/encoders/build/lib/libopusfile.a(opusfile.o): in function `op_open_seekable2':
opusfile.c:(.text+0x2389): undefined reference to `ogg_sync_init'
/usr/bin/ld: opusfile.c:(.text+0x23a5): undefined reference to `ogg_stream_init'
/usr/bin/ld: opusfile.c:(.text+0x2498): undefined reference to `ogg_sync_reset'
/usr/bin/ld: opusfile.c:(.text+0x24f1): undefined reference to `ogg_page_serialno'
/usr/bin/ld: opusfile.c:(.text+0x252a): undefined reference to `ogg_page_granulepos'
/usr/bin/ld: opusfile.c:(.text+0x26e5): undefined reference to `ogg_stream_clear'
/usr/bin/ld: opusfile.c:(.text+0x26ef): undefined reference to `ogg_sync_clear'
/usr/bin/ld: opusfile.c:(.text+0x2a43): undefined reference to `ogg_sync_reset'
/usr/bin/ld: opusfile.c:(.text+0x2e1c): undefined reference to `ogg_page_serialno'
/usr/bin/ld: opusfile.c:(.text+0x2e27): undefined reference to `ogg_page_granulepos'
/usr/bin/ld: opusfile.c:(.text+0x3093): undefined reference to `ogg_sync_reset'
/usr/bin/ld: /home/topolinik/svn/encoders/build/lib/libopusfile.a(opusfile.o): in function `op_test':
opusfile.c:(.text+0x3256): undefined reference to `ogg_sync_init'
/usr/bin/ld: opusfile.c:(.text+0x3261): undefined reference to `ogg_sync_buffer'
/usr/bin/ld: opusfile.c:(.text+0x328d): undefined reference to `ogg_sync_wrote'
/usr/bin/ld: opusfile.c:(.text+0x329f): undefined reference to `ogg_stream_init'
/usr/bin/ld: opusfile.c:(.text+0x32af): undefined reference to `ogg_sync_pageout'
/usr/bin/ld: opusfile.c:(.text+0x32bd): undefined reference to `ogg_page_serialno'
/usr/bin/ld: opusfile.c:(.text+0x32c7): undefined reference to `ogg_stream_reset_serialno'
/usr/bin/ld: opusfile.c:(.text+0x32d2): undefined reference to `ogg_stream_pagein'
/usr/bin/ld: opusfile.c:(.text+0x32dd): undefined reference to `ogg_stream_packetout'
/usr/bin/ld: opusfile.c:(.text+0x3313): undefined reference to `ogg_stream_clear'
/usr/bin/ld: opusfile.c:(.text+0x331b): undefined reference to `ogg_sync_clear'
/usr/bin/ld: /home/topolinik/svn/encoders/build/lib/libopusfile.a(opusfile.o): in function `op_test_callbacks':
opusfile.c:(.text+0x349a): undefined reference to `ogg_sync_init'
/usr/bin/ld: opusfile.c:(.text+0x3521): undefined reference to `ogg_stream_init'
/usr/bin/ld: opusfile.c:(.text+0x35f7): undefined reference to `ogg_sync_buffer'
/usr/bin/ld: opusfile.c:(.text+0x3612): undefined reference to `ogg_sync_wrote'
/usr/bin/ld: /home/topolinik/svn/encoders/build/lib/libopusfile.a(opusfile.o): in function `op_raw_seek':
opusfile.c:(.text+0x418e): undefined reference to `ogg_sync_reset'
/usr/bin/ld: /home/topolinik/svn/encoders/build/lib/libopusfile.a(opusfile.o): in function `op_pcm_seek':
opusfile.c:(.text+0x4601): undefined reference to `ogg_sync_reset'
/usr/bin/ld: opusfile.c:(.text+0x468b): undefined reference to `ogg_sync_reset'
/usr/bin/ld: opusfile.c:(.text+0x46e3): undefined reference to `ogg_page_serialno'
/usr/bin/ld: opusfile.c:(.text+0x46f2): undefined reference to `ogg_page_packets'
/usr/bin/ld: opusfile.c:(.text+0x4703): undefined reference to `ogg_page_granulepos'
/usr/bin/ld: opusfile.c:(.text+0x4838): undefined reference to `ogg_stream_reset'
/usr/bin/ld: opusfile.c:(.text+0x4860): undefined reference to `ogg_stream_pagein'
/usr/bin/ld: opusfile.c:(.text+0x49ac): undefined reference to `ogg_stream_reset'
/usr/bin/ld: opusfile.c:(.text+0x4b6c): undefined reference to `ogg_stream_reset_serialno'
/usr/bin/ld: opusfile.c:(.text+0x4be5): undefined reference to `ogg_stream_pagein'
/usr/bin/ld: opusfile.c:(.text+0x4bf0): undefined reference to `ogg_stream_packetout'
/usr/bin/ld: opusfile.c:(.text+0x4c28): undefined reference to `ogg_stream_reset'
/usr/bin/ld: opusfile.c:(.text+0x4f20): undefined reference to `ogg_stream_reset'
/usr/bin/ld: opusfile.c:(.text+0x5033): undefined reference to `ogg_stream_pagein'
/usr/bin/ld: opusfile.c:(.text+0x5057): undefined reference to `ogg_stream_packetout'
/usr/bin/ld: opusfile.c:(.text+0x54e7): undefined reference to `ogg_sync_reset'
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:666: opusdec] Error 1
make[2]: uscita dalla directory "/home/topolinik/svn/opus-tools"
make[1]: *** [Makefile:1090: all-recursive] Error 1
make[1]: uscita dalla directory "/home/topolinik/svn/opus-tools"
make: *** [Makefile:527: all] Error 2

so, my understanding is opusfile needing libogg, not opusdec directly.

zvezdochiot commented 4 years ago

@eblanca say:

I'm currently building opus-tools statically

What for?

eblanca commented 4 years ago

@eblanca say:

I'm currently building opus-tools statically

What for?

zvezdochiot commented 4 years ago

@eblanca say:

because

LD_LIBRARY_PATH=. ./opusdec you.opus

Instead of a compilation circus, maybe patch with rpath.

eblanca commented 4 years ago
LD_LIBRARY_PATH=. ./opusdec you.opus

Hey, thank you! didn't know about this solution. Finally, is static building definitely discouraged?

zvezdochiot commented 4 years ago

@eblanca say:

Finally, is static building definitely discouraged?

Until you try to include libogg in it, everything is fine.

rillian commented 4 years ago

Ok, it makes sense that the transitive dependencies don't work for linking static binaries. (Although I hoped libtool might still manage it.)

It's difficult to make GNU autotools produce a static binary, so I'd say it's not exactly supported. I think your recipe above only happens to work because you've also build all the dependent libraries with --disable-shared so the build system wasn't able to find a shared version it would prefer to link with. On my system your build command still dynamically links to system versions of libopus.so, etc.

When I've wanted to dynamically link, I've general run make V=1 and then manually re-run the final gcc invocations with -static added, since libtool strips that option out if you pass it through CFLAGS or LDFLAGS. On my system that requires -lssl -lcrypto -lpthread -ldl as well as -logg.

eblanca commented 4 years ago

I'd say static building is not difficult on its own, though it's not the preferred way autotools work, further it becomes tricky as I insist not to depend on pkg-config. Of course, nothing of the above is opus-tools' fault. Yet, since it's not impossible to achieve, I'll manage to get it. Thank you guys.

rillian commented 4 years ago

FWIW I did a little more digging. It turns out libtool does include the dependency information in its .la metadata files, so if one uses the libtool wrapper when linking, it will add all the transitive library dependencies to the actual link line when building a static executable.

Two things seem to get i the way of this: