Compare commits
	
		
			76 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					8842650c33 | ||
| 
						 | 
					d5bf128cee | ||
| 
						 | 
					5cd86e272f | ||
| 
						 | 
					740cbe9e02 | ||
| 
						 | 
					ed890a273a | ||
| 
						 | 
					068cd559e1 | ||
| 
						 | 
					dc127f39a7 | ||
| 
						 | 
					7a99a7008c | ||
| 
						 | 
					70b451db7b | ||
| 
						 | 
					2ab03a0914 | ||
| 
						 | 
					2fa8c7d2db | ||
| 
						 | 
					7c759ba8b0 | ||
| 
						 | 
					6d9b452fde | ||
| 
						 | 
					f7eb1c9a83 | ||
| 
						 | 
					2d22e6dee4 | ||
| 
						 | 
					4587bf759d | ||
| 
						 | 
					e1e37cfe3c | ||
| 
						 | 
					381934985a | ||
| 
						 | 
					a8042885ac | ||
| 
						 | 
					a71e68db50 | ||
| 
						 | 
					1417578b3d | ||
| 
						 | 
					96befa138c | ||
| 
						 | 
					16a99804de | ||
| 
						 | 
					75a39ed279 | ||
| 
						 | 
					4d357ab77c | ||
| 
						 | 
					d4f3dd49b4 | ||
| 
						 | 
					4ec6d0555a | ||
| 
						 | 
					a6a1182c4c | ||
| 
						 | 
					a59c9c602b | ||
| 
						 | 
					0c4d824d64 | ||
| 
						 | 
					a5281856c9 | ||
| 
						 | 
					0206a46d39 | ||
| 
						 | 
					9475ef2202 | ||
| 
						 | 
					edae00e719 | ||
| 
						 | 
					fb695bc55f | ||
| 
						 | 
					23a5b8fd3c | ||
| 
						 | 
					273a93cfcf | ||
| 
						 | 
					d105985d78 | ||
| 
						 | 
					f8cfeb39e9 | ||
| 
						 | 
					d5d3982d3c | ||
| 
						 | 
					47341107ea | ||
| 
						 | 
					90eaa87a4d | ||
| 
						 | 
					b09a54b2c2 | ||
| 
						 | 
					10aec174d5 | ||
| 
						 | 
					d32ed194e8 | ||
| 
						 | 
					70d0fbd715 | ||
| 
						 | 
					302432e157 | ||
| 
						 | 
					4ab8a677dc | ||
| 
						 | 
					52e4a4c904 | ||
| 
						 | 
					a0f6932ebe | ||
| 
						 | 
					6e700dab69 | ||
| 
						 | 
					35eaed7206 | ||
| 
						 | 
					e7c963f2ce | ||
| 
						 | 
					949d72e368 | ||
| 
						 | 
					8d2a184658 | ||
| 
						 | 
					c877a32d97 | ||
| 
						 | 
					541468f0ca | ||
| 
						 | 
					d2797effa3 | ||
| 
						 | 
					1170fb1e1e | ||
| 
						 | 
					65b9b3195c | ||
| 
						 | 
					258830e913 | ||
| 
						 | 
					d91da96798 | ||
| 
						 | 
					b3897df682 | ||
| 
						 | 
					3cacb56bb7 | ||
| 
						 | 
					15a1973e28 | ||
| 
						 | 
					ad7d47a8ba | ||
| 
						 | 
					0948c607b6 | ||
| 
						 | 
					60d04052c5 | ||
| 
						 | 
					c1780ac657 | ||
| 
						 | 
					e49cf0ec38 | ||
| 
						 | 
					e1d641f684 | ||
| 
						 | 
					4efd0a9f77 | ||
| 
						 | 
					f6f8751332 | ||
| 
						 | 
					abb28593ce | ||
| 
						 | 
					115693b046 | ||
| 
						 | 
					e4b055eb6d | 
							
								
								
									
										29
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								NEWS
									
									
									
									
									
								
							@@ -1,3 +1,32 @@
 | 
			
		||||
ver 0.23.13 (2023/05/22)
 | 
			
		||||
* input
 | 
			
		||||
  - curl: fix busy loop after connection failed
 | 
			
		||||
  - curl: hide "404" log messages for non-existent ".mpdignore" files
 | 
			
		||||
* archive
 | 
			
		||||
  - zzip: fix crash bug
 | 
			
		||||
* database
 | 
			
		||||
  - simple: reveal hidden songs after deleting containing CUE
 | 
			
		||||
* decoder
 | 
			
		||||
  - ffmpeg: reorder to a lower priority than "gme"
 | 
			
		||||
  - gme: require GME 0.6 or later
 | 
			
		||||
* output
 | 
			
		||||
  - pipewire: fix corruption bug due to missing lock
 | 
			
		||||
* Linux
 | 
			
		||||
  - shut down if parent process dies in --no-daemon mode
 | 
			
		||||
  - determine systemd unit directories via pkg-config
 | 
			
		||||
* support libfmt 10
 | 
			
		||||
 | 
			
		||||
ver 0.23.12 (2023/01/17)
 | 
			
		||||
* input
 | 
			
		||||
  - curl: require CURL 7.55.0 or later
 | 
			
		||||
* decoder
 | 
			
		||||
  - mad: fix integer underflow with very small files
 | 
			
		||||
* tags
 | 
			
		||||
  - fix crash bug due to race condition
 | 
			
		||||
* output
 | 
			
		||||
  - pipewire: adjust to PipeWire 0.3.64 API change
 | 
			
		||||
* fix build failures with GCC 13
 | 
			
		||||
 | 
			
		||||
ver 0.23.11 (2022/11/28)
 | 
			
		||||
* database
 | 
			
		||||
  - simple: move default database to ~/.cache/mpd/db from ~/.cache/mpd.db
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,8 @@
 | 
			
		||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
          package="org.musicpd"
 | 
			
		||||
          android:installLocation="auto"
 | 
			
		||||
          android:versionCode="70"
 | 
			
		||||
          android:versionName="0.23.11">
 | 
			
		||||
          android:versionCode="71"
 | 
			
		||||
          android:versionName="0.23.12">
 | 
			
		||||
 | 
			
		||||
  <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30"/>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -100,6 +100,7 @@ class AndroidNdkToolchain:
 | 
			
		||||
        common_flags += ' -fvisibility=hidden -fdata-sections -ffunction-sections'
 | 
			
		||||
 | 
			
		||||
        self.ar = os.path.join(llvm_bin, 'llvm-ar')
 | 
			
		||||
        self.arflags = 'rcs'
 | 
			
		||||
        self.ranlib = os.path.join(llvm_bin, 'llvm-ranlib')
 | 
			
		||||
        self.nm = os.path.join(llvm_bin, 'llvm-nm')
 | 
			
		||||
        self.strip = os.path.join(llvm_bin, 'llvm-strip')
 | 
			
		||||
 
 | 
			
		||||
@@ -181,7 +181,7 @@
 | 
			
		||||
#
 | 
			
		||||
#database {
 | 
			
		||||
#       plugin "simple"
 | 
			
		||||
#       path "~/.local/share/mpd/db
 | 
			
		||||
#       path "~/.local/share/mpd/db"
 | 
			
		||||
#       cache_directory "~/.local/share/mpd/cache"
 | 
			
		||||
#}
 | 
			
		||||
#
 | 
			
		||||
 
 | 
			
		||||
@@ -611,6 +611,11 @@ If ReplayGain is enabled, then the setting ``replaygain_preamp`` is
 | 
			
		||||
set to a value (in dB) between ``-15`` and ``15``.  This is the gain
 | 
			
		||||
applied to songs with ReplayGain tags.
 | 
			
		||||
 | 
			
		||||
On songs without ReplayGain tags, the setting
 | 
			
		||||
``replaygain_missing_preamp`` is used instead.  If this setting is not
 | 
			
		||||
configured, then no ReplayGain is applied to such songs, and they will
 | 
			
		||||
appear too loud.
 | 
			
		||||
 | 
			
		||||
ReplayGain is usually implemented with a software volume filter (which
 | 
			
		||||
prevents `Bit-perfect playback`_).  To use a hardware mixer, set
 | 
			
		||||
``replay_gain_handler`` to ``mixer`` in the ``audio_output`` section
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
project(
 | 
			
		||||
  'mpd',
 | 
			
		||||
  ['c', 'cpp'],
 | 
			
		||||
  version: '0.23.11',
 | 
			
		||||
  version: '0.23.13',
 | 
			
		||||
  meson_version: '>= 0.56.0',
 | 
			
		||||
  default_options: [
 | 
			
		||||
    'c_std=c11',
 | 
			
		||||
@@ -205,7 +205,6 @@ enable_daemon = not is_windows and not is_android and get_option('daemon')
 | 
			
		||||
conf.set('ENABLE_DAEMON', enable_daemon)
 | 
			
		||||
 | 
			
		||||
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'))
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -45,14 +45,27 @@ class AutotoolsProject(MakeProject):
 | 
			
		||||
            'LDFLAGS=' + toolchain.ldflags + ' ' + self.ldflags,
 | 
			
		||||
            'LIBS=' + toolchain.libs + ' ' + self.libs,
 | 
			
		||||
            'AR=' + toolchain.ar,
 | 
			
		||||
            'ARFLAGS=' + toolchain.arflags,
 | 
			
		||||
            'RANLIB=' + toolchain.ranlib,
 | 
			
		||||
            'STRIP=' + toolchain.strip,
 | 
			
		||||
            '--host=' + toolchain.arch,
 | 
			
		||||
            '--prefix=' + toolchain.install_prefix,
 | 
			
		||||
            '--enable-silent-rules',
 | 
			
		||||
            '--disable-silent-rules',
 | 
			
		||||
        ] + self.configure_args
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            print(configure)
 | 
			
		||||
            subprocess.check_call(configure, cwd=build, env=toolchain.env)
 | 
			
		||||
        except subprocess.CalledProcessError:
 | 
			
		||||
            # dump config.log after a failed configure run
 | 
			
		||||
            try:
 | 
			
		||||
                with open(os.path.join(build, 'config.log')) as f:
 | 
			
		||||
                    sys.stdout.write(f.read())
 | 
			
		||||
            except:
 | 
			
		||||
                pass
 | 
			
		||||
            # re-raise the exception
 | 
			
		||||
            raise
 | 
			
		||||
 | 
			
		||||
        return build
 | 
			
		||||
 | 
			
		||||
    def _build(self, toolchain):
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import os
 | 
			
		||||
import re
 | 
			
		||||
import subprocess
 | 
			
		||||
 | 
			
		||||
from build.project import Project
 | 
			
		||||
@@ -25,13 +26,33 @@ set(CMAKE_SYSTEM_PROCESSOR {toolchain.actual_arch.split('-', 1)[0]})
 | 
			
		||||
set(CMAKE_C_COMPILER_TARGET {toolchain.actual_arch})
 | 
			
		||||
set(CMAKE_CXX_COMPILER_TARGET {toolchain.actual_arch})
 | 
			
		||||
 | 
			
		||||
set(CMAKE_C_FLAGS "{toolchain.cflags} {toolchain.cppflags}")
 | 
			
		||||
set(CMAKE_CXX_FLAGS "{toolchain.cxxflags} {toolchain.cppflags}")
 | 
			
		||||
set(CMAKE_C_FLAGS_INIT "{toolchain.cflags} {toolchain.cppflags}")
 | 
			
		||||
set(CMAKE_CXX_FLAGS_INIT "{toolchain.cxxflags} {toolchain.cppflags}")
 | 
			
		||||
""")
 | 
			
		||||
    __write_cmake_compiler(f, 'C', toolchain.cc)
 | 
			
		||||
    __write_cmake_compiler(f, 'CXX', toolchain.cxx)
 | 
			
		||||
 | 
			
		||||
def configure(toolchain, src, build, args=()):
 | 
			
		||||
    if cmake_system_name == 'Darwin':
 | 
			
		||||
        # On macOS, cmake forcibly adds an "-isysroot" flag even if
 | 
			
		||||
        # one is already present in the flags variable; this breaks
 | 
			
		||||
        # cross-compiling for iOS, and can be worked around by setting
 | 
			
		||||
        # the CMAKE_OSX_SYSROOT variable
 | 
			
		||||
        # (https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_SYSROOT.html).
 | 
			
		||||
        m = re.search(r'-isysroot +(\S+)', toolchain.cflags)
 | 
			
		||||
        if m:
 | 
			
		||||
            sysroot = m.group(1)
 | 
			
		||||
 | 
			
		||||
            print(f'set(CMAKE_OSX_SYSROOT {sysroot})', file=f)
 | 
			
		||||
 | 
			
		||||
            # search libraries and headers only in the sysroot, not on
 | 
			
		||||
            # the build host
 | 
			
		||||
            f.write(f"""
 | 
			
		||||
set(CMAKE_FIND_ROOT_PATH "{toolchain.install_prefix};{sysroot}")
 | 
			
		||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
 | 
			
		||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
def configure(toolchain, src, build, args=(), env=None):
 | 
			
		||||
    cross_args = []
 | 
			
		||||
 | 
			
		||||
    if toolchain.is_windows:
 | 
			
		||||
@@ -61,15 +82,23 @@ def configure(toolchain, src, build, args=()):
 | 
			
		||||
        '-GNinja',
 | 
			
		||||
    ] + cross_args + args
 | 
			
		||||
 | 
			
		||||
    subprocess.check_call(configure, env=toolchain.env, cwd=build)
 | 
			
		||||
    if env is None:
 | 
			
		||||
        env = toolchain.env
 | 
			
		||||
    else:
 | 
			
		||||
        env = {**toolchain.env, **env}
 | 
			
		||||
 | 
			
		||||
    print(configure)
 | 
			
		||||
    subprocess.check_call(configure, env=env, cwd=build)
 | 
			
		||||
 | 
			
		||||
