msys2 / MINGW-packages

Package scripts for MinGW-w64 targets to build under MSYS2.
https://packages.msys2.org
BSD 3-Clause "New" or "Revised" License
2.22k stars 1.19k forks source link

[SDL2_mixer] SDL2_mixer-static target fails to link #17040

Open klei1984 opened 1 year ago

klei1984 commented 1 year ago

Description / Steps to reproduce the issue

I have these packages installed: mingw-w64-i686-toolchain mingw32/mingw-w64-i686-SDL2 mingw32/mingw-w64-i686-SDL2_mixer mingw32/mingw-w64-i686-SDL2_net mingw32/mingw-w64-i686-libiconv mingw32/mingw-w64-i686-freetype mingw-w64-i686-nsis mingw32/mingw-w64-i686-cmake make.

I use cmake find_package to find SDL2_mixer as follows:

find_package(SDL2_mixer REQUIRED CONFIG REQUIRED COMPONENTS SDL2_mixer-static)

Target properties are set up as follows (stripped down to SDL2_mixer-static relevant parts for clarity. Link time optimization is not used. Optimizations are disabled at -O0 level.):

target_include_directories(${APPLICATION} PRIVATE
    SDL2::SDL2main SDL2::SDL2-static SDL2_net::SDL2_net-static SDL2_mixer::SDL2_mixer-static
)

set_target_properties(${APPLICATION} PROPERTIES
    LINK_FLAGS "-m32 -static")

target_link_libraries(${APPLICATION} PRIVATE SDL2::SDL2main SDL2::SDL2-static SDL2_net::SDL2_net-static SDL2_mixer::SDL2_mixer-static)

GCC linker throws following errors (many more similar for libopusfile.a (opusfile.o). Path prefix is stripped for clarity:

../lib\libmpg123.a(compat.o):(.text+0x6f): undefined reference to `_imp__PathIsRelativeW@4'
../lib\libmpg123.a(compat.o):(.text+0x1b6): undefined reference to `_imp__PathIsUNCW@4'
../lib\libmpg123.a(compat.o):(.text+0x5a9): undefined reference to `_imp__PathCombineW@12'
../lib\libopusfile.a(opusfile.o):(.text+0x378): undefined reference to `ogg_sync_pageseek'
../lib\libopusfile.a(opusfile.o):(.text+0x3fa): undefined reference to `ogg_sync_buffer'
../lib\libopusfile.a(opusfile.o):(.text+0x41b): undefined reference to `ogg_sync_wrote'

It seems to me that when pacman installs SDL2_mixer and its dependencies, their static library versions are not compatible, they are pre-built with different feature sets.

Could someone confirm my assumption?

Without rebuilding SDL2_mixer from source code, is there a way to statically link it using the msys2 package's built in CMAKE find package target?

Expected behavior

Expectation is that installing mingw32/mingw-w64-i686-SDL2_mixer, and implicitly the dependencies to the package, should allow users to compile and link the SDL2_mixer::SDL2_mixer-static target.

Actual behavior

The SDL2_mixer::SDL2_mixer-static target pulls in static library dependencies that do not export symbols that SDL2_mixer default pre-built configuration expects from them.

Verification

Windows Version

MSYS_NT-10.0-19045

MINGW environments affected

Are you willing to submit a PR?

I do not know how to resolve the issue I face.

lb90 commented 1 year ago

Yeah, the i686 + static configuration is not tested all that much nowdays, unfortunately :)

Looks like there are two issues:

  1. libmpg123.a references shlwapi functions without a _ prepended, which is needed on x86.
  2. opusfile depends on libogg, but probably the CMake files do not list it as a dependency. Can you share the entire compiler invocation command-line when the error is thrown? Probably it doesn't contain -logg
lb90 commented 1 year ago

No, actually libmpg123.a has the _ prepended, so maybe the compiler is missing -lshlwapi?

