FluidSynth / fluidsynth

Software synthesizer based on the SoundFont 2 specifications
https://www.fluidsynth.org
GNU Lesser General Public License v2.1
1.89k stars 259 forks source link

Cannot build Fluidsynth with libsndfile on Windows. #1422

Closed carlo-bramini closed 1 week ago

carlo-bramini commented 3 weeks ago

Building Fluidsynth with support for libsndfile with MinGW stops with this error:

src/bindings/fluid_filerenderer.c:320:32: error: implicit declaration of function ‘sf_wchar_open’ [-Werror=implicit-function-declaration]
  320 |                 dev->sndfile = sf_wchar_open(wc_filename, SFM_WRITE, &info);
      |                                ^~~~~~~~~~~~~

According to the description inside sndfile.h, you must activate sf_wchar_open() by declaring ENABLE_SNDFILE_WINDOWS_PROTOTYPES somewhere:

/* The function sf_wchar_open() is Windows Only!
** Open a file passing in a Windows Unicode filename. Otherwise, this is
** the same as sf_open().
**
** In order for this to work, you need to do the following:
**
**      #include <windows.h>
**      #define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
**      #including <sndfile.h>
*/

But this is missing.

pedrolcl commented 3 weeks ago

The symbol ENABLE_SNDFILE_WINDOWS_PROTOTYPES has been deprecated since v1.1.0: https://github.com/libsndfile/libsndfile/blob/58c05b87162264200b1aa7790be260fd74c9deee/CHANGELOG.md?plain=1#L114

derselbst commented 3 weeks ago

@carlo-bramini Which version of libsndfile where you using, when you experienced the build error?

pedrolcl commented 3 weeks ago

The sf_wchar_open() function call was introduced to Fluidsynth in commit 0a86368 but this same commit also bumps LIBSNDFILE_MINIMUM_VERSION to 1.2.1 in CMakeLists.txt, so this bug report is invalid.

The latest libsndfile version having ENABLE_SNDFILE_WINDOWS_PROTOTYPES was 1.0.31: https://github.com/libsndfile/libsndfile/blob/1.0.31/include/sndfile.h.in#L755

carlo-bramini commented 3 weeks ago

I don't know exactly what's going on with LIBSNDFILE_MINIMUM_VERSION, but actually libsndfile 1.0.31 is found and used for building without troubles after the patch. In my opinion, if a single #define allows to make things working, I don't think that just adding ENABLE_SNDFILE_WINDOWS_PROTOTYPES somewhere would be a big trouble.

EDIT: perhaps, the comment near ENABLE_SNDFILE_WINDOWS_PROTOTYPES could be updated, for telling to the user that this is required only from a version of libsndfile.

pedrolcl commented 3 weeks ago

I don't know exactly what's going on with LIBSNDFILE_MINIMUM_VERSION, but actually libsndfile 1.0.31 is found and used for building without troubles after the patch.

That would be a real bug if it could be reproduced, which I can't. I've just configured fluidsynth current master in Linux, enabling libsndfile, installed libsndfile v1.1.0 and cmake correctly rejects it:

-- Could NOT find SndFile: Found unsuitable version "1.1.0", but required is at least "1.2.1" (found /usr/lib64/libsndfile.so)

And the same can be observed in Azure pipelines when building for Windows:

-- Could NOT find SndFile: Found unsuitable version "1.0.28", but required is at least "1.2.1" (found D:/deps/lib/sndfile.lib)
carlo-bramini commented 3 weeks ago

I'm using CYGWIN:

$ uname -a
CYGWIN_NT-10.0-19045 carlopc 3.5.4-1.x86_64 2024-08-25 16:52 UTC x86_64 Cygwin

this pkg-config:

$ x86_64-w64-mingw32-pkg-config --version
2.3.0

This CMake:

$ cmake --version
cmake version 3.28.3

and x86_64-w64-mingw32 cross compiler version 12.4.0, which is the latest available for this platform. Configuring Fluidsynth prints these messages:

