Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: undefined reference when using audio to play music  (Read 6065 times)

0 Members and 1 Guest are viewing this topic.

Lenny

  • Newbie
  • *
  • Posts: 5
    • View Profile
undefined reference when using audio to play music
« on: November 26, 2022, 10:54:45 pm »
I've been trying to play music using SFML but the program does not compile when I try this.
Opening and playing the music:
sf::Music music;
music.openFromFile("assets/music/FLAC/password-infinity.flac");
music.play();
I'm using CMake / G++ (12.2.0) to compile, the CMake configuration is as follows:
cmake_minimum_required(VERSION 3.25.0)
set(CMAKE_CXX_STANDARD 23)

# Setup
project(main) # Must match the main file name
set(EXECUTABLE_NAME "main") # Executable name

set(PROJECT_SOURCES # *.cpp that was made
        ${PROJECT_NAME}.cpp # Main file
        int/src/logger.cpp # Custom logger
        )

set(PROJECT_HEADERS # *.hpp that was made
        int/hdr/logger.hpp # Custom logger
        )

include_directories( # dirs to include (.hpp)
                int/hdr/ # Allows for ease of use when using custom hpp files
                ext/SFML/include/
                )

link_directories( # dirs to link (.a)
                ext/SFML/lib/
                )

# SFML
set(SFML_STATIC_LIBRARIES TRUE) # Using a static built
set(SFML_DIR ext/SFML/cmake) # SFML CMake files
find_package(SFML 2.5 COMPONENTS system window graphics network audio REQUIRED) # Just getting everything

set(SFML_LIBRARIES
        sfml-graphics-s # Needs to be first
        sfml-window-s # Needs to be second
        sfml-audio-s # Needs to be before system
        sfml-network-s # Needs to be before system
        sfml-main # Needs to be before system
        sfml-system-s # Needs to be last
        )

set(SFML_DEPENDENCIES
        opengl32 # window, graphics
        freetype # graphics
        winmm # window, system
        gdi32 # window
        vorbisenc # audio
        vorbisfile # audio
        vorbis # audio
        flac # audio
        openal32 # audio
        ogg # audio
        ws2_32 # network
        )

# Build
add_executable(${EXECUTABLE_NAME} ${PROJECT_NAME} ${PROJECT_SOURCES} ${PROJECT_HEADERS})
target_link_libraries(${PROJECT_NAME} ${SFML_LIBRARIES} ${SFML_DEPENDENCIES}) # SFML first, dependencies second
I've built SFML from source since I'm using a different setup from the precompiled versions. As for the order, the one I use is what I was able to find online.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: undefined reference when using audio to play music
« Reply #1 on: November 30, 2022, 09:43:05 am »
Since you didn't provide the error message, we can't really understand what's going wrong.

As for your CMake code, it's not really how you should be linking SFML.
See the CMake template here: https://github.com/SFML/cmake-sfml-project
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Lenny

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: undefined reference when using audio to play music
« Reply #2 on: December 01, 2022, 10:20:53 am »
Since you didn't provide the error message, we can't really understand what's going wrong.

As for your CMake code, it's not really how you should be linking SFML.
See the CMake template here: https://github.com/SFML/cmake-sfml-project

The error I get:
c:/mingw/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/Deze PC/Documenten/GitHub/LI-REDC/ext/SFML/lib/libflac.a(stream_decoder.o):stream_decoder.c:(.text+0x217): undefined reference to `__imp___iob_func'
c:/mingw/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/Deze PC/Documenten/GitHub/LI-REDC/ext/SFML/lib/libflac.a(stream_decoder.o):stream_decoder.c:(.text+0x267): undefined reference to `__imp___iob_func'
c:/mingw/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/Deze PC/Documenten/GitHub/LI-REDC/ext/SFML/lib/libflac.a(stream_decoder.o):stream_decoder.c:(.text+0x2c7): undefined reference to `__imp___iob_func'
c:/mingw/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/Deze PC/Documenten/GitHub/LI-REDC/ext/SFML/lib/libflac.a(stream_decoder.o):stream_decoder.c:(.text+0x532): undefined reference to `__imp___iob_func'
c:/mingw/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/Deze PC/Documenten/GitHub/LI-REDC/ext/SFML/lib/libflac.a(stream_decoder.o):stream_decoder.c:(.text+0x4db2): undefined reference to `__imp___iob_func'
c:/mingw/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/Deze PC/Documenten/GitHub/LI-REDC/ext/SFML/lib/libflac.a(stream_decoder.o):stream_decoder.c:(.text+0x4e03): more undefined references to `__imp___iob_func' follow
collect2.exe: error: ld returned 1 exit status
mingw32-make[3]: *** [CMakeFiles\RedC.dir\build.make:219: RedC.exe] Error 1
mingw32-make[2]: *** [CMakeFiles\Makefile2:82: CMakeFiles/RedC.dir/all] Error 2
mingw32-make[1]: *** [CMakeFiles\Makefile2:89: CMakeFiles/RedC.dir/rule] Error 2
mingw32-make: *** [Makefile:123: RedC] Error 2