klei1984 commented 1 year ago
e:\git\max\build>make VERBOSE=1
"/C/Program Files/CMake/bin/cmake.exe" -S/E/git/max -B/E/git/max/build --check-build-system CMakeFiles/Makefile.cmake 0
"/C/Program Files/CMake/bin/cmake.exe" -E cmake_progress_start /E/git/max/build/CMakeFiles /E/git/max/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/e/git/max/build'
make -f CMakeFiles/max.dir/build.make CMakeFiles/max.dir/depend
make[2]: Entering directory '/e/git/max/build'
"/C/Program Files/CMake/bin/cmake.exe" -E cmake_depends "MSYS Makefiles" /E/git/max /E/git/max /E/git/max/build /E/git/max/build /E/git/max/build/CMakeFiles/max.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/e/git/max/build'
make -f CMakeFiles/max.dir/build.make CMakeFiles/max.dir/build
make[2]: Entering directory '/e/git/max/build'
[  1%] Linking CXX executable max.exe
"/C/Program Files/CMake/bin/cmake.exe" -E remove -f CMakeFiles/max.dir/objects.a
/C/msys64/mingw32/bin/ar.exe cr CMakeFiles/max.dir/objects.a @CMakeFiles/max.dir/objects1.rsp
/C/msys64/mingw32/bin/g++.exe -g  -m32 -static -Wl,--whole-archive CMakeFiles/max.dir/objects.a -Wl,--no-whole-archive  -o max.exe -Wl,--out-implib,libmax.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles/max.dir/linklibs.rsp

The linklibs.rsp file contents are:

C:/msys64/mingw32/lib/libSDL2main.a C:/msys64/mingw32/lib/libfreetype.dll.a C:/msys64/mingw32/lib/libSDL2.a C:/msys64/mingw32/lib/libSDL2_net.a C:/msys64/mingw32/lib/libSDL2_mixer.a -Wl,--undefined=_WinMain@16 C:/msys64/mingw32/lib/libiconv.dll.a -luser32 -lgdi32 -limm32 -lole32 -loleaut32 -lversion -luuid -ladvapi32 -lsetupapi -lshell32 -ldinput8 -lws2_32 -liphlpapi -lmpg123 -lopusfile -lm -lwinmm -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 

The list does not contain ogg nor shlwapi. Adding them after the -Wl,--undefined= part resolved most missing dependencies. Additionally -lopus was needed by opusfile.

So working response file was:

C:/msys64/mingw32/lib/libSDL2main.a C:/msys64/mingw32/lib/libfreetype.dll.a C:/msys64/mingw32/lib/libSDL2.a C:/msys64/mingw32/lib/libSDL2_net.a C:/msys64/mingw32/lib/libSDL2_mixer.a -Wl,--undefined=_WinMain@16 C:/msys64/mingw32/lib/libiconv.dll.a -luser32 -lgdi32 -limm32 -lole32 -loleaut32 -lversion -luuid -ladvapi32 -lsetupapi -lshell32 -ldinput8 -lws2_32 -liphlpapi -lmpg123 -lopusfile -lm -lwinmm -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -logg -lshlwapi -lopus
lb90 commented 1 year ago

Thanks! Do you know how does CMake finds dependencies?

Biswa96 commented 1 year ago

@klei1984 Would you like to provide a minimal example or a project to reproduce the issue?

klei1984 commented 1 year ago

minimum example: playwave.zip

configuration: cmake -G "MSYS Makefiles" -B build -S . build: cd build && make

stuff to be installed: pacman -S mingw-w64-i686-toolchain mingw32/mingw-w64-i686-SDL2 mingw32/mingw-w64-i686-SDL2_mixer mingw32/mingw-w64-i686-cmake make

klei1984 commented 1 year ago

@lb90 as far as I know cmake does not do implicitly anything. The find_package cmake rule file provided by packagers provide variables or context aware targets. In this case c:\msys64\mingw32\lib\cmake\SDL2_mixer\sdl2_mixer-config.cmake is processed by cmake's find_package module which provides the requested SDL2_mixer::SDL2_mixer-static target which sets INTERFACE_LINK_LIBRARIES "${_sdl2mixer_extra_static_libraries}" which is populated by hand it seems before some voodoo magic post processing as follows: set(_sdl2mixer_extra_static_libraries " -lwinmm -lmpg123 -lopusfile -lm -lwinmm"). I assume this is where opusfile's and mpg123's further (static) dependencies are missing.