$ cmake /home/carlo/github/fluidsynth/ -G Ninja -DCMAKE_TOOLCHAIN_FILE=/home/carlo/mingw64.cmake -Denable-sdl2=off
-- The C compiler identification is GNU 12.4.0
-- The CXX compiler identification is GNU 12.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/x86_64-w64-mingw32-gcc.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: /usr/bin/x86_64-w64-mingw32-g++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Checking whether system has ANSI C header files
-- Looking for 8 include files dlfcn.h, ..., float.h
-- Looking for 8 include files dlfcn.h, ..., float.h - not found
-- ANSI C header files - not found
-- Looking for include file unistd.h
-- Looking for include file unistd.h - found
-- Looking for DIR in sys/stat.h;sys/types.h;dirent.h
-- Looking for DIR in sys/stat.h;sys/types.h;dirent.h - found
-- Looking for string.h
-- Looking for string.h - found
-- Looking for strings.h
-- Looking for strings.h - found
-- Looking for stdlib.h
-- Looking for stdlib.h - found
-- Looking for stdio.h
-- Looking for stdio.h - found
-- Looking for math.h
-- Looking for math.h - found
-- Looking for errno.h
-- Looking for errno.h - found
-- Looking for stdarg.h
-- Looking for stdarg.h - found
-- Looking for sys/mman.h
-- Looking for sys/mman.h - not found
-- Looking for sys/time.h
-- Looking for sys/time.h - found
-- Looking for fcntl.h
-- Looking for fcntl.h - found
-- Looking for sys/socket.h
-- Looking for sys/socket.h - not found
-- Looking for netinet/in.h
-- Looking for netinet/in.h - not found
-- Looking for netinet/tcp.h
-- Looking for netinet/tcp.h - not found
-- Looking for arpa/inet.h
-- Looking for arpa/inet.h - not found
-- Looking for limits.h
-- Looking for limits.h - found
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for signal.h
-- Looking for signal.h - found
-- Looking for getopt.h
-- Looking for getopt.h - found
-- Looking for stdint.h
-- Looking for stdint.h - found
-- Looking for stddef.h
-- Looking for stddef.h - found
-- Check size of long long
-- Check size of long long - done
-- Performing Test _have_inline
-- Performing Test _have_inline - Success
-- Performing Test _have_vla
-- Performing Test _have_vla - Success
-- Performing Test HAVE_INCOMPATIBLE_POINTER_TYPES
-- Performing Test HAVE_INCOMPATIBLE_POINTER_TYPES - Success
-- Targeting Windows Version 0x0400
-- Looking for windows.h
-- Looking for windows.h - found
-- Looking for io.h
-- Looking for io.h - found
-- Looking for include files windows.h, dsound.h
-- Looking for include files windows.h, dsound.h - found
-- Looking for include files windows.h, mmsystem.h
-- Looking for include files windows.h, mmsystem.h - found
-- Looking for include files mmdeviceapi.h, audioclient.h
-- Looking for include files mmdeviceapi.h, audioclient.h - found
-- Looking for objbase.h
-- Looking for objbase.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Found GLib2: /usr/x86_64-w64-mingw32/sys-root/mingw/lib/libglib-2.0.dll.a (found suitable version "2.54.3", minimum required is "2.6.5")
-- Unable to get Opus version without pkg-config.
-- Cross-compiling without pkg-config - cannot check for external libraries.If you have the upstream CMake config set CMAKE_FIND_PACKAGE_PREFER_CONFIG to true for accurate results.
-- Found SndFile: /usr/x86_64-w64-mingw32/sys-root/mingw/lib/libsndfile.dll.a (Required is at least version "1.2.1")
Seems like libsndfile was compiled without OGG/Vorbis support.
-- Could NOT find PulseAudio (Set PulseAudio_DIR to the directory containing its CMake config)
-- Could NOT find ALSA (missing: ALSA_LIBRARY ALSA_INCLUDE_DIR) (Required is at least version "0.9.1")
-- Could NOT find Jack (missing: Jack_LIBRARY Jack_INCLUDE_DIR)
-- Could NOT find PipeWire (missing: PipeWire_LIBRARY PipeWire_INCLUDE_DIR Spa_INCLUDE_DIR) (Required is at least version "0.3")
-- Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE) (found version "2.3.0")
-- Could NOT find DBus1 (Set DBus1_DIR to the directory containing its CMake config)
-- Looking for ladspa.h
-- Looking for ladspa.h - not found
-- Found InstPatch: /usr/x86_64-w64-mingw32/sys-root/mingw/lib/libinstpatch-2.dll.a (found suitable version "1.1.6", minimum required is "1.1.0")
-- Found Readline: /usr/x86_64-w64-mingw32/sys-root/mingw/lib/libreadline.dll.a
-- No pkg-config file for readline found - trying to make it work anyway.
-- Looking for sys/soundcard.h
-- Looking for sys/soundcard.h - not found
-- Looking for linux/soundcard.h
-- Looking for linux/soundcard.h - not found
-- Looking for machine/soundcard.h
-- Looking for machine/soundcard.h - not found
-- Found OpenMP_C: -fopenmp (found version "4.5")
-- Found OpenMP: TRUE (found version "4.5") found components: C
-- Found OpenMP version: 4.5 date: 201511
-- Looking for sinf
-- Looking for sinf - found
-- Looking for cosf
-- Looking for cosf - found
-- Looking for fabsf
-- Looking for fabsf - found
-- Looking for powf
-- Looking for powf - found
-- Looking for sqrtf
-- Looking for sqrtf - found
-- Looking for logf
-- Looking for logf - found
-- Looking for inet_ntop
-- Looking for inet_ntop - not found
-- Check size of socklen_t
-- Check size of socklen_t - done
-- Found Doxygen: /usr/bin/doxygen.exe (found version "1.12.0") found components: doxygen dot
-- Found LibXslt: /usr/x86_64-w64-mingw32/sys-root/mingw/lib/libxslt.dll.a (found version "1.1.29")
--
**************************************************************
Build Summary:
Build type:            RelWithDebInfo
Install Prefix:        /usr/local