As for how I've used CMake, the libraries I'm using are static and built for GCC 12.2.0. As I understand it the example CMake would get me DLLs and I'm not sure if they work with my GCC version. But' I'll look further into it.
« Last Edit: December 01, 2022, 10:22:29 am by Lenny »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: undefined reference when using audio to play music
« Reply #3 on: December 01, 2022, 10:28:37 am »
Ah, what I've suspected.
This happens because you're using the UCRT version of WinLibs' MinGW compiler and the C libraries provided by SFML were built with the "old" MSVCRT "version". The two are not compatible.

See also: https://winlibs.com/#:~:text=MSVCRT%20or%20UCRT%20runtime%20library%3F

The only workaround is to use the MSVCRT version of WinLibs' MinGW or well build libflac yourself :D

Of course you can use shared libraries with GCC as well.
But you can also set BUILD_SHARED_LIBS to OFF, which should then build SFML statically.
If you don't use FetchContent and just find_package you can set SFML_STATIC_LIBRARIES to true before calling find_package.
For more details on how to find SFML, see the comments in the Config file: https://github.com/SFML/SFML/blob/master/cmake/SFMLConfig.cmake.in
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Lenny

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: undefined reference when using audio to play music
« Reply #4 on: December 01, 2022, 11:02:16 am »
Ah, what I've suspected.
This happens because you're using the UCRT version of WinLibs' MinGW compiler and the C libraries provided by SFML were built with the "old" MSVCRT "version". The two are not compatible.

See also: https://winlibs.com/#:~:text=MSVCRT%20or%20UCRT%20runtime%20library%3F

The only workaround is to use the MSVCRT version of WinLibs' MinGW or well build libflac yourself :D

Of course you can use shared libraries with GCC as well.
But you can also set BUILD_SHARED_LIBS to OFF, which should then build SFML statically.
If you don't use FetchContent and just find_package you can set SFML_STATIC_LIBRARIES to true before calling find_package.
For more details on how to find SFML, see the comments in the Config file: https://github.com/SFML/SFML/blob/master/cmake/SFMLConfig.cmake.in

I've just updated my CMake to
cmake_minimum_required(VERSION 3.25.0)
set(CMAKE_CXX_STANDARD 23)

# Setup
project(RedC) # Must match the main file name
set(EXECUTABLE_NAME "RedC") # Executable name

set(PROJECT_SOURCES # *.cpp that was made
        ${PROJECT_NAME}.cpp # Main file
        int/src/logger.cpp # Custom logger
        int/src/object.cpp # Base for any object in game that can be drawn
        int/src/enemyCharacter.cpp # Enemy object
        int/src/playerCharacter.cpp # Player objects
        int/src/staticObj.cpp # Not interactable object (wall)
        int/src/interactableObj.cpp # Interactable object (chest, loot, door)
        int/src/characterObj.cpp # Base for a character
        )

set(PROJECT_HEADERS # *.hpp that was made
        int/hdr/logger.hpp # Custom logger
        int/hdr/object.hpp
        int/hdr/enemyCharacter.hpp
        int/hdr/playerCharacter.hpp
        int/hdr/staticObj.hpp
        int/hdr/interactableObj.hpp
        int/hdr/characterObj.hpp
        )

include_directories( # dirs to include (.hpp)
                int/hdr/ # Allows for ease of use when using custom hpp files
                ext/SFML/include/
                )

link_directories( # dirs to link (.a)
                ext/SFML/lib/
                )

# SFML
option(BUILD_SHARED_LIBS OFF)

include(FetchContent)
FetchContent_Declare(SFML GIT_REPOSITORY https://github.com/SFML/SFML.git GIT_TAG 2.6.x)
FetchContent_MakeAvailable(SFML)

add_executable(${EXECUTABLE_NAME} ${PROJECT_NAME} ${PROJECT_SOURCES} ${PROJECT_HEADERS})

set(SFML_LIBRARIES
        sfml-graphics-s # Needs to be first
        sfml-window-s # Needs to be second
        sfml-audio-s # Needs to be before system
        sfml-network-s # Needs to be before system
        sfml-main # Needs to be before system
        sfml-system-s # Needs to be last
        )

set(SFML_DEPENDENCIES
        opengl32 # window, graphics
        freetype # graphics
        winmm # window, system
        gdi32 # window
        vorbisenc # audio
        vorbisfile # audio
        vorbis # audio
        flac # audio
        openal32 # audio
        ogg # audio
        ws2_32 # network
        )

target_link_libraries(${PROJECT_NAME} PRIVATE ${SFML_LIBRARIES} ${SFML_DEPENDENCIES})
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23)