When cmake installs the target dependencies are searched by cpack via the BundleUtilities module, but I do not know how it finds actual DLLs required.

Biswa96 commented 1 year ago

It seems that the target_link_libraries in CMake file does not get all the required libraries for static linking. The following command works for static linking.

cc -static $(pkgconf -cflags -static sdl2 sdl2_mixer) playwave.c $(pkgconf -libs -static sdl2 sdl2_mixer)

Using FindPkgConfig module may help in cmake.

lb90 commented 1 year ago

Probably should fixed in SDL: https://github.com/libsdl-org/SDL_mixer/blob/SDL2/sdl2_mixer-config.cmake.in#L79

klei1984 commented 1 year ago

Hello @sezero , could you please check on this? Thanks in advance for your support.

It seems that sdl2_mixer-config.cmake does not include all required dependencies for the static SDL2_mixer target. The package config tool adds all dependencies based on lib\pkgconfig\SDL2_mixer.pc recursively.

Output of pkgconf -libs -static sdl2 sdl2_mixer:

-lmingw32 -mwindows -lSDL2main -lSDL2 -lm -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lversion -luuid
-ladvapi32 -lsetupapi -lshell32 -ldinput8 -lSDL2_mixer -lwinmm -lmingw32 -mwindows -lSDL2main -lSDL2 -lmingw32
-mwindows -lSDL2main -lSDL2 -lm -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lversion -luuid -ladvapi32
-lsetupapi -lshell32 -ldinput8 -lmpg123 -lm -lshlwapi -lopusfile -logg -lopus -lm
sezero commented 1 year ago

Hello @sezero , could you please check on this? Thanks in advance for your support.

It seems that sdl2_mixer-config.cmake does not include all required dependencies for the static SDL2_mixer target. The package config tool adds all dependencies based on lib\pkgconfig\SDL2_mixer.pc recursively.

@madebr is our cmake guy: pinging him for support

Output of pkgconf -libs -static sdl2 sdl2_mixer:

-lmingw32 -mwindows -lSDL2main -lSDL2 -lm -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lversion -luuid
-ladvapi32 -lsetupapi -lshell32 -ldinput8 -lSDL2_mixer -lwinmm -lmingw32 -mwindows -lSDL2main -lSDL2 -lmingw32
-mwindows -lSDL2main -lSDL2 -lm -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lversion -luuid -ladvapi32
-lsetupapi -lshell32 -ldinput8 -lmpg123 -lm -lshlwapi -lopusfile -logg -lopus -lm
madebr commented 1 year ago

SDL2_mixer's autotools build system does not model the required extra dependencies of third party libraries (=libmpg123/libogg/libflac/...). These are needed when you link to them at build time instead of dynamically opening them using LoadLibrary, which msys2 does: it passes --disable-xxx-shared flags.

Ideally, the autotools build system should get the build options using PKG_CHECK_MODULES and pass these to Makefile.in/sdl2_mixer-config.cmake/SDL2_mixer.pc. Unless somebody steps up, this will probably never be fixed.

Until msys2 switches over to the CMake build system (which should model this just fine), you need to add the missing libraries yourselves manually.

The CMake build system has targets for every dependency, which you might need to tweak using CMake cache variables. (This tweaking is not possible when using the cmake scripts, generated by autools because everything is hard coded.)

klei1984 commented 1 year ago

Hello @madebr , thanks for the top-notch summary. Unfortunately as a dumb end user I do not understand half of it :D Which is a further proof that you are surely the content expert.

SDL2_mixer's autotools build system does not model the required extra dependencies of third party libraries (=libmpg123/libogg/libflac/...).

What I understood is that SDL2_mixer uses autotools as build system that does not model extra dependencies. But as far as I can tell pkgconf was able to find all those extra dependencies which implies to me that SDL2_mixer.pc generated from SDL2_mixer.pc.in is written correctly by SDL2 team and packaged properly by msys2 team. It just works. So I assume everything is fine and this is not the root cause.