Audio / MIDI driver support:
  ALSA:                  no
  CoreAudio:             no
  CoreMIDI:              no
  DSound:                yes
  JACK:                  no
  MidiShare:             no
  Oboe:                  no
  OpenSLES:              no
  OS/2 DART:             no
  OS/2 KAI:              no
  OSS:                   no
  PipeWire:              no
  PortAudio:             no
  PulseAudio:            no
  SDL2:                  no
  WASAPI:                yes
  WaveOut:               yes
  WinMidi:               yes

Support for SF3 files:   no (libsndfile has no ogg vorbis support)
Support for DLS files:   yes

Audio to file rendering: yes
  libsndfile:            yes

Miscellaneous support:
  D-Bus:                 no
  LADSPA support:        no
  NETWORK Support:       yes
    IPV6 Support:        no
  Readline:              yes (NOTE: GPL library)
  systemd:               no
  getopt:                yes

Developer nerds info:
  Samples type:          double
  Multithread rendering: yes
  OpenMP 4.0:            yes
  Profiling:             no
  Debug Build:           no
  Trap on FPE (debug):   no
  Check FPE (debug):     no
  UBSan (debug):         no
  Coverage:              no

**************************************************************

-- Configuring done (46.3s)
-- Generating done (0.3s)
-- Build files have been written to: /home/carlo/f

As you can see, it prints:

-- Found SndFile: /usr/x86_64-w64-mingw32/sys-root/mingw/lib/libsndfile.dll.a (Required is at least version "1.2.1")

But this message also looks interesting:

-- Cross-compiling without pkg-config - cannot check for external libraries.If you have the upstream CMake config set CMAKE_FIND_PACKAGE_PREFER_CONFIG to true for accurate results.

Perhaps, the cross compiling is the cause. However, is there a particular reason for blocking the use of previous versions of libsndfile? I didn't big tests, but at least until now I have not found any particular problem with an old library. In any case, for me it's not a big problem to compile and install a newer version of libsndfile, I just used the one that was available actually.

derselbst commented 3 weeks ago

IMO, keeping the now unnecessary ENABLE_SNDFILE_WINDOWS_PROTOTYPES macro is fine. If we find that bumping the minimum version of libsndfile causing any problems, we can easily revert the bump without having to worry about the issue Carlo ran into.

I'd keep this open as a reminder to update libsndfile used in Windows CI.

pedrolcl commented 3 weeks ago

The reason for @carlo-bramini's succeeded build where libsndfile 1.0.31 is found and used for building fluidsynth's master is a non functional pkg-config. And this comes from our own FindSndFile.cmake depending on pkg-config for reading the version, and being too nice when it can't be retrieved.