install(TARGETS ${PROJECT_NAME})
It works, but I'm not sure this is correct.

As for the compiler, I'll have a look into changing it. But if I built libflac myself how should I use that one over the one that it now downloads (I assume that is what the fetch content does)?

Lenny

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: undefined reference when using audio to play music
« Reply #5 on: December 01, 2022, 12:30:42 pm »
I've got it to work I think.
CMake:
cmake_minimum_required(VERSION 3.25.0)
set(CMAKE_CXX_STANDARD 23)

# Setup
project(RedC) # Must match the main file name
set(EXECUTABLE_NAME "RedC") # Executable name
set(LANGUAGE CXX)

set(PROJECT_SOURCES # *.cpp that was made
        ${PROJECT_NAME}.cpp # Main file
        int/src/logger.cpp # Custom logger
        int/src/object.cpp # Base for any object in game that can be drawn
        int/src/enemyCharacter.cpp # Enemy object
        int/src/playerCharacter.cpp # Player objects
        int/src/staticObj.cpp # Not interactable object (wall)
        int/src/interactableObj.cpp # Interactable object (chest, loot, door)
        int/src/characterObj.cpp # Base for a character
        )

set(PROJECT_HEADERS # *.hpp that was made
        int/hdr/logger.hpp # Custom logger
        int/hdr/object.hpp
        int/hdr/enemyCharacter.hpp
        int/hdr/playerCharacter.hpp
        int/hdr/staticObj.hpp
        int/hdr/interactableObj.hpp
        int/hdr/characterObj.hpp
        )

include_directories( # dirs to include (.hpp)
                int/hdr/ # Allows for ease of use when using custom hpp files
                ext/SFML/include/
                )

link_directories( # dirs to link (.a)
                ext/SFML/lib/
                )

add_executable(${EXECUTABLE_NAME} ${PROJECT_NAME} ${PROJECT_SOURCES} ${PROJECT_HEADERS})

# Copying assets
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/assets/ $<TARGET_FILE_DIR:${PROJECT_NAME}>/assets/)

# SFML
option(BUILD_SHARED_LIBS OFF)

include(FetchContent)
FetchContent_Declare(SFML GIT_REPOSITORY https://github.com/SFML/SFML.git GIT_TAG master) # 2.6.x
FetchContent_MakeAvailable(SFML)

set(SFML_LIBRARIES
        sfml-graphics # Needs to be first
        sfml-window # Needs to be second
        sfml-audio # Needs to be before system
        sfml-network # Needs to be before system
        sfml-main # Needs to be before system
        sfml-system # Needs to be last
        )

target_link_libraries(${PROJECT_NAME} PRIVATE ${SFML_LIBRARIES})
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23)

if (WIN32 AND BUILD_SHARED_LIBS)
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:${PROJECT_NAME}> $<TARGET_FILE_DIR:${PROJECT_NAME}> COMMAND_EXPAND_LISTS)
endif ()

install(TARGETS ${PROJECT_NAME})
It plays the music and doesn't give any errors. Using mcvcrt runtime.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: undefined reference when using audio to play music
« Reply #6 on: December 01, 2022, 01:15:54 pm »
If you use git master (which is SFML 3 WIP and not SFML 2.6), you should use namespaces.
And if you don't link SFML dynamically, you can also get rid of the line at the bottom.
You don't need to set the standard globally if if you set the compile feature below.

For example:

cmake_minimum_required(VERSION 3.25.0)

# Setup
project(RedC LANGUAGES CXX) # Must match the main file name
set(EXECUTABLE_NAME "RedC") # Executable name
set(LANGUAGE CXX)

set(PROJECT_SOURCES # *.cpp that was made
        ${PROJECT_NAME}.cpp # Main file
        int/src/logger.cpp # Custom logger
        int/src/object.cpp # Base for any object in game that can be drawn
        int/src/enemyCharacter.cpp # Enemy object
        int/src/playerCharacter.cpp # Player objects
        int/src/staticObj.cpp # Not interactable object (wall)
        int/src/interactableObj.cpp # Interactable object (chest, loot, door)
        int/src/characterObj.cpp # Base for a character
        )