These are needed when you link to them at build time instead of dynamically opening them using LoadLibrary, which msys2 does: it passes --disable-xxx-shared flags.

What I understood from this is that msys2 team's PKGBUILD script supports both shared and static library generation and for the static case the shared libs are correctly disabled and static ones enabled for direct dependencies, not for deps of those dependencies which should probably work out of the box through some kind of recursion. So I assume everything is fine and this is not the root cause.

Ideally, the autotools build system should get the build options using PKG_CHECK_MODULES and pass these to Makefile.in/sdl2_mixer-config.cmake/SDL2_mixer.pc. Unless somebody steps up, this will probably never be fixed.

As far as I can tell SDL_mixer.pc works fine with pkgconf. On the other hand sdl2_mixer-config.cmake is not handling dependencies of explicitly tracked dependencies. So is this the root cause of the issue then? That the sdl2_mixer-config.cmake.in template needs to use PKG_CHECK_MODULES to iterate through all explicitly listed dependencies to find their dependencies recursively? And presumably this will never happen as autotools should be replaced by cmake which would implicitly resolve this issue and it makes no sense to improve a solution which is supposed to be replaced for a better alternative?

Until msys2 switches over to the CMake build system (which should model this just fine), you need to add the missing libraries yourselves manually. The CMake build system has targets for every dependency, which you might need to tweak using CMake cache variables. (This tweaking is not possible when using the cmake scripts, generated by autools because everything is hard coded.)

So as far as I understood, the issue could still be worked around by msys2 team without SDL2 team if the msys2 PKGBUILD script adds missing libraries that SDL2 team will not add via sdl2_mixer-config.cmake.in until Autotools is replaced. Is this correct?

Or the conclusion is that as an end user I should not use find_package for SDL2_mixer, instead I should use pckconf with SDL2_mixer.pc as it works.

madebr commented 1 year ago

Ok, let's try this.

Apply the following patch to your sdl2_mixer-config.cmake, and replace @PC_REQUIRES@ with the the space separated Requires.private value of your SDL2_mixer.pc.

What warning/error/result does this give when you link playwave.c against SDL2_mixer::SDL2_mixer-static?

diff --git a/sdl2_mixer-config.cmake.in b/sdl2_mixer-config.cmake.in
index a2eaf7e5..7cd78770 100644
--- a/sdl2_mixer-config.cmake.in
+++ b/sdl2_mixer-config.cmake.in
@@ -140,6 +140,21 @@ if(NOT TARGET SDL2_mixer::SDL2_mixer-static)
                 INTERFACE_LINK_LIBRARIES "${_sdl2mixer_extra_static_libraries}"
         )
     endif()