class CmakeProject(Project):
 | 
			
		||||
    def __init__(self, url, md5, installed, configure_args=[],
 | 
			
		||||
                 windows_configure_args=[],
 | 
			
		||||
                 env=None,
 | 
			
		||||
                 **kwargs):
 | 
			
		||||
        Project.__init__(self, url, md5, installed, **kwargs)
 | 
			
		||||
        self.configure_args = configure_args
 | 
			
		||||
        self.windows_configure_args = windows_configure_args
 | 
			
		||||
        self.env = env
 | 
			
		||||
 | 
			
		||||
    def configure(self, toolchain):
 | 
			
		||||
        src = self.unpack(toolchain)
 | 
			
		||||
@@ -77,10 +106,10 @@ class CmakeProject(Project):
 | 
			
		||||
        configure_args = self.configure_args
 | 
			
		||||
        if toolchain.is_windows:
 | 
			
		||||
            configure_args = configure_args + self.windows_configure_args
 | 
			
		||||
        configure(toolchain, src, build, configure_args)
 | 
			
		||||
        configure(toolchain, src, build, configure_args, self.env)
 | 
			
		||||
        return build
 | 
			
		||||
 | 
			
		||||
    def _build(self, toolchain):
 | 
			
		||||
        build = self.configure(toolchain)
 | 
			
		||||
        subprocess.check_call(['ninja', 'install'],
 | 
			
		||||
        subprocess.check_call(['ninja', '-v', 'install'],
 | 
			
		||||
                              cwd=build, env=toolchain.env)
 | 
			
		||||
 
 | 
			
		||||
@@ -131,17 +131,14 @@ libopenmpt = AutotoolsProject(
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
wildmidi = CmakeProject(
 | 
			
		||||
    'https://codeload.github.com/Mindwerks/wildmidi/tar.gz/wildmidi-0.4.4',
 | 
			
		||||
    '6f267c8d331e9859906837e2c197093fddec31829d2ebf7b958cf6b7ae935430',
 | 
			
		||||
    'https://github.com/Mindwerks/wildmidi/releases/download/wildmidi-0.4.5/wildmidi-0.4.5.tar.gz',
 | 
			
		||||
    'd5e7bef00a7aa47534a53d43b1265f8d3d27f6a28e7f563c1cdf02ff4fa35b99',
 | 
			
		||||
    'lib/libWildMidi.a',
 | 
			
		||||
    [
 | 
			
		||||
        '-DBUILD_SHARED_LIBS=OFF',
 | 
			
		||||
        '-DWANT_PLAYER=OFF',
 | 
			
		||||
        '-DWANT_STATIC=ON',
 | 
			
		||||
    ],
 | 
			
		||||
    base='wildmidi-wildmidi-0.4.4',
 | 
			
		||||
    name='wildmidi',
 | 
			
		||||
    version='0.4.4',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
gme = CmakeProject(
 | 
			
		||||
@@ -157,8 +154,8 @@ gme = CmakeProject(
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
ffmpeg = FfmpegProject(
 | 
			
		||||
    'http://ffmpeg.org/releases/ffmpeg-5.1.2.tar.xz',
 | 
			
		||||
    '619e706d662c8420859832ddc259cd4d4096a48a2ce1eefd052db9e440eef3dc',
 | 
			
		||||
    'http://ffmpeg.org/releases/ffmpeg-6.0.tar.xz',
 | 
			
		||||
    '57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082',
 | 
			
		||||
    'lib/libavcodec.a',
 | 
			
		||||
    [
 | 
			
		||||
        '--disable-shared', '--enable-static',
 | 
			
		||||
@@ -176,13 +173,16 @@ ffmpeg = FfmpegProject(
 | 
			
		||||
        '--disable-pixelutils',
 | 
			
		||||
        '--disable-network',
 | 
			
		||||
        '--disable-encoders',
 | 
			
		||||
        '--disable-hwaccels',
 | 
			
		||||
        '--disable-muxers',
 | 
			
		||||
        '--disable-protocols',
 | 
			
		||||
        '--disable-devices',
 | 
			
		||||
        '--disable-filters',
 | 
			
		||||
        '--disable-v4l2_m2m',
 | 
			
		||||
 | 
			
		||||
        '--disable-sdl2',
 | 
			
		||||
        '--disable-vulkan',
 | 
			
		||||
        '--disable-xlib',
 | 
			
		||||
 | 
			
		||||
        '--disable-parser=bmp',
 | 
			
		||||
        '--disable-parser=cavsvideo',
 | 
			
		||||
@@ -196,17 +196,22 @@ ffmpeg = FfmpegProject(
 | 
			
		||||
        '--disable-parser=h263',
 | 
			
		||||
        '--disable-parser=h264',
 | 
			
		||||
        '--disable-parser=hevc',
 | 
			
		||||
        '--disable-parser=jpeg2000',
 | 
			
		||||
        '--disable-parser=mjpeg',
 | 
			
		||||
        '--disable-parser=mlp',
 | 
			
		||||
        '--disable-parser=mpeg4video',
 | 
			
		||||
        '--disable-parser=mpegvideo',
 | 
			
		||||
        '--disable-parser=opus',
 | 
			
		||||
        '--disable-parser=qoi',
 | 
			
		||||
        '--disable-parser=rv30',
 | 
			
		||||
        '--disable-parser=rv40',
 | 
			
		||||
        '--disable-parser=vc1',
 | 
			
		||||
        '--disable-parser=vp3',
 | 
			
		||||
        '--disable-parser=vp8',
 | 
			
		||||
        '--disable-parser=vp9',
 | 
			
		||||
        '--disable-parser=png',
 | 
			
		||||
        '--disable-parser=pnm',
 | 
			
		||||
        '--disable-parser=webp',
 | 
			
		||||
        '--disable-parser=xma',
 | 
			
		||||
 | 
			
		||||
        '--disable-demuxer=aqtitle',
 | 
			
		||||
@@ -222,6 +227,42 @@ ffmpeg = FfmpegProject(
 | 
			
		||||
        '--disable-demuxer=h264',
 | 
			
		||||
        '--disable-demuxer=ico',
 | 
			
		||||
        '--disable-demuxer=image2',
 | 
			
		||||
        '--disable-demuxer=image2pipe',
 | 
			
		||||
        '--disable-demuxer=image_bmp_pipe',
 | 
			
		||||
        '--disable-demuxer=image_cri_pipe',
 | 
			
		||||
        '--disable-demuxer=image_dds_pipe',
 | 
			
		||||
        '--disable-demuxer=image_dpx_pipe',
 | 
			
		||||
        '--disable-demuxer=image_exr_pipe',
 | 
			
		||||
        '--disable-demuxer=image_gem_pipe',
 | 
			
		||||
        '--disable-demuxer=image_gif_pipe',
 | 
			
		||||
        '--disable-demuxer=image_j2k_pipe',
 | 
			
		||||
        '--disable-demuxer=image_jpeg_pipe',
 | 
			
		||||
        '--disable-demuxer=image_jpegls_pipe',
 | 
			
		||||
        '--disable-demuxer=image_jpegxl_pipe',
 | 
			
		||||
        '--disable-demuxer=image_pam_pipe',
 | 
			
		||||
        '--disable-demuxer=image_pbm_pipe',
 | 
			
		||||
        '--disable-demuxer=image_pcx_pipe',
 | 
			
		||||
        '--disable-demuxer=image_pfm_pipe',
 | 
			
		||||
        '--disable-demuxer=image_pgm_pipe',
 | 
			
		||||
        '--disable-demuxer=image_pgmyuv_pipe',
 | 
			
		||||
        '--disable-demuxer=image_pgx_pipe',
 | 
			
		||||
        '--disable-demuxer=image_phm_pipe',
 | 
			
		||||
        '--disable-demuxer=image_photocd_pipe',
 | 
			
		||||
        '--disable-demuxer=image_pictor_pipe',
 | 
			
		||||
        '--disable-demuxer=image_png_pipe',
 | 
			
		||||
        '--disable-demuxer=image_ppm_pipe',
 | 
			
		||||
        '--disable-demuxer=image_psd_pipe',
 | 
			
		||||
        '--disable-demuxer=image_qdraw_pipe',
 | 
			
		||||
        '--disable-demuxer=image_qoi_pipe',
 | 
			
		||||
        '--disable-demuxer=image_sgi_pipe',
 | 
			
		||||
        '--disable-demuxer=image_sunrast_pipe',
 | 
			
		||||
        '--disable-demuxer=image_svg_pipe',
 | 
			
		||||
        '--disable-demuxer=image_tiff_pipe',
 | 
			
		||||
        '--disable-demuxer=image_vbn_pipe',
 | 
			
		||||
        '--disable-demuxer=image_webp_pipe',
 | 
			
		||||
        '--disable-demuxer=image_xbm_pipe',
 | 
			
		||||
        '--disable-demuxer=image_xpm_pipe',
 | 
			
		||||
        '--disable-demuxer=image_xwd_pipe',
 | 
			
		||||
        '--disable-demuxer=jacosub',
 | 
			
		||||
        '--disable-demuxer=lrc',
 | 
			
		||||
        '--disable-demuxer=microdvd',
 | 
			
		||||
@@ -244,6 +285,7 @@ ffmpeg = FfmpegProject(
 | 
			
		||||
        '--disable-demuxer=tedcaptions',
 | 
			
		||||
        '--disable-demuxer=vobsub',
 | 
			
		||||
        '--disable-demuxer=vplayer',
 | 
			
		||||
        '--disable-demuxer=webm_dash_manifest',
 | 
			
		||||
        '--disable-demuxer=webvtt',
 | 
			
		||||
        '--disable-demuxer=yuv4mpegpipe',
 | 
			
		||||
 | 
			
		||||
@@ -273,78 +315,179 @@ ffmpeg = FfmpegProject(
 | 
			
		||||
        '--disable-decoder=qdmc',
 | 
			
		||||
 | 
			
		||||
        # disable lots of image and video codecs
 | 
			
		||||
        '--disable-decoder=acelp_kelvin',
 | 
			
		||||
        '--disable-decoder=agm',
 | 
			
		||||
        '--disable-decoder=aic',
 | 
			
		||||
        '--disable-decoder=alias_pix',
 | 
			
		||||
        '--disable-decoder=ansi',
 | 
			
		||||
        '--disable-decoder=apng',
 | 
			
		||||
        '--disable-decoder=arbc',
 | 
			
		||||
        '--disable-decoder=argo',
 | 
			
		||||
        '--disable-decoder=ass',
 | 
			
		||||
        '--disable-decoder=asv1',
 | 
			
		||||
        '--disable-decoder=asv2',
 | 
			
		||||
        '--disable-decoder=apng',
 | 
			
		||||
        '--disable-decoder=aura',
 | 
			
		||||
        '--disable-decoder=aura2',
 | 
			
		||||
        '--disable-decoder=avrn',
 | 
			
		||||
        '--disable-decoder=avrp',
 | 
			
		||||
        '--disable-decoder=avui',
 | 
			
		||||
        '--disable-decoder=ayuv',
 | 
			
		||||
        '--disable-decoder=bethsoftvid',
 | 
			
		||||
        '--disable-decoder=bfi',
 | 
			
		||||
        '--disable-decoder=bink',
 | 
			
		||||
        '--disable-decoder=bintext',
 | 
			
		||||
        '--disable-decoder=bitpacked',
 | 
			
		||||
        '--disable-decoder=bmp',
 | 
			
		||||
        '--disable-decoder=bmv_video',
 | 
			
		||||
        '--disable-decoder=brender_pix',
 | 
			
		||||
        '--disable-decoder=c93',
 | 
			
		||||
        '--disable-decoder=cavs',
 | 
			
		||||
        '--disable-decoder=ccaption',
 | 
			
		||||
        '--disable-decoder=cdgraphics',
 | 
			
		||||
        '--disable-decoder=cdtoons',
 | 
			
		||||
        '--disable-decoder=cdxl',
 | 
			
		||||
        '--disable-decoder=cfhd',
 | 
			
		||||
        '--disable-decoder=cinepak',
 | 
			
		||||
        '--disable-decoder=clearvideo',
 | 
			
		||||
        '--disable-decoder=cljr',
 | 
			
		||||
        '--disable-decoder=cllc',
 | 
			
		||||
        '--disable-decoder=cpia',
 | 
			
		||||
        '--disable-decoder=cscd',
 | 
			
		||||
        '--disable-decoder=cyuv',
 | 
			
		||||
        '--disable-decoder=dds',
 | 
			
		||||
        '--disable-decoder=dirac',
 | 
			
		||||
        '--disable-decoder=dnxhd',
 | 
			
		||||
        '--disable-decoder=dpx',
 | 
			
		||||
        '--disable-decoder=dsicinvideo',
 | 
			
		||||
        '--disable-decoder=dvbsub',
 | 
			
		||||
        '--disable-decoder=dvdsub',
 | 
			
		||||
        '--disable-decoder=dvvideo',
 | 
			
		||||
        '--disable-decoder=dxa',
 | 
			
		||||
        '--disable-decoder=dxtory',
 | 
			
		||||
        '--disable-decoder=dxv',
 | 
			
		||||
        '--disable-decoder=eacmv',
 | 
			
		||||
        '--disable-decoder=eamad',
 | 
			
		||||
        '--disable-decoder=eatgq',
 | 
			
		||||
        '--disable-decoder=eatgv',
 | 
			
		||||
        '--disable-decoder=eatqi',
 | 
			
		||||
        '--disable-decoder=eightbps',
 | 
			
		||||
        '--disable-decoder=escape124',
 | 
			
		||||
        '--disable-decoder=escape130',
 | 
			
		||||
        '--disable-decoder=exr',
 | 
			
		||||
        '--disable-decoder=ffv1',
 | 
			
		||||
        '--disable-decoder=ffvhuff',
 | 
			
		||||
        '--disable-decoder=ffwavesynth',
 | 
			
		||||
        '--disable-decoder=fic',
 | 
			
		||||
        '--disable-decoder=fits',
 | 
			
		||||
        '--disable-decoder=flashsv',
 | 
			
		||||
        '--disable-decoder=flashsv2',
 | 
			
		||||
        '--disable-decoder=flic',
 | 
			
		||||
        '--disable-decoder=flv',
 | 
			
		||||
        '--disable-decoder=fmvc',
 | 
			
		||||
        '--disable-decoder=fraps',
 | 
			
		||||
        '--disable-decoder=fourxm',
 | 
			
		||||
        '--disable-decoder=frwu',
 | 
			
		||||
        '--disable-decoder=g2m',
 | 
			
		||||
        '--disable-decoder=gdv',
 | 
			
		||||
        '--disable-decoder=gem',
 | 
			
		||||
        '--disable-decoder=gif',
 | 
			
		||||
        '--disable-decoder=h261',
 | 
			
		||||
        '--disable-decoder=h263',
 | 
			
		||||
        '--disable-decoder=h263i',
 | 
			
		||||
        '--disable-decoder=h263p',
 | 
			
		||||
        '--disable-decoder=h264',
 | 
			
		||||
        '--disable-decoder=hap',
 | 
			
		||||
        '--disable-decoder=hevc',
 | 
			
		||||
        '--disable-decoder=hnm4_video',
 | 
			
		||||
        '--disable-decoder=hq_hqa',
 | 
			
		||||
        '--disable-decoder=hqx',
 | 
			
		||||
        '--disable-decoder=huffyuv',
 | 
			
		||||
        '--disable-decoder=hymt',
 | 
			
		||||
        '--disable-decoder=idcin',
 | 
			
		||||
        '--disable-decoder=idf',
 | 
			
		||||
        '--disable-decoder=iff_ilbm',
 | 
			
		||||
        '--disable-decoder=imm4',
 | 
			
		||||
        '--disable-decoder=indeo2',
 | 
			
		||||
        '--disable-decoder=indeo3',
 | 
			
		||||
        '--disable-decoder=indeo4',
 | 
			
		||||
        '--disable-decoder=indeo5',
 | 
			
		||||
        '--disable-decoder=interplay_video',
 | 
			
		||||
        '--disable-decoder=ipu',
 | 
			
		||||
        '--disable-decoder=jacosub',
 | 
			
		||||
        '--disable-decoder=jpeg2000',
 | 
			
		||||
        '--disable-decoder=jpegls',
 | 
			
		||||
        '--disable-decoder=jv',
 | 
			
		||||
        '--disable-decoder=kgv1',
 | 
			
		||||
        '--disable-decoder=kmvc',
 | 
			
		||||
        '--disable-decoder=lagarith',
 | 
			
		||||
        '--disable-decoder=loco',
 | 
			
		||||
        '--disable-decoder=lscr',
 | 
			
		||||
        '--disable-decoder=m101',
 | 
			
		||||
        '--disable-decoder=magicyuv',
 | 
			
		||||
        '--disable-decoder=mdec',
 | 
			
		||||
        '--disable-decoder=microdvd',
 | 
			
		||||
        '--disable-decoder=mimic',
 | 
			
		||||
        '--disable-decoder=mjpeg',
 | 
			
		||||
        '--disable-decoder=mmvideo',
 | 
			
		||||
        '--disable-decoder=mpl2',
 | 
			
		||||
        '--disable-decoder=mobiclip',
 | 
			
		||||
        '--disable-decoder=motionpixels',
 | 
			
		||||
        '--disable-decoder=movtext',
 | 
			
		||||
        '--disable-decoder=mpeg1video',
 | 
			
		||||
        '--disable-decoder=mpeg2video',
 | 
			
		||||
        '--disable-decoder=mpeg4',
 | 
			
		||||
        '--disable-decoder=mpegvideo',
 | 
			
		||||
        '--disable-decoder=msa1',
 | 
			
		||||
        '--disable-decoder=mscc',
 | 
			
		||||
        '--disable-decoder=msmpeg4_crystalhd',
 | 
			
		||||
        '--disable-decoder=msmpeg4v1',
 | 
			
		||||
        '--disable-decoder=msmpeg4v2',
 | 
			
		||||
        '--disable-decoder=msmpeg4v3',
 | 
			
		||||
        '--disable-decoder=msp2',
 | 
			
		||||
        '--disable-decoder=msrle',
 | 
			
		||||
        '--disable-decoder=mss1',
 | 
			
		||||
        '--disable-decoder=msvideo1',
 | 
			
		||||
        '--disable-decoder=mszh',
 | 
			
		||||
        '--disable-decoder=mts2',
 | 
			
		||||
        '--disable-decoder=mv30',
 | 
			
		||||
        '--disable-decoder=mvc1',
 | 
			
		||||
        '--disable-decoder=mvc2',
 | 
			
		||||
        '--disable-decoder=mvdv',
 | 
			
		||||
        '--disable-decoder=mvha',
 | 
			
		||||
        '--disable-decoder=mwsc',
 | 
			
		||||
        '--disable-decoder=notchlc',
 | 
			
		||||
        '--disable-decoder=nuv',
 | 
			
		||||
        '--disable-decoder=on2avc',
 | 
			
		||||
        '--disable-decoder=paf_video',
 | 
			
		||||
        '--disable-decoder=pam',
 | 
			
		||||
        '--disable-decoder=pbm',
 | 
			
		||||
        '--disable-decoder=pcx',
 | 
			
		||||
        '--disable-decoder=pgm',
 | 
			
		||||
        '--disable-decoder=pgmyuv',
 | 
			
		||||
        '--disable-decoder=pgssub',
 | 
			
		||||
        '--disable-decoder=pgx',
 | 
			
		||||
        '--disable-decoder=phm',
 | 
			
		||||
        '--disable-decoder=photocd',
 | 
			
		||||
        '--disable-decoder=png',
 | 
			
		||||
        '--disable-decoder=pictor',
 | 
			
		||||
        '--disable-decoder=pixlet',
 | 
			
		||||
        '--disable-decoder=pjs',
 | 
			
		||||
        '--disable-decoder=ppm',
 | 
			
		||||
        '--disable-decoder=prores',
 | 
			
		||||
        '--disable-decoder=prosumer',
 | 
			
		||||
        '--disable-decoder=psd',
 | 
			
		||||
        '--disable-decoder=ptx',
 | 
			
		||||
        '--disable-decoder=qdraw',
 | 
			
		||||
        '--disable-decoder=qoi',
 | 
			
		||||
        '--disable-decoder=qpeg',
 | 
			
		||||
        '--disable-decoder=qtrle',
 | 
			
		||||
        '--disable-decoder=rawvideo',
 | 
			
		||||
        '--disable-decoder=r10k',
 | 
			
		||||
        '--disable-decoder=r210',
 | 
			
		||||
        '--disable-decoder=rasc',
 | 
			
		||||
        '--disable-decoder=realtext',
 | 
			
		||||
        '--disable-decoder=rl2',
 | 
			
		||||
        '--disable-decoder=rpza',
 | 
			
		||||
        '--disable-decoder=roq',
 | 
			
		||||
        '--disable-decoder=roq_dpcm',
 | 
			
		||||
        '--disable-decoder=rscc',
 | 
			
		||||
@@ -353,48 +496,116 @@ ffmpeg = FfmpegProject(
 | 
			
		||||
        '--disable-decoder=rv30',
 | 
			
		||||
        '--disable-decoder=rv40',
 | 
			
		||||
        '--disable-decoder=sami',
 | 
			
		||||
        '--disable-decoder=sanm',
 | 
			
		||||
        '--disable-decoder=scpr',
 | 
			
		||||
        '--disable-decoder=screenpresso',
 | 
			
		||||
        '--disable-decoder=sga',
 | 
			
		||||
        '--disable-decoder=sgi',
 | 
			
		||||
        '--disable-decoder=sgirle',
 | 
			
		||||
        '--disable-decoder=sheervideo',
 | 
			
		||||
        '--disable-decoder=simbiosis_imx',
 | 
			
		||||
        '--disable-decoder=smc',
 | 
			
		||||
        '--disable-decoder=snow',
 | 
			
		||||
        '--disable-decoder=speedhq',
 | 
			
		||||
        '--disable-decoder=srgc',
 | 
			
		||||
        '--disable-decoder=srt',
 | 
			
		||||
        '--disable-decoder=ssa',
 | 
			
		||||
        '--disable-decoder=stl',
 | 
			
		||||
        '--disable-decoder=subrip',
 | 
			
		||||
        '--disable-decoder=subviewer',
 | 
			
		||||
        '--disable-decoder=subviewer1',
 | 
			
		||||
        '--disable-decoder=sunrast',
 | 
			
		||||
        '--disable-decoder=svq1',
 | 
			
		||||
        '--disable-decoder=svq3',
 | 
			
		||||
        '--disable-decoder=targa',
 | 
			
		||||
        '--disable-decoder=targa_y216',
 | 
			
		||||
        '--disable-decoder=text',
 | 
			
		||||
        '--disable-decoder=tiff',
 | 
			
		||||
        '--disable-decoder=tiertexseqvideo',
 | 
			
		||||
        '--disable-decoder=tmv',
 | 
			
		||||
        '--disable-decoder=truemotion1',
 | 
			
		||||
        '--disable-decoder=truemotion2',
 | 
			
		||||
        '--disable-decoder=truemotion2rt',
 | 
			
		||||
        '--disable-decoder=tscc',
 | 
			
		||||
        '--disable-decoder=tscc2',
 | 
			
		||||
        '--disable-decoder=twinvq',
 | 
			
		||||
        '--disable-decoder=txd',
 | 
			
		||||
        '--disable-decoder=ulti',
 | 
			
		||||
        '--disable-decoder=utvideo',
 | 
			
		||||
        '--disable-decoder=v210',
 | 
			
		||||
        '--disable-decoder=v210x',
 | 
			
		||||
        '--disable-decoder=v308',
 | 
			
		||||
        '--disable-decoder=v408',
 | 
			
		||||
        '--disable-decoder=v410',
 | 
			
		||||
        '--disable-decoder=vb',
 | 
			
		||||
        '--disable-decoder=vble',
 | 
			
		||||
        '--disable-decoder=vbn',
 | 
			
		||||
        '--disable-decoder=vc1',
 | 
			
		||||
        '--disable-decoder=vcr1',
 | 
			
		||||
        '--disable-decoder=vmdvideo',
 | 
			
		||||
        '--disable-decoder=vmnc',
 | 
			
		||||
        '--disable-decoder=vp3',
 | 
			
		||||
        '--disable-decoder=vp5',
 | 
			
		||||
        '--disable-decoder=vp6',
 | 
			
		||||
        '--disable-decoder=vp7',
 | 
			
		||||
        '--disable-decoder=vp8',
 | 
			
		||||
        '--disable-decoder=vp9',
 | 
			
		||||
        '--disable-decoder=vplayer',
 | 
			
		||||
        '--disable-decoder=vqa',
 | 
			
		||||
        '--disable-decoder=webvtt',
 | 
			
		||||
        '--disable-decoder=wcmv',
 | 
			
		||||
        '--disable-decoder=wmv1',
 | 
			
		||||
        '--disable-decoder=wmv2',
 | 
			
		||||
        '--disable-decoder=wmv3',
 | 
			
		||||
        '--disable-decoder=wnv1',
 | 
			
		||||
        '--disable-decoder=wrapped_avframe',
 | 
			
		||||
        '--disable-decoder=xan_wc3',
 | 
			
		||||
        '--disable-decoder=xan_wc4',
 | 
			
		||||
        '--disable-decoder=xbin',
 | 
			
		||||
        '--disable-decoder=xbm',
 | 
			
		||||
        '--disable-decoder=xface',
 | 
			
		||||
        '--disable-decoder=xl',
 | 
			
		||||
        '--disable-decoder=xpm',
 | 
			
		||||
        '--disable-decoder=xsub',
 | 
			
		||||
        '--disable-decoder=xwd',
 | 
			
		||||
        '--disable-decoder=y41p',
 | 
			
		||||
        '--disable-decoder=ylc',
 | 
			
		||||
        '--disable-decoder=yop',
 | 
			
		||||
        '--disable-decoder=yuv4',
 | 
			
		||||
        '--disable-decoder=zero12v',
 | 
			
		||||
        '--disable-decoder=zerocodec',
 | 
			
		||||
        '--disable-decoder=zlib',
 | 
			
		||||
        '--disable-decoder=zmbv',
 | 
			
		||||
 | 
			
		||||
        '--disable-bsf=av1_frame_merge',
 | 
			
		||||
        '--disable-bsf=av1_frame_split',
 | 
			
		||||
        '--disable-bsf=av1_metadata',
 | 
			
		||||
        '--disable-bsf=dts2pts',
 | 
			
		||||
        '--disable-bsf=h264_metadata',
 | 
			
		||||
        '--disable-bsf=h264_mp4toannexb',
 | 
			
		||||
        '--disable-bsf=h264_redundant_pps',
 | 
			
		||||
        '--disable-bsf=hevc_metadata',
 | 
			
		||||
        '--disable-bsf=hevc_mp4toannexb',
 | 
			
		||||
        '--disable-bsf=mjpeg2jpeg',
 | 
			
		||||
        '--disable-bsf=opus_metadata',
 | 
			
		||||
        '--disable-bsf=pgs_frame_merge',
 | 
			
		||||
        '--disable-bsf=text2movsub',
 | 
			
		||||
        '--disable-bsf=vp9_metadata',
 | 
			
		||||
        '--disable-bsf=vp9_raw_reorder',
 | 
			
		||||
        '--disable-bsf=vp9_superframe',
 | 
			
		||||
        '--disable-bsf=vp9_superframe_split',
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
openssl = OpenSSLProject(
 | 
			
		||||
    'https://www.openssl.org/source/openssl-3.0.7.tar.gz',
 | 
			
		||||
    '83049d042a260e696f62406ac5c08bf706fd84383f945cf21bd61e9ed95c396e',
 | 
			
		||||
    'https://www.openssl.org/source/openssl-3.1.0.tar.gz',
 | 
			
		||||
    'aaa925ad9828745c4cad9d9efeb273deca820f2cdcf2c3ac7d7c1212b7c497b4',
 | 
			
		||||
    'include/openssl/ossl_typ.h',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
curl = CmakeProject(
 | 
			
		||||
    'https://curl.se/download/curl-7.86.0.tar.xz',
 | 
			
		||||
    '2d61116e5f485581f6d59865377df4463f2e788677ac43222b496d4e49fb627b',
 | 
			
		||||
    'https://curl.se/download/curl-8.0.1.tar.xz',
 | 
			
		||||
    '0a381cd82f4d00a9a334438b8ca239afea5bfefcfa9a1025f2bf118e79e0b5f0',
 | 
			
		||||
    'lib/libcurl.a',
 | 
			
		||||
    [
 | 
			
		||||
        '-DBUILD_CURL_EXE=OFF',
 | 
			
		||||
@@ -450,7 +661,7 @@ jack = JackProject(
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
boost = BoostProject(
 | 
			
		||||
    'https://boostorg.jfrog.io/artifactory/main/release/1.80.0/source/boost_1_80_0.tar.bz2',
 | 
			
		||||
    '1e19565d82e43bc59209a168f5ac899d3ba471d55c7610c677d4ccf2c9c500c0',
 | 
			
		||||
    'https://boostorg.jfrog.io/artifactory/main/release/1.81.0/source/boost_1_81_0.tar.bz2',
 | 
			
		||||
    '71feeed900fbccca04a3b4f2f84a7c217186f28a940ed8b7ed4725986baf99fa',
 | 
			
		||||
    'include/boost/version.hpp',
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import subprocess
 | 
			
		||||
import subprocess, multiprocessing
 | 
			
		||||
 | 
			
		||||
from build.project import Project
 | 
			
		||||
 | 
			
		||||
@@ -10,6 +10,11 @@ class MakeProject(Project):
 | 
			
		||||
        self.install_target = install_target
 | 
			
		||||
 | 
			
		||||
    def get_simultaneous_jobs(self):
 | 
			
		||||
        try:
 | 
			
		||||
            # use twice as many simultaneous jobs as we have CPU cores
 | 
			
		||||
            return multiprocessing.cpu_count() * 2
 | 
			
		||||
        except NotImplementedError:
 | 
			
		||||
            # default to 12, if multiprocessing.cpu_count() is not implemented
 | 
			
		||||
            return 12
 | 
			
		||||
 | 
			
		||||
    def get_make_args(self, toolchain):
 | 
			
		||||
@@ -19,7 +24,7 @@ class MakeProject(Project):
 | 
			
		||||
        return ['--quiet', self.install_target]
 | 
			
		||||
 | 
			
		||||
    def make(self, toolchain, wd, args):
 | 
			
		||||
        subprocess.check_call(['/usr/bin/make'] + args,
 | 
			
		||||
        subprocess.check_call(['make'] + args,
 | 
			
		||||
                              cwd=wd, env=toolchain.env)
 | 
			
		||||
 | 
			
		||||
    def build_make(self, toolchain, wd, install=True):
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import os.path, subprocess, sys
 | 
			
		||||
import os
 | 
			
		||||
import subprocess
 | 
			
		||||
import platform
 | 
			
		||||
 | 
			
		||||
from build.project import Project
 | 
			
		||||
@@ -115,5 +116,5 @@ class MesonProject(Project):
 | 
			
		||||
 | 
			
		||||
    def _build(self, toolchain):
 | 
			
		||||
        build = self.configure(toolchain)
 | 
			
		||||
        subprocess.check_call(['ninja', 'install'],
 | 
			
		||||
        subprocess.check_call(['ninja', '-v', 'install'],
 | 
			
		||||
                              cwd=build, env=toolchain.env)
 | 
			
		||||
 
 | 
			
		||||
@@ -14,13 +14,14 @@ class Project:
 | 
			
		||||
        if base is None:
 | 
			
		||||
            basename = os.path.basename(url)
 | 
			
		||||
            m = re.match(r'^(.+)\.(tar(\.(gz|bz2|xz|lzma))?|zip)$', basename)
 | 
			
		||||
            if not m: raise
 | 
			
		||||
            if not m: raise RuntimeError('Could not identify tarball name: ' + basename)
 | 
			
		||||
            self.base = m.group(1)
 | 
			
		||||
        else:
 | 
			
		||||
            self.base = base
 | 
			
		||||
 | 
			
		||||
        if name is None or version is None:
 | 
			
		||||
            m = re.match(r'^([-\w]+)-(\d[\d.]*[a-z]?[\d.]*(?:-(?:alpha|beta)\d+)?)(\+.*)?$', self.base)
 | 
			
		||||
            if not m: raise RuntimeError('Could not identify tarball name: ' + self.base)
 | 
			
		||||
            if name is None: name = m.group(1)
 | 
			
		||||
            if version is None: version = m.group(2)
 | 
			
		||||
 | 
			
		||||
@@ -55,8 +56,8 @@ class Project:
 | 
			
		||||
            parent_path = toolchain.src_path
 | 
			
		||||
        else:
 | 
			
		||||
            parent_path = toolchain.build_path
 | 
			
		||||
        path = untar(self.download(toolchain), parent_path, self.base)
 | 
			
		||||
 | 
			
		||||
        path = untar(self.download(toolchain), parent_path, self.base,
 | 
			
		||||
                     lazy=out_of_tree and self.patches is None)
 | 
			
		||||
        if self.patches is not None:
 | 
			
		||||
            push_all(toolchain, path, self.patches)
 | 
			
		||||
 | 
			
		||||
@@ -71,8 +72,10 @@ class Project:
 | 
			
		||||
 | 
			
		||||
        return path
 | 
			
		||||
 | 
			
		||||
    def make_build_path(self, toolchain):
 | 
			
		||||
    def make_build_path(self, toolchain, lazy=False):
 | 
			
		||||
        path = os.path.join(toolchain.build_path, self.base)
 | 
			
		||||
        if lazy and os.path.isdir(path):
 | 
			
		||||
            return path
 | 
			
		||||
        try:
 | 
			
		||||
            shutil.rmtree(path)
 | 
			
		||||
        except FileNotFoundError:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,16 @@
 | 
			
		||||
import os, shutil, subprocess
 | 
			
		||||
 | 
			
		||||
def untar(tarball_path, parent_path, base):
 | 
			
		||||
def untar(tarball_path, parent_path, base, lazy=False):
 | 
			
		||||
    path = os.path.join(parent_path, base)
 | 
			
		||||
    if lazy and os.path.isdir(path):
 | 
			
		||||
        return path
 | 
			
		||||
    try:
 | 
			
		||||
        shutil.rmtree(path)
 | 
			
		||||
    except FileNotFoundError:
 | 
			
		||||
        pass
 | 
			
		||||
    os.makedirs(parent_path, exist_ok=True)
 | 
			
		||||
    try:
 | 
			
		||||
        subprocess.check_call(['/bin/tar', 'xfC', tarball_path, parent_path])
 | 
			
		||||
        subprocess.check_call(['tar', 'xfC', tarball_path, parent_path])
 | 
			
		||||
    except FileNotFoundError:
 | 
			
		||||
        import tarfile
 | 
			
		||||
        tar = tarfile.open(tarball_path)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,22 +1,32 @@
 | 
			
		||||
import os.path, subprocess
 | 
			
		||||
import subprocess
 | 
			
		||||
 | 
			
		||||
from build.project import Project
 | 
			
		||||
from build.makeproject import MakeProject
 | 
			
		||||
 | 
			
		||||
class ZlibProject(Project):
 | 
			
		||||
class ZlibProject(MakeProject):
 | 
			
		||||
    def __init__(self, url, md5, installed,
 | 
			
		||||
                 **kwargs):
 | 
			
		||||
        Project.__init__(self, url, md5, installed, **kwargs)
 | 
			
		||||
        MakeProject.__init__(self, url, md5, installed, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def get_make_args(self, toolchain):
 | 
			
		||||
        return MakeProject.get_make_args(self, toolchain) + [
 | 
			
		||||
            'CC=' + toolchain.cc + ' ' + toolchain.cppflags + ' ' + toolchain.cflags,
 | 
			
		||||
            'CPP=' + toolchain.cc + ' -E ' + toolchain.cppflags,
 | 
			
		||||
            'AR=' + toolchain.ar,
 | 
			
		||||
            'ARFLAGS=' + toolchain.arflags,
 | 
			
		||||
            'RANLIB=' + toolchain.ranlib,
 | 
			
		||||
            'LDSHARED=' + toolchain.cc + ' -shared',
 | 
			
		||||
            'libz.a'
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
    def get_make_install_args(self, toolchain):
 | 
			
		||||
        return [
 | 
			
		||||
            'RANLIB=' + toolchain.ranlib,
 | 
			
		||||
            self.install_target
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
    def _build(self, toolchain):
 | 
			
		||||
        src = self.unpack(toolchain, out_of_tree=False)
 | 
			
		||||
 | 
			
		||||
        subprocess.check_call(['/usr/bin/make', '--quiet',
 | 
			
		||||
            '-f', 'win32/Makefile.gcc',
 | 
			
		||||
            'PREFIX=' + toolchain.arch + '-',
 | 
			
		||||
            '-j12',
 | 
			
		||||
            'install',
 | 
			
		||||
            'INCLUDE_PATH='+ os.path.join(toolchain.install_prefix, 'include'),
 | 
			
		||||
            'LIBRARY_PATH=' + os.path.join(toolchain.install_prefix, 'lib'),
 | 
			
		||||
            'BINARY_PATH=' + os.path.join(toolchain.install_prefix, 'bin'),
 | 
			
		||||
            ],
 | 
			
		||||
        subprocess.check_call(['./configure', '--prefix=' + toolchain.install_prefix, '--static'],
 | 
			
		||||
                              cwd=src, env=toolchain.env)
 | 
			
		||||
        self.build_make(toolchain, src)
 | 
			
		||||
 
 | 
			
		||||
@@ -352,12 +352,16 @@ ParseCommandLine(int argc, char **argv, CommandLineOptions &options,
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case OPTION_NO_DAEMON:
 | 
			
		||||
#ifdef ENABLE_DAEMON
 | 
			
		||||
			options.daemon = false;
 | 
			
		||||
#endif
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
		case OPTION_SYSTEMD:
 | 
			
		||||
#ifdef ENABLE_DAEMON
 | 
			
		||||
			options.daemon = false;
 | 
			
		||||
#endif
 | 
			
		||||
			options.systemd = true;
 | 
			
		||||
			break;
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -20,11 +20,18 @@
 | 
			
		||||
#ifndef MPD_COMMAND_LINE_HXX
 | 
			
		||||
#define MPD_COMMAND_LINE_HXX
 | 
			
		||||
 | 
			
		||||
#include "config.h" // for ENABLE_DAEMON
 | 
			
		||||
 | 
			
		||||
struct ConfigData;
 | 
			
		||||
 | 
			
		||||
struct CommandLineOptions {
 | 
			
		||||
	bool kill = false;
 | 
			
		||||
 | 
			
		||||
#ifdef ENABLE_DAEMON
 | 
			
		||||
	bool daemon = true;
 | 
			
		||||
#else
 | 
			
		||||
	static constexpr bool daemon = false;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
	bool systemd = false;
 | 
			
		||||
 
 | 
			
		||||
@@ -482,7 +482,10 @@ MainConfigured(const CommandLineOptions &options,
 | 
			
		||||
#ifndef ANDROID
 | 
			
		||||
	setup_log_output();
 | 
			
		||||
 | 
			
		||||
	const ScopeSignalHandlersInit signal_handlers_init(instance);
 | 
			
		||||
	const ScopeSignalHandlersInit signal_handlers_init{
 | 
			
		||||
		instance,
 | 
			
		||||
		options.daemon,
 | 
			
		||||
	};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	instance.io_thread.Start();
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,11 @@
 | 
			
		||||
#include <boost/intrusive/list.hpp>
 | 
			
		||||
#include <boost/intrusive/unordered_set.hpp>
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <utility>
 | 
			
		||||
 | 
			
		||||
class RemoteTagCacheHandler;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@
 | 
			
		||||
#include "TagPrint.hxx"
 | 
			
		||||
#include "client/Response.hxx"
 | 
			
		||||
#include "fs/Traits.hxx"
 | 
			
		||||
#include "lib/fmt/AudioFormatFormatter.hxx"
 | 
			
		||||
#include "time/ChronoUtil.hxx"
 | 
			
		||||
#include "util/StringBuffer.hxx"
 | 
			
		||||
#include "util/UriUtil.hxx"
 | 
			
		||||
@@ -93,7 +94,7 @@ song_print_info(Response &r, const LightSong &song, bool base) noexcept
 | 
			
		||||
		time_print(r, "Last-Modified", song.mtime);
 | 
			
		||||
 | 
			
		||||
	if (song.audio_format.IsDefined())
 | 
			
		||||
		r.Fmt(FMT_STRING("Format: {}\n"), ToString(song.audio_format));
 | 
			
		||||
		r.Fmt(FMT_STRING("Format: {}\n"), song.audio_format);
 | 
			
		||||
 | 
			
		||||
	tag_print_values(r, song.tag);
 | 
			
		||||
 | 
			
		||||
@@ -116,7 +117,7 @@ song_print_info(Response &r, const DetachedSong &song, bool base) noexcept
 | 
			
		||||
		time_print(r, "Last-Modified", song.GetLastModified());
 | 
			
		||||
 | 
			
		||||
	if (const auto &f = song.GetAudioFormat(); f.IsDefined())
 | 
			
		||||
		r.Fmt(FMT_STRING("Format: {}\n"), ToString(f));
 | 
			
		||||
		r.Fmt(FMT_STRING("Format: {}\n"), f);
 | 
			
		||||
 | 
			
		||||
	tag_print_values(r, song.GetTag());
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -63,6 +63,9 @@ song_save(BufferedOutputStream &os, const Song &song)
 | 
			
		||||
	if (song.audio_format.IsDefined())
 | 
			
		||||
		os.Format("Format: %s\n", ToString(song.audio_format).c_str());
 | 
			
		||||
 | 
			
		||||
	if (song.in_playlist)
 | 
			
		||||
		os.Write("InPlaylist: yes\n");
 | 
			
		||||
 | 
			
		||||
	if (!IsNegative(song.mtime))
 | 
			
		||||
		os.Format(SONG_MTIME ": %li\n",
 | 
			
		||||
			  (long)std::chrono::system_clock::to_time_t(song.mtime));
 | 
			
		||||
@@ -86,7 +89,7 @@ song_save(BufferedOutputStream &os, const DetachedSong &song)
 | 
			
		||||
 | 
			
		||||
DetachedSong
 | 
			
		||||
song_load(LineReader &file, const char *uri,
 | 
			
		||||
	  std::string *target_r)
 | 
			
		||||
	  std::string *target_r, bool *in_playlist_r)
 | 
			
		||||
{
 | 
			
		||||
	DetachedSong song(uri);
 | 
			
		||||
 | 
			
		||||
@@ -132,6 +135,9 @@ song_load(LineReader &file, const char *uri,
 | 
			
		||||
 | 
			
		||||
			song.SetStartTime(SongTime::FromMS(start_ms));
 | 
			
		||||
			song.SetEndTime(SongTime::FromMS(end_ms));
 | 
			
		||||
		} else if (StringIsEqual(line, "InPlaylist")) {
 | 
			
		||||
			if (in_playlist_r != nullptr)
 | 
			
		||||
				*in_playlist_r = StringIsEqual(value, "yes");
 | 
			
		||||
		} else {
 | 
			
		||||
			throw FormatRuntimeError("unknown line in db: %s", line);
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -44,6 +44,6 @@ song_save(BufferedOutputStream &os, const DetachedSong &song);
 | 
			
		||||
 */
 | 
			
		||||
DetachedSong
 | 
			
		||||
song_load(LineReader &file, const char *uri,
 | 
			
		||||
	  std::string *target_r=nullptr);
 | 
			
		||||
	  std::string *target_r=nullptr, bool *in_playlist_r=nullptr);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -35,8 +35,9 @@ tag_print_types(Response &r) noexcept
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tag_print(Response &r, TagType type, StringView value) noexcept
 | 
			
		||||
tag_print(Response &r, TagType type, StringView _value) noexcept
 | 
			
		||||
{
 | 
			
		||||
	const std::string_view value{_value};
 | 
			
		||||
	r.Fmt(FMT_STRING("{}: {}\n"), tag_item_names[type], value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -36,5 +36,5 @@ time_print(Response &r, const char *name,
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r.Fmt(FMT_STRING("{}: {}\n"), name, s);
 | 
			
		||||
	r.Fmt(FMT_STRING("{}: {}\n"), name, s.c_str());
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,8 @@
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <limits.h> // for UINT_MAX
 | 
			
		||||
 | 
			
		||||
CommandResult
 | 
			
		||||
handle_listfiles_db(Client &client, Response &r, const char *uri)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -100,10 +100,6 @@ handle_listfiles_local(Response &r, Path path_fs)
 | 
			
		||||
	return CommandResult::OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) && GCC_CHECK_VERSION(4,6)
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
gcc_pure
 | 
			
		||||
static bool
 | 
			
		||||
IsValidName(const StringView s) noexcept
 | 
			
		||||
@@ -130,7 +126,8 @@ public:
 | 
			
		||||
	explicit PrintCommentHandler(Response &_response) noexcept
 | 
			
		||||
		:NullTagHandler(WANT_PAIR), response(_response) {}
 | 
			
		||||
 | 
			
		||||
	void OnPair(StringView key, StringView value) noexcept override {
 | 
			
		||||
	void OnPair(StringView _key, StringView _value) noexcept override {
 | 
			
		||||
		const std::string_view key{_key}, value{_value};
 | 
			
		||||
		if (IsValidName(key) && IsValidValue(value))
 | 
			
		||||
			response.Fmt(FMT_STRING("{}: {}\n"), key, value);
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,7 @@
 | 
			
		||||
#include "Partition.hxx"
 | 
			
		||||
#include "Instance.hxx"
 | 
			
		||||
#include "IdleFlags.hxx"
 | 
			
		||||
#include "lib/fmt/AudioFormatFormatter.hxx"
 | 
			
		||||
#include "util/StringBuffer.hxx"
 | 
			
		||||
#include "util/ScopeExit.hxx"
 | 
			
		||||
#include "util/Exception.hxx"
 | 
			
		||||
@@ -185,7 +186,7 @@ handle_status(Client &client, [[maybe_unused]] Request args, Response &r)
 | 
			
		||||
 | 
			
		||||
		if (player_status.audio_format.IsDefined())
 | 
			
		||||
			r.Fmt(FMT_STRING(COMMAND_STATUS_AUDIO ": {}\n"),
 | 
			
		||||
			      ToString(player_status.audio_format));
 | 
			
		||||
			      player_status.audio_format);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef ENABLE_DATABASE
 | 
			
		||||
 
 | 
			
		||||
@@ -83,10 +83,6 @@ handle_listfiles_storage(Response &r, StorageDirectoryReader &reader)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) && GCC_CHECK_VERSION(4,6)
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
CommandResult
 | 
			
		||||
handle_listfiles_storage(Response &r, Storage &storage, const char *uri)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -126,6 +126,18 @@ Directory::LookupTargetSong(std::string_view _target) noexcept
 | 
			
		||||
	return lr.directory->FindSong(lr.rest);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Directory::ClearInPlaylist() noexcept
 | 
			
		||||
{
 | 
			
		||||
	assert(holding_db_lock());
 | 
			
		||||
 | 
			
		||||
	for (auto &child : children)
 | 
			
		||||
		child.ClearInPlaylist();
 | 
			
		||||
 | 
			
		||||
	for (auto &song : songs)
 | 
			
		||||
		song.in_playlist = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Directory::PruneEmpty() noexcept
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -287,6 +287,14 @@ public:
 | 
			
		||||
	 */
 | 
			
		||||
	SongPtr RemoveSong(Song *song) noexcept;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Recursively walk through the whole tree and set all
 | 
			
		||||
	 * `Song::in_playlist` fields to `false`.
 | 
			
		||||
	 *
 | 
			
		||||
	 * Caller must lock the #db_mutex.
 | 
			
		||||
	 */
 | 
			
		||||
	void ClearInPlaylist() noexcept;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Caller must lock the #db_mutex.
 | 
			
		||||
	 */
 | 
			
		||||
 
 | 
			
		||||
@@ -168,12 +168,14 @@ directory_load(LineReader &file, Directory &directory)
 | 
			
		||||
				throw FormatRuntimeError("Duplicate song '%s'", name);
 | 
			
		||||
 | 
			
		||||
			std::string target;
 | 
			
		||||
			bool in_playlist = false;
 | 
			
		||||
			auto detached_song = song_load(file, name,
 | 
			
		||||
						       &target);
 | 
			
		||||
						       &target, &in_playlist);
 | 
			
		||||
 | 
			
		||||
			auto song = std::make_unique<Song>(std::move(detached_song),
 | 
			
		||||
							   directory);
 | 
			
		||||
			song->target = std::move(target);
 | 
			
		||||
			song->in_playlist = in_playlist;
 | 
			
		||||
 | 
			
		||||
			directory.AddSong(std::move(song));
 | 
			
		||||
		} else if ((p = StringAfterPrefix(line, PLAYLIST_META_BEGIN))) {
 | 
			
		||||
 
 | 
			
		||||
@@ -51,6 +51,15 @@ LockFindSong(Directory &directory, std::string_view name) noexcept
 | 
			
		||||
	return directory.FindSong(name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
[[gnu::pure]]
 | 
			
		||||
static bool
 | 
			
		||||
IsAcceptableFilename(std::string_view name) noexcept
 | 
			
		||||
{
 | 
			
		||||
	return !name.empty() &&
 | 
			
		||||
		/* newlines cannot be represented in MPD's protocol */
 | 
			
		||||
		name.find('\n') == name.npos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
UpdateWalk::UpdateArchiveTree(ArchiveFile &archive, Directory &directory,
 | 
			
		||||
			      const char *name) noexcept
 | 
			
		||||
@@ -58,6 +67,9 @@ UpdateWalk::UpdateArchiveTree(ArchiveFile &archive, Directory &directory,
 | 
			
		||||
	const char *tmp = std::strchr(name, '/');
 | 
			
		||||
	if (tmp) {
 | 
			
		||||
		const std::string_view child_name(name, tmp - name);
 | 
			
		||||
		if (!IsAcceptableFilename(child_name))
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		//add dir is not there already
 | 
			
		||||
		Directory *subdir = LockMakeChild(directory, child_name);
 | 
			
		||||
		subdir->device = DEVICE_INARCHIVE;
 | 
			
		||||
@@ -65,11 +77,8 @@ UpdateWalk::UpdateArchiveTree(ArchiveFile &archive, Directory &directory,
 | 
			
		||||
		//create directories first
 | 
			
		||||
		UpdateArchiveTree(archive, *subdir, tmp + 1);
 | 
			
		||||
	} else {
 | 
			
		||||
		if (StringIsEmpty(name)) {
 | 
			
		||||
			LogWarning(update_domain,
 | 
			
		||||
				   "archive returned directory only");
 | 
			
		||||
		if (!IsAcceptableFilename(name))
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//add file
 | 
			
		||||
		Song *song = LockFindSong(directory, name);
 | 
			
		||||
 
 | 
			
		||||
@@ -531,6 +531,7 @@ UpdateWalk::Walk(Directory &root, const char *path, bool discard) noexcept
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		const ScopeDatabaseLock protect;
 | 
			
		||||
		root.ClearInPlaylist();
 | 
			
		||||
		PurgeDanglingFromPlaylists(root);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -114,11 +114,11 @@ constexpr const struct DecoderPlugin *decoder_plugins[] = {
 | 
			
		||||
#ifdef ENABLE_ADPLUG
 | 
			
		||||
	&adplug_decoder_plugin,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ENABLE_FFMPEG
 | 
			
		||||
	&ffmpeg_decoder_plugin,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ENABLE_GME
 | 
			
		||||
	&gme_decoder_plugin,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ENABLE_FFMPEG
 | 
			
		||||
	&ffmpeg_decoder_plugin,
 | 
			
		||||
#endif
 | 
			
		||||
	&pcm_decoder_plugin,
 | 
			
		||||
	nullptr
 | 
			
		||||
 
 | 
			
		||||
@@ -56,20 +56,17 @@ struct GmeContainerPath {
 | 
			
		||||
	unsigned track;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if GME_VERSION >= 0x000600
 | 
			
		||||
static int gme_accuracy;
 | 
			
		||||
#endif
 | 
			
		||||
static unsigned gme_default_fade;
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
gme_plugin_init([[maybe_unused]] const ConfigBlock &block)
 | 
			
		||||
{
 | 
			
		||||
#if GME_VERSION >= 0x000600
 | 
			
		||||
	auto accuracy = block.GetBlockParam("accuracy");
 | 
			
		||||
	gme_accuracy = accuracy != nullptr
 | 
			
		||||
		? (int)accuracy->GetBoolValue()
 | 
			
		||||
		: -1;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	auto fade = block.GetBlockParam("default_fade");
 | 
			
		||||
	gme_default_fade = fade != nullptr
 | 
			
		||||
		? fade->GetUnsignedValue() * 1000
 | 
			
		||||
@@ -163,10 +160,8 @@ gme_file_decode(DecoderClient &client, Path path_fs)
 | 
			
		||||
	FmtDebug(gme_domain, "emulator type '{}'",
 | 
			
		||||
		 gme_type_system(gme_type(emu)));
 | 
			
		||||
 | 
			
		||||
#if GME_VERSION >= 0x000600
 | 
			
		||||
	if (gme_accuracy >= 0)
 | 
			
		||||
		gme_enable_accuracy(emu, gme_accuracy);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	gme_info_t *ti;
 | 
			
		||||
	const char *gme_err = gme_track_info(emu, &ti, container.track);
 | 
			
		||||
 
 | 
			
		||||
@@ -798,6 +798,8 @@ MadDecoder::UpdateTimerNextFrame() noexcept
 | 
			
		||||
DecoderCommand
 | 
			
		||||
MadDecoder::SubmitPCM(size_t i, size_t pcm_length) noexcept
 | 
			
		||||
{
 | 
			
		||||
	assert(i <= pcm_length);
 | 
			
		||||
 | 
			
		||||
	size_t num_samples = pcm_length - i;
 | 
			
		||||
 | 
			
		||||
	mad_fixed_to_24_buffer(output_buffer, synth.pcm,
 | 
			
		||||
@@ -843,7 +845,7 @@ MadDecoder::SynthAndSubmit() noexcept
 | 
			
		||||
	size_t pcm_length = synth.pcm.length;
 | 
			
		||||
	if (drop_end_samples &&
 | 
			
		||||
	    current_frame == max_frames - drop_end_frames - 1) {
 | 
			
		||||
		if (drop_end_samples >= pcm_length)
 | 
			
		||||
		if (i + drop_end_samples >= pcm_length)
 | 
			
		||||
			return DecoderCommand::STOP;
 | 
			
		||||
 | 
			
		||||
		pcm_length -= drop_end_samples;
 | 
			
		||||
 
 | 
			
		||||
@@ -81,7 +81,7 @@ if libfaad_dep.found()
 | 
			
		||||
  decoder_plugins_sources += 'FaadDecoderPlugin.cxx'
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
libgme_dep = c_compiler.find_library('gme', required: get_option('gme'))
 | 
			
		||||
libgme_dep = dependency('libgme', version: '>= 0.6', required: get_option('gme'))
 | 
			
		||||
decoder_features.set('ENABLE_GME', libgme_dep.found())
 | 
			
		||||
if libgme_dep.found()
 | 
			
		||||
  decoder_plugins_sources += 'GmeDecoderPlugin.cxx'
 | 
			
		||||
 
 | 
			
		||||
@@ -272,9 +272,8 @@ EventLoop::Run() noexcept
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	assert(IsInside());
 | 
			
		||||
	assert(!quit);
 | 
			
		||||
#ifdef HAVE_THREADED_EVENT_LOOP
 | 
			
		||||
	assert(alive);
 | 
			
		||||
	assert(alive || quit);
 | 
			
		||||
	assert(busy);
 | 
			
		||||
 | 
			
		||||
	wake_event.Schedule(SocketEvent::READ);
 | 
			
		||||
@@ -299,7 +298,7 @@ EventLoop::Run() noexcept
 | 
			
		||||
 | 
			
		||||
	steady_clock_cache.flush();
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
	while (!quit) {
 | 
			
		||||
		again = false;
 | 
			
		||||
 | 
			
		||||
		/* invoke timers */
 | 
			
		||||
@@ -361,7 +360,7 @@ EventLoop::Run() noexcept
 | 
			
		||||
 | 
			
		||||
			socket_event.Dispatch();
 | 
			
		||||
		}
 | 
			
		||||
	} while (!quit);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_THREADED_EVENT_LOOP
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,6 @@
 | 
			
		||||
#include "Charset.hxx"
 | 
			
		||||
#include "Features.hxx"
 | 
			
		||||
#include "Domain.hxx"
 | 
			
		||||
#include "Log.hxx"
 | 
			
		||||
#include "lib/icu/Converter.hxx"
 | 
			
		||||
#include "util/AllocatedString.hxx"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
@@ -45,11 +44,9 @@ SetFSCharset(const char *charset)
 | 
			
		||||
	assert(charset != nullptr);
 | 
			
		||||
	assert(fs_converter == nullptr);
 | 
			
		||||
 | 
			
		||||
	fs_charset = charset;
 | 
			
		||||
	fs_converter = IcuConverter::Create(charset);
 | 
			
		||||
	assert(fs_converter != nullptr);
 | 
			
		||||
 | 
			
		||||
	FmtDebug(path_domain,
 | 
			
		||||
		 "SetFSCharset: fs charset is {}", fs_charset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,6 @@
 | 
			
		||||
#include <shlobj.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <pwd.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -80,15 +79,6 @@ public:
 | 
			
		||||
		return result != nullptr;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool ReadByUid(uid_t uid) {
 | 
			
		||||
#ifdef HAVE_GETPWUID_R
 | 
			
		||||
		getpwuid_r(uid, &pw, buf.data(), buf.size(), &result);
 | 
			
		||||
#else
 | 
			
		||||
		result = getpwuid(uid);
 | 
			
		||||
#endif
 | 
			
		||||
		return result != nullptr;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const passwd *operator->() {
 | 
			
		||||
		assert(result != nullptr);
 | 
			
		||||
		return result;
 | 
			
		||||
@@ -375,10 +365,8 @@ GetHomeDir() noexcept
 | 
			
		||||
	if (const auto home = getenv("HOME");
 | 
			
		||||
	    IsValidPathString(home) && IsValidDir(home))
 | 
			
		||||
		return AllocatedPath::FromFS(home);
 | 
			
		||||
 | 
			
		||||
	if (PasswdEntry pw; pw.ReadByUid(getuid()))
 | 
			
		||||
		return SafePathFromFS(pw->pw_dir);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -101,9 +101,17 @@ AsyncInputStream::Seek(std::unique_lock<Mutex> &lock,
 | 
			
		||||
	assert(IsReady());
 | 
			
		||||
	assert(seek_state == SeekState::NONE);
 | 
			
		||||
 | 
			
		||||
	if (new_offset == offset)
 | 
			
		||||
		/* no-op */
 | 
			
		||||
	if (new_offset == offset) {
 | 
			
		||||
		/* no-op, but if the stream is not open anymore (maybe
 | 
			
		||||
		   because it has failed), nothing can be read, so we
 | 
			
		||||
		   should check for errors here instead of pretending
 | 
			
		||||
		   everything's fine */
 | 
			
		||||
 | 
			
		||||
		if (!open)
 | 
			
		||||
			Check();
 | 
			
		||||
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!IsSeekable())
 | 
			
		||||
		throw std::runtime_error("Not seekable");
 | 
			
		||||
 
 | 
			
		||||
@@ -417,7 +417,6 @@ CurlInputStream::InitEasy()
 | 
			
		||||
	request->SetOption(CURLOPT_HTTP200ALIASES, http_200_aliases);
 | 
			
		||||
	request->SetOption(CURLOPT_FOLLOWLOCATION, 1L);
 | 
			
		||||
	request->SetOption(CURLOPT_MAXREDIRS, 5L);
 | 
			
		||||
	request->SetOption(CURLOPT_FAILONERROR, 1L);
 | 
			
		||||
 | 
			
		||||
	/* this option eliminates the probe request when
 | 
			
		||||
	   username/password are specified */
 | 
			
		||||
 
 | 
			
		||||
@@ -42,6 +42,8 @@
 | 
			
		||||
#include "io/UniqueFileDescriptor.hxx"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
class Path;
 | 
			
		||||
class FileInfo;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,13 +18,13 @@ endif
 | 
			
		||||
 | 
			
		||||
conf.set('HAVE_MD5', crypto_md5_dep.found())
 | 
			
		||||
 | 
			
		||||
if libavutil_dep.found()
 | 
			
		||||
if ffmpeg_util_dep.found()
 | 
			
		||||
  crypto_base64 = static_library(
 | 
			
		||||
    'crypto_base64',
 | 
			
		||||
    'Base64.cxx',
 | 
			
		||||
    include_directories: inc,
 | 
			
		||||
    dependencies: [
 | 
			
		||||
      libavutil_dep,
 | 
			
		||||
      ffmpeg_util_dep,
 | 
			
		||||
    ],
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -186,10 +186,6 @@ public:
 | 
			
		||||
		SetOption(CURLOPT_POSTFIELDSIZE, (long)size);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void SetHttpPost(const struct curl_httppost *post) {
 | 
			
		||||
		SetOption(CURLOPT_HTTPPOST, post);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	template<typename T>
 | 
			
		||||
	bool GetInfo(CURLINFO info, T value_r) const noexcept {
 | 
			
		||||
		return ::curl_easy_getinfo(handle, info, value_r) == CURLE_OK;
 | 
			
		||||
@@ -199,10 +195,10 @@ public:
 | 
			
		||||
	 * Returns the response body's size, or -1 if that is unknown.
 | 
			
		||||
	 */
 | 
			
		||||
	[[gnu::pure]]
 | 
			
		||||
	int64_t GetContentLength() const noexcept {
 | 
			
		||||
		double value;
 | 
			
		||||
		return GetInfo(CURLINFO_CONTENT_LENGTH_DOWNLOAD, &value)
 | 
			
		||||
			? (int64_t)value
 | 
			
		||||
	curl_off_t GetContentLength() const noexcept {
 | 
			
		||||
		curl_off_t value;
 | 
			
		||||
		return GetInfo(CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &value)
 | 
			
		||||
			? value
 | 
			
		||||
			: -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
curl_dep = dependency('libcurl', version: '>= 7.33', required: get_option('curl'))
 | 
			
		||||
curl_dep = dependency('libcurl', version: '>= 7.55', required: get_option('curl'))
 | 
			
		||||
conf.set('ENABLE_CURL', curl_dep.found())
 | 
			
		||||
if not curl_dep.found()
 | 
			
		||||
  subdir_done()
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,7 @@
 | 
			
		||||
#include "Iter.hxx"
 | 
			
		||||
#include "Values.hxx"
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
namespace ODBus {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,42 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2021 The Music Player Daemon Project
 | 
			
		||||
 * http://www.musicpd.org
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along
 | 
			
		||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "LogError.hxx"
 | 
			
		||||
#include "Domain.hxx"
 | 
			
		||||
#include "Log.hxx"
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
#include <libavutil/error.h>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
LogFfmpegError(int errnum)
 | 
			
		||||
{
 | 
			
		||||
	char msg[256];
 | 
			
		||||
	av_strerror(errnum, msg, sizeof(msg));
 | 
			
		||||
	LogError(ffmpeg_domain, msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
LogFfmpegError(int errnum, const char *prefix)
 | 
			
		||||
{
 | 
			
		||||
	char msg[256];
 | 
			
		||||
	av_strerror(errnum, msg, sizeof(msg));
 | 
			
		||||
	FmtError(ffmpeg_domain, "{}: {}", prefix, msg);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,29 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2021 The Music Player Daemon Project
 | 
			
		||||
 * http://www.musicpd.org
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along
 | 
			
		||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef MPD_FFMPEG_LOG_ERROR_HXX
 | 
			
		||||
#define MPD_FFMPEG_LOG_ERROR_HXX
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
LogFfmpegError(int errnum);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
LogFfmpegError(int errnum, const char *prefix);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -13,6 +13,29 @@ else
 | 
			
		||||
endif
 | 
			
		||||
conf.set('HAVE_LIBAVFILTER', libavfilter_dep.found())
 | 
			
		||||
 | 
			
		||||
if not libavutil_dep.found()
 | 
			
		||||
  ffmpeg_util_dep = dependency('', required: false)
 | 
			
		||||
  ffmpeg_dep = dependency('', required: false)
 | 
			
		||||
  subdir_done()
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ffmpeg_util = static_library(
 | 
			
		||||
  'ffmpeg_util',
 | 
			
		||||
  'Interleave.cxx',
 | 
			
		||||
  'Error.cxx',
 | 
			
		||||
  include_directories: inc,
 | 
			
		||||
  dependencies: [
 | 
			
		||||
    libavutil_dep,
 | 
			
		||||
  ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
ffmpeg_util_dep = declare_dependency(
 | 
			
		||||
  link_with: ffmpeg_util,
 | 
			
		||||
  dependencies: [
 | 
			
		||||
    libavutil_dep,
 | 
			
		||||
  ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if not enable_ffmpeg
 | 
			
		||||
  ffmpeg_dep = dependency('', required: false)
 | 
			
		||||
  subdir_done()
 | 
			
		||||
@@ -30,17 +53,16 @@ ffmpeg = static_library(
 | 
			
		||||
  'ffmpeg',
 | 
			
		||||
  'Init.cxx',
 | 
			
		||||
  'Interleave.cxx',
 | 
			
		||||
  'LogError.cxx',
 | 
			
		||||
  'LogCallback.cxx',
 | 
			
		||||
  'Error.cxx',
 | 
			
		||||
  'Domain.cxx',
 | 
			
		||||
  ffmpeg_sources,
 | 
			
		||||
  include_directories: inc,
 | 
			
		||||
  dependencies: [
 | 
			
		||||
    ffmpeg_util_dep,
 | 
			
		||||
    libavformat_dep,
 | 
			
		||||
    libavcodec_dep,
 | 
			
		||||
    libavfilter_dep,
 | 
			
		||||
    libavutil_dep,
 | 
			
		||||
    log_dep,
 | 
			
		||||
  ],
 | 
			
		||||
)
 | 
			
		||||
@@ -48,9 +70,9 @@ ffmpeg = static_library(
 | 
			
		||||
ffmpeg_dep = declare_dependency(
 | 
			
		||||
  link_with: ffmpeg,
 | 
			
		||||
  dependencies: [
 | 
			
		||||
    ffmpeg_util_dep,
 | 
			
		||||
    libavformat_dep,
 | 
			
		||||
    libavcodec_dep,
 | 
			
		||||
    libavfilter_dep,
 | 
			
		||||
    libavutil_dep,
 | 
			
		||||
  ],
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -627,7 +627,7 @@ osx_render(void *vdata,
 | 
			
		||||
{
 | 
			
		||||
	OSXOutput *od = (OSXOutput *) vdata;
 | 
			
		||||
 | 
			
		||||
	int count = in_number_frames * od->asbd.mBytesPerFrame;
 | 
			
		||||
	std::size_t count = in_number_frames * od->asbd.mBytesPerFrame;
 | 
			
		||||
	buffer_list->mBuffers[0].mDataByteSize =
 | 
			
		||||
		od->ring_buffer->pop((uint8_t *)buffer_list->mBuffers[0].mData,
 | 
			
		||||
				     count);
 | 
			
		||||
 
 | 
			
		||||
@@ -523,7 +523,13 @@ PipeWireOutput::Open(AudioFormat &audio_format)
 | 
			
		||||
		pw_properties_setf(props, PW_KEY_REMOTE_NAME, "%s", remote);
 | 
			
		||||
 | 
			
		||||
	if (target != nullptr && target_id == PW_ID_ANY)
 | 
			
		||||
		pw_properties_setf(props, PW_KEY_NODE_TARGET, "%s", target);
 | 
			
		||||
		pw_properties_setf(props,
 | 
			
		||||
#if PW_CHECK_VERSION(0, 3, 64)
 | 
			
		||||
				   PW_KEY_TARGET_OBJECT,
 | 
			
		||||
#else
 | 
			
		||||
				   PW_KEY_NODE_TARGET,
 | 
			
		||||
#endif
 | 
			
		||||
				   "%s", target);
 | 
			
		||||
 | 
			
		||||
#ifdef PW_KEY_NODE_RATE
 | 
			
		||||
	/* ask PipeWire to change the graph sample rate to ours
 | 
			
		||||
@@ -967,6 +973,8 @@ PipeWireOutput::SendTag(const Tag &tag)
 | 
			
		||||
 | 
			
		||||
	struct spa_dict dict = SPA_DICT_INIT(items, n_items);
 | 
			
		||||
 | 
			
		||||
	const PipeWire::ThreadLoopLock lock(thread_loop);
 | 
			
		||||
 | 
			
		||||
	auto rc = pw_stream_update_properties(stream, &dict);
 | 
			
		||||
	if (rc < 0)
 | 
			
		||||
		LogWarning(pipewire_output_domain, "Error updating properties");
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@
 | 
			
		||||
#include "storage/StorageInterface.hxx"
 | 
			
		||||
#include "storage/FileInfo.hxx"
 | 
			
		||||
#include "storage/MemoryDirectoryReader.hxx"
 | 
			
		||||
#include "lib/curl/Error.hxx"
 | 
			
		||||
#include "lib/curl/Init.hxx"
 | 
			
		||||
#include "lib/curl/Global.hxx"
 | 
			
		||||
#include "lib/curl/Slist.hxx"
 | 
			
		||||
@@ -300,8 +301,9 @@ private:
 | 
			
		||||
	/* virtual methods from CurlResponseHandler */
 | 
			
		||||
	void OnHeaders(unsigned status, Curl::Headers &&headers) final {
 | 
			
		||||
		if (status != 207)
 | 
			
		||||
			throw FormatRuntimeError("Status %d from WebDAV server; expected \"207 Multi-Status\"",
 | 
			
		||||
						 status);
 | 
			
		||||
			throw HttpStatusError(status,
 | 
			
		||||
					      StringFormat<80>("Status %u from WebDAV server; expected \"207 Multi-Status\"",
 | 
			
		||||
							       status).c_str());
 | 
			
		||||
 | 
			
		||||
		if (!IsXmlContentType(headers))
 | 
			
		||||
			throw std::runtime_error("Unexpected Content-Type from WebDAV server");
 | 
			
		||||
 
 | 
			
		||||
@@ -263,8 +263,14 @@ TagBuilder::RemoveAll() noexcept
 | 
			
		||||
void
 | 
			
		||||
TagBuilder::RemoveType(TagType type) noexcept
 | 
			
		||||
{
 | 
			
		||||
	if (items.empty())
 | 
			
		||||
		/* don't acquire the tag_pool_lock if we're not going
 | 
			
		||||
		   to call tag_pool_put_item() anyway */
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	const auto begin = items.begin(), end = items.end();
 | 
			
		||||
 | 
			
		||||
	const std::scoped_lock<Mutex> protect(tag_pool_lock);
 | 
			
		||||
	items.erase(std::remove_if(begin, end,
 | 
			
		||||
				   [type](TagItem *item) {
 | 
			
		||||
					   if (item->type != type)
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,10 @@
 | 
			
		||||
 | 
			
		||||
#include <csignal>
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
#include <sys/prctl.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static constexpr Domain signal_handlers_domain("signal_handlers");
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -60,7 +64,7 @@ handle_reload_event(void *ctx) noexcept
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
SignalHandlersInit(Instance &instance)
 | 
			
		||||
SignalHandlersInit(Instance &instance, bool daemon)
 | 
			
		||||
{
 | 
			
		||||
	auto &loop = instance.event_loop;
 | 
			
		||||
 | 
			
		||||
@@ -79,6 +83,14 @@ SignalHandlersInit(Instance &instance)
 | 
			
		||||
 | 
			
		||||
	SignalMonitorRegister(SIGHUP, {&instance, handle_reload_event});
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (!daemon) {
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
		/* if MPD was not daemonized, shut it down when the
 | 
			
		||||
		   parent process dies */
 | 
			
		||||
		prctl(PR_SET_PDEATHSIG, SIGTERM);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
@@ -23,15 +23,15 @@
 | 
			
		||||
struct Instance;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
SignalHandlersInit(Instance &instance);
 | 
			
		||||
SignalHandlersInit(Instance &instance, bool daemon);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
SignalHandlersFinish() noexcept;
 | 
			
		||||
 | 
			
		||||
class ScopeSignalHandlersInit {
 | 
			
		||||
public:
 | 
			
		||||
	ScopeSignalHandlersInit(Instance &instance) {
 | 
			
		||||
		SignalHandlersInit(instance);
 | 
			
		||||
	ScopeSignalHandlersInit(Instance &instance, bool daemon) {
 | 
			
		||||
		SignalHandlersInit(instance, daemon);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	~ScopeSignalHandlersInit() noexcept {
 | 
			
		||||
 
 | 
			
		||||
@@ -40,14 +40,17 @@ class ScopeExitGuard : F {
 | 
			
		||||
	bool enabled = true;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	explicit ScopeExitGuard(F &&f):F(std::forward<F>(f)) {}
 | 
			
		||||
	explicit ScopeExitGuard(F &&f) noexcept:F(std::forward<F>(f)) {}
 | 
			
		||||
 | 
			
		||||
	ScopeExitGuard(ScopeExitGuard &&src)
 | 
			
		||||
		:F(std::move(src)), enabled(src.enabled) {
 | 
			
		||||
		src.enabled = false;
 | 
			
		||||
	}
 | 
			
		||||
	ScopeExitGuard(ScopeExitGuard &&src) noexcept
 | 
			
		||||
		:F(std::move(src)),
 | 
			
		||||
		 enabled(std::exchange(src.enabled, false)) {}
 | 
			
		||||
 | 
			
		||||
	~ScopeExitGuard() {
 | 
			
		||||
	/* destructors are "noexcept" by default; this explicit
 | 
			
		||||
	   "noexcept" declaration allows the destructor to throw if
 | 
			
		||||
	   the function can throw; without this, a throwing function
 | 
			
		||||
	   would std::terminate() */
 | 
			
		||||
	~ScopeExitGuard() noexcept(noexcept(std::declval<F>()())) {
 | 
			
		||||
		if (enabled)
 | 
			
		||||
			F::operator()();
 | 
			
		||||
	}
 | 
			
		||||
@@ -64,7 +67,7 @@ struct ScopeExitTag {
 | 
			
		||||
	   parantheses at the end of the expression AtScopeExit()
 | 
			
		||||
	   call */
 | 
			
		||||
	template<typename F>
 | 
			
		||||
	ScopeExitGuard<F> operator+(F &&f) {
 | 
			
		||||
	ScopeExitGuard<F> operator+(F &&f) noexcept {
 | 
			
		||||
		return ScopeExitGuard<F>(std::forward<F>(f));
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -3,10 +3,11 @@ directory = expat-2.5.0
 | 
			
		||||
source_url = https://github.com/libexpat/libexpat/releases/download/R_2_5_0/expat-2.5.0.tar.xz
 | 
			
		||||
source_filename = expat-2.5.0.tar.bz2
 | 
			
		||||
source_hash = ef2420f0232c087801abf705e89ae65f6257df6b7931d37846a193ef2e8cdcbe
 | 
			
		||||
patch_filename = expat_2.5.0-1_patch.zip
 | 
			
		||||
patch_url = https://wrapdb.mesonbuild.com/v2/expat_2.5.0-1/get_patch
 | 
			
		||||
patch_hash = 0d0d6e07ed21cf4892126a8270f5fd182012ab34b3ebe24932a2bef5ca608a61
 | 
			
		||||
wrapdb_version = 2.5.0-1
 | 
			
		||||
patch_filename = expat_2.5.0-2_patch.zip
 | 
			
		||||
patch_url = https://wrapdb.mesonbuild.com/v2/expat_2.5.0-2/get_patch
 | 
			
		||||
patch_hash = f6cc5ff0d909a2f51a907cc6ca655fb18517a0f58bbe67e4a9c621f1549560c9
 | 
			
		||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/expat_2.5.0-2/expat-2.5.0.tar.bz2
 | 
			
		||||
wrapdb_version = 2.5.0-2
 | 
			
		||||
 | 
			
		||||
[provide]
 | 
			
		||||
expat = expat_dep
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,13 @@
 | 
			
		||||
[wrap-file]
 | 
			
		||||
directory = sqlite-amalgamation-3390300
 | 
			
		||||
source_url = https://sqlite.org/2022/sqlite-amalgamation-3390300.zip
 | 
			
		||||
source_filename = sqlite-amalgamation-3390300.zip
 | 
			
		||||
source_hash = a89db3030d229d860ae56a8bac50ac9761434047ae886e47e7c8f9f428fa98ad
 | 
			
		||||
patch_filename = sqlite3_3.39.3-1_patch.zip
 | 
			
		||||
patch_url = https://wrapdb.mesonbuild.com/v2/sqlite3_3.39.3-1/get_patch
 | 
			
		||||
patch_hash = f5c41ff7b3da1108ed221b9a820b41188550cafb8a6c3d247bb40bd598775050
 | 
			
		||||
wrapdb_version = 3.39.3-1
 | 
			
		||||
directory = sqlite-amalgamation-3410200
 | 
			
		||||
source_url = https://www.sqlite.org/2023/sqlite-amalgamation-3410200.zip
 | 
			
		||||
source_filename = sqlite-amalgamation-3410200.zip
 | 
			
		||||
source_hash = 01df06a84803c1ab4d62c64e995b151b2dbcf5dbc93bbc5eee213cb18225d987
 | 
			
		||||
patch_filename = sqlite3_3.41.2-2_patch.zip
 | 
			
		||||
patch_url = https://wrapdb.mesonbuild.com/v2/sqlite3_3.41.2-2/get_patch
 | 
			
		||||
patch_hash = 246681dfb731a14bfa61bcde651d5581a7e1c7d14851bfb57a941fac540a6810
 | 
			
		||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/sqlite3_3.41.2-2/sqlite-amalgamation-3410200.zip
 | 
			
		||||
wrapdb_version = 3.41.2-2
 | 
			
		||||
 | 
			
		||||
[provide]
 | 
			
		||||
sqlite3 = sqlite3_dep
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,10 @@
 | 
			
		||||
systemd_system_unit_dir = get_option('systemd_system_unit_dir')
 | 
			
		||||
if systemd_system_unit_dir == ''
 | 
			
		||||
  systemd = dependency('systemd', required: false)
 | 
			
		||||
  if systemd.found()
 | 
			
		||||
      systemd_system_unit_dir = systemd.get_variable(pkgconfig: 'systemdsystemunitdir')
 | 
			
		||||
  endif
 | 
			
		||||
endif
 | 
			
		||||
if systemd_system_unit_dir == ''
 | 
			
		||||
  systemd_system_unit_dir = join_paths(get_option('prefix'), 'lib', 'systemd', 'system')
 | 
			
		||||
endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,10 @@
 | 
			
		||||
systemd_user_unit_dir = get_option('systemd_user_unit_dir')
 | 
			
		||||
if systemd_user_unit_dir == ''
 | 
			
		||||
  systemd = dependency('systemd', required: false)
 | 
			
		||||
  if systemd.found()
 | 
			
		||||
    systemd_user_unit_dir = systemd.get_variable(pkgconfig: 'systemduserunitdir')
 | 
			
		||||
  endif
 | 
			
		||||
endif
 | 
			
		||||
if systemd_user_unit_dir == ''
 | 
			
		||||
  systemd_user_unit_dir = join_paths(get_option('prefix'), 'lib', 'systemd', 'user')
 | 
			
		||||
endif
 | 
			
		||||
 
 | 
			
		||||
@@ -48,6 +48,7 @@ class CrossGccToolchain:
 | 
			
		||||
        self.cc = os.path.join(toolchain_bin, arch + '-gcc')
 | 
			
		||||
        self.cxx = os.path.join(toolchain_bin, arch + '-g++')
 | 
			
		||||
        self.ar = os.path.join(toolchain_bin, arch + '-ar')
 | 
			
		||||
        self.arflags = 'rcs'
 | 
			
		||||
        self.ranlib = os.path.join(toolchain_bin, arch + '-ranlib')
 | 
			
		||||
        self.nm = os.path.join(toolchain_bin, arch + '-nm')
 | 
			
		||||
        self.strip = os.path.join(toolchain_bin, arch + '-strip')
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user