set(PROJECT_HEADERS # *.hpp that was made
        int/hdr/logger.hpp # Custom logger
        int/hdr/object.hpp
        int/hdr/enemyCharacter.hpp
        int/hdr/playerCharacter.hpp
        int/hdr/staticObj.hpp
        int/hdr/interactableObj.hpp
        int/hdr/characterObj.hpp
        )

include_directories( # dirs to include (.hpp)
                int/hdr/ # Allows for ease of use when using custom hpp files
                )

add_executable(${EXECUTABLE_NAME} ${PROJECT_NAME} ${PROJECT_SOURCES} ${PROJECT_HEADERS})

# Copying assets
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/assets/ $<TARGET_FILE_DIR:${PROJECT_NAME}>/assets/)

# SFML
option(BUILD_SHARED_LIBS OFF)

include(FetchContent)
FetchContent_Declare(SFML GIT_REPOSITORY https://github.com/SFML/SFML.git GIT_TAG master) # 2.6.x
FetchContent_MakeAvailable(SFML)

target_link_libraries(${PROJECT_NAME} PRIVATE SFML::Graphics SFML::Audio SFML::Network)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23)

install(TARGETS ${PROJECT_NAME})

You could additionally also use globbing to get all the files without having to list them all, but that's mostly a question of preference.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Lenny

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: undefined reference when using audio to play music
« Reply #7 on: December 02, 2022, 10:06:55 am »
If you use git master (which is SFML 3 WIP and not SFML 2.6), you should use namespaces.
And if you don't link SFML dynamically, you can also get rid of the line at the bottom.
You don't need to set the standard globally if if you set the compile feature below.

For example:

cmake_minimum_required(VERSION 3.25.0)

# Setup
project(RedC LANGUAGES CXX) # Must match the main file name
set(EXECUTABLE_NAME "RedC") # Executable name
set(LANGUAGE CXX)

set(PROJECT_SOURCES # *.cpp that was made
        ${PROJECT_NAME}.cpp # Main file
        int/src/logger.cpp # Custom logger
        int/src/object.cpp # Base for any object in game that can be drawn
        int/src/enemyCharacter.cpp # Enemy object
        int/src/playerCharacter.cpp # Player objects
        int/src/staticObj.cpp # Not interactable object (wall)
        int/src/interactableObj.cpp # Interactable object (chest, loot, door)
        int/src/characterObj.cpp # Base for a character
        )

set(PROJECT_HEADERS # *.hpp that was made
        int/hdr/logger.hpp # Custom logger
        int/hdr/object.hpp
        int/hdr/enemyCharacter.hpp
        int/hdr/playerCharacter.hpp
        int/hdr/staticObj.hpp
        int/hdr/interactableObj.hpp
        int/hdr/characterObj.hpp
        )

include_directories( # dirs to include (.hpp)
                int/hdr/ # Allows for ease of use when using custom hpp files
                )

add_executable(${EXECUTABLE_NAME} ${PROJECT_NAME} ${PROJECT_SOURCES} ${PROJECT_HEADERS})

# Copying assets
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/assets/ $<TARGET_FILE_DIR:${PROJECT_NAME}>/assets/)

# SFML
option(BUILD_SHARED_LIBS OFF)

include(FetchContent)
FetchContent_Declare(SFML GIT_REPOSITORY https://github.com/SFML/SFML.git GIT_TAG master) # 2.6.x
FetchContent_MakeAvailable(SFML)

target_link_libraries(${PROJECT_NAME} PRIVATE SFML::Graphics SFML::Audio SFML::Network)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23)

install(TARGETS ${PROJECT_NAME})

You could additionally also use globbing to get all the files without having to list them all, but that's mostly a question of preference.

That does look cleaner, thanks. The reason I'm using the master version is that on my pc I have an AMD GPU, if I don't use the master version it gives an error.

But now I'm having an issue when trying to run it on my laptop, it needs the openal32.dll next to the executable, but I thought it linked static libraries. If I don't place the DLL next to the EXE it crashes the program when using the audio library. I currently can't confirm this, but I think I did not have to do this when running it on my pc.
The error: Process finished with exit code -1073741515 (0xC0000135); after looking for this it is a missing DLL error.
« Last Edit: December 02, 2022, 10:09:41 am by Lenny »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: undefined reference when using audio to play music
« Reply #8 on: December 02, 2022, 10:15:15 am »
Due to OpenAL's LGPL license you can't link OpenAL statically, so you'll always need to ship the OpenAL DLL.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Kallyn

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: undefined reference when using audio to play music
« Reply #9 on: February 20, 2023, 06:57:21 pm »
If I have used the "new" version of MinGW in my previous projects, will everything still work if I replace it with the "old" version? Or is there a way to avoid redownloading and having to relink everything?