+    string(REPLACE " " ";" _sdl2mixer_pc_private_requires "@PC_REQUIRES@")
+    if(_sdl2mixer_pc_private_requires)
+        find_package(PkgConfig)
+        if(PKG_CONFIG_FOUND)
+            pkg_check_modules(SDL2MIXER_PC_REQUIRES_PRIVATE ${_sdl2mixer_pc_private_requires})
+            if(SDL2MIXER_PC_REQUIRES_PRIVATE_FOUND)
+                set_property(TARGET SDL2_mixer::SDL2_mixer-static APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${SDL2MIXER_PC_REQUIRES_PRIVATE_LIBRARIES}")
+            else()
+                message(WARNING "Private pkg-config requirements not found (${_sdl2mixer_pc_private_requires}). SDL2_mixer::SDL2_mixer-static might not link."
+            endif()
+        else()
+            message(WARNING "pkg-config not found. SDL2_mixer::SDL2_mixer-static might not link.")
+        endif()
+    endif()
+    unset(_sdl2mixer_pc_private_requires)
     unset(_sdl2mixer_stl)
 endif()

This is untested code, btw.

klei1984 commented 1 year ago

So I applied the patch on a local sdl2_mixer baseline. The autogen, configure and make, make install steps all worked, test applications are built during the process, etc.

The resulting SDL2_mixer.pc looks as follows:

--- SDL2_mixer.pc       2023-02-17 17:05:24.000000000 +0100
+++ "e:\\git\\SDL_mixer-SDL2\\SDL2_mixer.pc"  2023-04-30 09:19:25.516754500 +0200
@@ -5,9 +5,9 @@

 Name: SDL2_mixer
 Description: mixer library for Simple DirectMedia Layer
-Version: 2.6.3
+Version: 2.7.0
 Requires: sdl2 >= 2.0.9
 Libs: -L${libdir} -lSDL2_mixer
 Cflags: -I${includedir}/SDL2
-Requires.private:  libmpg123 opusfile
+Requires.private:
 Libs.private:  -lwinmm

The resulting pckconf invocation does not consider opusfile, ogg, opus libraries any more:

$ pkgconf -libs -static sdl2_mixer
-lSDL2_mixer -lwinmm -lmingw32 -mwindows -lSDL2main -lSDL2 -lmingw32 -mwindows -lSDL2main -lSDL2 -lm
-luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lversion -luuid -ladvapi32 -lsetupapi -lshell32 -ldinput8

Regardless, cc -static $(pkgconf -cflags -static sdl2 sdl2_mixer) playwave.c $(pkgconf -libs -static sdl2 sdl2_mixer) still builds playwave.exe oO

And the resulting executable works. It plays wav files.

I tested with a dependency walker tool and the resulting executable does not depend on SDL_mixer.dll or opus, ogg or similar.

W.r.t. the find_package method, the first message() missed the closing bracket. But otherwise it worked. I had to fix my minimum example cmake file too. SDL2::SDL2main target was missing from link targets: target_link_libraries(playwave PRIVATE SDL2::SDL2main SDL2::SDL2-static SDL2_mixer::SDL2_mixer-static)

The cmake generate command ran:

$ cmake -G "MSYS Makefiles" -B build -S .
-- The C compiler identification is GNU 12.2.0
-- The CXX compiler identification is GNU 12.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/msys64/mingw32/bin/cc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/msys64/mingw32/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (2.8s)
-- Generating done (0.0s)
-- Build files have been written to: E:/git/test/build

And produced the following linker command:

/C/msys64/mingw32/bin/cc.exe -m32 -static -Wl,--whole-archive CMakeFiles/playwave.dir/objects.a -Wl,--no-whole-archive -o playwave.exe -Wl,--out-implib,libplaywave.dll.a -Wl,--major-image-version,0,--minor-image-version,0  /C/msys64/mingw32/lib/libSDL2main.a /C/msys64/mingw32/lib/libSDL2.a /C/msys64/mingw32/lib/libSDL2_mixer.a -Wl,--undefined=_WinMain@16 -luser32 -lgdi32 -limm32 -lole32 -loleaut32 -lversion -luuid -ladvapi32 -lsetupapi -lshell32 -ldinput8 -lm -lwinmm -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 

Which worked and played the sound sample and all.

klei1984 commented 1 year ago

So if I am not mistaken, the patch from @madebr somehow embeds the dependencies of SDL2_mixer.a into that archive and so deps of deps are not missing anymore? Or what is the black magic that made it work? Or I am dumb as I could not even follow the first sentence from the instructions and building only worked as there was no code in the example that referred to opus or ogg thus the linker discarded those dependencies?

klei1984 commented 1 year ago

Adding libmpg123 opusfile from pc file to sdl2_mixer-config.cmake.in replacing @PC_REQUIRES@ by hand as instructed changes the behavior as follows:

So opusfile and mpg123 are back on the list without ogg or opus but linker does not fail regardless...

madebr commented 1 year ago

You need to build SDL2_mixer with these configure arguments. The --disable-xxx-shared args arguments are important. Those will add a build time dependency.

klei1984 commented 1 year ago

Oh I see.

It seems music-ogg-shared, music-flac-shared and music-mp3-mad-gpl do not exist anymore in v2.7.0.

I used these settings:

$ ./configure --disable-music-ogg-vorbis-shared --enable-music-ogg-vorbis --disable-music-ogg-tremor-shared --enable-music-ogg-tremor --enable-music-flac-libflac --disable-music-flac-libflac-shared --enable-music-mp3-mpg123 --disable-music-mp3-mpg123-shared --disable-music-opus-shared --disable-music-wavpack-shared

I did not have some of the libraries installed, so MOD and WavPack support are disabled.

SDL2_mixer.pc: Requires.private: vorbisfile flac libmpg123 opusfile

pkgconf test:

$ cc -static $(pkgconf -cflags -static sdl2 sdl2_mixer) playwave.c $(pkgconf -libs -static sdl2 sdl2_mixer)
C:/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../lib\libSDL2_mixer.a(music_flac.o): in function `FLAC_Load':
E:\git\test\SDL_mixer-SDL2/src/codecs/music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_init_stream'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_finish'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_new'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_delete'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_process_until_end_of_stream'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_process_single'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_process_until_end_of_metadata'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_flush'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_set_metadata_respond'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_get_state'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_get_total_samples'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_seek_absolute'

cmake generator:

$ cmake -G "MSYS Makefiles" -B build -S .
-- The C compiler identification is GNU 12.2.0
-- The CXX compiler identification is GNU 12.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/msys64/mingw32/bin/cc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/msys64/mingw32/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: C:/msys64/mingw32/bin/pkg-config.exe (found version "1.8.0")
-- Checking for modules 'libmpg123;opusfile'
--   Found libmpg123, version 1.31.3
--   Found opusfile, version 0.12
-- Configuring done (2.9s)
-- Generating done (0.0s)
-- Build files have been written to: E:/git/test/build

cmake build:

$ cd build && make
[ 50%] Building C object CMakeFiles/playwave.dir/playwave.c.obj
[100%] Linking C executable playwave.exe
C:/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/12.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/msys64/mingw32/lib/libSDL2_mixer.a(music_flac.o): in function `FLAC_Load':
E:\git\lesson11\SDL_mixer-SDL2/src/codecs/music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_init_stream'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_finish'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_new'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_delete'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_process_until_end_of_stream'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_process_single'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_process_until_end_of_metadata'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_flush'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_set_metadata_respond'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_get_state'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_get_total_samples'
.../music_flac.c:94: undefined reference to `_imp__FLAC__stream_decoder_seek_absolute'
...\libmpg123.a(compat.o):(.text+0x6f): undefined reference to `_imp__PathIsRelativeW@4'
...\libmpg123.a(compat.o):(.text+0x1b6): undefined reference to `_imp__PathIsUNCW@4'
...\libmpg123.a(compat.o):(.text+0x5a9): undefined reference to `_imp__PathCombineW@12'
...\libopusfile.a(opusfile.o):(.text+0x378): undefined reference to `ogg_sync_pageseek'
...\libopusfile.a(opusfile.o):(.text+0x3fa): undefined reference to `ogg_sync_buffer'
...\libopusfile.a(opusfile.o):(.text+0x41b): undefined reference to `ogg_sync_wrote'
...\libopusfile.a(opusfile.o):(.text+0x4f5): undefined reference to `opus_multistream_decoder_destroy'
...\libopusfile.a(opusfile.o):(.text+0x53d): undefined reference to `ogg_stream_clear'
...\libopusfile.a(opusfile.o):(.text+0x548): undefined reference to `ogg_sync_clear'

Tons of other ogg_xyz follows.

madebr commented 1 year ago

On Windows, when linking to a static FLAC library, you need to define FLAC__NO_DLL. Because SDL2_image does not do this, you cannot link to a (default) static FLAC library. Building this exapmle source fails linking when building with:

gcc --static flactest.c -o flactest.exe  $(pkg-config FLAC  --cflags --libs --static)

but succeeds when you add -DFLAC__NO_DLL. I suppose the other libraries (ogg/vorbis) have the same issue.

Because of this, you need to link with /mingw64/lib/libFLAC.dll.a. /mingw64/lib/libFLAC.a does not provide the __imp_ symbols.

lb90 commented 1 year ago

Thanks! So if we switch to CMake for building SDL2_mixer this issue should be solved

@Biswa96 are you working on that? otherwise I can give it a shot!

madebr commented 1 year ago

I think the errors will be the same. The shared and static flac library are not 100% compatible.