MINGW-packages: [SDL2_mixer] SDL2_mixer-static target fails to link

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

  • MINGW64
  • MINGW32
  • UCRT64
  • CLANG64
  • CLANG32
  • CLANGARM64

Are you willing to submit a PR?

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

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Comments: 22 (8 by maintainers)

Most upvoted comments

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

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.

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