diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | .travis.yml | 3 | ||||
-rw-r--r-- | NEWS | 11 | ||||
-rwxr-xr-x | android/build.py | 2 | ||||
-rw-r--r-- | meson.build | 11 | ||||
-rw-r--r-- | python/build/cmake.py | 45 | ||||
-rw-r--r-- | python/build/libs.py | 28 | ||||
-rw-r--r-- | src/decoder/plugins/ModplugDecoderPlugin.cxx | 6 | ||||
-rw-r--r-- | src/decoder/plugins/WildmidiDecoderPlugin.cxx | 14 | ||||
-rw-r--r-- | src/decoder/plugins/meson.build | 11 | ||||
-rw-r--r-- | src/lib/ffmpeg/Time.hxx | 4 | ||||
-rwxr-xr-x | win32/build.py | 2 |
12 files changed, 128 insertions, 12 deletions
diff --git a/.gitignore b/.gitignore index c2fc6512f..cf00b5c57 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ /output/ __pycache__/ + +/.clangd/ +/compile_commands.json diff --git a/.travis.yml b/.travis.yml index 38bf7a331..baa55430e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -109,7 +109,8 @@ jobs: - chromaprint - libsamplerate - libsoxr - - libzzip + # libzzip appears to be broken on Homebrew: "ld: library not found for -lzzip" + #- libzzip - flac - opus - libvorbis @@ -43,8 +43,17 @@ ver 0.21.24 (not yet released) - "tagtypes" requires no permissions * database - simple: fix crash when mounting twice +* decoder + - modplug: fix Windows build failure + - wildmidi: attempt to detect WildMidi using pkg-config + - wildmidi: fix Windows build failure +* Android + - enable the decoder plugins ModPlug and WildMidi + - fix build failure with Android NDK r21 +* Windows + - enable the decoder plugins ModPlug and WildMidi + - work around Meson bug breaking the Windows build with GCC 10 * fix unit test failure -* fix build failure with Android NDK r21 ver 0.21.23 (2020/04/23) * protocol diff --git a/android/build.py b/android/build.py index 91e292683..8716fc1a9 100755 --- a/android/build.py +++ b/android/build.py @@ -168,6 +168,8 @@ thirdparty_libs = [ opus, flac, libid3tag, + libmodplug, + wildmidi, ffmpeg, curl, libexpat, diff --git a/meson.build b/meson.build index 085b97bbc..ed1a36eb2 100644 --- a/meson.build +++ b/meson.build @@ -5,7 +5,8 @@ project( meson_version: '>= 0.49.0', default_options: [ 'c_std=c99', - 'cpp_std=c++17' + 'cpp_std=c++17', + 'warning_level=2', ], license: 'GPLv2+', ) @@ -153,7 +154,13 @@ conf.set('HAVE_GETPWNAM_R', compiler.has_function('getpwnam_r')) conf.set('HAVE_GETPWUID_R', compiler.has_function('getpwuid_r')) conf.set('HAVE_INITGROUPS', compiler.has_function('initgroups')) conf.set('HAVE_FNMATCH', compiler.has_function('fnmatch')) -conf.set('HAVE_STRNDUP', compiler.has_function('strndup', prefix: '#define _GNU_SOURCE\n#include <string.h>')) + +# Explicitly exclude Windows in this check because +# https://github.com/mesonbuild/meson/issues/3672 (reported in 2018, +# still not fixed in 2020) causes Meson to believe it exists, because +# __builtin_strndup() exists (but strndup() still cannot be used). +conf.set('HAVE_STRNDUP', not is_windows and compiler.has_function('strndup', prefix: '#define _GNU_SOURCE\n#include <string.h>')) + conf.set('HAVE_STRCASESTR', compiler.has_function('strcasestr')) conf.set('HAVE_PRCTL', is_linux) diff --git a/python/build/cmake.py b/python/build/cmake.py new file mode 100644 index 000000000..76f217715 --- /dev/null +++ b/python/build/cmake.py @@ -0,0 +1,45 @@ +import subprocess + +from build.project import Project + +def configure(toolchain, src, build, args=()): + cross_args = [] + + if toolchain.is_windows: + cross_args.append('-DCMAKE_SYSTEM_NAME=Windows') + cross_args.append('-DCMAKE_RC_COMPILER=' + toolchain.windres) + + configure = [ + 'cmake', + src, + + '-DCMAKE_INSTALL_PREFIX=' + toolchain.install_prefix, + '-DCMAKE_BUILD_TYPE=release', + + '-DCMAKE_C_COMPILER=' + toolchain.cc, + '-DCMAKE_CXX_COMPILER=' + toolchain.cxx, + + '-DCMAKE_C_FLAGS=' + toolchain.cflags + ' ' + toolchain.cppflags, + '-DCMAKE_CXX_FLAGS=' + toolchain.cxxflags + ' ' + toolchain.cppflags, + + '-GNinja', + ] + cross_args + args + + subprocess.check_call(configure, env=toolchain.env, cwd=build) + +class CmakeProject(Project): + def __init__(self, url, md5, installed, configure_args=[], + **kwargs): + Project.__init__(self, url, md5, installed, **kwargs) + self.configure_args = configure_args + + def configure(self, toolchain): + src = self.unpack(toolchain) + build = self.make_build_path(toolchain) + configure(toolchain, src, build, self.configure_args) + return build + + def build(self, toolchain): + build = self.configure(toolchain) + subprocess.check_call(['ninja', 'install'], + cwd=build, env=toolchain.env) diff --git a/python/build/libs.py b/python/build/libs.py index 0063e220c..c7b2250cd 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -4,6 +4,7 @@ from os.path import abspath from build.project import Project from build.zlib import ZlibProject from build.meson import MesonProject +from build.cmake import CmakeProject from build.autotools import AutotoolsProject from build.ffmpeg import FfmpegProject from build.boost import BoostProject @@ -111,9 +112,32 @@ liblame = AutotoolsProject( ], ) +libmodplug = AutotoolsProject( + 'https://downloads.sourceforge.net/modplug-xmms/libmodplug/0.8.9.0/libmodplug-0.8.9.0.tar.gz', + '457ca5a6c179656d66c01505c0d95fafaead4329b9dbaa0f997d00a3508ad9de', + 'lib/libmodplug.a', + [ + '--disable-shared', '--enable-static', + ], +) + +wildmidi = CmakeProject( + 'https://codeload.github.com/Mindwerks/wildmidi/tar.gz/wildmidi-0.4.3', + '498e5a96455bb4b91b37188ad6dcb070824e92c44f5ed452b90adbaec8eef3c5', + 'lib/libWildMidi.a', + [ + '-DBUILD_SHARED_LIBS=OFF', + '-DWANT_PLAYER=OFF', + '-DWANT_STATIC=ON', + ], + base='wildmidi-wildmidi-0.4.3', + name='wildmidi', + version='0.4.3', +) + ffmpeg = FfmpegProject( - 'http://ffmpeg.org/releases/ffmpeg-4.2.2.tar.xz', - 'cb754255ab0ee2ea5f66f8850e1bd6ad5cac1cd855d0a2f4990fb8c668b0d29c', + 'http://ffmpeg.org/releases/ffmpeg-4.2.3.tar.xz', + '9df6c90aed1337634c1fb026fb01c154c29c82a64ea71291ff2da9aacb9aad31', 'lib/libavcodec.a', [ '--disable-shared', '--enable-static', diff --git a/src/decoder/plugins/ModplugDecoderPlugin.cxx b/src/decoder/plugins/ModplugDecoderPlugin.cxx index 380891f34..1cd820e80 100644 --- a/src/decoder/plugins/ModplugDecoderPlugin.cxx +++ b/src/decoder/plugins/ModplugDecoderPlugin.cxx @@ -27,6 +27,12 @@ #include "util/StringView.hxx" #include "Log.hxx" +#ifdef _WIN32 +/* assume ModPlug is built as static library on Windows; without + this, linking to the static library would fail */ +#define MODPLUG_STATIC +#endif + #include <libmodplug/modplug.h> #include <cassert> diff --git a/src/decoder/plugins/WildmidiDecoderPlugin.cxx b/src/decoder/plugins/WildmidiDecoderPlugin.cxx index ff3d42e19..d6ab6da40 100644 --- a/src/decoder/plugins/WildmidiDecoderPlugin.cxx +++ b/src/decoder/plugins/WildmidiDecoderPlugin.cxx @@ -25,8 +25,15 @@ #include "fs/AllocatedPath.hxx" #include "fs/FileSystem.hxx" #include "fs/Path.hxx" +#include "fs/NarrowPath.hxx" #include "PluginUnavailable.hxx" +#ifdef _WIN32 +/* assume WildMidi is built as static library on Windows; without + this, linking to the static library would fail */ +#define WILDMIDI_STATIC +#endif + extern "C" { #include <wildmidi_lib.h> } @@ -52,7 +59,8 @@ wildmidi_init(const ConfigBlock &block) AtScopeExit() { WildMidi_ClearError(); }; #endif - if (WildMidi_Init(path.c_str(), wildmidi_audio_format.sample_rate, + if (WildMidi_Init(NarrowPath(path), + wildmidi_audio_format.sample_rate, 0) != 0) { #ifdef LIBWILDMIDI_VERSION /* WildMidi_GetError() requires libwildmidi 0.4 */ @@ -95,7 +103,7 @@ wildmidi_file_decode(DecoderClient &client, Path path_fs) midi *wm; const struct _WM_Info *info; - wm = WildMidi_Open(path_fs.c_str()); + wm = WildMidi_Open(NarrowPath(path_fs)); if (wm == nullptr) return; @@ -135,7 +143,7 @@ wildmidi_file_decode(DecoderClient &client, Path path_fs) static bool wildmidi_scan_file(Path path_fs, TagHandler &handler) noexcept { - midi *wm = WildMidi_Open(path_fs.c_str()); + midi *wm = WildMidi_Open(NarrowPath(path_fs)); if (wm == nullptr) return false; diff --git a/src/decoder/plugins/meson.build b/src/decoder/plugins/meson.build index 6cb5d427d..0b37363fe 100644 --- a/src/decoder/plugins/meson.build +++ b/src/decoder/plugins/meson.build @@ -129,7 +129,16 @@ if wavpack_dep.found() decoder_plugins_sources += 'WavpackDecoderPlugin.cxx' endif -wildmidi_dep = c_compiler.find_library('WildMidi', required: get_option('wildmidi')) +wildmidi_required = get_option('wildmidi') +if wildmidi_required.enabled() + # if the user has force-enabled WildMidi, allow the pkg-config test + # to fail; after that, the find_library() check must succeed + wildmidi_required = false +endif +wildmidi_dep = dependency('wildmidi', required: wildmidi_required) +if not wildmidi_dep.found() + wildmidi_dep = c_compiler.find_library('WildMidi', required: get_option('wildmidi')) +endif decoder_features.set('ENABLE_WILDMIDI', wildmidi_dep.found()) if wildmidi_dep.found() decoder_plugins_sources += 'WildmidiDecoderPlugin.cxx' diff --git a/src/lib/ffmpeg/Time.hxx b/src/lib/ffmpeg/Time.hxx index 86bea09a2..52f6bc25f 100644 --- a/src/lib/ffmpeg/Time.hxx +++ b/src/lib/ffmpeg/Time.hxx @@ -45,7 +45,7 @@ FfmpegTimeToDouble(int64_t t, const AVRational time_base) noexcept { assert(t != (int64_t)AV_NOPTS_VALUE); - return FloatDuration(av_rescale_q(t, time_base, (AVRational){1, 1024})) + return FloatDuration(av_rescale_q(t, time_base, {1, 1024})) / 1024; } @@ -69,7 +69,7 @@ FromFfmpegTime(int64_t t, const AVRational time_base) noexcept assert(t != (int64_t)AV_NOPTS_VALUE); return SongTime::FromMS(av_rescale_q(t, time_base, - (AVRational){1, 1000})); + {1, 1000})); } /** diff --git a/win32/build.py b/win32/build.py index 0e09003fe..9e1b6e9e4 100755 --- a/win32/build.py +++ b/win32/build.py @@ -96,6 +96,8 @@ thirdparty_libs = [ zlib, libid3tag, liblame, + libmodplug, + wildmidi, ffmpeg, curl, libexpat, |