And why we have a FindSndFile.cmake script in the first place? because #1211, and because libsndfile's cmake buildsystem was broken until @FtZPetruska was able to contribute fixes to that project, which were published in libsndfile v1.2.1

That was the reason for bumping LIBSNDFILE_MINIMUM_VERSION. Now we should be able to remove our FindSndFile.cmake script and its dependencies: FindFLAC.cmake, FindOGG.cmake, FindMPG123.cmake, Findmp3lame.cmake and FindVorbis.cmake.

One problem I've detected is that some Linux distros (debian, red hat/fedora) still fail to package libsndfile with cmake config scripts. But it is not our place to workaround that, and we may open bug reports on the distros about it. At the end, they will find the problem when building a newest fluidsynth version.

carlo-bramini commented 2 weeks ago

It looks like there is an additional side effect to this. I compiled libsndfile-1.2.2 for MinGW-w64 cross compiler of CYGWIN.

$ x86_64-w64-mingw32-pkg-config sndfile -modversion
1.2.2

If somebody will be interested, it is possible to retrieve those precompiled CYGWIN packages for i686 and x86_64 from my repository here: https://github.com/carlo-bramini/packages-cygwin/tree/main/libsndfile But something is still going wrong with Fluidsynth and libsndfile. This is an extract of the configuration summary of my new libsndfile-1.2.2-1:

-- The following features have been enabled:

 * ENABLE_EXTERNAL_LIBS, enable FLAC, Vorbis, and Opus codecs
 * ENABLE_MPEG, enable MPEG audio (including mp3) codecs
 * BUILD_TESTING, build tests
 * ENABLE_CPACK, enable CPack support
 * ENABLE_PACKAGE_CONFIG, generate and install package config file
 * INSTALL_PKGCONFIG_MODULE, generate and install pkg-config module
 * ENABLE_SSE2, add SSE2 compiler flag

-- The following OPTIONAL packages have been found:

 * Speex, an audio codec tuned for speech, <www.speex.org/>
   Enables experemental Speex support
 * SQLite3, light weight SQL database engine., <www.sqlite.org/>
   Enables regtest

-- The following RECOMMENDED packages have been found:

 * Vorbis, open source lossy audio codec, <www.vorbis.com/>
   Enables Vorbis support
 * FLAC, Free Lossless Audio Codec Library, <www.xiph.org/flac/>
   Enables FLAC support
 * Opus, Standardized open source low-latency fullband codec, <www.opus-codec.org/>
   Enables experimental Opus support
 * mp3lame, High quality MPEG Audio Layer III (MP3) encoder, <https://lame.sourceforge.io/>
   Enables MPEG layer III (MP3) writing support
 * mpg123 (required version >= 1.25.10), MPEG Audio Layer I/II/III decoder, <https://www.mpg123.de/>
   Enables MPEG Audio reading support

And I also verified with ldd the dependecies of libsndfile-1.dll to be more sure. When I configure Fluidsynth, I'm getting this:

-- Cross-compiling without pkg-config - cannot check for external libraries.If you have the upstream CMake config set CMAKE_FIND_PACKAGE_PREFER_CONFIG to true for accurate results.
-- Found SndFile: /usr/i686-w64-mingw32/sys-root/mingw/lib/libsndfile.dll.a (found suitable version "1.2.2", minimum required is "1.0.0")
Seems like libsndfile was compiled without OGG/Vorbis support.

But I'm 100% sure that libsndfile includes them instead. Actually, it was happening also with older 1.0.x versions of libsndfile, but since I didn't know how old libsndfile was compiled, I didn't pay too much attention to that message. At the moment, I don't know if this is somehow related to this issue, but probably yes, it is.

derselbst commented 1 week ago

Seems like libsndfile was compiled without OGG/Vorbis support.

libsndfile must be found and consumed through the cmake file SndFileConfig.cmake, because that's where SndFile_WITH_EXTERNAL_LIBS is set that fluidsynth evaluates for vorbis support. In your build logs and binaries, I can see that it's set. No clue why fulidsynth prints this error - I would still expect fluidsynth to be capable of loading SF3 files. At least I don't see any relevant part in the code that would depend of LIBSNDFILE_HASVORBIS being defined or not. If so, I would just ignore that message.