diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index db5a16871..b3167cccc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,21 +2,36 @@ include: - project: 'freedesktop/ci-templates' ref: 'master' file: '/templates/fedora.yml' + - project: 'freedesktop/ci-templates' + ref: 'master' + file: '/templates/ubuntu.yml' + ### + # IMPORTANT + # These are the version tags for the docker images the CI runs against. + # If you are hacking on them or need a them to rebuild, its enough + # to change any part of the string of the image you want. + ### + - local: '.gitlab-image-tags.yml' stages: + - 'trigger' - 'build docker' - 'check sources' + - 'tests' - 'build' # Use the resulting binaries - 'integrate' variables: - # CI_GSTREAMER_* variables are overridden by gstreamer's CI when it triggers cerbero CI. - CI_GSTREAMER_REF_NAME: '1.24' - CI_GSTREAMER_URL: 'https://gitlab.freedesktop.org/gstreamer/gstreamer.git' + # CI_GSTREAMER_* variables are set by gstreamer's CI when it triggers cerbero CI. CI_GSTREAMER_TRIGGERED: 'false' - GST_UPSTREAM_BRANCH: '1.24' - WINDOWS_IMAGE: 'registry.freedesktop.org/gstreamer/gstreamer/amd64/windows:2024-03-05.0-1.24' + GST_UPSTREAM_BRANCH: '1.26' + # Our gitlab instance and runner are using a proxy and have + # trouble with the normal fetch. git itself handles the proxy + # more reliably. + # + # https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli + CARGO_NET_GIT_FETCH_WITH_CLI: true DEFAULT_CERBERO_ARGS: > --variants werror --clocktime @@ -55,28 +70,16 @@ default: .fedora image: variables: - ### - # IMPORTANT - # These are the version tags for the docker images the CI runs against. - # If you are hacking on them or need a them to rebuild, its enough - # to change any part of the string of the image you want. - ### - FDO_DISTRIBUTION_TAG: '2023-06-08.0' - FDO_DISTRIBUTION_VERSION: '37' - FDO_DISTRIBUTION_PACKAGES: "sudo git-core lbzip2 rsync wine which python3-distro python3-distro-info" + FDO_DISTRIBUTION_TAG: "$FEDORA_TAG-$GST_UPSTREAM_BRANCH" + FDO_DISTRIBUTION_VERSION: '40' + FDO_DISTRIBUTION_PACKAGES: "sudo git-core lbzip2 rsync wine which xorg-x11-server-Xvfb python3-distro python3-distro-info python3-setuptools" FDO_DISTRIBUTION_EXEC: ci/docker_setup.sh FDO_UPSTREAM_REPO: gstreamer/cerbero .checks fedora image: variables: - ### - # IMPORTANT - # These are the version tags for the docker images the CI runs against. - # If you are hacking on them or need a them to rebuild, its enough - # to change any part of the string of the image you want. - ### - FDO_DISTRIBUTION_TAG: '2023-01-12.0' - FDO_DISTRIBUTION_VERSION: '37' + FDO_DISTRIBUTION_TAG: "$CHECKS_FEDORA_TAG-$GST_UPSTREAM_BRANCH" + FDO_DISTRIBUTION_VERSION: '40' FDO_DISTRIBUTION_PACKAGES: "git-core python3-pip" FDO_DISTRIBUTION_EXEC: ci/checks_setup.sh FDO_UPSTREAM_REPO: gstreamer/cerbero @@ -84,22 +87,68 @@ default: .android fedora image: variables: - ### - # IMPORTANT - # These are the version tags for the docker images the CI runs against. - # If you are hacking on them or need a them to rebuild, its enough - # to change any part of the string of the image you want. - ### - FDO_DISTRIBUTION_TAG: '2023-05-31.0' - FDO_DISTRIBUTION_VERSION: '37' - FDO_DISTRIBUTION_PACKAGES: "file git-core java-11-openjdk-devel lbzip2 python3-distro python3-distro-info make pkg-config unzip which xz" + FDO_DISTRIBUTION_TAG: "$ANDROID_FEDORA_TAG-$GST_UPSTREAM_BRANCH" + FDO_DISTRIBUTION_VERSION: '40' + FDO_DISTRIBUTION_PACKAGES: "file git-core java-11-openjdk-devel lbzip2 python3-distro python3-distro-info make pkg-config unzip which xz python3-setuptools pax-utils binutils" FDO_DISTRIBUTION_EXEC: ci/docker_android_setup.sh $ANDROID_HOME $ANDROID_NDK_HOME $GST_UPSTREAM_BRANCH FDO_UPSTREAM_REPO: gstreamer/cerbero FDO_REPO_SUFFIX: android ANDROID_HOME: "/android/sdk" ANDROID_NDK_HOME: "/android/ndk" -.manual trigger: +.ubuntu image: + variables: + FDO_DISTRIBUTION_TAG: "$UBUNTU_TAG-$GST_UPSTREAM_BRANCH" + FDO_DISTRIBUTION_VERSION: "22.04" + FDO_DISTRIBUTION_PACKAGES: >- + bash + ca-certificates + curl + git + lbzip2 + python3-distro + python3-distro-info + python3-venv + python3-setuptools + rsync + ssh-client + sudo + FDO_DISTRIBUTION_EXEC: "ci/docker_setup.sh" + FDO_UPSTREAM_REPO: "gstreamer/cerbero" + +.tests ubuntu image: + variables: + FDO_DISTRIBUTION_TAG: "$TESTS_UBUNTU_TAG-$GST_UPSTREAM_BRANCH" + FDO_DISTRIBUTION_VERSION: "22.04" + FDO_DISTRIBUTION_PACKAGES: >- + bash + ca-certificates + curl + file + git + lbzip2 + pkg-config + python3-distro + python3-distro-info + python3-venv + python3-setuptools + python3-minimal + python3-xmlrunner + rsync + ssh-client + sudo + xz-utils + FDO_UPSTREAM_REPO: gstreamer/cerbero + FDO_REPO_SUFFIX: tests + +manual trigger: + image: "debian:stable-slim" + stage: "trigger" + variables: + GIT_STRATEGY: "none" + tags: [ "placeholder-job" ] + script: + - echo "Trigger job done, now running the pipeline." rules: # If this pipeline is triggered from gstreamer, trigger the pipeline automatically - if: '$CI_PIPELINE_SOURCE == "pipeline"' @@ -118,46 +167,66 @@ default: fedora image: stage: "build docker" + needs: [ "manual trigger" ] extends: - - .manual trigger - .fedora image - .fdo.container-build@fedora variables: GIT_STRATEGY: none - tags: [ 'placeholder-job' ] + tags: [ 'kvm' ] checks fedora image: stage: "build docker" + needs: [] extends: - .checks fedora image - .fdo.container-build@fedora variables: GIT_STRATEGY: none - tags: [ 'placeholder-job' ] + tags: [ 'kvm' ] + +tests ubuntu image: + stage: "build docker" + extends: + - .tests ubuntu image + - .fdo.container-build@ubuntu + variables: + GIT_STRATEGY: none + tags: [ 'kvm' ] android fedora image: stage: "build docker" + needs: [ "manual trigger" ] extends: - - .manual trigger - .android fedora image - .fdo.container-build@fedora variables: GIT_STRATEGY: none - tags: [ 'placeholder-job' ] + tags: [ 'kvm' ] + +ubuntu image: + stage: "build docker" + needs: [ "manual trigger" ] + extends: + - .ubuntu image + - .fdo.container-build@ubuntu + variables: + GIT_STRATEGY: none + tags: [ 'kvm' ] # Rules for when to use a specific job # Used when a GStreamer MR is used using the triggered pipeline .cerbero mr rules: rules: - - if: '$CI_GSTREAMER_TRIGGERED == "true" && $CI_PROJECT_NAMESPACE == "gstreamer"' + - if: '$CI_GSTREAMER_TRIGGERED == "true"' # Don't interrupt gstreamer MR CI when cerbero main gets pushes interruptible: false # Used when any other usage is encountered, cerbero MR, branch push, etc .cerbero not-mr rules: rules: - - if: '$CI_GSTREAMER_TRIGGERED != "true" || $CI_PROJECT_NAMESPACE != "gstreamer"' + - if: '$CI_GSTREAMER_TRIGGERED != "true"' # Template for all Cerbero GStreamer builds # @@ -170,7 +239,7 @@ android fedora image: # Ensure that the runners it will be executed on # will have plenty of space for the cache tags: ['gstreamer'] - timeout: '3h' + timeout: '1 hour 30 minutes' variables: CCACHE_COMPILERCHECK: "content" CCACHE_COMPRESS: "true" @@ -187,8 +256,6 @@ android fedora image: CERBERO_RUN_SUFFIX: "" # '.exe' on cross-winXX CERBERO_BOOTSTRAP_SYSTEM: "no" HAVE_CCACHE: "yes" - # used by macos packages as we only ever install to a fixed directory - CERBERO_OVERRIDDEN_DIST_DIR: "" # location where the cerbero git repo is stored on the image CERBERO_HOST_DIR: "/" before_script: @@ -207,9 +274,9 @@ android fedora image: when: 'always' paths: - "*/logs" - - "*/sources/*/*/b/meson-logs/meson-log.txt" - - "*/sources/*/*/b/CMakeFiles/CMakeError.log" - - "*/sources/*/*/b/CMakeFiles/CMakeLog.log" + - "*/sources/**/b/meson-logs/meson-log.txt" + - "*/sources/**/b/CMakeFiles/CMakeError.log" + - "*/sources/**/b/CMakeFiles/CMakeLog.log" - "*.tar.*" exclude: - .git @@ -222,6 +289,13 @@ android fedora image: needs: - "fedora image" +.cerbero ubuntu base: + extends: + - .ubuntu image + - .fdo.distribution-image@ubuntu + needs: + - "ubuntu image" + # Template for Cerbero GStreamer Deps # # This template is used by cerbero/ project to pre-built the GStreamer @@ -267,6 +341,26 @@ pre-commit checks: PRE_COMMIT_HOME: '/cache/${CI_PROJECT_NAMESPACE}/pre-commit' tags: [ 'placeholder-job' ] +tests: + extends: + - .tests ubuntu image + - .fdo.suffixed-image@ubuntu + needs: + - "tests ubuntu image" + stage: 'tests' + script: + python3 -m xmlrunner --output-file tests.xml discover -s test + variables: + CERBERO_UNINSTALLED: 1 + PYTHONPATH: ':./test:./cerbero' + tags: [ 'placeholder-job' ] + artifacts: + when: always + paths: + - tests.xml + reports: + junit: tests.xml + # # Cerbero Linux X86_64 build # @@ -285,6 +379,21 @@ build cerbero fedora x86_64: variables: CONFIG: "linux.config" +cerbero deps ubuntu x86_64: + extends: + - '.cerbero ubuntu base' + - '.cerbero deps' + variables: + CONFIG: "linux.config" + ARCH: "linux_x86_64" + +build cerbero ubuntu x86_64: + extends: + - '.cerbero ubuntu base' + - '.cerbero mr' + variables: + CONFIG: "linux.config" + # # Cerbero Android Universal build # @@ -298,9 +407,9 @@ build cerbero fedora x86_64: when: 'always' paths: - "*/logs" - - "*/sources/*/*/*/b/meson-logs/meson-log.txt" - - "*/sources/*/*/*/b/CMakeFiles/CMakeError.log" - - "*/sources/*/*/*/b/CMakeFiles/CMakeLog.log" + - "*/sources/**/b/meson-logs/meson-log.txt" + - "*/sources/**/b/CMakeFiles/CMakeError.log" + - "*/sources/**/b/CMakeFiles/CMakeLog.log" - "*[0-9].tar.*" exclude: - .git @@ -335,9 +444,9 @@ build cerbero cross-android universal: when: 'always' paths: - "*/logs" - - "*/sources/*/*/b/meson-logs/meson-log.txt" - - "*/sources/*/*/b/CMakeFiles/CMakeError.log" - - "*/sources/*/*/b/CMakeFiles/CMakeLog.log" + - "*/sources/**/b/meson-logs/meson-log.txt" + - "*/sources/**/b/CMakeFiles/CMakeError.log" + - "*/sources/**/b/CMakeFiles/CMakeLog.log" - "*.msi" exclude: - .git @@ -387,30 +496,7 @@ build cerbero cross win64: EXAMPLES_HOME: ${CI_PROJECT_DIR}/gstreamer/subprojects GSTREAMER_ROOT_ANDROID: ${CI_PROJECT_DIR}/cerbero-android-universal script: - # Clone gstreamer repository to get gst-examples and gst-docs - - rm -rf gstreamer - - git clone $CI_GSTREAMER_URL -b $CI_GSTREAMER_REF_NAME --depth 1 gstreamer/ - - mkdir -p ${OUTPUT_DIR} - - # extract our binaries - - rm -f gstreamer-1.0-android-universal-*-runtime.tar.* - - mkdir ${GSTREAMER_ROOT_ANDROID} - - time tar -C ${GSTREAMER_ROOT_ANDROID} -xf gstreamer-1.0-android-universal-*.tar.* - - # gst-examples - player - - chmod +x ${EXAMPLES_HOME}/gst-examples/playback/player/android/gradlew - - ./ci/run_retry.sh ${EXAMPLES_HOME}/gst-examples/playback/player/android/gradlew --no-daemon --project-dir ${EXAMPLES_HOME}/gst-examples/playback/player/android assembleDebug - - cp ${EXAMPLES_HOME}/gst-examples/playback/player/android/app/build/outputs/apk/debug/*.apk ${OUTPUT_DIR} - - # gst-examples - vulkan - - chmod +x ${EXAMPLES_HOME}/gst-examples/vulkan/android/gradlew - - ./ci/run_retry.sh ${EXAMPLES_HOME}/gst-examples/vulkan/android/gradlew --no-daemon --project-dir ${EXAMPLES_HOME}/gst-examples/vulkan/android assembleDebug - - cp ${EXAMPLES_HOME}/gst-examples/vulkan/android/build/outputs/apk/debug/*.apk ${OUTPUT_DIR} - - # gst-docs android tutorials - - chmod +x ${EXAMPLES_HOME}/gst-docs/examples/tutorials/android/gradlew - - ./ci/run_retry.sh ${EXAMPLES_HOME}/gst-docs/examples/tutorials/android/gradlew --no-daemon --project-dir ${EXAMPLES_HOME}/gst-docs/examples/tutorials/android assembleDebug - - cp ${EXAMPLES_HOME}/gst-docs/examples/tutorials/android/android-tutorial-*/build/outputs/apk/debug/*.apk ${OUTPUT_DIR} + - ci/examples_setup.sh build_android_examples after_script: - rm -rf ${GSTREAMER_ROOT_ANDROID} gstreamer artifacts: @@ -447,23 +533,26 @@ cerbero cross-android universal examples: HAVE_CCACHE: "" CERBERO_HOST_DIR: "/Users/gst-ci/cerbero/" cache: [] + needs: [ "manual trigger" ] artifacts: name: "${CI_JOB_NAME}_${CI_COMMIT_SHA}" expire_in: '5 days' when: 'always' paths: - "*/logs" - - "*/sources/*/*/*/b/meson-logs/meson-log.txt" - - "*/sources/*/*/*/b/CMakeFiles/CMakeError.log" - - "*/sources/*/*/*/b/CMakeFiles/CMakeLog.log" - - "gstreamer-1.0-1.*.pkg" - - "gstreamer-1.0-devel-1.*.pkg" + - "*/sources/**/b/meson-logs/meson-log.txt" + - "*/sources/**/b/CMakeFiles/CMakeError.log" + - "*/sources/**/b/CMakeFiles/CMakeLog.log" + # Skip uploading these (rather large) build artefacts until fdo + # infrastructure gets fixed or we find another workaround + # - "gstreamer-1.0-1.*.pkg" + # - "gstreamer-1.0-devel-1.*.pkg" exclude: - .git - .git/**/* .cerbero macos arm64 image: - image: "registry.freedesktop.org/gstreamer/cerbero/macos-arm64/14-sonoma:2023-10-25.2" + image: "registry.freedesktop.org/gstreamer/cerbero/macos-arm64/15-sequoia:2024-10-28.2" tags: - gst-mac-arm @@ -479,22 +568,6 @@ build cerbero cross-macos universal arm64-host: - '.cerbero cross-macos universal' - '.cerbero macos arm64 image' -cerbero deps cross-macos universal x86_64-host: - extends: - - '.cerbero deps' - - '.cerbero cross-macos universal' - tags: - - gst-macos-13 - when: 'manual' - -build cerbero cross-macos universal x86_64-host: - extends: - - '.cerbero mr' - - '.cerbero cross-macos universal' - tags: - - gst-macos-13 - when: 'manual' - # # Cerbero iOS build # @@ -507,15 +580,16 @@ build cerbero cross-macos universal x86_64-host: HAVE_CCACHE: "" CERBERO_HOST_DIR: "/Users/gst-ci/cerbero/" cache: [] + needs: [ "manual trigger" ] artifacts: name: "${CI_JOB_NAME}_${CI_COMMIT_SHA}" expire_in: '5 days' when: 'always' paths: - "*/logs" - - "*/sources/*/*/*/b/meson-logs/meson-log.txt" - - "*/sources/*/*/*/b/CMakeFiles/CMakeError.log" - - "*/sources/*/*/*/b/CMakeFiles/CMakeLog.log" + - "*/sources/**/b/meson-logs/meson-log.txt" + - "*/sources/**/b/CMakeFiles/CMakeError.log" + - "*/sources/**/b/CMakeFiles/CMakeLog.log" - "gstreamer-1.0-*-ios-universal.pkg" exclude: - .git @@ -533,22 +607,6 @@ build cerbero cross-ios universal arm64-host: - '.cerbero cross-ios universal' - '.cerbero macos arm64 image' -cerbero deps cross-ios universal x86_64-host: - extends: - - '.cerbero deps' - - '.cerbero cross-ios universal' - tags: - - gst-ios-16 - when: 'manual' - -build cerbero cross-ios universal x86_64-host: - extends: - - '.cerbero mr' - - '.cerbero cross-ios universal' - tags: - - gst-ios-16 - when: 'manual' - # # Build an iOS App using the iOS binaries # @@ -564,48 +622,11 @@ build cerbero cross-ios universal x86_64-host: CODE_SIGNING_ALLOWED="NO" CODE_SIGN_ENTITLEMENTS="" script: - # install the binaries - - installer -pkg gstreamer-1.0-devel-*-ios-universal.pkg -target CurrentUserHomeDirectory -verbose - - # Clone gstreamer repository to get gst-examples and gst-docs - - git clone $CI_GSTREAMER_URL -b $CI_GSTREAMER_REF_NAME --depth 1 gstreamer/ - - # dump some useful information - - xcodebuild -version - - xcodebuild -showsdks - - echo ${XCODE_BUILD_ARGS} > xcode_buildargs - - # gst-docs ios tutorials - - ./ci/run_retry.sh xcodebuild -showBuildSettings -alltargets -project ${EXAMPLES_HOME}/gst-docs/examples/tutorials/xcode\ iOS/GStreamer\ iOS\ Tutorials.xcodeproj $(cat xcode_buildargs) - - ./ci/run_retry.sh xcodebuild -alltargets -destination generic/platform=iOS -project ${EXAMPLES_HOME}/gst-docs/examples/tutorials/xcode\ iOS/GStreamer\ iOS\ Tutorials.xcodeproj $(cat xcode_buildargs) - - # gst-examples - - ./ci/run_retry.sh xcodebuild -showBuildSettings -alltargets -project ${EXAMPLES_HOME}/gst-examples/playback/player/ios/GstPlay.xcodeproj $(cat xcode_buildargs) - - ./ci/run_retry.sh xcodebuild -alltargets -destination generic/platform=iOS -project ${EXAMPLES_HOME}/gst-examples/playback/player/ios/GstPlay.xcodeproj $(cat xcode_buildargs) + - ci/examples_setup.sh build_ios_examples after_script: - rm -rf gstreamer cache: [] -cross-ios universal examples x86_64-host: - extends: - - '.cross-ios universal examples' - - '.cerbero mr rules' - needs: - - "build cerbero cross-ios universal x86_64-host" - tags: - - gst-ios-16 - when: 'manual' - -cerbero cross-ios universal examples x86_64-host: - extends: - - '.cross-ios universal examples' - - '.cerbero not-mr rules' - needs: - - "cerbero deps cross-ios universal x86_64-host" - tags: - - gst-ios-16 - when: 'manual' - cross-ios universal examples arm64-host: extends: - '.cross-ios universal examples' @@ -627,6 +648,7 @@ cerbero cross-ios universal examples arm64-host: # .cerbero windows native: image: $WINDOWS_IMAGE + needs: [ "manual trigger" ] tags: - 'docker' - 'windows' @@ -639,10 +661,26 @@ cerbero cross-ios universal examples arm64-host: CERBERO_RUN_SUFFIX: ".exe" CERBERO_BOOTSTRAP_SYSTEM: "no" HAVE_CCACHE: "" + CERBERO_PACKAGE_ARGS: "-t" before_script: # Test that the powershell script works - ./cerbero-uninstalled --help - C:\msys64\msys2_shell.cmd -ucrt64 -defterm -no-start -here -use-full-path -lc "./ci/cerbero_setup.sh cerbero_before_script" + artifacts: + name: "${CI_JOB_NAME}_${CI_COMMIT_SHA}" + expire_in: '5 days' + when: 'always' + paths: + - "*/logs" + - "*/sources/**/b/meson-logs/meson-log.txt" + - "*/sources/**/b/CMakeFiles/CMakeError.log" + - "*/sources/**/b/CMakeFiles/CMakeLog.log" + # Skip uploading these (rather large) build artefacts until fdo + # infrastructure gets fixed or we find another workaround + # - "*.msi" + exclude: + - .git + - .git/**/* cerbero deps msvc x86_64: extends: ['.cerbero deps', '.cerbero windows native'] @@ -650,14 +688,15 @@ cerbero deps msvc x86_64: ARCH: 'msvc_x86_64' script: - C:\msys64\msys2_shell.cmd -ucrt64 -defterm -no-start -here -use-full-path -lc "./ci/cerbero_setup.sh cerbero_deps_script" - rules: - # This is an extended rule of .cerbero not-mr rules - - if: ($CI_GSTREAMER_TRIGGERED != "true" || $CI_PROJECT_NAMESPACE != "gstreamer") && $CI_PIPELINE_SOURCE != "schedule" - # Don't run automatically for scheduled pipeline - - if: ($CI_GSTREAMER_TRIGGERED != "true" || $CI_PROJECT_NAMESPACE != "gstreamer") && $CI_PIPELINE_SOURCE == "schedule" - when: 'manual' - # workaround for gitlab bug where it otherwise blocks the pipeline for manual jobs from rules - allow_failure: true + +cerbero deps msvc x86: + extends: ['.cerbero deps', '.cerbero windows native'] + variables: + ARCH: 'msvc_x86' + CONFIG: 'win32.cbc' + script: + - C:\msys64\msys2_shell.cmd -ucrt64 -defterm -no-start -here -use-full-path -lc "./ci/cerbero_setup.sh cerbero_deps_script" + when: 'manual' cerbero deps mingw x86_64: extends: ['.cerbero deps', '.cerbero windows native'] @@ -668,45 +707,31 @@ cerbero deps mingw x86_64: - C:\msys64\msys2_shell.cmd -ucrt64 -defterm -no-start -here -use-full-path -lc "./ci/cerbero_setup.sh cerbero_deps_script" when: 'manual' -cerbero deps msvc x86_64 msi package: +cerbero deps mingw x86: extends: ['.cerbero deps', '.cerbero windows native'] variables: - CERBERO_PACKAGE_ARGS: "" + ARCH: 'mingw_x86' + CONFIG: 'win32.cbc' + CERBERO_ARGS: "${DEFAULT_CERBERO_ARGS} -v nowerror,mingw" script: - C:\msys64\msys2_shell.cmd -ucrt64 -defterm -no-start -here -use-full-path -lc "./ci/cerbero_setup.sh cerbero_deps_script" - artifacts: - name: "${CI_JOB_NAME}_${CI_COMMIT_SHA}" - expire_in: '5 days' - when: 'always' - paths: - - "*/logs" - - "*/sources/*/*/b/meson-logs/meson-log.txt" - - "*/sources/*/*/b/CMakeFiles/CMakeError.log" - - "*/sources/*/*/b/CMakeFiles/CMakeLog.log" - - "*.msi" - exclude: - - .git - - .git/**/* - rules: - # This is an extended rule of .cerbero not-mr rules - # Run automatically if it's a scheduled pipeline - - if: ($CI_GSTREAMER_TRIGGERED != "true" || $CI_PROJECT_NAMESPACE != "gstreamer") && $CI_PIPELINE_SOURCE == "schedule" - # Otherwise require manual trigger - - if: ($CI_GSTREAMER_TRIGGERED != "true" || $CI_PROJECT_NAMESPACE != "gstreamer") && $CI_PIPELINE_SOURCE != "schedule" - when: 'manual' - # workaround for gitlab bug where it otherwise blocks the pipeline for manual jobs from rules - allow_failure: true + when: 'manual' -cerbero deps msvc x86 msi package: - extends: ['cerbero deps msvc x86_64 msi package'] +build cerbero msvc x86_64: + extends: ['.cerbero mr', '.cerbero windows native'] variables: - ARCH: 'msvc_x86' - CONFIG: 'win32.cbc' + ARCH: 'msvc_x86_64' + script: + - C:\msys64\msys2_shell.cmd -ucrt64 -defterm -no-start -here -use-full-path -lc "./ci/cerbero_setup.sh cerbero_script" -build cerbero msvc x86_64: +build cerbero msvc x86: extends: ['.cerbero mr', '.cerbero windows native'] + variables: + ARCH: 'msvc_x86' + CONFIG: 'win32.cbc' script: - C:\msys64\msys2_shell.cmd -ucrt64 -defterm -no-start -here -use-full-path -lc "./ci/cerbero_setup.sh cerbero_script" + when: 'manual' build cerbero mingw x86_64: extends: ['.cerbero mr', '.cerbero windows native'] @@ -717,6 +742,16 @@ build cerbero mingw x86_64: - C:\msys64\msys2_shell.cmd -ucrt64 -defterm -no-start -here -use-full-path -lc "./ci/cerbero_setup.sh cerbero_script" when: 'manual' +build cerbero mingw x86: + extends: ['.cerbero mr', '.cerbero windows native'] + variables: + ARCH: 'mingw_x86' + CONFIG: 'win32.cbc' + CERBERO_ARGS: "${DEFAULT_CERBERO_ARGS} -v nowerror,mingw" + script: + - C:\msys64\msys2_shell.cmd -ucrt64 -defterm -no-start -here -use-full-path -lc "./ci/cerbero_setup.sh cerbero_script" + when: 'manual' + # FIXME: UWP build is disabled until build issues with latest GLib version are sorted out cerbero deps uwp universal: extends: ['cerbero deps msvc x86_64'] diff --git a/.gitlab-image-tags.yml b/.gitlab-image-tags.yml new file mode 100644 index 000000000..eb15680da --- /dev/null +++ b/.gitlab-image-tags.yml @@ -0,0 +1,18 @@ +variables: + ### + # IMPORTANT + # These are the version tags for the docker images the CI runs against. + # If you are hacking on them or need a them to rebuild, its enough + # to change any part of the string of the image you want. + ### + FEDORA_TAG: '2025-03-13.0' + + CHECKS_FEDORA_TAG: '2025-03-13.0' + + ANDROID_FEDORA_TAG: '2025-06-21.0-1.26' + + UBUNTU_TAG: '2025-03-13.0' + + TESTS_UBUNTU_TAG: '2025-03-13.0' + + WINDOWS_IMAGE: 'registry.freedesktop.org/gstreamer/gstreamer/amd64/windows:2025-03-12.0-1.26' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d997d4522..ac67cb981 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.1.8 + rev: v0.5.6 hooks: # Run the linter. - id: ruff diff --git a/Makefile b/Makefile index 60ea8fbe0..e2f51128f 100644 --- a/Makefile +++ b/Makefile @@ -20,13 +20,5 @@ check-format: ruff check . check: - PYTHONPATH=$(PYTHONPATH):./test:./cerbero; trial test + CERBERO_UNINSTALLED=1 PYTHONPATH=$(PYTHONPATH):./test:./cerbero python -m unittest discover -s test -f make check-format - -coverage: - rm -rf _trial_temp - PYTHONPATH=$(PYTHONPATH):./test:./cerbero; trial --coverage test - make show-coverage - -show-coverage: - python tools/show-coverage.py _trial_temp/coverage/cerbero.* diff --git a/README.md b/README.md index 26018a5cf..a858cb224 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,9 @@ On macOS you will need to have install the following software: Cerbero will build all other required packages during [bootstrap](#Bootstrap). +Note that introspection and python support will only be enabled when building +on ARM64 (Apple Silicon). + ### Windows Setup The initial setup on Windows is automated with the PowerShell script @@ -45,7 +48,7 @@ installs the necessary tools with [Chocolatey](https://chocolatey.org/): * MSYS2 * Git * Python 3 -* WiX +* WiX 5.0.1 or higher Start an admin PowerShell and run: diff --git a/cerbero-uninstalled b/cerbero-uninstalled index 35bb80760..ecc18604e 100755 --- a/cerbero-uninstalled +++ b/cerbero-uninstalled @@ -24,7 +24,8 @@ ARGS=$@ SCRIPTDIR="`dirname $0`" -if [ "$OSTYPE" = "msys" ]; then +# https://www.msys2.org/news/#2025-02-14-moving-msys2-closer-to-cygwin +if [ "$OSTYPE" = "msys" ] || [ "$OSTYPE" = "cygwin" ]; then if [ -f "/mingw/bin/mingw-get.exe" ]; then MSYS_VERSION=1 elif [ -f "/usr/bin/pacman" ]; then diff --git a/cerbero/bootstrap/__init__.py b/cerbero/bootstrap/__init__.py index 37e595617..c409f00c3 100644 --- a/cerbero/bootstrap/__init__.py +++ b/cerbero/bootstrap/__init__.py @@ -22,9 +22,10 @@ class BootstrapTarball(BaseTarball, Source): - def __init__(self, config, offline, url, checksum, download_dir, tarball_name=None): + def __init__(self, config, offline, name, url, checksum, download_dir, tarball_name=None): self.config = config self.offline = offline + self.name = name self.url = url self.download_dir = download_dir self.tarball_name = tarball_name @@ -47,9 +48,10 @@ class BootstrapperBase(object): # List of extract steps to be performed extract_steps = None - def __init__(self, config, offline): + def __init__(self, config, offline, name): self.config = config self.offline = offline + self.name = name self.fetch_urls = [] self.extract_steps = [] self.sources = {} @@ -58,9 +60,15 @@ async def start(self): raise NotImplementedError("'start' must be implemented by subclasses") async def fetch_urls_impl(self, urls): - for url, name, checksum in urls: + for url, tarball_name, checksum in urls: source = BootstrapTarball( - self.config, self.offline, url, checksum, self.config.local_sources, tarball_name=name + self.config, + self.offline, + self.name, + url, + checksum, + self.config.local_sources, + tarball_name=tarball_name, ) self.sources[url] = source await source.fetch() diff --git a/cerbero/bootstrap/android.py b/cerbero/bootstrap/android.py index bc5288ff3..492ccf2bb 100644 --- a/cerbero/bootstrap/android.py +++ b/cerbero/bootstrap/android.py @@ -35,7 +35,7 @@ class AndroidBootstrapper(BootstrapperBase): def __init__(self, config, offline, assume_yes): - super().__init__(config, offline) + super().__init__(config, offline, 'android') self.prefix = self.config.toolchain_prefix url = NDK_BASE_URL % (NDK_VERSION, self.config.platform) self.fetch_urls.append((url, None, NDK_CHECKSUMS[os.path.basename(url)])) diff --git a/cerbero/bootstrap/build_tools.py b/cerbero/bootstrap/build_tools.py index 481cf7be3..6ecbd8cc8 100644 --- a/cerbero/bootstrap/build_tools.py +++ b/cerbero/bootstrap/build_tools.py @@ -17,6 +17,7 @@ # Boston, MA 02111-1307, USA. import os +from pathlib import Path import venv import glob import shutil @@ -26,7 +27,7 @@ from cerbero.build.cookbook import CookBook from cerbero.commands.fetch import Fetch from cerbero.utils import shell -from cerbero.enums import Platform, Distro +from cerbero.enums import Platform, Distro, Architecture class BuildTools (BootstrapperBase, Fetch): @@ -39,7 +40,7 @@ class BuildTools (BootstrapperBase, Fetch): } def __init__(self, config, offline): - BootstrapperBase.__init__(self, config, offline) + BootstrapperBase.__init__(self, config, offline, None) if self.config.variants.rust: self.BUILD_TOOLS.append('cargo-c') @@ -116,14 +117,21 @@ def setup_venv(self): scriptsdir = os.path.join(self.config.build_tools_prefix, 'Scripts') bindir = os.path.join(self.config.build_tools_prefix, 'bin') os.makedirs(bindir, exist_ok=True) - for f in glob.glob('*', root_dir=scriptsdir): - tof = os.path.join(bindir, f) + for f in Path(scriptsdir).glob('*'): + tof = os.path.join(bindir, f.name) if os.path.isfile(tof): os.remove(tof) - shutil.move(os.path.join(scriptsdir, f), tof) + shutil.move(f, tof) os.rmdir(scriptsdir) python = os.path.join(self.config.build_tools_prefix, 'bin', 'python') - shell.new_call([python, '-m', 'pip', 'install', 'setuptools']) + shell.new_call([python, '-m', 'pip', 'install', '-U', 'setuptools', 'packaging']) + if self.config.platform == Platform.DARWIN and self.config.arch == Architecture.ARM64: + # Create an x86_64 python for introspection in universal builds + python_wrapper = os.path.join(self.config.build_tools_prefix, 'bin', 'python3-x86_64') + with open(python_wrapper, 'w') as f: + f.write('#!/bin/sh\n') + f.write('arch -x86_64 python3 "$@"\n') + os.chmod(python_wrapper, 0o755) async def start(self, jobs=0): self.setup_venv() diff --git a/cerbero/bootstrap/ios.py b/cerbero/bootstrap/ios.py index 0886b5c09..02b0d21db 100644 --- a/cerbero/bootstrap/ios.py +++ b/cerbero/bootstrap/ios.py @@ -23,18 +23,22 @@ # the Free Software Foundation; either version 3, or (at your option) # any later version. +import os +from cerbero.utils import shell +from cerbero.utils import messages as m from cerbero.bootstrap import BootstrapperBase from cerbero.bootstrap.bootstrapper import register_toolchain_bootstrapper -from cerbero.config import Distro +from cerbero.enums import Distro, Architecture class IOSBootstrapper(BootstrapperBase): def __init__(self, config, offline, assume_yes): - super().__init__(config, offline) + super().__init__(config, offline, 'ios') async def start(self, jobs=0): - # FIXME: enable it when buildbots are properly configured - return + if self.config.arch == Architecture.ARM64 and not os.path.exists('/Library/Apple/usr/lib/libRosettaAot.dylib'): + m.message('Installing rosetta needed for some package installation scripts') + shell.new_call(['/usr/sbin/softwareupdate', '--install-rosetta', '--agree-to-license']) def register_all(): diff --git a/cerbero/bootstrap/linux.py b/cerbero/bootstrap/linux.py index d7ab0836a..4ab1cf9b4 100644 --- a/cerbero/bootstrap/linux.py +++ b/cerbero/bootstrap/linux.py @@ -16,11 +16,13 @@ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. +import sys + from cerbero.bootstrap import BootstrapperBase from cerbero.bootstrap.bootstrapper import register_system_bootstrapper from cerbero.enums import Platform, Architecture, Distro, DistroVersion -from cerbero.errors import ConfigurationError, CommandError -from cerbero.utils import user_is_root, shell +from cerbero.errors import ConfigurationError, CommandError, FatalError +from cerbero.utils import user_is_root, shell, split_version from cerbero.utils import messages as m @@ -32,7 +34,7 @@ class UnixBootstrapper(BootstrapperBase): packages = [] def __init__(self, config, offline, assume_yes): - BootstrapperBase.__init__(self, config, offline) + BootstrapperBase.__init__(self, config, offline, 'linux') self.assume_yes = assume_yes if user_is_root() and 'sudo' in self.tool: # no need for sudo as root user self.tool.remove('sudo') @@ -43,9 +45,20 @@ async def start(self, jobs=0): if self.config.distro_packages_install: extra_packages = self.config.extra_bootstrap_packages.get(self.config.platform, None) + override_packages = self.config.override_bootstrap_packages.get(self.config.platform, None) + if extra_packages and override_packages: + raise ConfigurationError( + 'You are setting "extra_bootstrap_packages" and "override_bootstrap_packages" ' + 'on the same CBC. This might cause conflicts.' + ) if extra_packages: self.packages += extra_packages.get(self.config.distro, []) self.packages += extra_packages.get(self.config.distro_version, []) + if override_packages: + self.packages = [] + self.packages += override_packages.get(self.config.distro, []) + self.packages += override_packages.get(self.config.distro_version, []) + tool = self.tool if self.assume_yes: tool += self.yes_arg @@ -111,7 +124,7 @@ def __init__(self, config, offline, assume_yes): self.packages.append('libc6:i386') self.checks.append(self.create_debian_arch_check('i386')) if self.config.arch in [Architecture.X86_64, Architecture.X86]: - self.packages.append('wine') + self.packages += ['wine', 'xvfb'] def create_debian_arch_check(self, arch): def check_arch(): @@ -154,7 +167,6 @@ class RedHatBootstrapper(UnixBootstrapper): 'curl', 'rpm-build', 'redhat-rpm-config', - 'python3-devel', 'libXrender-devel', 'pulseaudio-libs-devel', 'libXv-devel', @@ -164,38 +176,82 @@ class RedHatBootstrapper(UnixBootstrapper): 'libXi-devel', 'perl-XML-Simple', 'gperf', - 'wget', 'libXrandr-devel', 'libXtst-devel', 'git', 'xorg-x11-util-macros', 'mesa-libEGL-devel', - 'ccache', 'openssl-devel', 'alsa-lib-devel', - 'perl-FindBin', + 'perl-IPC-Cmd', + 'libatomic', ] def __init__(self, config, offline, assume_yes): UnixBootstrapper.__init__(self, config, offline, assume_yes) - if self.config.distro_version < DistroVersion.FEDORA_23: - self.tool = ['yum'] - elif self.config.distro_version in [DistroVersion.REDHAT_6, DistroVersion.REDHAT_7]: + dn, dv = self.config.distro_version.split('_', 1) + dv = split_version(dv) + + if (dn == 'fedora' and dv < (23,)) or (dn == 'redhat' and dv < (8, 3)): self.tool = ['yum'] - elif self.config.distro_version == DistroVersion.REDHAT_8: - self.tool = ['yum', '--enablerepo=PowerTools'] + + if dn == 'redhat' and dv >= (8,): + if dv < (8, 3): + self.tool += ['--enablerepo=PowerTools'] + elif dv < (9,): + self.tool += ['--enablerepo=powertools'] + else: + self.tool += ['--enablerepo=crb'] + + def pkg_available(pkg): + return shell.new_call(self.tool + ['list', pkg, '-q'], fail=False) == 0 + + def add_pkg(names, required=True): + for pkg in names: + if pkg_available(pkg): + self.packages.append(pkg) + return True + if required: + raise FatalError('Required package not found, tried: ' + ', '.join(names)) + return False + + if not user_is_root(): + self.tool = ['sudo'] + self.tool + + # In RHEL based distros ccache is only available in the EPEL repo + if not add_pkg(['ccache'], required=False): + if pkg_available('epel-release'): + cmd = self.tool + ['install', 'epel-release'] + (['-y'] if assume_yes else []) + self.checks.append( + lambda: shell.new_call(cmd, interactive=True, fail=False) == 0 and self.packages.append('ccache') + ) + else: + m.warning('Compilation will not use ccache since it is not available') + self.config.use_ccache = False + + # Before RHEL 9 perl-FindBin wasn't a standalone package + if dn != 'redhat' or dv >= (9,): + add_pkg(['perl-FindBin']) + elif dv >= (8,): + add_pkg(['perl-interpreter']) + else: + add_pkg(['perl']) + + # Use curl if wget isn't found, because wget2 is not production-ready yet + add_pkg(['wget', 'curl']) + + # Try to get a better matching python3 library version + ver = sys.version_info[1] + add_pkg([f'python3{v}-devel' for v in [ver, f'.{ver}', '']]) if self.config.target_platform == Platform.WINDOWS: if self.config.arch == Architecture.X86_64: self.packages.append('glibc.i686') - if self.config.distro_version in [DistroVersion.FEDORA_24, DistroVersion.FEDORA_25]: + if self.config.distro_version in ['fedora_24', 'fedora_25']: self.packages.append('libncurses-compat-libs.i686') if self.config.arch in [Architecture.X86_64, Architecture.X86]: - self.packages.append('wine') - if user_is_root(): - return - self.tool = ['sudo'] + self.tool + self.packages += ['wine', 'which', 'xorg-x11-server-Xvfb'] class OpenSuseBootstrapper(UnixBootstrapper): @@ -238,7 +294,7 @@ def __init__(self, config, offline, assume_yes): UnixBootstrapper.__init__(self, config, offline, assume_yes) if self.config.target_platform == Platform.WINDOWS: if self.config.arch in [Architecture.X86_64, Architecture.X86]: - self.packages.append('wine') + self.packages += ['wine', 'xvfb-run'] class ArchBootstrapper(UnixBootstrapper): @@ -267,6 +323,8 @@ class ArchBootstrapper(UnixBootstrapper): 'ccache', 'openssl', 'alsa-lib', + 'which', + 'libpulse', ] def __init__(self, config, offline, assume_yes): @@ -284,7 +342,7 @@ def __init__(self, config, offline, assume_yes): self.packages.append('gcc') if self.config.target_platform == Platform.WINDOWS: if self.config.arch in [Architecture.X86_64, Architecture.X86]: - self.packages.append('wine') + self.packages += ['wine', 'xorg-server-xvfb'] class GentooBootstrapper(UnixBootstrapper): diff --git a/cerbero/bootstrap/osx.py b/cerbero/bootstrap/osx.py index 7be891c9e..c450aea69 100644 --- a/cerbero/bootstrap/osx.py +++ b/cerbero/bootstrap/osx.py @@ -16,7 +16,7 @@ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. - +import os from cerbero.bootstrap import BootstrapperBase from cerbero.bootstrap.bootstrapper import register_system_bootstrapper from cerbero.config import Distro @@ -27,13 +27,13 @@ class OSXBootstrapper(BootstrapperBase): def __init__(self, config, offline, assume_yes): - super().__init__(config, offline) + super().__init__(config, offline, 'macos') async def start(self, jobs=0): # skip system package install if not needed if not self.config.distro_packages_install: return - if self.config.arch == Architecture.ARM64: + if self.config.arch == Architecture.ARM64 and not os.path.exists('/Library/Apple/usr/lib/libRosettaAot.dylib'): m.message('Installing rosetta needed for some package installation scripts') shell.new_call(['/usr/sbin/softwareupdate', '--install-rosetta', '--agree-to-license']) diff --git a/cerbero/bootstrap/rust.py b/cerbero/bootstrap/rust.py index 64e2bfb7a..d7bb6f579 100644 --- a/cerbero/bootstrap/rust.py +++ b/cerbero/bootstrap/rust.py @@ -17,10 +17,19 @@ # Boston, MA 02111-1307, USA. import os +import sys import stat import shutil from urllib.parse import urlparse +if __name__ == '__main__': + # Add cerbero dir to path when invoked as a script so + # that the cerbero imports below resolve correctly. + parent = os.path.dirname(__file__) + parent = os.path.dirname(parent) + parent = os.path.dirname(parent) + sys.path.append(parent) + from cerbero.bootstrap import BootstrapperBase from cerbero.utils import shell from cerbero.utils import messages as m @@ -34,8 +43,8 @@ class RustBootstrapper(BootstrapperBase): """ SERVER = 'https://static.rust-lang.org' - RUSTUP_VERSION = '1.26.0' - RUST_VERSION = '1.76.0' + RUSTUP_VERSION = '1.27.1' + RUST_VERSION = '1.85.0' RUSTUP_URL_TPL = '{server}/rustup/archive/{version}/{triple}/rustup-init{exe_suffix}' RUSTUP_NAME_TPL = 'rustup-init-{version}-{triple}{exe_suffix}' CHANNEL_URL_TPL = '{server}/dist/channel-rust-{version}.toml' @@ -44,18 +53,17 @@ class RustBootstrapper(BootstrapperBase): TOMLI_URL = 'https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz' DOWNLOAD_CHECKSUMS = { # Rust packages metadata - 'channel-rust-1.76.0.toml': '7b89a56897a1581ca66312468276ee08e6d596a3254128a567c1658c6f733c76', + 'channel-rust-1.85.0.toml': '009e8b5ff43f12bf644b5e5b9fd89f96453072062a450c623882f64e85405da5', # Tomli Python module 'tomli-2.0.1.tar.gz': 'de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f', # Rustup - 'rustup-init-1.26.0-aarch64-unknown-linux-gnu': '673e336c81c65e6b16dcdede33f4cc9ed0f08bde1dbe7a935f113605292dc800', - 'rustup-init-1.26.0-x86_64-unknown-linux-gnu': '0b2f6c8f85a3d02fde2efc0ced4657869d73fccfce59defb4e8d29233116e6db', - 'rustup-init-1.26.0-aarch64-apple-darwin': 'ed299a8fe762dc28161a99a03cf62836977524ad557ad70e13882d2f375d3983', - 'rustup-init-1.26.0-x86_64-apple-darwin': 'f6d1a9fac1a0d0802d87c254f02369a79973bc8c55aa0016d34af4fcdbd67822', - 'rustup-init-1.26.0-i686-pc-windows-msvc.exe': '3fcfaf0018c12b96c49dc7e13e8638bd8de686ab27dd14238c3f11d0a936c003', - 'rustup-init-1.26.0-x86_64-pc-windows-msvc.exe': '365d072ac4ef47f8774f4d2094108035e2291a0073702db25fa7797a30861fc9', - 'rustup-init-1.26.0-i686-pc-windows-gnu.exe': 'f2cb7bb1e662a74bd9fa071cc0799dc4c814b3a56af979d6eba1169c3d98338b', - 'rustup-init-1.26.0-x86_64-pc-windows-gnu.exe': '32e9128a82ac130043012463ca5f9cb507c349a3f16e3c2b98a3f7a32e294e59', + 'rustup-init-1.27.1-x86_64-unknown-linux-gnu': '6aeece6993e902708983b209d04c0d1dbb14ebb405ddb87def578d41f920f56d', + 'rustup-init-1.27.1-aarch64-unknown-linux-gnu': '1cffbf51e63e634c746f741de50649bbbcbd9dbe1de363c9ecef64e278dba2b2', + 'rustup-init-1.27.1-x86_64-apple-darwin': 'f547d77c32d50d82b8228899b936bf2b3c72ce0a70fb3b364e7fba8891eba781', + 'rustup-init-1.27.1-aarch64-apple-darwin': '760b18611021deee1a859c345d17200e0087d47f68dfe58278c57abe3a0d3dd0', + 'rustup-init-1.27.1-x86_64-pc-windows-gnu.exe': 'b272587f5bf4b8be1396353d22829245955873425110398f110959c866296b2b', + 'rustup-init-1.27.1-x86_64-pc-windows-msvc.exe': '193d6c727e18734edbf7303180657e96e9d5a08432002b4e6c5bbe77c60cb3e8', + 'rustup-init-1.27.1-aarch64-pc-windows-msvc.exe': '5f4697ee3ea5d4592bffdbe9dc32d6a8865762821b14fdd1cf870e585083a2f0', } # The triple for the build platform/arch build_triple = None @@ -68,23 +76,26 @@ class RustBootstrapper(BootstrapperBase): channel = None def __init__(self, config, offline): - super().__init__(config, offline) + super().__init__(config, offline, 'rust') self.offline = offline self.build_triple = self.config.rust_build_triple self.target_triples = self.config.rust_target_triples if self.config.platform == Platform.WINDOWS: - # On Windows, build-tools always use MSVC so we need to always - # bootstrap $arch-windows-msvc - bs_triple = self.config.rust_triple(self.config.arch, self.config.platform, True) - if bs_triple not in self.target_triples: - self.target_triples.append(bs_triple) + tgt = set(self.target_triples) + # On Windows, build tools must be built using MSVC. However, + # the current variant determines the default target. + # So we need to always bootstrap $arch-windows-msvc, + # and override the build triple accordingly + self.build_triple = self.config.rust_triple(self.config.arch, self.config.platform, True) + tgt.add(self.build_triple) # rustup-init wants to always install both 64-bit and 32-bit # toolchains, so ensure that we fetch and install both archs = {Architecture.X86_64, Architecture.X86} other_arch = (archs - {self.config.arch}).pop() - arch_triple = self.config.rust_triple(other_arch, self.config.platform, self.config.variants.visualstudio) - if arch_triple not in self.target_triples: - self.target_triples.append(arch_triple) + # in both MSVC and MinGW ABIs + tgt.add(self.config.rust_triple(other_arch, self.config.platform, True)) + tgt.add(self.config.rust_triple(other_arch, self.config.platform, False)) + self.target_triples = list(tgt) self.fetch_urls = self.get_fetch_urls() self.fetch_urls_func = self.get_more_fetch_urls self.extract_steps = [] @@ -171,11 +182,15 @@ def get_entry_urls(entry): entry = channel_data['pkg'][c]['target'][self.build_triple] urls += list(get_entry_urls(entry)) - # And then maybe also rust-std for the target machine + # Then maybe also rust-std for the target machine for triple in self.target_triples: if triple != self.build_triple: entry = channel_data['pkg']['rust-std']['target'][triple] urls += list(get_entry_urls(entry)) + # And rust-mingw for any MinGW targets + if 'windows-gnu' in triple: + entry = channel_data['pkg']['rust-mingw']['target'][triple] + urls += list(get_entry_urls(entry)) return (urls, self.install_toolchain_for_cargoc_fetch) @@ -229,3 +244,95 @@ async def install_toolchain(self): async def start(self, jobs=0): await self.install_toolchain() + + +if __name__ == '__main__': + import re + import argparse + import urllib.request + from hashlib import sha256 + from cerbero.config import RUST_TRIPLE_MAPPING + + parser = argparse.ArgumentParser() + parser.add_argument('rust_version', nargs='?', help='Rust version to update to') + parser.add_argument('rustup_version', nargs='?', help='Rustup version to update to') + args = parser.parse_args() + + def get_rustup_version(): + d = urllib.request.urlopen('https://sh.rustup.rs', timeout=20) + s = d.read().decode('utf-8') + m = re.search('rustup-init ([0-9.]+)', s) + return m.groups(0)[0] + + def get_tomllib(): + import importlib + + if sys.version_info >= (3, 11, 0): + return importlib.import_module('tomllib') + for mod in ('tomli', 'toml', 'tomlkit'): + try: + return importlib.import_module(mod) + except ModuleNotFoundError: + continue + raise RuntimeError('No toml python module available') + + def get_rust_version(): + d = urllib.request.urlopen('https://static.rust-lang.org/dist/channel-rust-stable.toml', timeout=20) + tomllib = get_tomllib() + data = tomllib.loads(d.read().decode('utf-8')) + return data['pkg']['rust']['version'].split()[0] + + def get_checksum(url): + print(url + ' ', end='', flush=True) + d = urllib.request.urlopen(url, timeout=20) + h = sha256() + while True: + chunk = d.read(1024 * 1024) + if not chunk: + break + h.update(chunk) + print('.', end='', flush=True) + print('') + return h.hexdigest() + + cls = RustBootstrapper + kwargs = {'server': cls.SERVER} + checksums = {} + + rust_version = args.rust_version + if not rust_version: + rust_version = get_rust_version() + if rust_version != cls.RUST_VERSION: + kwargs['version'] = rust_version + name = f'channel-rust-{rust_version}.toml' + checksums[name] = get_checksum(cls.CHANNEL_URL_TPL.format(**kwargs)) + + rustup_version = args.rustup_version + if not rustup_version: + rustup_version = get_rustup_version() + if rustup_version != cls.RUSTUP_VERSION: + kwargs['version'] = rustup_version + kwargs['exe_suffix'] = '' + for platform in (Platform.LINUX, Platform.DARWIN): + for arch in (Architecture.X86_64, Architecture.ARM64): + kwargs['triple'] = RUST_TRIPLE_MAPPING[(platform, arch)] + name = cls.RUSTUP_NAME_TPL.format(**kwargs) + checksums[name] = get_checksum(cls.RUSTUP_URL_TPL.format(**kwargs)) + + platform = Platform.WINDOWS + kwargs['exe_suffix'] = '.exe' + for toolchain in ('gnu', 'msvc'): + for arch in (Architecture.X86_64, Architecture.ARM64): + if toolchain == 'gnu' and arch == Architecture.ARM64: + continue + kwargs['triple'] = RUST_TRIPLE_MAPPING[(platform, arch, toolchain)] + name = cls.RUSTUP_NAME_TPL.format(**kwargs) + checksums[name] = get_checksum(cls.RUSTUP_URL_TPL.format(**kwargs)) + + for key, value in checksums.items(): + print(' ' * 8, end='') + print(f"'{key}': '{value}',") + if rustup_version != cls.RUSTUP_VERSION: + print(f"RUSTUP_VERSION = '{rustup_version}'") + if rust_version != cls.RUST_VERSION: + print(f"RUST_VERSION = '{rust_version}'") diff --git a/cerbero/bootstrap/windows.py b/cerbero/bootstrap/windows.py index 6219195f8..575ea579d 100644 --- a/cerbero/bootstrap/windows.py +++ b/cerbero/bootstrap/windows.py @@ -30,15 +30,15 @@ from cerbero.utils import messages as m # Toolchain -TOOLCHAIN_BASE_URL = 'https://gstreamer.freedesktop.org/data/cerbero/toolchain/windows/' +TOOLCHAIN_BASE_URL = 'https://gstreamer.freedesktop.org/data/cerbero/toolchain/mingw/14.2.0/' TOOLCHAIN_PLATFORM = { Platform.LINUX: ( - 'mingw-6.0.0-gcc-8.2.0-linux-multilib.tar.xz', - '396ceb50161720b19971e2c71c87ce08150213b091ed8ffc00782df8759921bf', + 'mingw-12.0.0-gcc-14.2.0-linux-multilib.tar.xz', + 'ef3bcdd10716578b9300591da68beb73753002252a46e41f316bb94a577e3c04', ), Platform.WINDOWS: ( - 'mingw-6.0.0-gcc-8.2.0-windows-multilib.tar.xz', - '77fc1319b13894d7340d4994150e3af615e23a63113a9947412d11be95f4d8a9', + 'mingw-12.0.0-gcc-14.2.0-windows-multilib.tar.xz', + '2e9039c6404f68bfce1eecd34172b16715565a15555c76c1652ec26265d5ae89', ), } @@ -67,7 +67,7 @@ class MSYSBootstrapper(BootstrapperBase): packages = ['msys-flex', 'msys-bison', 'msys-perl'] def __init__(self, config, offline, assume_yes): - super().__init__(config, offline) + super().__init__(config, offline, 'msys') self.perl_prefix = self.config.mingw_perl_prefix self.prefix = self.config.toolchain_prefix # MinGW Perl needed by openssl @@ -159,7 +159,7 @@ class MSYS2Bootstrapper(BootstrapperBase): ] def __init__(self, config, offline, assume_yes): - super().__init__(config, offline) + super().__init__(config, offline, 'msys2') async def start(self, jobs=0): shell.new_call(['pacman', '-Sy', '--noconfirm', '--needed'] + self.packages) @@ -172,7 +172,7 @@ class MinGWBootstrapper(BootstrapperBase): """ def __init__(self, config, offline, assume_yes): - super().__init__(config, offline) + super().__init__(config, offline, 'mingw') self.prefix = self.config.toolchain_prefix self.arch = self.config.target_arch # Register all network resources this bootstrapper needs. They will all diff --git a/cerbero/build/build.py b/cerbero/build/build.py index d2d7f119a..29b0d5faa 100644 --- a/cerbero/build/build.py +++ b/cerbero/build/build.py @@ -18,20 +18,15 @@ import os import re -import glob -import copy import shutil import shlex -import sys -import subprocess import asyncio from pathlib import Path from itertools import chain -from cerbero.enums import Platform, Architecture, Distro, LibraryType +from cerbero.enums import Platform, Architecture, Distro, DistroVersion, LibraryType from cerbero.errors import FatalError, InvalidRecipeError from cerbero.utils import shell, add_system_libs, determine_num_cargo_jobs -from cerbero.utils import EnvValue, EnvValueSingle, EnvValueArg, EnvValueCmd, EnvValuePath from cerbero.utils import messages as m @@ -44,11 +39,12 @@ def get_optimization_from_config(config): def modify_environment(func): - ''' + """ Decorator to modify the build environment When called recursively, it only modifies the environment once. - ''' + """ + def call(*args): self = args[0] try: @@ -77,9 +73,10 @@ async def async_call(*args): class EnvVarOp: - ''' + """ An operation to be done on the values of a particular env var - ''' + """ + def __init__(self, op, var, vals, sep): self.execute = getattr(self, op) self.op = op @@ -134,16 +131,16 @@ def remove(self, env): env[self.var] = self.sep.join(new) def __repr__(self): - vals = "None" + vals = 'None' if self.sep: vals = self.sep.join(self.vals) - return "" + return '' class ModifyEnvBase: - ''' + """ Base class for build systems and recipes that require extra env variables - ''' + """ use_system_libs = False # Use the outdated MSYS perl instead of the new perl downloaded in bootstrap @@ -180,7 +177,15 @@ def __call__(this, var, *vals, sep=' ', when='later'): raise RuntimeError('Unknown when value: ' + when) def __repr__(this): - return "" + return ( + '' + ) for i in ('append', 'prepend', 'set', 'remove'): setattr(self, i + '_env', ModifyEnvFuncWrapper(self, i)) @@ -209,11 +214,13 @@ def setup_toolchain_env_ops(self): toolchain_env = self.config.mingw_env_for_toolchain.items() else: if self.using_msvc(): - toolchain_env = chain(self.config.msvc_env_for_toolchain.items(), - self.config.msvc_env_for_build_system.items()) + toolchain_env = chain( + self.config.msvc_env_for_toolchain.items(), self.config.msvc_env_for_build_system.items() + ) else: - toolchain_env = chain(self.config.mingw_env_for_toolchain.items(), - self.config.mingw_env_for_build_system.items()) + toolchain_env = chain( + self.config.mingw_env_for_toolchain.items(), self.config.mingw_env_for_build_system.items() + ) # Set the toolchain environment for var, val in toolchain_env: # PATH and LDFLAGS are already set in self.env by config.py, so we @@ -224,8 +231,20 @@ def setup_toolchain_env_ops(self): self.set_env(var, val.get(), sep=val.sep) def unset_toolchain_env(self): - for var in ('CC', 'CXX', 'OBJC', 'OBJCXX', 'AR', 'WINDRES', 'STRIP', - 'CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'OBJCFLAGS', 'LDFLAGS'): + for var in ( + 'CC', + 'CXX', + 'OBJC', + 'OBJCXX', + 'AR', + 'WINDRES', + 'STRIP', + 'CFLAGS', + 'CXXFLAGS', + 'CPPFLAGS', + 'OBJCFLAGS', + 'LDFLAGS', + ): if var in self.env: # Env vars that are edited by the recipe will be restored by # @modify_environment when we return from the build step but @@ -238,10 +257,10 @@ def check_reentrancy(self): @modify_environment def get_recipe_env(self): - ''' + """ Used in oven.py to start a shell prompt with the correct env on recipe build failure - ''' + """ return self.env.copy() def _save_env_var(self, var): @@ -253,9 +272,9 @@ def _save_env_var(self, var): self._old_env[var] = None def _modify_env(self): - ''' + """ Modifies the build environment by inserting env vars from new_env - ''' + """ # If requested, remove the new mingw-perl downloaded in bootstrap from # PATH and use the MSYS Perl instead if self.config.distro == Distro.MSYS and self.use_msys_perl: @@ -272,7 +291,7 @@ def _modify_env(self): env_op.execute(self.env) def _restore_env(self): - ''' Restores the old environment ''' + """Restores the old environment""" for var, val in self._old_env.items(): if val is None: if var in self.env: @@ -282,16 +301,16 @@ def _restore_env(self): self._old_env.clear() def maybe_add_system_libs(self, step=''): - ''' + """ Add /usr/lib/pkgconfig to PKG_CONFIG_PATH so the system's .pc file can be found. - ''' + """ # Note: this is expected to be called with the environment already # modified using @{async_,}modify_environment # don't add system libs unless explicitly asked for if not self.use_system_libs or not self.config.allow_system_libs: - return; + return # this only works because add_system_libs() does very little # this is a possible source of env conflicts @@ -310,14 +329,14 @@ def maybe_add_system_libs(self, step=''): class Build(object): - ''' + """ Base class for build handlers @ivar recipe: the parent recipe @type recipe: L{cerbero.recipe.Recipe} @ivar config: cerbero's configuration @type config: L{cerbero.config.Config} - ''' + """ library_type = LibraryType.BOTH # Whether this recipe's build system can be built with MSVC @@ -351,37 +370,40 @@ def using_uwp(self): return True async def configure(self): - ''' + """ Configures the module - ''' - raise NotImplemented("'configure' must be implemented by subclasses") + """ + raise NotImplementedError("'configure' must be implemented by subclasses") async def compile(self): - ''' + """ Compiles the module - ''' - raise NotImplemented("'make' must be implemented by subclasses") + """ + raise NotImplementedError("'make' must be implemented by subclasses") async def install(self): - ''' + """ Installs the module - ''' - raise NotImplemented("'install' must be implemented by subclasses") + """ + raise NotImplementedError("'install' must be implemented by subclasses") def check(self): - ''' + """ Runs any checks on the module - ''' + """ pass def num_of_cpus(self): - if self.config.allow_parallel_build and getattr(self, 'allow_parallel_build', True) \ - and self.config.num_of_cpus > 1: + if ( + self.config.allow_parallel_build + and getattr(self, 'allow_parallel_build', True) + and self.config.num_of_cpus > 1 + ): return self.config.num_of_cpus return None -class CustomBuild(Build, ModifyEnvBase): +class CustomBuild(Build, ModifyEnvBase): def __init__(self): Build.__init__(self) ModifyEnvBase.__init__(self) @@ -396,10 +418,10 @@ async def install(self): pass -class MakefilesBase (Build, ModifyEnvBase): - ''' +class MakefilesBase(Build, ModifyEnvBase): + """ Base class for makefiles build systems like autotools and cmake - ''' + """ config_sh = '' configure_tpl = '' @@ -423,10 +445,9 @@ def __init__(self): self.setup_buildtype_env_ops() if self.requires_non_src_build: - self.make_dir = os.path.join (self.config_src_dir, "cerbero-build-dir") + self.make_dir = os.path.join(self.config_src_dir, 'cerbero-build-dir') else: - self.make_dir = os.path.abspath(os.path.join(self.config_src_dir, - self.srcdir)) + self.make_dir = os.path.abspath(os.path.join(self.config_src_dir, self.srcdir)) self.make = self.make or ['make', 'V=1'] self.make_install = self.make_install or ['make', 'install'] @@ -442,12 +463,12 @@ def __init__(self): self.set_env('CONFIG_SITE', when='now') async def configure(self): - ''' + """ Base configure method When called from a method in deriverd class, that method has to be decorated with modify_environment decorator. - ''' + """ if not os.path.exists(self.make_dir): os.makedirs(self.make_dir) if self.requires_non_src_build: @@ -481,8 +502,7 @@ async def configure(self): self.maybe_add_system_libs(step='configure') - await shell.async_call(configure_cmd, self.make_dir, - logfile=self.logfile, env=self.env) + await shell.async_call(configure_cmd, self.make_dir, logfile=self.logfile, env=self.env) @modify_environment async def compile(self): @@ -506,29 +526,29 @@ def check(self): shell.new_call(self.make_check, self.build_dir, logfile=self.logfile, env=self.env) -class Makefile (MakefilesBase): - ''' +class Makefile(MakefilesBase): + """ Build handler for Makefile project - ''' + """ + @modify_environment async def configure(self): await MakefilesBase.configure(self) -class Autotools (MakefilesBase): - ''' +class Autotools(MakefilesBase): + """ Build handler for autotools project @cvar override_libtool: overrides ltmain.sh to generate a libtool script with the one built by cerbero. @type override_libtool: boolean - ''' + """ autoreconf = False autoreconf_sh = 'autoreconf -f -i' config_sh = './configure' - configure_tpl = "%(config-sh)s --prefix %(prefix)s "\ - "--libdir %(libdir)s" + configure_tpl = '%(config-sh)s --prefix %(prefix)s ' '--libdir %(libdir)s' add_host_build_target = True can_use_configure_cache = True supports_cache_variables = True @@ -546,22 +566,21 @@ async def configure(self): # Disable automatic dependency tracking, speeding up one-time builds self.configure_tpl += ' --disable-dependency-tracking ' # Only use --disable-maintainer mode for real autotools based projects - if os.path.exists(os.path.join(self.config_src_dir, 'configure.in')) or\ - os.path.exists(os.path.join(self.config_src_dir, 'configure.ac')): - self.configure_tpl += " --disable-maintainer-mode " - self.configure_tpl += " --disable-silent-rules " + if os.path.exists(os.path.join(self.config_src_dir, 'configure.in')) or os.path.exists( + os.path.join(self.config_src_dir, 'configure.ac') + ): + self.configure_tpl += ' --disable-maintainer-mode ' + self.configure_tpl += ' --disable-silent-rules ' # Never build gtk-doc documentation - self.configure_tpl += " --disable-gtk-doc " + self.configure_tpl += ' --disable-gtk-doc ' - if self.config.variants.gi and not self.disable_introspection \ - and self.use_gobject_introspection(): - self.configure_tpl += " --enable-introspection " + if self.config.variants.gi and not self.disable_introspection and self.use_gobject_introspection(): + self.configure_tpl += ' --enable-introspection ' else: - self.configure_tpl += " --disable-introspection " + self.configure_tpl += ' --disable-introspection ' if self.autoreconf: - await shell.async_call(self.autoreconf_sh, self.config_src_dir, - logfile=self.logfile, env=self.env) + await shell.async_call(self.autoreconf_sh, self.config_src_dir, logfile=self.logfile, env=self.env) # We don't build libtool on Windows if self.config.platform == Platform.WINDOWS: @@ -580,11 +599,10 @@ async def configure(self): files.remove('') for f in files: o = os.path.join(srcdir, cf) - m.log("CERBERO: copying %s to %s" % (o, f), self.logfile) + m.log('CERBERO: copying %s to %s' % (o, f), self.logfile) shutil.copy(o, f) - if self.config.platform == Platform.WINDOWS and \ - self.supports_cache_variables: + if self.config.platform == Platform.WINDOWS and self.supports_cache_variables: # On windows, environment variables are upperscase, but we still # need to pass things like am_cv_python_platform in lowercase for # configure and autogen.sh @@ -612,34 +630,36 @@ async def configure(self): self.configure_tpl += ' --cache-file=%s' % cache # Add at the very end to allow recipes to override defaults - self.configure_tpl += " %(options)s " + self.configure_tpl += ' %(options)s ' await MakefilesBase.configure(self) -class CMake (MakefilesBase): - ''' +class CMake(MakefilesBase): + """ Build handler for cmake projects - ''' + """ cmake_generator = 'make' config_sh_needs_shell = False config_sh = None - configure_tpl = '%(config-sh)s -DCMAKE_INSTALL_PREFIX=%(prefix)s ' \ - '-H%(make_dir)s ' \ - '-B%(build_dir)s ' \ - '-DCMAKE_LIBRARY_OUTPUT_PATH=%(libdir)s ' \ - '-DCMAKE_INSTALL_LIBDIR=%(libdir)s ' \ - '-DCMAKE_INSTALL_BINDIR=bin ' \ - '-DCMAKE_INSTALL_INCLUDEDIR=include ' \ - '%(options)s -DCMAKE_BUILD_TYPE=Release '\ - '-DCMAKE_FIND_ROOT_PATH=$CERBERO_PREFIX '\ - '-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true ' + configure_tpl = ( + '%(config-sh)s -DCMAKE_INSTALL_PREFIX=%(prefix)s ' + '-H%(make_dir)s ' + '-B%(build_dir)s ' + '-DCMAKE_LIBRARY_OUTPUT_PATH=%(libdir)s ' + '-DCMAKE_INSTALL_BINDIR=bin ' + '-DCMAKE_INSTALL_INCLUDEDIR=include ' + '%(options)s -DCMAKE_BUILD_TYPE=Release ' + '-DCMAKE_FIND_ROOT_PATH=%(prefix)s ' + '-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true ' + ) def __init__(self): MakefilesBase.__init__(self) self.build_dir = os.path.join(self.build_dir, 'b') self.config_sh = 'cmake' + self.configure_tpl += f'-DCMAKE_INSTALL_LIBDIR={self.config.rel_libdir} ' if self.config.distro == Distro.MSYS2: # We do not want the MSYS2 CMake because it doesn't support MSVC self.config_sh = shutil.which('cmake', path=shell.get_path_minus_msys(self.env['PATH'])) @@ -673,8 +693,7 @@ async def configure(self): self.make += ['-j1'] self.make_install = self.make + ['install'] else: - if self.config.platform == Platform.WINDOWS and \ - self.config.distro != Distro.MSYS : + if self.config.platform == Platform.WINDOWS and self.config.distro != Distro.MSYS: self.configure_options += ['-G', 'MSYS Makefiles'] else: self.configure_options += ['-G', 'Unix Makefiles'] @@ -689,21 +708,51 @@ async def configure(self): elif self.config.target_platform == Platform.IOS: system_name = 'iOS' - if self.config.cross_compiling() or self.config.target_platform == Platform.WINDOWS: - self.configure_options += [f'-DCMAKE_SYSTEM_NAME={system_name}'] - if self.config.target_platform in (Platform.DARWIN, Platform.IOS): self.configure_options += ['-DCMAKE_OSX_ARCHITECTURES=' + self.config.target_arch] + # We always need a toolchain file because CMakeLists.txt requires these values to be set. + # The Android NDK provides one, so we use that as-is. + # This recipe uses these to decide which cpuinfo implementation to use: + # https://github.com/libjpeg-turbo/libjpeg-turbo/blob/3.0.3/CMakeLists.txt#L92 + if self.config.target_platform == Platform.ANDROID: + arch = self.config.target_arch + if self.config.target_arch == Architecture.ARMv7: + arch = 'armeabi-v7a' + elif self.config.target_arch == Architecture.ARM64: + arch = 'arm64-v8a' + self.configure_options += [ + f"-DCMAKE_TOOLCHAIN_FILE={self.config.env['ANDROID_NDK_HOME']}/build/cmake/android.toolchain.cmake", + f'-DANDROID_ABI={arch}', + # Required by taglib and svt-av1 + f'-DANDROID_PLATFORM={DistroVersion.get_android_api_version(self.config.target_distro_version)}', + ] + # A toolchain file triggers specific cross compiling logic + # in wavpack and taglib + elif self.config.cross_compiling(): + with open(f'{self.config_src_dir}/toolchain.cmake', 'w') as f: + f.write(f'set(CMAKE_SYSTEM_NAME {system_name})\n') + f.write(f'set(CMAKE_SYSTEM_PROCESSOR {self.config.target_arch})\n') + self.configure_options += [f'-DCMAKE_TOOLCHAIN_FILE={self.config_src_dir}/toolchain.cmake'] + elif self.config.target_platform == Platform.WINDOWS: + self.configure_options += [ + f'-DCMAKE_SYSTEM_NAME={system_name}', + f'-DCMAKE_SYSTEM_PROCESSOR={self.config.target_arch}', + ] + # FIXME: Maybe export the sysroot properly instead of doing regexp magic if self.config.target_platform in [Platform.DARWIN, Platform.IOS]: - r = re.compile(r".*-isysroot ([^ ]+) .*") + r = re.compile(r'.*-isysroot ([^ ]+) .*') sysroot = r.match(cflags).group(1) self.configure_options += ['-DCMAKE_OSX_SYSROOT=' + sysroot] + # Supplying these with the Android toolchain file breaks the former + if self.config.target_platform != Platform.ANDROID: + self.configure_options += [ + '-DCMAKE_C_COMPILER=' + cc, + '-DCMAKE_CXX_COMPILER=' + cxx, + ] self.configure_options += [ - '-DCMAKE_C_COMPILER=' + cc, - '-DCMAKE_CXX_COMPILER=' + cxx, '-DCMAKE_C_FLAGS=' + cflags, '-DCMAKE_CXX_FLAGS=' + cxxflags, '-DLIB_SUFFIX=' + self.config.lib_suffix, @@ -721,8 +770,8 @@ async def configure(self): # as build_dir is different from source dir, makefile location will be in build_dir. self.make_dir = self.build_dir -MESON_FILE_TPL = \ -''' + +MESON_FILE_TPL = """ [host_machine] system = '{system}' cpu_family = '{cpu_family}' @@ -732,6 +781,9 @@ async def configure(self): [constants] toolchain = '{toolchain}' +[built-in options] +{builtin_options} + [properties] {extra_properties} @@ -741,14 +793,16 @@ async def configure(self): objc = {OBJC} objcpp = {OBJCXX} ar = {AR} -pkgconfig = {PKG_CONFIG} +nasm = {NASM} +pkg-config = {PKG_CONFIG} {extra_binaries} -''' +""" -class Meson (Build, ModifyEnvBase) : - ''' + +class Meson(Build, ModifyEnvBase): + """ Build handler for meson project - ''' + """ make = None make_install = None @@ -763,7 +817,7 @@ class Meson (Build, ModifyEnvBase) : can_msvc = True # Build files require a build machine compiler when cross-compiling meson_needs_build_machine_compiler = False - meson_builddir = "b" + meson_builddir = 'b' # We do not use cmake dependency files by default, speed up the build by disabling it need_cmake = False @@ -811,19 +865,28 @@ def _get_option_value(opt_type, value): raise AssertionError('Invalid option type {!r}'.format(opt_type)) def _set_option(self, opt_names, variant_name): - ''' + """ Parse the meson_options.txt file, figure out whether any of the provided option names exist, figure out the type, and enable/disable it as per the cerbero configuration. - ''' + """ # Don't overwrite if it's already set if opt_names.intersection(self.meson_options): return # Error out on invalid usage if not os.path.isdir(self.build_dir): - raise FatalError('Build directory doesn\'t exist yet?') + raise FatalError("Build directory doesn't exist yet?") # Check if the option exists, and if so, what the type is - meson_options = os.path.join(self.build_dir, 'meson_options.txt') - if not os.path.isfile(meson_options): + # https://mesonbuild.com/Build-options.html + meson_options_files = [ + 'meson_options.txt', # For versions of meson before 1.1 + 'meson.options', + ] + meson_options = None + for i in meson_options_files: + f = os.path.join(self.build_dir, i) + if os.path.isfile(f): + meson_options = f + if not meson_options: return opt_name = None opt_type = None @@ -838,7 +901,7 @@ def _set_option(self, opt_names, variant_name): if opt_name in opt_names: # get the type of the option type_regex = r"type\s*:\s*'(?P[^']+)'" - ty = re.search (type_regex, option, re.MULTILINE) + ty = re.search(type_regex, option, re.MULTILINE) if ty: if ty.group('type') in ('feature', 'boolean'): opt_type = ty.group('type') @@ -864,53 +927,15 @@ def _get_moc_path(self, qmake_path): return str(qmake.parent / moc_name) def _get_meson_target_file_contents(self): - ''' + """ Get the toolchain configuration for the target machine. This will either go into a cross file or a native file depending on whether we're cross-compiling or not. - ''' - def merge_env(old_env, new_env): - ret_env = {} - # Set/merge new values - for k, new_v in new_env.items(): - new_v = EnvValue.from_key(k, new_v) - if k not in old_env: - ret_env[k] = new_v - continue - old_v = old_env[k] - assert(isinstance(old_v, EnvValue)) - if isinstance(old_v, (EnvValueSingle, EnvValueCmd)) or (new_v == old_v): - ret_env[k] = new_v - elif isinstance(old_v, (EnvValuePath, EnvValueArg)): - ret_env[k] = new_v + old_v - else: - raise FatalError("Don't know how to combine the environment " - "variable '%s' with values '%s' and '%s'" % (k, new_v, old_v)) - # Set remaining old values - for k in old_env.keys(): - if k not in new_env: - ret_env[k] = old_env[k] - return ret_env - - # Extract toolchain config for the build system from the appropriate - # config env dict. Start with `self.env`, since it contains toolchain - # config set by the recipe and when building for target platforms other - # than Windows, it also contains build tools and the env for the - # toolchain set by config/*.config. - # - # On Windows, the toolchain config is `self.config.msvc_env_for_build_system` - # or `self.config.mingw_env_for_build_system` depending on which toolchain - # this recipe will use. - if self.config.target_platform == Platform.WINDOWS: - if self.using_msvc(): - build_env = dict(self.config.msvc_env_for_build_system) - else: - build_env = dict(self.config.mingw_env_for_build_system) - else: - build_env = {} + """ + # Override/merge toolchain env with recipe env and return a new dict # with values as EnvValue objects - build_env = merge_env(build_env, self.env) + build_env = self.config.get_build_env(self.env, self.using_msvc()) cc = build_env.pop('CC') cxx = build_env.pop('CXX') @@ -921,20 +946,20 @@ def merge_env(old_env, new_env): build_env.pop('CPP', None) build_env.pop('LD', None) - # Operate on a copy of the recipe properties to avoid accumulating args - # from all archs when doing universal builds - props = {} - build_env.pop('CPP', None) # Meson does not read this - build_env.pop('CPPFLAGS', None) # Meson does not read this, and it's duplicated in *FLAGS - props['c_args'] = build_env.pop('CFLAGS', []) - props['cpp_args'] = build_env.pop('CXXFLAGS', []) - props['objc_args'] = build_env.pop('OBJCFLAGS', []) - props['objcpp_args'] = build_env.pop('OBJCXXFLAGS', []) + builtins = {} + builtins['c_args'] = build_env.pop('CFLAGS', []) + builtins['cpp_args'] = build_env.pop('CXXFLAGS', []) + builtins['objc_args'] = build_env.pop('OBJCFLAGS', []) + builtins['objcpp_args'] = build_env.pop('OBJCXXFLAGS', []) # Link args - props['c_link_args'] = build_env.pop('LDFLAGS', []) - props['cpp_link_args'] = props['c_link_args'] - props['objc_link_args'] = build_env.pop('OBJLDFLAGS', props['c_link_args']) - props['objcpp_link_args'] = props['objc_link_args'] + builtins['c_link_args'] = build_env.pop('LDFLAGS', []) + builtins['cpp_link_args'] = builtins['c_link_args'] + builtins['objc_link_args'] = build_env.pop('OBJLDFLAGS', builtins['c_link_args']) + builtins['objcpp_link_args'] = builtins['objc_link_args'] + build_env.pop('CPP', None) # Meson does not read this + build_env.pop('CPPFLAGS', None) # Meson does not read this, and it's duplicated in *FLAGS + + props = {} for key, value in self.config.meson_properties.items(): if key not in props: props[key] = value @@ -953,15 +978,18 @@ def merge_env(old_env, new_env): # Point meson to rustc with correct arguments to ensure it's detected when cross-compiling if self.config.cargo_home: - target_triple = self.config.rust_triple(self.config.target_arch, - self.config.target_platform, self.using_msvc()) + target_triple = self.config.rust_triple( + self.config.target_arch, self.config.target_platform, self.using_msvc() + ) binaries['rust'] = [self.config.cargo_home + '/bin/rustc', '--target', target_triple] # Try to detect build tools in the remaining env vars build_tool_paths = build_env['PATH'].get() for name, tool in build_env.items(): # Autoconf env vars, incorrectly detected as a build tool because of 'yes' - if name.startswith('ac_cv'): + if '_cv_' in name: + continue + if name in ('EDITOR', 'SHELL', '_'): continue # Files are always executable on Windows if name in ('HISTFILE', 'GST_REGISTRY_1_0'): @@ -969,39 +997,65 @@ def merge_env(old_env, new_env): if tool and shutil.which(tool[0], path=build_tool_paths): binaries[name.lower()] = tool + builtin_options = '' + for k, v in builtins.items(): + builtin_options += '{} = {}\n'.format(k, str(v)) + extra_properties = '' for k, v in props.items(): extra_properties += '{} = {}\n'.format(k, str(v)) + # When building cross-macos-universal on arm64, we can use Rosetta to + # transparently run the x86_64 binaries. Inform Meson about this. + if ( + self.config.target_platform == Platform.DARWIN + and self.config.target_arch != self.config.arch + and self.config.arch == Architecture.ARM64 + ): + extra_properties += 'needs_exe_wrapper = false\n' + if self.config.target_arch == Architecture.X86_64: + tools = ['glib-compile-resources', 'gio-querymodules'] + pytools = ['glib-mkenums', 'glib-genmarshal', 'gdbus-codegen'] + if self.config.variants.gi: + tools += ['g-ir-compiler', 'g-ir-generate'] + pytools += ['g-ir-scanner', 'g-ir-annotation-tool'] + for tool in tools: + binaries[tool] = [os.path.join(self.config.prefix, 'bin', tool)] + for pytool in pytools: + binaries[pytool] = [self.config.python_exe, os.path.join(self.config.prefix, 'bin', pytool)] + extra_binaries = '' for k, v in binaries.items(): extra_binaries += '{} = {}\n'.format(k, str(v)) contents = MESON_FILE_TPL.format( - system=self.config.target_platform, - cpu=self.config.target_arch, - cpu_family=self._get_target_cpu_family(), - # Assume all supported target archs are little endian - endian='little', - toolchain='', - CC=cc, - CXX=cxx, - OBJC=objc, - OBJCXX=objcxx, - AR=ar, - PKG_CONFIG="'pkg-config'", - extra_binaries=extra_binaries, - extra_properties=extra_properties) + system=self.config.target_platform, + cpu=self.config.target_arch, + cpu_family=self._get_target_cpu_family(), + # Assume all supported target archs are little endian + endian='little', + toolchain='', + CC=cc, + CXX=cxx, + OBJC=objc, + OBJCXX=objcxx, + AR=ar, + NASM="'nasm'", + PKG_CONFIG="'pkg-config'", + extra_binaries=extra_binaries, + builtin_options=builtin_options, + extra_properties=extra_properties, + ) return contents def _get_meson_native_file_contents(self): - ''' + """ Get a toolchain configuration that points to the build machine's toolchain. On Windows, this is the MinGW toolchain that we ship. On Linux and macOS, this is the system-wide compiler. When targetting android, we can use the NDK bundled clang compiler for this purpose as well. - ''' + """ false = ['false'] if self.config.platform == Platform.WINDOWS: cc = self.config.mingw_env_for_build_system['CC'] @@ -1030,45 +1084,51 @@ def _get_meson_native_file_contents(self): # We do not use cmake dependency files, speed up the build by disabling it extra_binaries = 'cmake = {}'.format(str(false)) contents = MESON_FILE_TPL.format( - system=self.config.platform, - cpu=self.config.arch, - cpu_family=self.config.arch, - endian='little', - toolchain=self.get_env('ANDROID_NDK_TOOLCHAIN_BIN', ''), - CC=cc, - CXX=cxx, - OBJC=objc, - OBJCXX=objcxx, - AR=ar, - PKG_CONFIG=false, - extra_binaries=extra_binaries, - extra_properties='') + system=self.config.platform, + cpu=self.config.arch, + cpu_family=self.config.arch, + endian='little', + toolchain=self.get_env('ANDROID_NDK_TOOLCHAIN_BIN', ''), + CC=cc, + CXX=cxx, + OBJC=objc, + OBJCXX=objcxx, + AR=ar, + NASM="'nasm'", + PKG_CONFIG=false, + extra_binaries=extra_binaries, + builtin_options='', + extra_properties='', + ) return contents def _get_meson_dummy_file_contents(self): - ''' + """ Get a toolchain configuration that points to `false` for everything. This forces Meson to not detect a build-machine (native) compiler when cross-compiling. - ''' + """ # Tell meson to not use a native compiler for anything false = ['false'] # We do not use cmake dependency files, speed up the build by disabling it extra_binaries = 'cmake = {}'.format(str(false)) contents = MESON_FILE_TPL.format( - system=self.config.platform, - cpu=self.config.arch, - cpu_family=self.config.arch, - endian='little', - toolchain='', - CC=false, - CXX=false, - OBJC=false, - OBJCXX=false, - AR=false, - PKG_CONFIG=false, - extra_binaries=extra_binaries, - extra_properties='') + system=self.config.platform, + cpu=self.config.arch, + cpu_family=self.config.arch, + endian='little', + toolchain='', + CC=false, + CXX=false, + OBJC=false, + OBJCXX=false, + AR=false, + NASM=false, + PKG_CONFIG=false, + extra_binaries=extra_binaries, + builtin_options='', + extra_properties='', + ) return contents def _write_meson_file(self, contents, fname): @@ -1098,25 +1158,40 @@ async def configure(self): # Automatically disable examples self._set_option({'examples'}, None) + if self.config.variants.noassert and 'b_ndebug' not in self.meson_options: + self.meson_options['b_ndebug'] = 'true' + # NOTE: self.tagged_for_release is set in recipes/custom.py is_gstreamer_recipe = hasattr(self, 'tagged_for_release') - # Enable -Werror for gstreamer recipes and when running under CI - if is_gstreamer_recipe and self.config.variants.werror: - # Let recipes override the value - if 'werror' not in self.meson_options: + if is_gstreamer_recipe: + # Enable -Werror for gstreamer recipes and when running under CI but let recipes override the value + if self.config.variants.werror and 'werror' not in self.meson_options: self.meson_options['werror'] = 'true' + if 'glib_assert' not in self.meson_options: + self._set_option({'glib_assert'}, 'assert') + + if 'glib_checks' not in self.meson_options: + self._set_option({'glib_checks'}, 'checks') + debug = 'true' if self.config.variants.debug else 'false' opt = get_optimization_from_config(self.config) if self.library_type == LibraryType.NONE: - raise RuntimeException("meson recipes cannot be LibraryType.NONE") - - meson_cmd = [self.meson_sh, 'setup', '--prefix=' + self.config.prefix, - '--libdir=lib' + self.config.lib_suffix, '-Ddebug=' + debug, - '--default-library=' + self.library_type, '-Doptimization=' + opt, - '--backend=' + self.meson_backend, '--wrap-mode=nodownload', - '-Dpkgconfig.relocatable=true'] + raise RuntimeError('meson recipes cannot be LibraryType.NONE') + + meson_cmd = [ + self.meson_sh, + 'setup', + '--prefix=' + self.config.prefix, + '--libdir=' + self.config.rel_libdir, + '-Ddebug=' + debug, + '--default-library=' + self.library_type, + '-Doptimization=' + opt, + '--backend=' + self.meson_backend, + '--wrap-mode=nodownload', + '-Dpkgconfig.relocatable=true', + ] if self.using_msvc(): meson_cmd.append('-Db_vscrt=' + self.config.variants.vscrt) @@ -1138,7 +1213,7 @@ async def configure(self): if 'default_library' in self.meson_options: raise RuntimeError('Do not set `default_library` in self.meson_options, use self.library_type instead') - for (key, value) in self.meson_options.items(): + for key, value in self.meson_options.items(): meson_cmd += ['-D%s=%s' % (key, str(value))] # We export the target toolchain with env vars, but that confuses Meson @@ -1175,11 +1250,12 @@ def check(self): class Cargo(Build, ModifyEnvBase): - ''' + """ Cargo build system recipes NOTE: Currently only intended for build-tools recipes - ''' + """ + srcdir = '.' can_msvc = True cargo_features = None @@ -1196,11 +1272,9 @@ def __init__(self): if not self.using_msvc(): self.setup_buildtype_env_ops() - self.config_src_dir = os.path.abspath(os.path.join(self.build_dir, - self.srcdir)) + self.config_src_dir = os.path.abspath(os.path.join(self.build_dir, self.srcdir)) self.cargo_dir = os.path.join(self.config_src_dir, 'b') - self.cargo = os.path.join(self.config.cargo_home, 'bin', - 'cargo' + self.config._get_exe_suffix()) + self.cargo = os.path.join(self.config.cargo_home, 'bin', 'cargo' + self.config._get_exe_suffix()) # Debuginfo is enormous, about 0.5GB per plugin, so it's split out # where enabled by default (macOS and MSVC) and stripped everywhere @@ -1213,15 +1287,19 @@ def __init__(self): else: self.rustc_debuginfo = 'strip' try: - self.target_triple = self.config.rust_triple(self.config.target_arch, - self.config.target_platform, self.using_msvc()) + self.target_triple = self.config.rust_triple( + self.config.target_arch, self.config.target_platform, self.using_msvc() + ) except FatalError as e: raise InvalidRecipeError(self.name, e.msg) self.cargo_args = [ - '--verbose', '--offline', - '--target', self.target_triple, - '--target-dir', self.cargo_dir, + '--verbose', + '--offline', + '--target', + self.target_triple, + '--target-dir', + self.cargo_dir, ] jobs = self.num_of_cpus() @@ -1253,19 +1331,15 @@ def append_config_toml(self, s): f.write(s) def get_llvm_tool(self, tool: str) -> Path: - ''' + """ Gets one of the LLVM tools matching the current Rust toolchain. - ''' - root_dir = shell.check_output( - ["rustc", "--print", "sysroot"], env=self.env - ).strip() + """ + root_dir = shell.check_output(['rustc', '--print', 'sysroot'], env=self.env).strip() - tools = list(Path(root_dir).glob(f"**/{tool}")) + tools = list(Path(root_dir).glob(f'**/{tool}')) if len(tools) == 0: - raise FatalError( - f"Rust {tool} tool not found at {root_dir}, try re-running bootstrap" - ) + raise FatalError(f'Rust {tool} tool not found at {root_dir}, try re-running bootstrap') return tools[0] def get_cargo_toml_version(self): @@ -1295,6 +1369,10 @@ async def configure(self): s = '\n[profile.release]\nsplit-debuginfo = "packed"\n' self.append_config_toml(s) + if self.using_msvc() and self.library_type != LibraryType.SHARED: + # Trim codegen units to aid in prelinking + self.append_config_toml('codegen-units = 1\n') + if self.config.target_platform == Platform.ANDROID: # Use the compiler's forwarding # See https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md#linkers @@ -1303,10 +1381,8 @@ async def configure(self): # We need to extract necessary linker flags from LDFLAGS which is # passed to the compiler for arg in shlex.split(self.get_env('LDFLAGS', '')): - link_args += ['-C', f"link-arg={arg}"] - s = f'[target.{self.target_triple}]\n' \ - f'linker = "{linker}"\n' \ - f'rustflags = {link_args!r}\n' + link_args += ['-C', f'link-arg={arg}'] + s = f'[target.{self.target_triple}]\n' f'linker = "{linker}"\n' f'rustflags = {link_args!r}\n' self.append_config_toml(s) # No configure step with cargo @@ -1320,33 +1396,59 @@ async def compile(self): async def install(self): self.maybe_add_system_libs(step='configure+install') cmd = [ - self.cargo, 'install', - '--path', self.config_src_dir, - '--root', self.config.prefix, + self.cargo, + 'install', + '--path', + self.config_src_dir, + '--root', + self.config.prefix, ] + self.get_cargo_args() await self.retry_run(shell.async_call, cmd, logfile=self.logfile, env=self.env) class CargoC(Cargo): - ''' + """ Cargo-C build system recipes - ''' + """ + srcdir = '.' def __init__(self): Cargo.__init__(self) + # cargo-c ignores config.toml's rustflags, which are necessary for i386 + # cross-build + self.target_triple = self.config.rust_triple( + self.config.target_arch, self.config.target_platform, self.using_msvc() + ) + if self.target_triple == 'i686-pc-windows-gnu': + tgt = self.target_triple.upper().replace('-', '_') + self.set_env(f'CARGO_TARGET_{tgt}_LINKER', self.get_env('RUSTC_LINKER')) + link_args = [] + for arg in shlex.split(self.get_env('RUSTC_LDFLAGS')): + link_args += ['-C', f'link-arg={arg}'] + self.set_env('RUSTFLAGS', ' '.join(link_args)) + def get_cargoc_args(self): cargoc_args = [ - '--release', '--frozen', - '--prefix', self.config.prefix, - '--libdir', self.config.libdir, + '--release', + '--frozen', + '--prefix', + self.config.prefix, + '--libdir', + self.config.libdir, ] # --library-type args do not override, but are collected if self.library_type in (LibraryType.STATIC, LibraryType.BOTH): cargoc_args += ['--library-type', 'staticlib'] if self.library_type in (LibraryType.SHARED, LibraryType.BOTH): cargoc_args += ['--library-type', 'cdylib'] + + if self.config.variants.noassert: + cargoc_args += ['--config', 'debug-assertions=false'] + if self.config.variants.nochecks: + cargoc_args += ['--config', 'overflow-checks=false'] + cargoc_args += self.get_cargo_args() return cargoc_args @@ -1363,8 +1465,7 @@ async def install(self): await self.retry_run(shell.async_call, cmd, self.cargo_dir, logfile=self.logfile, env=self.env) -class BuildType (object): - +class BuildType(object): CUSTOM = CustomBuild MAKEFILE = Makefile AUTOTOOLS = Autotools diff --git a/cerbero/build/cookbook.py b/cerbero/build/cookbook.py index 7ce5249a4..9b06c8b65 100644 --- a/cerbero/build/cookbook.py +++ b/cerbero/build/cookbook.py @@ -22,8 +22,7 @@ import time import traceback -from cerbero.config import USER_CONFIG_DIR, Platform, Architecture, Distro,\ - DistroVersion, License, LibraryType +from cerbero.config import USER_CONFIG_DIR, Platform, Architecture, Distro, DistroVersion, License, LibraryType from cerbero.build.build import BuildType from cerbero.build.source import SourceType from cerbero.errors import FatalError, RecipeNotFoundError, InvalidRecipeError @@ -37,8 +36,8 @@ USER_COOKBOOK_FILE = os.path.join(USER_CONFIG_DIR, COOKBOOK_NAME) -class RecipeStatus (object): - ''' +class RecipeStatus(object): + """ Stores the current build status of a L{cerbero.recipe.Recipe} @ivar steps: list of steps currently done @@ -55,11 +54,10 @@ class RecipeStatus (object): @type built_version: str @ivar file_hash: hash of the file with the recipe description @type file_hash: int - ''' + """ - def __init__(self, filepath, steps=[], needs_build=True, - mtime=time.time(), built_version='', file_hash=0): - self.steps = steps + def __init__(self, filepath, steps=None, needs_build=True, mtime=time.time(), built_version='', file_hash=0): + self.steps = [] if steps is None else steps self.needs_build = needs_build self.mtime = mtime self.filepath = filepath @@ -67,16 +65,22 @@ def __init__(self, filepath, steps=[], needs_build=True, self.file_hash = file_hash def touch(self): - ''' Touches the recipe updating its modification time ''' + """Touches the recipe updating its modification time""" self.mtime = time.time() def __repr__(self): - return "steps: %r, needs_build: %r, mtime: %r, filepath: %r, built_version: %r, file_hash: %r" % \ - (self.steps, self.needs_build, self.mtime, self.filepath, self.built_version, self.file_hash.hex()) - - -class CookBook (object): - ''' + return 'steps: %r, needs_build: %r, mtime: %r, filepath: %r, built_version: %r, file_hash: %r' % ( + self.steps, + self.needs_build, + self.mtime, + self.filepath, + self.built_version, + self.file_hash.hex(), + ) + + +class CookBook(object): + """ Stores a list of recipes and their build status saving it's state to a cache file @@ -84,15 +88,15 @@ class CookBook (object): @type recipes: dict @ivar status: dictionary with the L{cerbero.cookbook.RecipeStatus} @type status: dict - ''' + """ RECIPE_EXT = '.recipe' - def __init__(self, config, load=True, offline=False, skip_errors=False): + def __init__(self, config, load=True, offline=False, skip_errors=False, reset_status=True): self.offline = offline self.set_config(config) self.recipes = {} # recipe_name -> recipe - self._invalid_recipes = {} # recipe -> error + self._invalid_recipes = {} # recipe -> error self._mtimes = {} if not load: @@ -101,75 +105,74 @@ def __init__(self, config, load=True, offline=False, skip_errors=False): self._restore_cache() if not os.path.exists(config.recipes_dir): - raise FatalError(_("Recipes dir %s not found") % - config.recipes_dir) - self.update(skip_errors) + raise FatalError(_('Recipes dir %s not found') % config.recipes_dir) + self.update(skip_errors, reset_status) def set_config(self, config): - ''' + """ Set the configuration used @param config: configuration used @type config: L{cerbero.config.Config} - ''' + """ self._config = config config.cookbook = self for c in config.arch_config.keys(): config.arch_config[c].cookbook = self def get_config(self): - ''' + """ Gets the configuration used @return: current configuration @rtype: L{cerbero.config.Config} - ''' + """ return self._config def set_status(self, status): - ''' + """ Sets the recipes status @param status: the recipes status @rtype: dict - ''' + """ self.status = status - def update(self, skip_errors): - ''' + def update(self, skip_errors, reset_status): + """ Reloads the recipes list and updates the cookbook - ''' - self._load_recipes(skip_errors) + """ + self._load_recipes(skip_errors, reset_status) self._load_manifest() self.save() def get_recipes_list(self): - ''' + """ Gets the list of recipes @return: list of recipes @rtype: list - ''' + """ recipes = list(self.recipes.values()) recipes.sort(key=lambda x: x.name) return recipes def add_recipe(self, recipe): - ''' + """ Adds a new recipe to the cookbook @param recipe: the recipe to add @type recipe: L{cerbero.build.cookbook.Recipe} - ''' + """ self.recipes[recipe.name] = recipe def get_recipe(self, name): - ''' + """ Gets a recipe from its name @param name: name of the recipe @type name: str - ''' + """ if name not in self.recipes: if name in self._invalid_recipes: raise self._invalid_recipes[name] @@ -177,14 +180,14 @@ def get_recipe(self, name): return self.recipes[name] def update_step_status(self, recipe_name, step): - ''' + """ Updates the status of a recipe's step @param recipe_name: name of the recipe @type recipe: str @param step: name of the step @type step: str - ''' + """ status = self._recipe_status(recipe_name) status.steps.append(step) status.touch() @@ -192,68 +195,68 @@ def update_step_status(self, recipe_name, step): self.save() def update_build_status(self, recipe_name, built_version): - ''' + """ Updates the recipe's build status @param recipe_name: name of the recipe @type recipe_name: str @param built_version: built version or None to reset it @type built_version: str - ''' + """ status = self._recipe_status(recipe_name) - status.needs_build = built_version == None + status.needs_build = built_version is None status.built_version = built_version status.touch() self.status[recipe_name] = status self.save() - def recipe_built_version (self, recipe_name): - ''' + def recipe_built_version(self, recipe_name): + """ Get the las built version of a recipe from the build status @param recipe_name: name of the recipe @type recipe_name: str - ''' + """ try: return self._recipe_status(recipe_name).built_version - except: + except Exception: return None def step_done(self, recipe_name, step): - ''' + """ Whether is step is done or not @param recipe_name: name of the recipe @type recipe_name: str @param step: name of the step @type step: bool - ''' + """ return step in self._recipe_status(recipe_name).steps def reset_recipe_status(self, recipe_name): - ''' + """ Resets the build status of a recipe @param recipe_name: name of the recipe @type recipe_name: str - ''' + """ if recipe_name in self.status: del self.status[recipe_name] self.save() def recipe_needs_build(self, recipe_name): - ''' + """ Whether a recipe needs to be build or not @param recipe_name: name of the recipe @type recipe_name: str @return: True if the recipe needs to be build @rtype: bool - ''' + """ return self._recipe_status(recipe_name).needs_build def list_recipe_deps(self, recipe_name): - ''' + """ List the dependencies that needs to be built in the correct build order for a recipe @@ -261,24 +264,24 @@ def list_recipe_deps(self, recipe_name): @type recipe_name: str @return: list of L{cerbero.recipe.Recipe} @rtype: list - ''' + """ recipe = self.get_recipe(recipe_name) return self._find_deps(recipe, {}, []) def list_recipe_reverse_deps(self, recipe_name): - ''' + """ List the dependencies that depends on this recipe @param recipe_name: name of the recipe @type recipe_name: str @return: list of reverse dependencies L{cerbero.recipe.Recipe} @rtype: list - ''' + """ recipe = self.get_recipe(recipe_name) return [r for r in list(self.recipes.values()) if recipe.name in r.deps] - def get_closest_recipe (self, name): - ''' + def get_closest_recipe(self, name): + """ Gets the closest recipe name from name in the cookbook if only one recipe name matches. @@ -287,7 +290,7 @@ def get_closest_recipe (self, name): @type recipe_name: str @return: the closest recipe name @rtype: str - ''' + """ # If there's an exact match, just return it if name in self.recipes: return name @@ -301,11 +304,11 @@ def get_closest_recipe (self, name): recipe_name = r if recipe_name: - m.message("Found a recipe %s matching name %s" % (recipe_name, name)) + m.message('Found a recipe %s matching name %s' % (recipe_name, name)) return recipe_name - def _runtime_deps (self): + def _runtime_deps(self): return [x.name for x in list(self.recipes.values()) if x.runtime_dep] def _cache_file(self, config): @@ -324,7 +327,7 @@ def _restore_cache(self): with open(cachefile, 'rb') as f: self.status = pickle.load(f) except Exception: - m.warning(_("Could not recover status")) + m.warning(_('Could not recover status')) def save(self): try: @@ -334,23 +337,26 @@ def save(self): with open(cache_file, 'wb') as f: pickle.dump(self.status, f) except IOError as ex: - m.warning(_("Could not cache the CookBook: %s") % ex) + m.warning(_('Could not cache the CookBook: %s') % ex) - def _find_deps(self, recipe, state={}, ordered=[]): + def _find_deps(self, recipe, state=None, ordered=None): + if state is None: + state = {} + if ordered is None: + ordered = [] if state.get(recipe, 'clean') == 'processed': return if state.get(recipe, 'clean') == 'in-progress': - raise FatalError(_("Dependency Cycle: {0}".format(recipe.name))) + raise FatalError(_('Dependency Cycle: {0}'.format(recipe.name))) state[recipe] = 'in-progress' recipe_deps = recipe.list_deps() if not recipe.runtime_dep: - recipe_deps = self._runtime_deps () + recipe_deps + recipe_deps = self._runtime_deps() + recipe_deps for recipe_name in recipe_deps: try: recipedep = self.get_recipe(recipe_name) - except RecipeNotFoundError as e: - raise FatalError(_("Recipe %s has a unknown dependency %s" - % (recipe.name, recipe_name))) + except RecipeNotFoundError: + raise FatalError(_('Recipe %s has a unknown dependency %s' % (recipe.name, recipe_name))) try: self._find_deps(recipedep, state, ordered) except FatalError: @@ -366,19 +372,30 @@ def _recipe_status(self, recipe_name): filepath = None if hasattr(recipe, '__file__'): filepath = recipe.__file__ - self.status[recipe_name] = RecipeStatus(filepath, steps=[], - file_hash=recipe.get_checksum()) + self.status[recipe_name] = RecipeStatus(filepath, steps=[], file_hash=recipe.get_checksum()) return self.status[recipe_name] - def _load_recipes(self, skip_errors): + def _load_recipes(self, skip_errors, reset_status): self.recipes = {} recipes = defaultdict(dict) recipes_repos = self._config.get_recipes_repos() for reponame, (repodir, priority) in recipes_repos.items(): - recipes[int(priority)].update(self._load_recipes_from_dir(repodir, skip_errors)) + new_recipes = self._load_recipes_from_dir(repodir, skip_errors) + priority_recipes = recipes[int(priority)] + overridden = set(new_recipes) & set(priority_recipes) + if overridden: + m.warning(f'Overriding recipes during repo {reponame} ({repodir}, {priority}): {overridden}') + priority_recipes.update(new_recipes) # Add recipes by asceding pripority for key in sorted(recipes.keys()): - self.recipes.update(recipes[key]) + new_recipes = recipes[key] + overridden = set(new_recipes) & set(self.recipes) + if overridden: + m.warning(f'Overriding recipes during priority {key}: {overridden}') + self.recipes.update(new_recipes) + + if not reset_status: + return # Check for updates in the recipe file to reset the status for recipe in list(self.recipes.values()): @@ -395,7 +412,7 @@ def _load_recipes(self, skip_errors): # allow safe relocation of the recipes. if recipe.__file__ != st.filepath: st.filepath = recipe.__file__ - st.mtime = 0; + st.mtime = 0 # Need to check the version too, because the version can be # inherited from a different file, f.ex. recipes/custom.py if recipe.built_version() != st.built_version: @@ -434,44 +451,53 @@ def _load_recipes_from_dir(self, repo, skip_errors): try: recipes_from_file = self._load_recipes_from_file(f, skip_errors, custom) except RecipeNotFoundError: - m.warning(_("Could not found a valid recipe in %s") % f) + m.warning(_('Could not found a valid recipe in %s') % f) if recipes_from_file is None: continue for recipe in recipes_from_file: + if recipe.name in recipes: + m.warning(f'Overriding {recipes[recipe.name]} by {recipe} from {f}') recipes[recipe.name] = recipe return recipes def _load_recipes_from_file(self, filepath, skip_errors, custom): recipes = [] - d = {'Platform': Platform, 'Architecture': Architecture, - 'BuildType': BuildType, 'SourceType': SourceType, - 'Distro': Distro, 'DistroVersion': DistroVersion, - 'License': License, 'recipe': crecipe, 'os': os, - 'BuildSteps': crecipe.BuildSteps, - 'InvalidRecipeError': InvalidRecipeError, - 'FatalError': FatalError, - 'custom': custom, '_': _, 'shell': shell, - 'LibraryType' : LibraryType} + d = { + 'Platform': Platform, + 'Architecture': Architecture, + 'BuildType': BuildType, + 'SourceType': SourceType, + 'Distro': Distro, + 'DistroVersion': DistroVersion, + 'License': License, + 'recipe': crecipe, + 'os': os, + 'BuildSteps': crecipe.BuildSteps, + 'InvalidRecipeError': InvalidRecipeError, + 'FatalError': FatalError, + 'custom': custom, + '_': _, + 'shell': shell, + 'LibraryType': LibraryType, + } d_keys = set(list(d.keys())) try: - new_d = d.copy () + new_d = d.copy() parse_file(filepath, new_d) # List new objects parsed added to the globals dict diff_keys = [x for x in set(new_d.keys()) - d_keys] # Find all objects inheriting from Recipe for recipe_cls_key in [x for x in diff_keys if self._is_recipe_class(new_d[x])]: if self._config.target_arch != Architecture.UNIVERSAL: - recipe = self._load_recipe_from_class( - new_d[recipe_cls_key], self._config, filepath) + recipe = self._load_recipe_from_class(new_d[recipe_cls_key], self._config, filepath) else: - recipe = self._load_universal_recipe(d, new_d[recipe_cls_key], - recipe_cls_key, filepath) + recipe = self._load_universal_recipe(d, new_d[recipe_cls_key], recipe_cls_key, filepath) if recipe is not None: recipes.append(recipe) except Exception: if not skip_errors: - m.warning("Error loading recipe in file %s" % (filepath)) + m.warning('Error loading recipe in file %s' % (filepath)) print(traceback.format_exc()) return recipes @@ -479,9 +505,7 @@ def _is_recipe_class(self, cls): # The final check for 'builtins' is to make sure we only take in # account classes defined in the recipe file and not the imported # ones in the, for example base classes that inherit from Recipe - return isinstance(cls, type) and \ - issubclass (cls, crecipe.Recipe) and \ - cls.__module__ == 'builtins' + return isinstance(cls, type) and issubclass(cls, crecipe.Recipe) and cls.__module__ == 'builtins' def _load_recipe_from_class(self, recipe_cls, config, filepath): try: @@ -493,15 +517,13 @@ def _load_recipe_from_class(self, recipe_cls, config, filepath): except InvalidRecipeError as e: self._invalid_recipes[recipe_cls.name] = e - def _load_universal_recipe(self, globals_dict, recipe_cls, - recipe_cls_key, filepath, custom=None): + def _load_universal_recipe(self, globals_dict, recipe_cls, recipe_cls_key, filepath, custom=None): if self._config.target_platform in [Platform.IOS, Platform.DARWIN]: - recipe = crecipe.UniversalFlatRecipe(self._config) + recipe = crecipe.UniversalMergedRecipe(self._config) else: recipe = crecipe.UniversalRecipe(self._config) for c in list(self._config.arch_config.keys()): conf = self._config.arch_config[c] - conf.prefix = os.path.join(self._config.prefix, c) # For univeral recipes, we need to parse again the recipe file. # Otherwise, class variables with mutable types like the "deps" # dictionary are reused in new instances @@ -521,19 +543,17 @@ def _load_manifest(self): manifest_path = self._config.manifest if not manifest_path: - return + return manifest = Manifest(manifest_path) manifest.parse() for project in manifest.projects.values(): for recipe in self.recipes.values(): - if recipe.stype not in [SourceType.GIT, - SourceType.GIT_TARBALL]: - continue; + if recipe.stype not in [SourceType.GIT, SourceType.GIT_TARBALL]: + continue default_fetch = manifest.get_fetch_uri(project, manifest.default_remote) - if recipe.remotes['origin'] in [default_fetch, - default_fetch[:-4]]: + if recipe.remotes['origin'] in [default_fetch, default_fetch[:-4]]: recipe.remotes['origin'] = project.fetch_uri recipe.commit = project.revision diff --git a/cerbero/build/filesprovider.py b/cerbero/build/filesprovider.py index f9ae30373..0e2c4b241 100644 --- a/cerbero/build/filesprovider.py +++ b/cerbero/build/filesprovider.py @@ -24,7 +24,7 @@ from functools import partial import shlex from pathlib import Path -import sysconfig +from typing import Optional, List from cerbero.config import Platform, LibraryType from cerbero.utils import shell @@ -32,6 +32,7 @@ from cerbero.errors import FatalError from cerbero.build.build import BuildType + def find_shlib_regex(config, libname, prefix, libdir, ext, regex): # Use globbing to find all files that look like they might match # this library to narrow down our exact search @@ -46,6 +47,7 @@ def find_shlib_regex(config, libname, prefix, libdir, ext, regex): matches.append(os.path.join(libdir, fname)) return matches + def get_implib_dllname(config, path): if config.msvc_env_for_toolchain and path.endswith('.lib'): lib_exe = shutil.which('lib', path=config.msvc_env_for_toolchain['PATH'].get()) @@ -65,6 +67,7 @@ def get_implib_dllname(config, path): except FatalError: return 0 + def find_dll_implib(config, libname, prefix, libdir, ext, regex): implibdir = 'lib' implibs = ['lib{}.dll.a'.format(libname), libname + '.lib', 'lib{}.lib'.format(libname)] @@ -89,13 +92,14 @@ def find_dll_implib(config, libname, prefix, libdir, ext, regex): if os.path.exists(path): return [os.path.join(libdir, dllname)] if len(implib_notfound) == len(implibs): - m.warning("No import libraries found for {!r}".format(libname)) + m.warning('No import libraries found for {!r}'.format(libname)) else: implibs = ', '.join(set(implibs) - set(implib_notfound)) - m.warning("No dllname found from implibs: {}".format(implibs)) - # This will trigger an error in _search_libraries() + m.warning('No dllname found from implibs: {}'.format(implibs)) + # This will trigger an error in _list_libraries() return [] + def find_pdb_implib(config, libname, prefix): dlls = find_dll_implib(config, libname, prefix, 'bin', None, None) pdbs = [] @@ -105,11 +109,12 @@ def find_pdb_implib(config, libname, prefix): pdbs.append(pdb) return pdbs + class FilesProvider(object): - ''' + """ List files by categories using class attributes named files_$category and platform_files_$category - ''' + """ LIBS_CAT = 'libs' BINS_CAT = 'bins' @@ -140,16 +145,47 @@ class FilesProvider(object): # pext = python module extension (.pyd on Windows) # libdir = relative libdir path (lib, lib64, lib/i386-linux-gnu) EXTENSIONS = { - Platform.WINDOWS: {'bext': '.exe', 'sregex': _DLL_REGEX, - 'mext': '.dll', 'smext': '.a', 'pext': '.pyd', 'srext': '.dll'}, - Platform.LINUX: {'bext': '', 'sregex': _LINUX_SO_REGEX, - 'mext': '.so', 'smext': '.a', 'pext': '.so', 'srext': '.so'}, - Platform.ANDROID: {'bext': '', 'sregex': _ANDROID_SO_REGEX, - 'mext': '.so', 'smext': '.a', 'pext': '.so', 'srext': '.so'}, - Platform.DARWIN: {'bext': '', 'sregex': _DYLIB_REGEX, - 'mext': '.so', 'smext': '.a', 'pext': '.so', 'srext': '.dylib'}, - Platform.IOS: {'bext': '', 'sregex': _DYLIB_REGEX, - 'mext': '.so', 'smext': '.a', 'pext': '.so', 'srext': '.dylib'}} + Platform.WINDOWS: { + 'bext': '.exe', + 'sregex': _DLL_REGEX, + 'mext': '.dll', + 'smext': '.a', + 'pext': '.pyd', + 'srext': '.dll', + }, + Platform.LINUX: { + 'bext': '', + 'sregex': _LINUX_SO_REGEX, + 'mext': '.so', + 'smext': '.a', + 'pext': '.so', + 'srext': '.so', + }, + Platform.ANDROID: { + 'bext': '', + 'sregex': _ANDROID_SO_REGEX, + 'mext': '.so', + 'smext': '.a', + 'pext': '.so', + 'srext': '.so', + }, + Platform.DARWIN: { + 'bext': '', + 'sregex': _DYLIB_REGEX, + 'mext': '.so', + 'smext': '.a', + 'pext': '.so', + 'srext': '.dylib', + }, + Platform.IOS: { + 'bext': '', + 'sregex': _DYLIB_REGEX, + 'mext': '.so', + 'smext': '.a', + 'pext': '.so', + 'srext': '.dylib', + }, + } # Match static gstreamer plugins, GIO modules, etc. _FILES_STATIC_PLUGIN_REGEX = re.compile(r'lib/.+/lib(gst|)([^/.]+)\.a') @@ -158,7 +194,8 @@ def __init__(self, config): self.config = config self.platform = config.target_platform self.extensions = self.EXTENSIONS[self.platform].copy() - self.extensions['pydir'] = config.py_prefix + self.extensions['pydir'] = str(config.get_python_prefix()) + self.extensions['pext'] = config.get_python_ext_suffix() self.extensions['pyplatdir'] = config.py_plat_prefix self.extensions['libdir'] = self.config.rel_libdir if self.platform == Platform.WINDOWS: @@ -167,16 +204,82 @@ def __init__(self, config): self.extensions['sdir'] = self.extensions['libdir'] if self._dylib_plugins(): self.extensions['mext'] = '.dylib' + self._findlibfunc = None + if self.extensions['sregex']: + self._findlibfunc = find_shlib_regex + elif self.config.target_platform == Platform.WINDOWS: + self._findlibfunc = find_dll_implib + else: + raise AssertionError self.py_prefixes = config.py_prefixes self.add_files_bins_devel() self.add_license_files() self.update_categories() - self._searchfuncs = {self.LIBS_CAT: self._search_libraries, - self.BINS_CAT: self._search_binaries, - self.PY_CAT: self._search_pyfiles, - self.LANG_CAT: self._search_langfiles, - self.TYPELIB_CAT: self._search_typelibfiles, - 'default': self._search_files} + self._listfuncs = { + self.LIBS_CAT: self._list_libraries, + self.BINS_CAT: self._list_binaries, + self.PY_CAT: self._list_pyfiles, + self.LANG_CAT: self._list_langfiles, + self.TYPELIB_CAT: self._list_typelibfiles, + 'default': self._list_files, + } + + def _search_file(self, file): + """ + Search for arbitrary files doing the extension replacements, globbing, and listing + directories + """ + # fill directories + if os.path.isdir(os.path.join(self.config.prefix, file)): + found = self._ls_dir(os.path.join(self.config.prefix, file)) + else: + found = shell.ls_files([file], self.config.prefix) + return found + + def _search_library(self, file): + """ + Search libraries in the prefix. Unfortunately the filename might vary + depending on the platform and we need to match the library name and + it's extension. There is a corner case on windows where the DLL might + have any name, so we search for the .lib or .dll.a import library + and get the DLL name from that. + """ + libdir = self.extensions['sdir'] + libext = self.extensions['srext'] + libregex = self.extensions['sregex'] + f = os.path.basename(file) + # Extract the libname again. This might be redundant, but it is done + # like this to avoid changing all the library search implementations + pattern = r'\*?(?P[^\*]*)\*?{}\*?'.format(libext) + m = re.match(pattern, f) + f = m.group('libname') + libsmatch = self._findlibfunc(self.config, f[3:], self.config.prefix, libdir, libext, libregex) + return libsmatch + + def _search_library_pdb(self, file): + f = os.path.basename(file) + pdbs = find_pdb_implib(self.config, f[:-4], self.config.prefix) + return pdbs + + def _validate_existing(self, files, only_existing=True): + if not only_existing: + nonvalidated = [] + for each in files: + nonvalidated.append(each) + return nonvalidated + + # Validate all the files with the ones in the prefix + vfs = [] + for f, searchfunc in files.items(): + if not searchfunc: + searchfunc = self._search_file + validated = searchfunc(f) + # Warn about missing files + if not validated: + m.warning('Missing on-disk files for {} with search function {}'.format(f, searchfunc.__name__)) + else: + vfs.extend(validated) + return vfs def _dylib_plugins(self): if self.btype not in (BuildType.MESON, BuildType.CARGO_C): @@ -202,21 +305,21 @@ def have_pdbs(self): return True def add_license_files(self): - ''' + """ Ensure that all license files are packaged - ''' + """ if not hasattr(self, 'files_devel'): self.files_devel = [] if self.licenses or getattr(self, 'licenses_bins', None): self.files_devel.append('share/licenses/{}'.format(self.name)) def add_files_bins_devel(self): - ''' + """ When a recipe is built with MSVC, all binaries have a corresponding .pdb file that must be included in the devel package. This files list is identical to `self.files_bins`, so we duplicate it here into a devel category. It will get included via the 'default' search function. - ''' + """ if not self.have_pdbs(): return pdbs = [] @@ -230,62 +333,75 @@ def add_files_bins_devel(self): self.files_bins_devel = [] self.files_bins_devel += pdbs - def devel_files_list(self): - ''' + def devel_files_list(self, only_existing=True): + """ Return the list of development files, which consists in the files and directories listed in the 'devel' category and the link libraries .a, .la and .so from the 'libs' category - ''' - devfiles = self.files_list_by_category(self.DEVEL_CAT) - devfiles.extend(self._search_girfiles()) - devfiles.extend(self._search_devel_libraries()) - + """ + devfiles = {} + devfiles.update(self._list_files_by_category(self.DEVEL_CAT)) + devfiles.update(self._list_girfiles()) + devfiles.update(self._list_devel_libraries()) + devfiles = self._validate_existing(devfiles, only_existing) return sorted(list(set(devfiles))) - def dist_files_list(self): - ''' + def dist_files_list(self, only_existing=True): + """ Return the list of files that should be included in a distribution tarball, which include all files except the development files - ''' + """ - return self.files_list_by_categories( - [x for x in self.categories if not x.endswith(self.DEVEL_CAT)]) + distfiles = {} + for x in self.categories: + if x.endswith(self.DEVEL_CAT): + continue + distfiles.update(self._list_files_by_category(x)) + distfiles = self._validate_existing(distfiles, only_existing) + return sorted(list(set(distfiles))) - def files_list(self): - ''' + def files_list(self, only_existing=True): + """ Return the complete list of files - ''' - files = self.dist_files_list() - files.extend(self.devel_files_list()) + """ + files = self.dist_files_list(only_existing) + files.extend(self.devel_files_list(only_existing)) return sorted(list(set(files))) - def files_list_by_categories(self, categories): - ''' + def files_list_by_categories(self, categories, only_existing=True): + """ Return the list of files in a list categories - ''' - files = [] + """ + files = {} for cat in categories: cat_files = self._list_files_by_category(cat) - # The library search function returns a dict that is a mapping from - # library name to filenames, but we only want a list of filenames - if isinstance(cat_files, dict): - for each in cat_files.values(): - files.extend(each) - else: - files.extend(cat_files) + files.update(cat_files) + files = self._validate_existing(files, only_existing) return sorted(list(set(files))) - def files_list_by_category(self, category): - ''' + def files_list_by_category(self, category, only_existing=True): + """ Return the list of files in a given category - ''' - return self.files_list_by_categories([category]) + """ + return self.files_list_by_categories([category], only_existing) def libraries(self): - ''' + """ Return a dict of the library names and library paths - ''' - return self._list_files_by_category(self.LIBS_CAT) + """ + libraries = {} + files = self._list_files_by_category(self.LIBS_CAT) + for f, searchfunc in files.items(): + if not searchfunc: + searchfunc = self._search_file + start = len(self.extensions['sdir']) + 1 + 3 + end = len(self.extensions['srext']) + if self.extensions['sregex']: + start += 1 + end += 2 + libname = f[start:-end] + libraries[libname] = searchfunc(f) + return libraries def use_gobject_introspection(self): return self.TYPELIB_CAT in self._files_categories() @@ -294,7 +410,7 @@ def update_categories(self): self.categories = self._files_categories() def _files_categories(self): - ''' Get the list of categories available ''' + """Get the list of categories available""" categories = [] for name, value in inspect.getmembers(self): if not isinstance(value, (dict, list)): @@ -306,16 +422,15 @@ def _files_categories(self): return sorted(list(set(categories))) def _get_category_files_list(self, category): - ''' + """ Get the raw list of files in a category, without pattern match nor extensions replacement, which should be done in the search function - ''' + """ files = [] for attr in dir(self): if attr.startswith('files_') and attr.endswith('_' + category): files.extend(getattr(self, attr)) - if attr.startswith('platform_files_') and \ - attr.endswith('_' + category): + if attr.startswith('platform_files_') and attr.endswith('_' + category): files.extend(getattr(self, attr).get(self.platform, [])) return files @@ -323,21 +438,9 @@ def _list_files_by_category(self, category): search_category = category if category.startswith(self.LIBS_CAT + '_'): search_category = self.LIBS_CAT - search = self._searchfuncs.get(search_category, - self._searchfuncs['default']) + search = self._listfuncs.get(search_category, self._listfuncs['default']) return search(self._get_category_files_list(category)) - def _search_pdb_files(self, static_lib_f, name): - # Plugin DLLs are required to be foo.dll when the recipe uses MSVC, and - # will be in the same directory as the .a static plugin/library - fdir = os.path.dirname(static_lib_f) - fdll = '{}/{}.dll'.format(fdir, name) - if not (Path(self.config.prefix) / fdll).is_file(): - # XXX: Make this an error when we have MSVC CI - m.warning('static library {} does not have a corresponding dll?'.format(static_lib_f)) - return [] - return ['{}/{}.pdb'.format(fdir, name)] - @staticmethod def _get_msvc_dll(f): f = Path(f) @@ -348,14 +451,13 @@ def _get_plugin_pc(f): f = Path(f) return str(f.parent / 'pkgconfig' / (f.name[3:-3] + '.pc')) - def _search_files(self, files): - ''' - Search plugin files and arbitrary files in the prefix, doing the - extension replacements, globbing, and listing directories + def _list_files(self, files): + """ + List plugin files and arbitrary files in the prefix FIXME: Curently plugins are also searched using this, but there should be a separate system for those. - ''' + """ # replace extensions files_expanded = [] for f in files: @@ -363,12 +465,12 @@ def _search_files(self, files): if '%(mext)s' in f and self.library_type == LibraryType.STATIC: continue files_expanded.append(f % self.extensions) - fs = [] + fs = {} for f in files_expanded: if f.endswith('.dll') and self.using_msvc(): - fs.append(self._get_msvc_dll(f)) + fs[self._get_msvc_dll(f)] = None else: - fs.append(f) + fs[f] = None # Look for a PDB file and add it if self.have_pdbs(): # We try to find a pdb file corresponding to the plugin's .a @@ -376,162 +478,144 @@ def _search_files(self, files): # devel package, not the runtime package. m = self._FILES_STATIC_PLUGIN_REGEX.match(f) if m: - fs += self._search_pdb_files(f, ''.join(m.groups())) + # Plugin DLLs are required to be foo.dll when the recipe uses MSVC, and + # will be in the same directory as the .a static plugin/library + fdir = os.path.dirname(f) + pdb = '{}/{}.pdb'.format(fdir, ''.join(m.groups())) + fs[pdb] = None # For plugins, the .la file is generated using the .pc file, but we # don't add the .pc to files_devel. It has the same name, so we can # add it using the .la entry. - if f.startswith(self.extensions['libdir'] + '/gstreamer-1.0/') and f.endswith('.la'): - fs.append(self._get_plugin_pc(f)) - # fill directories - dirs = [x for x in fs if - os.path.isdir(os.path.join(self.config.prefix, x))] - for directory in dirs: - fs.remove(directory) - fs.extend(self._ls_dir(os.path.join(self.config.prefix, - directory))) - # fill paths with pattern expansion * - paths = [x for x in fs if '*' in x] - if len(paths) != 0: - for path in paths: - fs.remove(path) - fs.extend(shell.ls_files(paths, self.config.prefix)) + if ( + self.platform == Platform.ANDROID + and f.startswith(self.extensions['libdir'] + '/gstreamer-1.0/') + and f.endswith('.la') + ): + fs[self._get_plugin_pc(f)] = None + + # And suppress .la files + if self.platform != Platform.ANDROID: + fs = {k: v for k, v in fs.items() if not k.endswith('.la')} + return fs - def _search_binaries(self, files): - ''' - Search binaries in the prefix. This function doesn't do any real serach - like the others, it only preprend the bin/ path and add the binary + def _list_binaries(self, files): + """ + List binaries in the prefix. This function preprends the bin/ path and add the binary extension to the given list of files - ''' - binaries = [] + """ + binaries = {} for f in files: - self.extensions['file'] = f - binaries.append('bin/%(file)s%(bext)s' % self.extensions) + b = 'bin/%(file)s%(bext)s' % {'file': f, **self.extensions} + binaries[b] = None return binaries - def _search_libraries(self, files): - ''' - Search libraries in the prefix. Unfortunately the filename might vary - depending on the platform and we need to match the library name and - it's extension. There is a corner case on windows where the DLL might - have any name, so we search for the .lib or .dll.a import library - and get the DLL name from that. - - NOTE: Unlike other searchfuncs which return lists, this returns a dict - with a mapping from the libname to a list of actual on-disk - files. We use the libname (the key) in gen_library_file so we - don't have to guess (incorrectly) based on the dll filename. - ''' + def _list_libraries(self, files): if self.library_type == LibraryType.STATIC: return {} - libdir = self.extensions['sdir'] - libext = self.extensions['srext'] - libregex = self.extensions['sregex'] - if libregex: - find_func = find_shlib_regex - elif self.config.target_platform == Platform.WINDOWS: - find_func = find_dll_implib - else: - raise AssertionError - - libsmatch = {} - notfound = [] + libs = {} for f in files: - libsmatch[f] = find_func(self.config, f[3:], self.config.prefix, - libdir, libext, libregex) - if not libsmatch[f]: - notfound.append(f) - - if notfound: - msg = "Some libraries weren't found while searching!" - for each in notfound: - msg += '\n' + each - raise FatalError(msg) - return libsmatch + if self.extensions['sregex']: + pattern = '%(sdir)s/*%(file)s*%(srext)s*' + else: + pattern = '%(sdir)s/%(file)s%(srext)s' + pattern = pattern % {'file': f, **self.extensions} + libs[pattern] = self._search_library + return libs - def _pyfile_get_name(self, f): + def _pyfile_get_name(self, f) -> Optional[List[str]]: if os.path.exists(os.path.join(self.config.prefix, f)): - return f + return [f] for py_prefix in self.py_prefixes: + original_path = os.path.join(py_prefix, f) + if os.path.exists(os.path.join(self.config.prefix, original_path)): + return [original_path] + elif '*' in f: + fs = glob.glob(os.path.join(self.config.prefix, original_path), recursive=True) + if fs: + return [os.path.relpath(f, start=self.config.prefix) for f in fs] + elif os.path.isabs(f): + # A files_* entry is not made relative properly + raise RuntimeError(f'An absolute path "{f}"was supplied, please set relative paths only') + pydir = os.path.basename(os.path.normpath(py_prefix)) - pyversioname = re.sub(r"python|\.", '', pydir) - cpythonname = "cpython-" + pyversioname + pyversioname = re.sub(r'python|\.', '', pydir) + cpythonname = 'cpython-' + pyversioname splitedext = os.path.splitext(f) for ex in ['', 'm']: f = splitedext[0] + '.' + cpythonname + ex + splitedext[1] if os.path.exists(os.path.join(self.config.prefix, f)): - return f + return [f] return None def _pyfile_get_cached(self, f): pyfiles = [] - pycachedir = os.path.join(os.path.dirname(f), "__pycache__") + pycachedir = os.path.join(os.path.dirname(f), '__pycache__') for e in ['o', 'c']: fe = self._pyfile_get_name(f + e) if fe: pyfiles.append(fe) else: cached = os.path.join(pycachedir, os.path.basename(f)) - fe = self._pyfile_get_name(os.path.join(self.config.prefix, cached)) + fe = self._pyfile_get_name(cached) if fe: pyfiles.append(fe) return pyfiles - def _search_pyfiles(self, files): - ''' - Search for python files in the prefix. This function doesn't do any - real search, it only preprend the lib/Python$PYVERSION/site-packages/ - path to the given list of files - ''' - pyfiles = [] + def _list_pyfiles(self, files): + """ + List python files in the prefix. This function preprends the + lib/Python$PYVERSION/site-packages/ path to the given list of files + """ + pyfiles = {} files_exts = [f % self.extensions for f in files] - files = self._search_files (files_exts) + files = self._list_files(files_exts) for f in files: - real_name = self._pyfile_get_name(f) - if real_name: - pyfiles.append(real_name) + real_names = self._pyfile_get_name(f) + if real_names: + pyfiles.update({i: None for i in real_names}) else: # Adding it so we notice there is a problem in the recipe - pyfiles.append(f) + pyfiles[f] = None if f.endswith('.py'): cached_files = self._pyfile_get_cached(f) - pyfiles.extend(cached_files) + for cached_file in cached_files: + pyfiles[cached_file] = None return pyfiles - def _search_langfiles(self, files): - ''' - Search for translations in share/locale/*/LC_MESSAGES/ ' - ''' + def _list_langfiles(self, files): + """ + List translations in share/locale/*/LC_MESSAGES/ ' + """ pattern = 'share/locale/*/LC_MESSAGES/%s.mo' - return shell.ls_files([pattern % x for x in files], - self.config.prefix) - - def _search_typelibfiles(self, files): - ''' - Search for typelibs in lib/girepository-1.0/ - ''' + langfiles = {} + for x in files: + f = pattern % x + langfiles[f] = None + return langfiles + + def _list_typelibfiles(self, files): + """ + List typelibs in lib/girepository-1.0/ + """ if not self.config.variants.gi: - return [] + return {} pattern = '{}/girepository-1.0/%s.typelib'.format(self.extensions['libdir']) - typelibs = shell.ls_files([pattern % x for x in files], - self.config.prefix) - if not typelibs: - # Add the architecture for universal builds - pattern = '{}/{}/girepository-1.0/%s.typelib'\ - .format(self.extensions['libdir'], self.config.target_arch) - typelibs = shell.ls_files([pattern % x for x in files], - self.config.prefix) + typelibs = {} + for x in files: + file = pattern % x + typelibs[file] = None return typelibs - def _search_girfiles(self): - ''' - Search for gir files in share/gir-1.0/ - ''' + def _list_girfiles(self): + """ + List gir files in share/gir-1.0/ + """ if not self.config.variants.gi: - return [] + return {} girs = [] if hasattr(self, 'files_' + self.TYPELIB_CAT): @@ -540,53 +624,50 @@ def _search_girfiles(self): d = getattr(self, 'platform_files_' + self.TYPELIB_CAT) girs += d.get(self.config.target_platform, []) + files = {} # Use a * for the arch in universal builds pattern = 'share/gir-1.0/%s.gir' - files = shell.ls_files([pattern % x for x in girs], - self.config.prefix) - if not girs: - # Add the architecture for universal builds - pattern = 'share/gir-1.0/%s/%%s.gir' % \ - self.config.target_arch - files = shell.ls_files([pattern % x for x in girs], - self.config.prefix) + for gir in girs: + file = pattern % gir + files[file] = None return files - def _search_devel_libraries(self): + def _list_devel_libraries(self): if self.runtime_dep: - return [] + return {} - devel_libs = [] + devel_libs = {} for category in self.categories: - if category != self.LIBS_CAT and \ - not category.startswith(self.LIBS_CAT + '_'): + if category != self.LIBS_CAT and not category.startswith(self.LIBS_CAT + '_'): continue - pattern = '' - if self.library_type != LibraryType.NONE: - pattern += '%(libdir)s/%(f)s.la ' + patterns = [] + if self.library_type != LibraryType.NONE and self.platform == Platform.ANDROID: + patterns.append('%(libdir)s/%(f)s.la') if self.library_type in (LibraryType.BOTH, LibraryType.STATIC): - pattern += '%(libdir)s/%(f)s.a ' + patterns.append('%(libdir)s/%(f)s.a') if self.library_type in (LibraryType.BOTH, LibraryType.SHARED): if self.platform == Platform.LINUX: - pattern += '%(libdir)s/%(f)s.so ' + patterns.append('%(libdir)s/%(f)s.so') elif self.platform == Platform.WINDOWS: - pattern += '%(libdir)s/%(f)s.dll.a ' - pattern += '%(libdir)s/%(f)s.def ' - pattern += '%(libdir)s/%(fnolib)s.lib ' + patterns.append('%(libdir)s/%(f)s.dll.a') + patterns.append('%(libdir)s/%(fnolib)s.def') + patterns.append('%(libdir)s/%(fnolib)s.lib') elif self.platform in [Platform.DARWIN, Platform.IOS]: - pattern += '%(libdir)s/%(f)s.dylib ' + patterns.append('%(libdir)s/%(f)s.dylib') - libsmatch = [] for x in self._get_category_files_list(category): - libsmatch.append(pattern % {'f': x, 'fnolib': x[3:], 'libdir': self.extensions['libdir']}) + for pattern in patterns: + file = pattern % {'f': x, 'fnolib': x[3:], 'libdir': self.extensions['libdir']} + devel_libs[file] = None # PDB names are derived from DLL library names (which are # arbitrary), so we must use the same search function for them. if self.have_pdbs(): - devel_libs += find_pdb_implib(self.config, x[3:], self.config.prefix) - devel_libs.extend(shell.ls_files(libsmatch, self.config.prefix)) + pdb = '%(sdir)s/%(f)s.pdb' % {'f': x[3:], **self.extensions} + devel_libs[pdb] = self._search_library_pdb + return devel_libs def _ls_dir(self, dirpath): @@ -600,67 +681,37 @@ def _ls_dir(self, dirpath): class UniversalFilesProvider(FilesProvider): + wrapped_list_funcs = ['devel_files_list', 'dist_files_list', 'files_list_by_categories'] def __init__(self, config): - # Override all search functions with an aggregating search function. + # Override all public functions that return a list of files. for name in dir(FilesProvider): - if not name.startswith('_search') or name == '_search_libraries': + if name not in self.wrapped_list_funcs: continue - setattr(self, name, partial(self._aggregate_files_search_func, name)) - - def get_arch_file(self, arch, f): - ''' - Layout is split into separate arch-specific prefixes (android-universal) - ''' - return '{}/{}'.format(arch, f) - - def _search_libraries(self, *args, **kwargs): - # This is handled separately, assert that it's not called directly to avoid bugs - raise AssertionError('Should not be called') - - def _aggregate_files_search_func(self, funcname, *args): - files = set() - for r in self._recipes.values(): - searchfunc = getattr(r, funcname) - for f in searchfunc(*args): - files.add(self.get_arch_file(r.config.target_arch, f)) - return list(files) + setattr(self, name, partial(self._aggregate_files_list_func, name)) + self.config = config - def _aggregate_libraries(self, category): - files = {} + def _aggregate_files_list_func(self, funcname, *args): + files = [] for r in self._recipes.values(): - for name, rfiles in r._list_files_by_category(category).items(): - if name not in files: - files[name] = set() - for f in rfiles: - files[name].add(self.get_arch_file(r.config.target_arch, f)) - for name in files: - files[name] = list(files[name]) + func = getattr(r, funcname) + rfiles = func(*args) + for rf in rfiles: + f = self.get_arch_file(r.config.target_arch, rf) + files.append(f) return files - def _aggregate_files(self, category): - files = set() - for r in self._recipes.values(): - for f in r._list_files_by_category(category): - files.add(self.get_arch_file(r.config.target_arch, f)) - return list(files) - - # This can't be on the UniversalRecipe class because it must override the - # same method on the FilesProvider class. - def _list_files_by_category(self, category): - ''' - Reimplement the files provider base function to aggregate files from - each target_arch recipe in UniversalRecipe. - ''' - if category == self.LIBS_CAT: - return self._aggregate_libraries(category) - return self._aggregate_files(category) + def get_arch_file(self, arch, f): + """ + Layout is split into separate arch-specific prefixes (android-universal) + """ + return '{}/{}'.format(arch, f) -class UniversalFlatFilesProvider(UniversalFilesProvider): +class UniversalMergedFilesProvider(UniversalFilesProvider): def get_arch_file(self, arch, f): - ''' + """ Layout is one common prefix will all arch-specific files merged into it with `lipo` (ios-universal) - ''' + """ return f diff --git a/cerbero/build/oven.py b/cerbero/build/oven.py index 2d2024b73..0bd287655 100644 --- a/cerbero/build/oven.py +++ b/cerbero/build/oven.py @@ -27,36 +27,42 @@ from cerbero.enums import Platform, LibraryType from cerbero.errors import BuildStepError, FatalError, AbortedError from cerbero.build.recipe import Recipe, BuildSteps -from cerbero.utils import _, N_, shell, run_until_complete, run_tasks, determine_num_of_cpus +from cerbero.utils import N_, shell, run_tasks, determine_num_of_cpus from cerbero.utils import add_system_libs, messages as m from cerbero.utils.shell import BuildStatusPrinter -import inspect class RecoveryActions(object): - ''' + """ Enumeration factory for recovery actions after an error - ''' + """ - SHELL = N_("Enter the shell") - RETRY_ALL = N_("Rebuild the recipe from scratch") - RETRY_STEP = N_("Rebuild starting from the failed step") - SKIP = N_("Skip recipe") - ABORT = N_("Abort") + SHELL = N_('Enter the shell') + RETRY_ALL = N_('Rebuild the recipe from scratch') + RETRY_STEP = N_('Rebuild starting from the failed step') + SKIP = N_('Skip recipe') + ABORT = N_('Abort') def __new__(klass): - return [RecoveryActions.SHELL, RecoveryActions.RETRY_ALL, - RecoveryActions.RETRY_STEP, RecoveryActions.SKIP, - RecoveryActions.ABORT] + return [ + RecoveryActions.SHELL, + RecoveryActions.RETRY_ALL, + RecoveryActions.RETRY_STEP, + RecoveryActions.SKIP, + RecoveryActions.ABORT, + ] + class RetryRecipeError(Exception): pass + class SkipRecipeError(Exception): pass -class Oven (object): - ''' + +class Oven(object): + """ This oven cooks recipes with all their ingredients @ivar recipes: Recipes to build @@ -75,11 +81,20 @@ class Oven (object): @type deps_only: bool @ivar steps_filter: only executes the steps in the list @type steps_filter: list - ''' - - def __init__(self, recipes, cookbook, force=False, no_deps=False, - missing_files=False, dry_run=False, deps_only=False, jobs=None, - steps_filter =None): + """ + + def __init__( + self, + recipes, + cookbook, + force=False, + no_deps=False, + missing_files=False, + dry_run=False, + deps_only=False, + jobs=None, + steps_filter=None, + ): if isinstance(recipes, Recipe): recipes = [recipes] self.recipes = recipes @@ -109,9 +124,9 @@ def __init__(self, recipes, cookbook, force=False, no_deps=False, self._install_lock = asyncio.Lock() async def start_cooking(self): - ''' + """ Cooks the recipe and all its dependencies - ''' + """ recipes = [self.cookbook.get_recipe(x) for x in self.recipes] if self.no_deps: @@ -127,15 +142,13 @@ async def start_cooking(self): if self.deps_only: ordered_recipes = [x for x in ordered_recipes if x not in recipes] - m.message(_("Building the following recipes: %s") % - ' '.join([x.name for x in ordered_recipes])) + m.message(N_('Building the following recipes: %s') % ' '.join([x.name for x in ordered_recipes])) steps = [step[1] for step in recipes[0].steps] if self.steps_filter is not None: steps = [s for s in steps if s in self.steps_filter] if len(steps) == 0: - raise FatalError(_('No valid steps found in %s') % - self.steps_filter) + raise FatalError(N_('No valid steps found in %s') % self.steps_filter) self._build_status_printer = BuildStatusPrinter(steps, self.interactive) self._static_libraries_built = [] @@ -143,8 +156,8 @@ async def start_cooking(self): async def _cook_recipes(self, recipes): recipes = set(recipes) - built_recipes = set() # recipes we have successfully built - building_recipes = set() # recipes that are queued or are in progress + built_recipes = set() # recipes we have successfully built + building_recipes = set() # recipes that are queued or are in progress def all_deps_without_recipe(recipe_name): return set((dep.name for dep in self.cookbook.list_recipe_deps(recipe_name) if recipe_name != dep.name)) @@ -201,7 +214,8 @@ def yield_path_lengths(): path = find_recipe_dep_path(f, t) if path: yield len(path) - return max((l for l in yield_path_lengths())) + + return max((length for length in yield_path_lengths())) def find_buildable_recipes(): # This is a dumb algorithm that only looks for all available @@ -225,6 +239,7 @@ def find_buildable_recipes(): class MutableInt: def __init__(self): self.i = 0 + counter = MutableInt() class RecipeStepPriority: @@ -243,17 +258,16 @@ def __init__(self, recipe, count, step): if step is BuildSteps.INSTALL[1]: # buf installs self.inverse_priority *= 8 - if hasattr(recipe, "allow_parallel_build") \ - and not recipe.allow_parallel_build: + if hasattr(recipe, 'allow_parallel_build') and not recipe.allow_parallel_build: self.inverse_priority *= 2 def __lt__(self, other): # return lower for larger path lengths return self.inverse_priority > other.inverse_priority - def recipe_next_step (recipe, step): - assert (step is not None) - if step == "init": + def recipe_next_step(recipe, step): + assert step is not None + if step == 'init': return recipe.steps[0][1] found_current = False for _, s in recipe.steps: @@ -265,9 +279,9 @@ def recipe_next_step (recipe, step): def add_buildable_recipes(recipe): built_recipes.add(recipe.name) building_recipes.remove(recipe.name) - for buildable in find_buildable_recipes (): + for buildable in find_buildable_recipes(): building_recipes.add(buildable.name) - default_queue.put_nowait(RecipeStepPriority(buildable, 0, "init")) + default_queue.put_nowait(RecipeStepPriority(buildable, 0, 'init')) async def cook_recipe_worker(q, steps): while True: @@ -276,19 +290,18 @@ async def cook_recipe_worker(q, steps): step = recipe_d.step count = recipe_d.count - if step == "init": + if step == 'init': counter.i += 1 count = counter.i - if self._cook_start_recipe (recipe, count): + if self._cook_start_recipe(recipe, count): add_buildable_recipes(recipe) q.task_done() continue - step = recipe_next_step (recipe, step) + step = recipe_next_step(recipe, step) lock = locks[step] if step == BuildSteps.COMPILE[1]: - if not hasattr(recipe, "allow_parallel_build") \ - or not recipe.allow_parallel_build: + if not hasattr(recipe, 'allow_parallel_build') or not recipe.allow_parallel_build: # only allow a limited number of recipes that can fill all # CPU cores to execute concurrently. Any recipe that does # not support parallel builds will always be executed @@ -297,13 +310,12 @@ async def cook_recipe_worker(q, steps): async def build_recipe_steps(step): # run the steps while step in steps: - await self._cook_recipe_step_with_prompt (recipe, step, count) - step = recipe_next_step (recipe, step) + await self._cook_recipe_step_with_prompt(recipe, step, count) + step = recipe_next_step(recipe, step) return step try: - if hasattr(recipe, "allow_universal_parallel_build") \ - and not recipe.allow_universal_parallel_build: + if hasattr(recipe, 'allow_universal_parallel_build') and not recipe.allow_universal_parallel_build: recipe._lock = self._architecture_lock else: recipe._lock = None @@ -313,12 +325,12 @@ async def build_recipe_steps(step): else: step = await build_recipe_steps(step) except RetryRecipeError: - step = "init" + step = 'init' except SkipRecipeError: step = None if step is None: - self._cook_finish_recipe (recipe, counter.i) + self._cook_finish_recipe(recipe, counter.i) add_buildable_recipes(recipe) next_queue = None else: @@ -329,11 +341,11 @@ async def build_recipe_steps(step): next_queue.put_nowait(RecipeStepPriority(recipe, count, step)) # all the steps we are performing - all_steps = ["init"] + [s[1] for s in next(iter(recipes)).steps] + all_steps = ['init'] + [s[1] for s in next(iter(recipes)).steps] # async queues used for each step default_queue = asyncio.PriorityQueue() - queues = {step : default_queue for step in all_steps} + queues = {step: default_queue for step in all_steps} # find the install steps for ensuring consistency between all of them install_steps = [] @@ -343,7 +355,7 @@ async def build_recipe_steps(step): step = recipe_next_step(next(iter(recipes)), step) # allocate jobs - job_allocation = collections.defaultdict(lambda : 0) + job_allocation = collections.defaultdict(lambda: 0) if self.jobs > 4: queues[BuildSteps.COMPILE[1]] = asyncio.PriorityQueue() job_allocation[BuildSteps.COMPILE[1]] = 2 @@ -374,7 +386,7 @@ async def build_recipe_steps(step): queues[BuildSteps.FETCH[1]] = asyncio.PriorityQueue() # async locks used to synchronize step execution - locks = collections.defaultdict(lambda : None) + locks = collections.defaultdict(lambda: None) # create the jobs tasks = [] @@ -398,17 +410,27 @@ async def build_recipe_steps(step): used_steps.append(step) used_jobs += count general_jobs = self.jobs - used_jobs - assert (general_jobs > 0) + assert general_jobs > 0 if job_allocation[BuildSteps.INSTALL[1]] == 0 and general_jobs > 1: locks[BuildSteps.INSTALL[1]] = self._install_lock if job_allocation[BuildSteps.COMPILE[1]] > 2 or job_allocation[BuildSteps.COMPILE[1]] == 0 and general_jobs > 2: locks[BuildSteps.COMPILE[1]] = self._build_lock - job_allocation_msg = ", ".join([str(step) + ": " + str(count) for step, count in job_allocation.items() if count > 0]) + job_allocation_msg = ', '.join( + [str(step) + ': ' + str(count) for step, count in job_allocation.items() if count > 0] + ) if used_jobs > 0: - job_allocation_msg += ", and " - m.output ("Building using " + str(self.jobs) + " job(s) with the following job subdivisions: " + job_allocation_msg + str(self.jobs - used_jobs) + " general job(s)", sys.stdout) + job_allocation_msg += ', and ' + m.output( + 'Building using ' + + str(self.jobs) + + ' job(s) with the following job subdivisions: ' + + job_allocation_msg + + str(self.jobs - used_jobs) + + ' general job(s)', + sys.stdout, + ) for i in range(self.jobs - used_jobs): tasks.append(asyncio.ensure_future(cook_recipe_worker(default_queue, set(all_steps) - set(used_steps)))) @@ -427,16 +449,15 @@ async def heartbeat_output(): heartbeat_task.cancel() - # push the initial set of recipes that have no dependencies to start # building - for recipe in find_buildable_recipes (): + for recipe in find_buildable_recipes(): building_recipes.add(recipe.name) - default_queue.put_nowait(RecipeStepPriority(recipe, 0, "init")) + default_queue.put_nowait(RecipeStepPriority(recipe, 0, 'init')) try: await run_tasks(tasks, recipes_done()) - m.output(_("All done!"), sys.stdout) + m.output(N_('All done!'), sys.stdout) except Exception as e: raise e @@ -448,7 +469,7 @@ async def _cook_recipe_step_with_prompt(self, recipe, step, count): raise be print() msg = be.msg - msg += _("Select an action to proceed:") + msg += N_('Select an action to proceed:') action = shell.prompt_multiple(msg, RecoveryActions()) if action == RecoveryActions.SHELL: environ = recipe.get_recipe_env() @@ -458,8 +479,9 @@ async def _cook_recipe_step_with_prompt(self, recipe, step, count): source_dir = recipe.get_for_arch(be.arch, 'config_src_dir') else: source_dir = recipe.get_for_arch(be.arch, 'build_dir') - shell.enter_build_environment(self.config.target_platform, - be.arch, self.config.distro, source_dir, env=environ) + shell.enter_build_environment( + self.config.target_platform, be.arch, self.config.distro, source_dir, env=environ + ) raise be elif action == RecoveryActions.RETRY_ALL: shutil.rmtree(recipe.get_for_arch(be.arch, 'build_dir')) @@ -486,7 +508,7 @@ async def _cook_recipe_step(self, recipe, step, count): stepfunc = getattr(recipe, step) if not stepfunc: self._build_status_printer.update_recipe_step(count, recipe.name, step) - raise FatalError(_('Step %s not found') % step) + raise FatalError(N_('Step %s not found') % step) self._build_status_printer.update_recipe_step(count, recipe.name, step) ret = stepfunc() @@ -521,8 +543,7 @@ def _cook_start_recipe(self, recipe, count): if len(set(self._static_libraries_built) & set(recipe.deps)) != 0: self.cookbook.reset_recipe_status(recipe.name) - if not self.cookbook.recipe_needs_build(recipe.name) and \ - not self.force: + if not self.cookbook.recipe_needs_build(recipe.name) and not self.force: self._build_status_printer.already_built(count, recipe.name) return True @@ -553,17 +574,14 @@ def _handle_build_step_error(self, recipe, step, trace, arch): def _print_missing_files(self, recipe, tmp): recipe_files = set(recipe.files_list()) - installed_files = set(shell.find_newer_files(recipe.config.prefix, - tmp.name)) + installed_files = set(shell.find_newer_files(recipe.config.prefix, tmp.name)) not_in_recipe = list(installed_files - recipe_files) not_installed = list(recipe_files - installed_files) if len(not_in_recipe) != 0: - m.message(_("The following files were installed, but are not " - "listed in the recipe:")) + m.message(N_('The following files were installed, but are not ' 'listed in the recipe:')) m.message('\n'.join(sorted(not_in_recipe))) if len(not_installed) != 0: - m.message(_("The following files are listed in the recipe, but " - "were not installed:")) + m.message(N_('The following files are listed in the recipe, but ' 'were not installed:')) m.message('\n'.join(sorted(not_installed))) diff --git a/cerbero/build/recipe.py b/cerbero/build/recipe.py index 8e4d768ba..1b860cab8 100644 --- a/cerbero/build/recipe.py +++ b/cerbero/build/recipe.py @@ -19,23 +19,21 @@ import os import logging import shutil -import tempfile -import time import inspect import asyncio from functools import reduce from pathlib import Path -from cerbero.enums import License, LicenseDescription, LibraryType +from cerbero.enums import License, LicenseDescription from cerbero.build import build, source -from cerbero.build.filesprovider import FilesProvider, UniversalFilesProvider, UniversalFlatFilesProvider -from cerbero.config import Platform +from cerbero.build.filesprovider import FilesProvider, UniversalFilesProvider, UniversalMergedFilesProvider +from cerbero.config import Distro, Platform from cerbero.errors import FatalError, CommandError from cerbero.ide.pkgconfig import PkgConfig from cerbero.ide.vs.genlib import GenLib, GenGnuLib from cerbero.tools.osxuniversalgenerator import OSXUniversalGenerator from cerbero.tools.osxrelocator import OSXRelocator -from cerbero.utils import N_, _ +from cerbero.utils import N_ from cerbero.utils import shell, add_system_libs, run_tasks from cerbero.utils import messages as m from cerbero.tools.libtool import LibtoolLibrary @@ -46,8 +44,8 @@ def log_step_output(recipe, stepfunc): def open_file(): step = stepfunc.__name__ - path = "%s/%s-%s.log" % (recipe.config.logs, recipe.name, step) - recipe.old_logfile = recipe.logfile # Allow calling build steps recursively + path = '%s/%s-%s.log' % (recipe.config.logs, recipe.name, step) + recipe.old_logfile = recipe.logfile # Allow calling build steps recursively recipe.logfile = open(path, 'w+') def close_file(): @@ -65,7 +63,7 @@ def get_all_prev_steps_logfiles(): step = step[1] if step == current_step: break - path = "%s/%s-%s.log" % (recipe.config.logs, recipe.name, step) + path = '%s/%s-%s.log' % (recipe.config.logs, recipe.name, step) try: logfiles.append(open(path, 'r')) except OSError: @@ -73,9 +71,9 @@ def get_all_prev_steps_logfiles(): return logfiles def handle_exception(): - ''' + """ Dump contents of log files for current and previous steps on error - ''' + """ logfiles = get_all_prev_steps_logfiles() # log file of current step recipe.logfile.seek(0) @@ -88,61 +86,64 @@ def handle_exception(): if data: print(data) - def wrapped(): + def wrapped(*args, **kwargs): open_file() try: - stepfunc() + ret = stepfunc(*args, **kwargs) except FatalError: handle_exception() raise close_file() + return ret - async def async_wrapped(): + async def async_wrapped(*args, **kwargs): open_file() try: - await stepfunc() + ret = await stepfunc(*args, **kwargs) except FatalError: handle_exception() raise close_file() + return ret if asyncio.iscoroutinefunction(stepfunc): return async_wrapped else: return wrapped + class MetaRecipe(type): - ''' This metaclass modifies the base classes of a Receipt, adding 2 new + """This metaclass modifies the base classes of a Recipe, adding 2 new base classes based on the class attributes 'stype' and 'btype'. - class NewReceipt(Receipt): - btype = Class1 ------> class NewReceipt(Receipt, Class1, Class2) + class NewRecipe(Recipe): + btype = Class1 ------> class NewRecipe(Recipe, Class1, Class2) stype = Class2 - ''' + """ def __new__(cls, name, bases, dct): clsname = '%s.%s' % (dct['__module__'], name) recipeclsname = '%s.%s' % (cls.__module__, 'Recipe') - # only modify it for Receipt's subclasses + # only modify it for Recipe's subclasses if clsname != recipeclsname and name == 'Recipe': - # get the default build and source classes from Receipt - # Receipt(DefaultSourceType, DefaultBaseType) + # get the default build and source classes from Recipe + # Recipe(DefaultSourceType, DefaultBuildType) basedict = {'btype': bases[0].btype, 'stype': bases[0].stype} # if this class define stype or btype, override the default one - # Receipt(OverridenSourceType, OverridenBaseType) + # Recipe(OverridenSourceType, OverridenBuildType) for base in ['stype', 'btype']: if base in dct: basedict[base] = dct[base] - # finally add this classes the Receipt bases - # Receipt(BaseClass, OverridenSourceType, OverridenBaseType) + # finally add this classes the Recipe bases + # Recipe(BaseClass, OverridenSourceType, OverridenBuildType) bases = bases + tuple(basedict.values()) return type.__new__(cls, name, bases, dct) class BuildSteps(object): - ''' + """ Enumeration factory for build steps - ''' + """ FETCH = (N_('Fetch'), 'fetch') EXTRACT = (N_('Extract'), 'extract') @@ -159,18 +160,25 @@ class BuildSteps(object): CODE_SIGN = (N_('Codesign build-tools'), 'code_sign') def __new__(cls): - return [BuildSteps.FETCH, BuildSteps.EXTRACT, - BuildSteps.CONFIGURE, BuildSteps.COMPILE, BuildSteps.INSTALL, - BuildSteps.POST_INSTALL] + return [ + BuildSteps.FETCH, + BuildSteps.EXTRACT, + BuildSteps.CONFIGURE, + BuildSteps.COMPILE, + BuildSteps.INSTALL, + BuildSteps.POST_INSTALL, + ] @classmethod def all_names(cls): - members = inspect.getmembers(cls, lambda x: isinstance(x, tuple)) + # In 3.13, __static_attributes__ is a new tuple attribute. Just ignore + # all attributes starting with __. + members = inspect.getmembers(cls, lambda x: isinstance(x, tuple) and x and not x[0].startswith('__')) return tuple(e[1][1] for e in members) class Recipe(FilesProvider, metaclass=MetaRecipe): - ''' + """ Base class for recipes. A Recipe describes a module and the way it's built. @@ -194,7 +202,7 @@ class Recipe(FilesProvider, metaclass=MetaRecipe): @type runtime_dep: bool @cvar bash_completions: list of bash completion scripts for shell @type bash_completions: list - ''' + """ # Licenses are declared as an array of License.enums or dicts of the type: # @@ -244,10 +252,10 @@ class Recipe(FilesProvider, metaclass=MetaRecipe): force = False logfile = None _default_steps = BuildSteps() - _licenses_disclaimer = '''\ + _licenses_disclaimer = """\ DISCLAIMER: THIS LICENSING INFORMATION IS PROVIDED ON A BEST-EFFORT BASIS AND IS NOT MEANT TO BE LEGAL ADVICE. PLEASE TALK TO A LAWYER FOR ADVICE ON -SOFTWARE LICENSE COMPLIANCE.\n\n''' +SOFTWARE LICENSE COMPLIANCE.\n\n""" _licenses_terms = 'The {} in this package may be used under the terms of license file(s):\n\n' # Used in recipes/custom.py. See also: cookbook.py:_load_recipes_from_dir() _using_manifest_force_git = False @@ -273,10 +281,9 @@ class Recipe(FilesProvider, metaclass=MetaRecipe): def __init__(self, config, env): self.config = config if self.package_name is None: - self.package_name = "%s-%s" % (self.name, self.version) + self.package_name = '%s-%s' % (self.name, self.version) if not hasattr(self, 'repo_dir'): - self.repo_dir = os.path.join(self.config.local_sources, - self.package_name) + self.repo_dir = os.path.join(self.config.local_sources, self.package_name) self.repo_dir = os.path.abspath(self.repo_dir) self.build_dir = os.path.abspath(os.path.join(self.config.sources, self.package_name)) self.config_src_dir = self.build_dir @@ -298,18 +305,17 @@ def __init__(self, config, env): self.platform_deps = self.platform_deps or {} self.skip_steps = self.skip_steps or [] - allowed_skip = {BuildSteps.RELOCATE_OSX_LIBRARIES, BuildSteps.CODE_SIGN} + allowed_skip = {BuildSteps.MERGE, BuildSteps.RELOCATE_OSX_LIBRARIES, BuildSteps.CODE_SIGN} bad_skip = set(self.skip_steps) - allowed_skip if bad_skip: - raise FatalError(f"Can only skip steps {allowed_skip}, not {bad_skip}") + raise FatalError(f'Can only skip steps {allowed_skip}, not {bad_skip}') self._steps = self._default_steps[:] if self.config.target_platform == Platform.WINDOWS: self._steps.append(BuildSteps.GEN_LIBFILES) if self.config.target_platform == Platform.DARWIN: self._steps.append(BuildSteps.RELOCATE_OSX_LIBRARIES) - if self.config.target_platform == Platform.DARWIN and \ - self.config.prefix == self.config.build_tools_prefix: + if self.config.target_platform == Platform.DARWIN and self.config.prefix == self.config.build_tools_prefix: self._steps.append(BuildSteps.CODE_SIGN) FilesProvider.__init__(self, config) @@ -326,13 +332,13 @@ def __str__(self): return self.name def __repr__(self): - return "" % self.name + return '' % self.name def decorate_build_steps(self): - ''' + """ Decorate build step functions with a function that sets self.logfile for each build step for this recipe - ''' + """ steps = BuildSteps.all_names() for name, func in inspect.getmembers(self, inspect.ismethod): if name not in steps: @@ -340,16 +346,17 @@ def decorate_build_steps(self): setattr(self, name, log_step_output(self, func)) def prepare(self): - ''' + """ Can be overriden by subclasess to modify the recipe in function of the configuration - ''' + """ pass async def retry_run(self, func, *args, **kwargs): errors = self.SPURIOUS_ERRORS.get(self.config.platform, None) + def is_spurious_error(): - assert(self.logfile) + assert self.logfile self.logfile.seek(0) for line in self.logfile: for error in errors: @@ -370,14 +377,9 @@ def is_spurious_error(): retries -= 1 m.action(f'Retrying, caught spurious failure: {ret.strip()}') - def _get_arch_prefix(self): - if self.config.cross_universal_type() == 'flat': - return os.path.join(self.config.prefix, self.config.target_arch) - return self.config.prefix - - def _get_la_deps_from_pc (self, laname, pcname, env): + def _get_la_deps_from_pc(self, laname, pcname, env): pkgc = PkgConfig([pcname], env=env) - libs = set(pkgc.static_libraries()) + libs = set(pkgc.static_libraries()) # Don't add the library itself to the list of dependencies return ['lib' + lib for lib in libs if lib != laname[3:]] @@ -410,14 +412,14 @@ def resolve_step(node): return ret def fixup_pc_files(self): - ''' + """ Make all .pc files relocatable by setting `prefix` relative to ${pcfiledir} - ''' + """ for f in self.files_list_by_category(self.DEVEL_CAT): if not f.endswith('.pc'): continue - fpath = os.path.join(self._get_arch_prefix(), f) + fpath = os.path.join(self.config.prefix, f) if not os.path.isfile(fpath): m.warning(f'{self.config.target_arch} {fpath} not found') continue @@ -431,13 +433,41 @@ def fixup_pc_files(self): for line in contents: if line.startswith('prefix=') and 'pcfiledir' not in line: line = f'prefix={prefix_value}' + elif f'={self.config.prefix}' in line: + line = line.replace(self.config.prefix, '${prefix}') fo.write(line + '\n') + def relocate_site_packages(self): + """ + Relocate Python packages from the distro default + to the standard site-packages + """ + extensions = self.extensions.copy() + if self.config.target_distro == Distro.DEBIAN: + extensions['pydir'] = Path(self.config.prefix, 'lib', 'python3', 'dist-packages').as_posix() + else: + extensions['pydir'] = Path(self.config.prefix, self.config.py_macos_prefix).as_posix() + srcfiles = [Path(f % extensions) for f in self.files_python] + + destdir = Path(self.config.prefix) / self.config.get_python_prefix() + destdir.mkdir(parents=True, exist_ok=True) + extensions['pydir'] = Path(self.config.prefix, self.config.get_python_prefix()).as_posix() + destfiles = [Path(f % extensions) for f in self.files_python] + + for src, dest in zip(srcfiles, destfiles): + if src.is_file(): + dest.parent.mkdir(parents=True, exist_ok=True) + shutil.copyfile(src, dest) + elif src.is_dir(): + dest.parent.mkdir(parents=True, exist_ok=True) + shutil.copytree(src, dest, dirs_exist_ok=True) + def generate_gst_la_files(self): - ''' + """ Generate .la files for all libraries and plugins packaged by this Meson recipe using the pkg-config files installed by our Meson build files. - ''' + """ + class GeneratedLA(object): name = None major = None @@ -464,25 +494,31 @@ def __eq__(self, other): return self.name == other.name and self.libdir == other.libdir def __str__(self): - return " 1: - m.warning("BUG: Found multiple DLLs for libname {!r}:\n{}".format(libname, '\n'.join(dllpaths))) + m.warning('BUG: Found multiple DLLs for libname {!r}:\n{}'.format(libname, '\n'.join(dllpaths))) continue if len(dllpaths) == 0: - m.warning("Could not create import library for {!r}, no matching DLLs found".format(libname)) + m.warning('Could not create import library for {!r}, no matching DLLs found'.format(libname)) continue try: - implib = genlib.create(libname, + implib = genlib.create( + libname, os.path.join(self.config.prefix, dllpaths[0]), - self.config.platform, self.config.target_arch, - output_dir) + self.config.platform, + self.config.target_arch, + output_dir, + ) logging.debug('Created %s' % implib) except FatalError as e: - m.warning("Could not create {!r}: {}".format(genlib.filename, e.msg)) + m.warning('Could not create {!r}: {}'.format(genlib.filename, e.msg)) def recipe_dir(self): - ''' + """ Gets the directory path where this recipe is stored @return: directory path @rtype: str - ''' + """ return os.path.dirname(self.__file__) def relative_path(self, path): - ''' + """ Gets a path relative to the recipe's directory @return: absolute path relative to the pacakge's directory @rtype: str - ''' + """ return os.path.abspath(os.path.join(self.recipe_dir(), path)) def get_checksum(self): - ''' + """ Returns the current checksum of the recipe file and other files it depends on, like patches. This checksum is used in the cache to determine if a @@ -829,52 +874,55 @@ def get_checksum(self): @return: a checksum of the recipe file and its dependencies @rtype: str - ''' + """ return shell.files_checksum(self._get_files_dependencies()) def get_mtime(self): - ''' + """ Returns the recipe last modification time, including the dependent files @return: last modification time @rtype: str - ''' - return max(map(os.path.getmtime, self._get_files_dependencies())) + """ + return max(map(os.path.getmtime, self._get_files_dependencies())) @property def steps(self): return self._steps def get_for_arch(self, arch, name): - return getattr (self, name) + return getattr(self, name) class MetaUniversalRecipe(type): - ''' + """ Wraps all the build steps for the universal recipe to be called for each one of the child recipes. - ''' + """ def __init__(cls, name, bases, ns): step_func = ns.get('_do_step') for _, step in BuildSteps(): + async def doit(recipe, step_name=step): ret = step_func(recipe, step_name) if asyncio.iscoroutine(ret): - await ret + ret = await ret + return ret + if step_func: setattr(cls, step, doit) class BaseUniversalRecipe(object, metaclass=MetaUniversalRecipe): - ''' + """ Stores similar recipe objects that are going to be built together Useful for the universal architecture, where the same recipe needs to be built for different architectures before being merged. For the other targets, it will likely be a unitary group - ''' + """ def __init__(self, config): self._config = config @@ -888,15 +936,15 @@ def __str__(self): return super(UniversalRecipe, self).__str__() def add_recipe(self, recipe): - ''' + """ Adds a new recipe to the group - ''' + """ if self._proxy_recipe is None: self._proxy_recipe = recipe else: for attr in ('name', 'deps', 'platform_deps'): if getattr(recipe, attr) != getattr(self._proxy_recipe, attr): - raise FatalError(_("Recipes must have the same " + attr)) + raise FatalError(N_('Recipes must have the same ' + attr)) self._recipes[recipe.config.target_arch] = recipe def is_empty(self): @@ -904,9 +952,13 @@ def is_empty(self): def __getattr__(self, name): if not self._proxy_recipe: - raise AttributeError(_("Attribute %s was not found in the " - "Universal recipe, which is empty. You might need to add a " - "recipe first.")) + raise AttributeError( + N_( + 'Attribute %s was not found in the ' + 'Universal recipe, which is empty. You might need to add a ' + 'recipe first.' % name + ) + ) return getattr(self._proxy_recipe, name) def __setattr__(self, name, value): @@ -922,13 +974,12 @@ def steps(self): return self._proxy_recipe.steps[:] async def _do_step(self, step): - async def _async_run_step(recipe, step, arch): # Call the step function stepfunc = getattr(recipe, step) try: ret = stepfunc() - if asyncio.iscoroutine (ret): + if asyncio.iscoroutine(ret): await ret except FatalError as e: e.arch = arch @@ -948,43 +999,43 @@ async def _async_run_with_lock(recipe, step, arch): tasks = [] for arch, recipe in self._recipes.items(): - if step in (BuildSteps.CONFIGURE[1],) \ - or (step == BuildSteps.EXTRACT[1] \ - and self.stype in (source.SourceType.TARBALL,)) \ - or (step == BuildSteps.COMPILE[1] \ - and self.btype == build.BuildType.CARGO_C): + if ( + step in (BuildSteps.CONFIGURE[1],) + or (step == BuildSteps.EXTRACT[1] and self.stype in (source.SourceType.TARBALL,)) + or (step == BuildSteps.COMPILE[1] and self.btype == build.BuildType.CARGO_C) + ): tasks.append(asyncio.ensure_future(_async_run_with_lock(recipe, step, arch))) else: await _async_run_step(recipe, step, arch) if tasks: - await run_tasks (tasks) + await run_tasks(tasks) def get_for_arch(self, arch, name): if arch: - return getattr (self._recipes[arch], name) + return getattr(self._recipes[arch], name) else: - return getattr (self, name) + return getattr(self, name) class UniversalRecipe(BaseUniversalRecipe, UniversalFilesProvider): - ''' + """ Unversal recipe for Android with subdirs for each architecture - ''' + """ def __init__(self, config): super().__init__(config) UniversalFilesProvider.__init__(self, config) -class UniversalFlatRecipe(BaseUniversalRecipe, UniversalFlatFilesProvider): - ''' - Unversal recipe for iOS and OS X creating flat libraries +class UniversalMergedRecipe(BaseUniversalRecipe, UniversalMergedFilesProvider): + """ + Unversal recipe for iOS and OS X creating merged (fat) libraries in the target prefix instead of subdirs for each architecture - ''' + """ def __init__(self, config): super().__init__(config) - UniversalFlatFilesProvider.__init__(self, config) + UniversalMergedFilesProvider.__init__(self, config) @property def steps(self): @@ -1006,6 +1057,9 @@ def relocate_osx_libraries(self): recipe.relocate_osx_libraries() async def merge(self): + if BuildSteps.MERGE in self.skip_steps: + return + arch_inputs = {} for arch, recipe in self._recipes.items(): arch_inputs[arch] = set(recipe.files_list()) @@ -1028,3 +1082,19 @@ async def merge(self): # merge the architecture specific files for f, archs in arch_files.items(): await generator.merge_files([f], [recipe.config.prefix for arch, recipe in archs]) + + +def import_recipe(file, class_name='Recipe'): + """ + Mechanism to load a recipe from other file in order to inherit from it + @file The path where the .recipe file is + @class_name The recipe to return, by default 'Recipe' + """ + upframe = inspect.stack()[1].frame + new_globals = upframe.f_globals.copy() + new_globals['__file__'] = file + exec(open(file).read(), new_globals) + recipe_class = new_globals[class_name] + # Cerbero checks for the __module__ being 'builtins' in order to load it again + recipe_class.__module__ = None + return recipe_class diff --git a/cerbero/build/source.py b/cerbero/build/source.py index 381cffd68..5b8407cfe 100644 --- a/cerbero/build/source.py +++ b/cerbero/build/source.py @@ -20,13 +20,15 @@ import shutil import zipfile import tarfile -import urllib.request, urllib.parse, urllib.error +import urllib.request +import urllib.parse +import urllib.error import collections import asyncio from hashlib import sha256 from cerbero.config import Distro, DistroVersion, Platform, DEFAULT_MIRRORS -from cerbero.utils import git, svn, shell, _, run_until_complete +from cerbero.utils import git, svn, shell, N_ from cerbero.errors import FatalError, CommandError, InvalidRecipeError from cerbero.build.build import BuildType import cerbero.utils.messages as m @@ -39,12 +41,14 @@ 'xiph': ('https://downloads.xiph.org/releases/', '%(name)s/%(name)s-%(version)s', '.tar.xz'), } + def get_logfile(instance): # only Recipe has the logfile attr. Bootstraping doesn't return getattr(instance, 'logfile') if hasattr(instance, 'logfile') else None -class Source (object): - ''' + +class Source(object): + """ Base class for sources handlers @ivar recipe: the parent recipe @@ -55,7 +59,7 @@ class Source (object): @type patches: list @cvar strip: number passed to the --strip 'patch' option @type patches: int - ''' + """ patches = None cargo_lock = None @@ -69,8 +73,7 @@ def __init__(self): self.patches = [] if not self.version: - raise InvalidRecipeError( - self, _("'version' attribute is missing in the recipe")) + raise InvalidRecipeError(self, N_("'version' attribute is missing in the recipe")) @property def check_cert(self): @@ -83,40 +86,64 @@ def cargo_vendor_cache_dir(self): return f'{self.repo_dir}/cargo-vendor' def _get_download_path(self, fname): - ''' + """ Fetch download path dynamically because self.tarball_name may be reset in prepare() - ''' + """ return os.path.join(self.download_dir, fname) def have_cargo_lock_file(self): return os.path.exists(os.path.join(self.config_src_dir, 'Cargo.lock')) + def get_fallback_urls(self, url): + urls = [] + fname = os.path.basename(url) + # Namespaced directory structure + for mirror in self.config.extra_mirrors: + urls.append(f'{mirror}/{self.name}/{fname}') + for mirror in DEFAULT_MIRRORS: + # Some recipes use a mirror as the primary URL + if url.startswith(mirror): + continue + urls.append(f'{mirror}/{self.name}/{fname}') + # Flat directory structure (for backwards compat) + for mirror in self.config.extra_mirrors: + urls.append(f'{mirror}/{fname}') + return urls + async def cargo_update(self, offline, logfile): update_args = ['--verbose'] if offline: update_args += ['--offline'] m.log('Running cargo update to generate Cargo.lock', logfile=logfile) - await shell.async_call([self.cargo, 'update'] + update_args, - cmd_dir=self.config_src_dir, logfile=logfile, - env=self.env, cpu_bound=False) + await shell.async_call( + [self.cargo, 'update'] + update_args, + cmd_dir=self.config_src_dir, + logfile=logfile, + env=self.env, + cpu_bound=False, + ) async def cargo_vendor(self, offline): logfile = get_logfile(self) if self.cargo_lock: - shutil.copy(self.relative_path(self.cargo_lock), - os.path.join(self.config_src_dir, 'Cargo.lock')) + shutil.copy(self.relative_path(self.cargo_lock), os.path.join(self.config_src_dir, 'Cargo.lock')) if not self.have_cargo_lock_file(): await self.retry_run(self.cargo_update, offline, logfile) m.log('Running cargo vendor to vendor sources', logfile=logfile) vendor_args = [self.cargo_vendor_cache_dir] if offline: vendor_args += ['--frozen', '--offline'] - ct = await shell.async_call_output([self.cargo, 'vendor'] + vendor_args, - cmd_dir=self.config_src_dir, env=self.env, - cpu_bound=False, logfile=logfile) - os.makedirs(os.path.join(self.config_src_dir, '.cargo')) - with open(os.path.join(self.config_src_dir, '.cargo', 'config.toml'), 'w') as f: + ct = await shell.async_call_output( + [self.cargo, 'vendor'] + vendor_args, + cmd_dir=self.config_src_dir, + env=self.env, + cpu_bound=False, + logfile=logfile, + ) + os.makedirs(os.path.join(self.config_src_dir, '.cargo'), exist_ok=True) + # Append so we don't overwrite any existing .cargo/config.toml settings + with open(os.path.join(self.config_src_dir, '.cargo', 'config.toml'), 'a') as f: f.write(ct) m.log('Created cargo vendor config.toml', logfile=logfile) @@ -141,16 +168,17 @@ def parse_wrap(self, wrap_file): async def meson_subprojects_download(self, downloads, logfile): subprojects = [] - for (subproj_name, _) in downloads: + for subproj_name, _ in downloads: subprojects.append(subproj_name) m.log(f'Downloading meson subprojects: {", ".join(subprojects)}', logfile=logfile) - for (subproj_name, ((url, fallback_url), fpath, fhash)) in downloads: - mirrors = self.config.extra_mirrors + DEFAULT_MIRRORS + for subproj_name, ((url, fallback_url), fpath, fhash) in downloads: + fallback_urls = self.get_fallback_urls(fpath) if fallback_url: # Our mirror implementation assumes that the basename is the same - mirrors.insert(0, os.path.dirname(fallback_url)) - await shell.download(url, fpath, check_cert=self.check_cert, - overwrite=False, logfile=logfile, mirrors=mirrors) + fallback_urls.append(fallback_url) + await shell.download( + url, fpath, check_cert=self.check_cert, overwrite=False, logfile=logfile, fallback_urls=fallback_urls + ) self.verify(fpath, fhash) async def meson_subprojects_extract(self, offline): @@ -163,18 +191,28 @@ async def meson_subprojects_extract(self, offline): m.log(f'Parsing wrap file {wrap_file}', logfile=logfile) items = self.parse_wrap(wrap_file) fpath = self._get_download_path(items['source_filename']) - downloads.append((subproj_name, ( - (items['source_url'], items.get('source_fallback_url', None)), - fpath, - items['source_hash'], - ))) + downloads.append( + ( + subproj_name, + ( + (items['source_url'], items.get('source_fallback_url', None)), + fpath, + items['source_hash'], + ), + ) + ) if 'patch_url' in items: fpath = self._get_download_path(items['patch_filename']) - downloads.append((subproj_name, ( - (items['patch_url'], None), - fpath, - items['patch_hash'], - ))) + downloads.append( + ( + subproj_name, + ( + (items['patch_url'], None), + fpath, + items['patch_hash'], + ), + ) + ) # Download, if not running in offline mode (or if we're fetching) if not offline: @@ -182,14 +220,14 @@ async def meson_subprojects_extract(self, offline): # Provide the subproject downloads, via symlink or a file copy subprojects = [] - for (subproj_name, _) in downloads: + for subproj_name, _ in downloads: subprojects.append(subproj_name) m.log(f'Providing meson subprojects: {", ".join(subprojects)}', logfile=logfile) subproj_pkg_cache = os.path.join(subproj_dir, 'packagecache') os.makedirs(subproj_pkg_cache, exist_ok=True) - for (_, ((url, _), fpath, _)) in downloads: + for _, ((url, _), fpath, _) in downloads: if not os.path.isfile(fpath): - raise FatalError(f'{url} is required and hasn\'t been downloaded yet') + raise FatalError(f"{url} is required and hasn't been downloaded yet") fname = os.path.basename(fpath) dst = os.path.join(subproj_pkg_cache, fname) if self.config.platform != Platform.WINDOWS: @@ -198,10 +236,10 @@ async def meson_subprojects_extract(self, offline): shutil.copy(fpath, dst) def expand_url_template(self, s): - ''' + """ Expand a standard URL template (GNOME, SourceForge, GNU, etc) and get a URL that just needs the name and version substituted. - ''' + """ schemes = tuple(s + '://' for s in URL_TEMPLATES.keys()) if s.startswith(schemes): scheme, url = s.split('://', 1) @@ -214,9 +252,9 @@ def expand_url_template(self, s): return s def replace_name_and_version(self, string): - ''' + """ Replaces name and version in strings - ''' + """ name = self.name if name.startswith('gst') and name.endswith('-1.0'): # gst-libav-1.0, etc is useless for substitution, convert to 'gst-libav' @@ -225,14 +263,14 @@ def replace_name_and_version(self, string): return string % {'name': name, 'version': self.version, 'maj_ver': maj_ver} def _get_files_dependencies(self): - ''' + """ Subclasses should override this funtion to provide any file that this recipe depends on, including the recipe's file @return: the recipe file and other files this recipes depends on like patches @rtype: list - ''' + """ files = list(map(self.relative_path, self.patches)) if hasattr(self, '__file__'): files.append(self.__file__) @@ -242,10 +280,10 @@ async def fetch(self, **kwargs): self.fetch_impl(**kwargs) def fetch_impl(self): - ''' + """ Fetch the sources - ''' - raise NotImplemented("'fetch' must be implemented by subclasses") + """ + raise NotImplementedError("'fetch' must be implemented by subclasses") async def extract(self): # Could have multiple recipes using the same git repo, or extract @@ -260,14 +298,13 @@ async def extract(self): self._extract_done.add(self.config_src_dir) async def extract_impl(self): - ''' + """ Extracts the sources - ''' - raise NotImplemented("'extract' must be implemented by subclasses") + """ + raise NotImplementedError("'extract' must be implemented by subclasses") -class CustomSource (Source): - +class CustomSource(Source): async def fetch(self): pass @@ -276,7 +313,7 @@ async def extract(self): class BaseTarball(object): - ''' + """ Source handler for tarballs @cvar url: download URL for the tarball @@ -296,7 +333,7 @@ class BaseTarball(object): @cvar force_tarfile: forces the use of python's tarfile instead of tar @type force_tarfile: bool - ''' + """ url = None tarball_name = None @@ -324,13 +361,18 @@ async def fetch(self, redownload=False): msg = 'Offline mode: tarball {!r} not found in local sources ({})' raise FatalError(msg.format(self.tarball_name, self.download_dir)) self.verify(fname, self.tarball_checksum) - m.action(_('Found %s at %s') % (self.url, fname), logfile=get_logfile(self)) + m.action(N_('Found %s at %s') % (self.url, fname), logfile=get_logfile(self)) return if not os.path.exists(self.download_dir): os.makedirs(self.download_dir) - await shell.download(self.url, fname, check_cert=self.check_cert, - overwrite=redownload, logfile=get_logfile(self), - mirrors=(self.config.extra_mirrors + DEFAULT_MIRRORS)) + await shell.download( + self.url, + fname, + check_cert=self.check_cert, + overwrite=redownload, + logfile=get_logfile(self), + fallback_urls=self.get_fallback_urls(self.url), + ) self.verify(fname, self.tarball_checksum) @staticmethod @@ -346,17 +388,18 @@ def _checksum(fname): def verify(self, fname, checksum, fatal=True): found_checksum = self._checksum(fname) if checksum is None: - raise FatalError('tarball_checksum is missing in {}.recipe for tarball {}\n' - 'The SHA256 of the current file is {}\nPlease verify and ' - 'add it to the recipe'.format(self.name, self.url, found_checksum)) + raise FatalError( + 'tarball_checksum is missing in {}.recipe for tarball {}\n' + 'The SHA256 of the current file is {}\nPlease verify and ' + 'add it to the recipe'.format(self.name, self.url, found_checksum) + ) if found_checksum != checksum: movedto = fname + '.failed-checksum' os.replace(fname, movedto) - m.action(_('Checksum failed, tarball %s moved to %s') % (fname, movedto), logfile=get_logfile(self)) + m.action(N_('Checksum failed, tarball %s moved to %s') % (fname, movedto), logfile=get_logfile(self)) if not fatal: return False - raise FatalError('Checksum for {} is {!r} instead of {!r}' - .format(fname, found_checksum, checksum)) + raise FatalError('Checksum for {} is {!r} instead of {!r}'.format(fname, found_checksum, checksum)) return True async def extract_tarball(self, unpack_dir): @@ -367,8 +410,9 @@ async def extract_tarball(self, unpack_dir): except (CommandError, tarfile.ReadError, zipfile.BadZipFile): movedto = fname + '.failed-extract' os.replace(fname, movedto) - m.action('Corrupted or partial tarball {} moved to {}, redownloading...'.format(fname, movedto), - logfile=logfile) + m.action( + 'Corrupted or partial tarball {} moved to {}, redownloading...'.format(fname, movedto), logfile=logfile + ) if self.offline: # Can't fetch in offline mode raise @@ -377,20 +421,16 @@ async def extract_tarball(self, unpack_dir): class Tarball(BaseTarball, Source): - def __init__(self): Source.__init__(self) if not self.url: - raise InvalidRecipeError( - self, _("'url' attribute is missing in the recipe")) + raise InvalidRecipeError(self, N_("'url' attribute is missing in the recipe")) self.url = self.expand_url_template(self.url) self.url = self.replace_name_and_version(self.url) if self.tarball_name is not None: - self.tarball_name = \ - self.replace_name_and_version(self.tarball_name) + self.tarball_name = self.replace_name_and_version(self.tarball_name) if self.tarball_dirname is not None: - self.tarball_dirname = \ - self.replace_name_and_version(self.tarball_dirname) + self.tarball_dirname = self.replace_name_and_version(self.tarball_dirname) self.download_dir = self.repo_dir BaseTarball.__init__(self) @@ -399,12 +439,16 @@ async def fetch(self, redownload=False): if not os.path.exists(self.download_dir): os.makedirs(self.download_dir) - cached_file = os.path.join(self.config.cached_sources, - self.package_name, self.tarball_name) - if not redownload and os.path.isfile(cached_file) and \ - self.verify(cached_file, self.tarball_checksum, fatal=False): - m.action(_('Copying cached tarball from %s to %s instead of %s') % - (cached_file, fname, self.url), logfile=get_logfile(self)) + cached_file = os.path.join(self.config.cached_sources, self.package_name, self.tarball_name) + if ( + not redownload + and os.path.isfile(cached_file) + and self.verify(cached_file, self.tarball_checksum, fatal=False) + ): + m.action( + N_('Copying cached tarball from %s to %s instead of %s') % (cached_file, fname, self.url), + logfile=get_logfile(self), + ) shutil.copy(cached_file, fname) else: await super().fetch(redownload=redownload) @@ -418,7 +462,7 @@ async def fetch(self, redownload=False): self._extract_done.add(self.config_src_dir) async def extract_impl(self, fetching=False): - m.action(_('Extracting tarball to %s') % self.config_src_dir, logfile=get_logfile(self)) + m.action(N_('Extracting tarball to %s') % self.config_src_dir, logfile=get_logfile(self)) if os.path.exists(self.config_src_dir): shutil.rmtree(self.config_src_dir) @@ -446,10 +490,10 @@ async def extract_impl(self, fetching=False): await self.meson_subprojects_extract(not fetching or self.offline) -class GitCache (Source): - ''' +class GitCache(Source): + """ Base class for source handlers using a Git repository - ''' + """ remotes = None commit = None @@ -465,16 +509,15 @@ def __init__(self): url = self.replace_name_and_version(self.remotes['origin']) o = urllib.parse.urlparse(url) if o.scheme in ('http', 'git'): - raise FatalError('git remote origin URL {!r} must use HTTPS not {!r}' - ''.format(url, o.scheme)) + raise FatalError('git remote origin URL {!r} must use HTTPS not {!r}' ''.format(url, o.scheme)) if o.scheme in ('file', 'ssh'): - m.warning('git remote origin URL {!r} uses {!r}, please only use this ' - 'for testing'.format(url, o.scheme)) + m.warning( + 'git remote origin URL {!r} uses {!r}, please only use this ' 'for testing'.format(url, o.scheme) + ) self.remotes['origin'] = url else: # XXX: When is this used? - self.remotes['origin'] = '%s/%s.git' % \ - (self.config.git_root, self.name) + self.remotes['origin'] = '%s/%s.git' % (self.config.git_root, self.name) self.repo_dir = os.path.join(self.config.local_sources, self.name) # For forced commits in the config self.commit = self.config.recipe_commit(self.name) or self.commit @@ -491,7 +534,7 @@ async def fetch(self, checkout=True): async def fetch_impl(self, checkout): # First try to get the sources from the cached dir if there is one - cached_dir = os.path.join(self.config.cached_sources, self.name) + cached_dir = os.path.join(self.config.cached_sources, self.name) if not os.path.exists(self.repo_dir): if not cached_dir and self.offline: @@ -499,9 +542,9 @@ async def fetch_impl(self, checkout): raise FatalError(msg.format(self.name, self.config.cached_sources, self.repo_dir)) git.init(self.repo_dir, logfile=get_logfile(self)) - if os.path.isdir(os.path.join(cached_dir, ".git")): + if os.path.isdir(os.path.join(cached_dir, '.git')): for remote, url in self.remotes.items(): - git.add_remote(self.repo_dir, remote, "file://" + cached_dir, logfile=get_logfile(self)) + git.add_remote(self.repo_dir, remote, 'file://' + cached_dir, logfile=get_logfile(self)) await git.fetch(self.repo_dir, fail=False, logfile=get_logfile(self)) else: cached_dir = None @@ -515,9 +558,11 @@ async def fetch_impl(self, checkout): if checkout: await git.checkout(self.repo_dir, self.commit, logfile=get_logfile(self)) if self.use_submodules: - await git.submodules_update(self.repo_dir, cached_dir, fail=False, offline=self.offline, logfile=get_logfile(self)) + await git.submodules_update( + self.repo_dir, cached_dir, fail=False, offline=self.offline, logfile=get_logfile(self) + ) if issubclass(self.btype, BuildType.CARGO): - m.log(f'Extracting project to run cargo vendor', logfile=get_logfile(self)) + m.log('Extracting project to run cargo vendor', logfile=get_logfile(self)) await self.extract_impl(fetching=True) self._extract_done.add(self.config_src_dir) elif self.btype == BuildType.MESON and self.meson_subprojects: @@ -525,15 +570,14 @@ async def fetch_impl(self, checkout): await self.extract_impl(fetching=True) self._extract_done.add(self.config_src_dir) - def built_version(self): return '%s+git~%s' % (self.version, git.get_hash(self.repo_dir, self.commit, logfile=get_logfile(self))) -class Git (GitCache): - ''' +class Git(GitCache): + """ Source handler for git repositories - ''' + """ def __init__(self): GitCache.__init__(self) @@ -556,7 +600,13 @@ async def extract_impl(self, fetching=False): os.makedirs(self.config_src_dir) # checkout the current version - await git.local_checkout(self.config_src_dir, self.repo_dir, self.commit, logfile=get_logfile(self), use_submodules=self.use_submodules) + await git.local_checkout( + self.config_src_dir, + self.repo_dir, + self.commit, + logfile=get_logfile(self), + use_submodules=self.use_submodules, + ) for patch in self.patches: if not os.path.isabs(patch): @@ -575,7 +625,7 @@ async def extract_impl(self, fetching=False): class GitExtractedTarball(Git): - ''' + """ Source handle for git repositories with an extracted tarball Git doesn't conserve timestamps, which are reset after clonning the repo. @@ -583,7 +633,7 @@ class GitExtractedTarball(Git): to autoconf, aclocal, autoheaders or automake. For instance after doing './configure && make', 'configure' is called again if 'configure.ac' is newer than 'configure'. - ''' + """ matches = ['.m4', '.in', 'configure'] @@ -597,8 +647,7 @@ async def extract_impl(self): for match in self.matches: self._files[match] = [] self._find_files(self.config_src_dir) - self._files['.in'] = [x for x in self._files['.in'] if - os.path.join(self.config_src_dir, 'm4') not in x] + self._files['.in'] = [x for x in self._files['.in'] if os.path.join(self.config_src_dir, 'm4') not in x] self._fix_ts() def _fix_ts(self): @@ -619,9 +668,9 @@ def _find_files(self, directory): class Svn(Source): - ''' + """ Source handler for svn repositories - ''' + """ url = None revision = 'HEAD' @@ -633,11 +682,13 @@ def __init__(self): async def fetch(self): cached_dir = os.path.join(self.config.cached_sources, self.package_name) - if os.path.isdir(os.path.join(cached_dir, ".svn")): + if os.path.isdir(os.path.join(cached_dir, '.svn')): if os.path.exists(self.repo_dir): shutil.rmtree(self.repo_dir) - m.action(_('Copying cached repo from %s to %s instead of %s') % - (cached_dir, self.repo_dir, self.url), logfile=get_logfile(self)) + m.action( + N_('Copying cached repo from %s to %s instead of %s') % (cached_dir, self.repo_dir, self.url), + logfile=get_logfile(self), + ) shell.copy_dir(cached_dir, self.repo_dir) return @@ -670,8 +721,7 @@ def built_version(self): return '%s+svn~%s' % (self.version, svn.revision(self.repo_dir)) -class SourceType (object): - +class SourceType(object): CUSTOM = CustomSource TARBALL = Tarball GIT = Git diff --git a/cerbero/commands/__init__.py b/cerbero/commands/__init__.py index c90080ae0..863ae75fa 100644 --- a/cerbero/commands/__init__.py +++ b/cerbero/commands/__init__.py @@ -31,8 +31,8 @@ class Command: doc = '' name = None - def __init__(self, arguments=[]): - self.arguments = arguments + def __init__(self, arguments=None): + self.arguments = [] if arguments is None else arguments def run(self, config, args): """The body of the command""" diff --git a/cerbero/commands/build.py b/cerbero/commands/build.py index ca374d567..78eb9c49f 100644 --- a/cerbero/commands/build.py +++ b/cerbero/commands/build.py @@ -31,7 +31,7 @@ class Build(Command): def __init__(self, force=None, no_deps=None, deps_only=False): args = [ - ArgparseArgument('recipe', nargs='*', help=_('name of the recipe to build')), + ArgparseArgument('recipe', nargs='+', help=_('name of the recipe to build')), ArgparseArgument( '--missing-files', action='store_true', @@ -62,7 +62,7 @@ def __init__(self, force=None, no_deps=None, deps_only=False): ArgparseArgument( '--steps', '-s', - nargs='*', + nargs='+', action='store', type=str, help=_('List of steps to execute, instead of all build steps.'), diff --git a/cerbero/commands/bundlesource.py b/cerbero/commands/bundlesource.py index 68ee7f89f..588af02ef 100644 --- a/cerbero/commands/bundlesource.py +++ b/cerbero/commands/bundlesource.py @@ -31,7 +31,7 @@ class BundleSource(Command): doc = N_('Bundle Source code of recipes and Cerbero') name = 'bundle-source' - def __init__(self, args=[]): + def __init__(self, args=None): args = [ ArgparseArgument('bundlepackages', nargs='+', help=_('packages to bundle')), ArgparseArgument('--add-recipe', action='append', default=[], help=_('additional recipes to bundle')), diff --git a/cerbero/commands/cache.py b/cerbero/commands/cache.py index 2560b7d24..6ee182036 100644 --- a/cerbero/commands/cache.py +++ b/cerbero/commands/cache.py @@ -20,44 +20,80 @@ import sys import json import tempfile +import pickle import shutil from hashlib import sha256 from cerbero.commands import Command, register_command from cerbero.enums import Platform, Distro from cerbero.errors import FatalError -from cerbero.utils import _, N_, ArgparseArgument, git, shell, run_until_complete +from cerbero.utils import N_, ArgparseArgument, git, shell, run_until_complete from cerbero.utils import messages as m class BaseCache(Command): - base_url = 'https://artifacts.gstreamer-foundation.net/cerbero-deps/%s/%s/%s' + base_url = 'https://artifacts.gstreamer-foundation.net/cerbero-deps' ssh_address = 'cerbero-deps-uploader@artifacts.gstreamer-foundation.net' - # FIXME: fetch this value from CI env vars - build_dir = '/builds/%s/cerbero/cerbero-build' deps_filename = 'cerbero-deps.tar.xz' log_filename = 'cerbero-deps.log' log_size = 10 + dry_run = False - def __init__(self, args=[]): - args.append( + def __init__(self, args=None): + if args is None: + args = [] + args += [ ArgparseArgument( - '--commit', action='store', type=str, default='HEAD', help=_('the commit to pick artifact from') - ) - ) - args.append( - ArgparseArgument('--branch', action='store', type=str, default='main', help=_('Git branch to search from')) - ) + '--commit', action='store', type=str, default='HEAD', help='the commit to pick artifact from' + ), + ArgparseArgument('--branch', action='store', type=str, default='main', help='Git branch to search from'), + ArgparseArgument('--dry-run', action='store_true', help='Run without doing any writes'), + ArgparseArgument( + '--project', + action='store', + type=str, + default='gstreamer', + help='Gitlab project (gstreamer or gst-plugins-rs)', + ), + ] Command.__init__(self, args) + def get_cache_home_dir(self, config): + """ + Use the python virtual env config file in the build-tools dir to fetch + cerbero's home_dir. If it doesn't exist, we will error out loudly, + since it indicates a corrupted cache. + """ + cache_file = os.path.join(config.build_tools_prefix, 'pyvenv.cfg') + with open(cache_file, 'r', encoding='utf-8') as f: + for line in f: + if not line.startswith('command = '): + continue + _, cmd = line.split(' = ') + cache_build_tools_prefix = cmd.split(' -m venv ')[1].strip() + return os.path.dirname(cache_build_tools_prefix) + cache_file = os.path.join(config.build_tools_prefix, 'bin', 'meson') + with open(cache_file, 'r', encoding='utf-8') as f: + line = f.readline() + if line.startswith('#!'): + split_idx = line.rfind('/build-tools/bin/python') + return line[2:split_idx] + raise FatalError('Failed to relocate prefix: could not deduce cache homedir') + + def get_gnu_sed(self, config): + if config.platform == Platform.DARWIN: + return os.path.join(config.build_tools_prefix, 'bin', 'sed') + return 'sed' + # FIXME: move this to utils def checksum(self, fname): h = sha256() - with open(fname, 'rb') as f: - # Read in chunks of 512k till f.read() returns b'' instead of reading - # the whole file at once which will fail on systems with low memory - for block in iter(lambda: f.read(512 * 1024), b''): - h.update(block) + if not self.dry_run: + with open(fname, 'rb') as f: + # Read in chunks of 512k till f.read() returns b'' instead of reading + # the whole file at once which will fail on systems with low memory + for block in iter(lambda: f.read(512 * 1024), b''): + h.update(block) return h.hexdigest() def get_git_sha(self, commit): @@ -87,9 +123,9 @@ def get_distro_and_arch(self, config): target_arch = config.target_arch if distro == Distro.REDHAT: distro = 'fedora' - if distro == Distro.OS_X: + elif distro == Distro.OS_X: distro = 'macos' - if distro == Distro.WINDOWS: + elif distro == Distro.WINDOWS: # When targeting Windows, we need to differentiate between mingw, # msvc, and uwp (debug/release) jobs. When cross-compiling this # will always be 'cross-windows-mingw' right now, but that might @@ -101,11 +137,15 @@ def get_distro_and_arch(self, config): target_distro = f'{distro}_{config.arch}' return target_distro, target_arch - def make_url(self, config, args, filename): + def get_artifact_dir(self, config, args): + project = args.project branch = args.branch distro, arch = self.get_distro_and_arch(config) - base_url = self.base_url % (branch, distro, arch) - return '%s/%s' % (base_url, filename) + return '/'.join([project, branch, distro, arch]) + + def make_url(self, config, args, filename): + artifact_dir = self.get_artifact_dir(config, args) + return '%s/%s/%s' % (self.base_url, artifact_dir, filename) def get_deps(self, config, args): url = self.make_url(config, args, self.log_filename) @@ -124,22 +164,15 @@ def get_log_filepath(self, config): return os.path.join(config.home_dir, self.log_filename) def run(self, config, args): + self.dry_run = args.dry_run if not config.uninstalled: - raise FatalError(_('fetch-cache is only available with ' 'cerbero-uninstalled')) + raise FatalError('fetch-cache is only available with cerbero-uninstalled') class FetchCache(BaseCache): doc = N_('Fetch a cached build from external storage based on cerbero git ' 'revision.') name = 'fetch-cache' - def __init__(self, args=[]): - args.append( - ArgparseArgument( - '--namespace', action='store', type=str, default='gstreamer', help=_('GitLab namespace to search from') - ) - ) - BaseCache.__init__(self, args) - def find_dep(self, deps, sha, allow_old=False): for dep in deps: if dep['commit'] == sha: @@ -156,35 +189,113 @@ def find_dep(self, deps, sha, allow_old=False): m.warning(f'Did not find cache for commit {sha}') return None - async def fetch_dep(self, config, dep, namespace): + @staticmethod + def _is_mach_o_file(filename): + fileext = os.path.splitext(filename)[1] + if '.dylib' in fileext: + return True + filedesc = shell.check_output(['file', '-bh', filename]) + if fileext == '.a' and 'ar archive' in filedesc: + return False + return filedesc.startswith('Mach-O') + + @staticmethod + def _list_shared_libraries(object_file): + res = shell.check_output(['otool', '-L', object_file]).splitlines() + # We don't use the first line + libs = res[1:] + # Remove the first character tabulation + libs = [x[1:] for x in libs] + # Remove the version info + libs = [x.split(' ', 1)[0] for x in libs] + return libs + + @classmethod + def _change_lib_paths(self, object_file, old_path, new_path): + for lib in self._list_shared_libraries(object_file): + if old_path not in lib: + continue + new = lib.replace(old_path, new_path) + cmd = ['install_name_tool', '-change', lib, new, object_file] + shell.new_call(cmd, fail=True, verbose=True) + + def relocate_macos_build_tools(self, config, old_paths, new_path): + """ + build-tools on macOS have absolute paths as install names for all + Mach-O files, so we need to relocate them to the new prefix. + The Universal build isn't affected because Cerbero relocates the + binaries there. + """ + paths = [ + os.path.join(config.build_tools_prefix, 'bin'), + os.path.join(config.build_tools_prefix, 'lib'), + ] + for dir_path in paths: + for dirpath, _dirnames, filenames in os.walk(dir_path): + for f in filenames: + object_file = os.path.join(dirpath, f) + if not self._is_mach_o_file(object_file): + continue + for path in old_paths: + self._change_lib_paths(object_file, path, new_path) + + def mark_windows_build_tools_dirty(self, config): + """ + On Windows, Python virtualenv writes out an executable for all + pip-installed Python programs, which need to be rebuilt for the current + prefix. Currently, this is just Meson in build-tools. + """ + cache_file = os.path.join(config.home_dir, config.build_tools_cache) + with open(cache_file, 'rb+') as f: + p = pickle.load(f) + # Reset the recipe status + del p['meson'] + f.seek(0) + f.truncate(0) + pickle.dump(p, f) + + def relocate_prefix(self, config): + """ + We need to relocate pc files that weren't generated by meson and + python programs installed with pip because the shebang set by the + virtualenv python uses an absolute path. + """ + origin = self.get_cache_home_dir(config) + dest = config.home_dir + if origin == dest: + return + m.action(f'Relocating text files from {origin} to {dest}') + sed = self.get_gnu_sed(config) + # This is hacky, but fast enough + origins = [origin] + if origin.startswith('/var/'): + origins.append(f'/private/{origin}') # macOS APFS symbolic link + for o in origins: + shell.call(f'grep -lrIe {o} {dest} | xargs {sed} "s#{o}#{dest}#g" -i', verbose=True) + # Need to relocate RPATHs and names in binaries + if config.platform == Platform.DARWIN: + self.relocate_macos_build_tools(config, origins, dest) + elif config.platform == Platform.WINDOWS: + self.mark_windows_build_tools_dirty(config) + + async def fetch_dep(self, config, dep): + is_ci = 'CI' in os.environ try: dep_path = os.path.join(config.home_dir, os.path.basename(dep['url'])) m.action(f'Downloading deps cache {dep["url"]}') - await shell.download(dep['url'], dep_path, overwrite=True) - if dep['checksum'] == self.checksum(dep_path): - m.action(f'Unpacking deps cache {dep_path}') - await shell.unpack(dep_path, config.home_dir) - else: + if self.dry_run: + return + await shell.download(dep['url'], dep_path, overwrite=is_ci) + if dep['checksum'] != self.checksum(dep_path): m.warning('Corrupted dependency file, ignoring.') - m.action('Unpack complete, deleting artifact') - os.remove(dep_path) - - # Don't need to relocate on Windows and macOS since we build - # pkg-config with --enable-define-prefix. - # In case this needs to be re-enabled at some point, note that the - # current self.build_dir value is hard-coded and is wrong on macOS - # and Windows. It should instead be derived from CI env vars. - if config.platform == Platform.LINUX: - origin = self.build_dir % namespace - m.action('Relocating from %s to %s' % (origin, config.home_dir)) - # FIXME: Just a quick hack for now - shell.call( - ('grep -lnrIU %(origin)s | xargs ' 'sed "s#%(origin)s#%(dest)s#g" -i') - % {'origin': origin, 'dest': config.home_dir}, - config.home_dir, - ) + m.action(f'Unpacking deps cache {dep_path}') + await shell.unpack(dep_path, config.home_dir) + if is_ci: + m.action('Unpack complete, deleting artifact') + os.remove(dep_path) except FatalError as e: m.warning('Could not retrieve dependencies for commit %s: %s' % (dep['commit'], e.msg)) + self.relocate_prefix(config) def run(self, config, args): BaseCache.run(self, config, args) @@ -193,7 +304,7 @@ def run(self, config, args): deps = self.get_deps(config, args) dep = self.find_dep(deps, sha, allow_old=True) if dep: - run_until_complete(self.fetch_dep(config, dep, args.namespace)) + run_until_complete(self.fetch_dep(config, dep)) m.message('All done!') @@ -201,7 +312,9 @@ class GenCache(BaseCache): doc = N_('Generate build cache from current state.') name = 'gen-cache' - def __init__(self, args=[]): + def __init__(self, args=None): + if args is None: + args = [] BaseCache.__init__(self, args) def create_tarball_tarfile(self, workdir, out_file, *in_files, exclude=None): @@ -213,7 +326,6 @@ def exclude_filter(tarinfo): for each in exclude: if each in tarinfo.name: return None - print(tarinfo.name) return tarinfo prev_cwd = os.getcwd() @@ -226,14 +338,13 @@ def exclude_filter(tarinfo): finally: os.chdir(prev_cwd) m.action('Compressing cache file with xz') - shell.new_call(['xz', '-vv', '--threads=0', out_tar]) + shell.new_call(['xz', '--threads=0', out_tar]) def create_tarball_tar(self, workdir, out_file, *in_files, exclude=None): cmd = [ shell.get_tar_cmd(), '-C', workdir, - '--verbose', '--use-compress-program=xz --threads=0', ] for each in exclude: @@ -241,7 +352,8 @@ def create_tarball_tar(self, workdir, out_file, *in_files, exclude=None): cmd += ['-cf', out_file] cmd += in_files m.action(f'Generating cache file with {cmd!r}') - shell.new_call(cmd) + if not self.dry_run: + shell.new_call(cmd) def create_tarball(self, config, workdir, *args): exclude = ['var/tmp'] @@ -254,11 +366,11 @@ def create_tarball(self, config, workdir, *args): def gen_dep(self, config, args, deps, sha): deps_filepath = self.get_deps_filepath(config) - if os.path.exists(deps_filepath): + if not self.dry_run and os.path.exists(deps_filepath): os.remove(deps_filepath) log_filepath = self.get_log_filepath(config) - if os.path.exists(log_filepath): + if not self.dry_run and os.path.exists(log_filepath): os.remove(log_filepath) workdir = config.home_dir @@ -271,15 +383,23 @@ def gen_dep(self, config, args, deps, sha): url = self.make_url(config, args, '%s-%s' % (sha, self.deps_filename)) deps.insert(0, {'commit': sha, 'checksum': self.checksum(deps_filepath), 'url': url}) deps = deps[0 : self.log_size] - with open(log_filepath, 'w') as outfile: - json.dump(deps, outfile, indent=1) + log_json = json.dumps(deps, indent=1) + if self.dry_run: + print('Generated JSON:') + print(log_json) + else: + with open(log_filepath, 'w') as outfile: + outfile.write(log_json) except FatalError: if os.path.exists(deps_filepath): os.remove(deps_filepath) if os.path.exists(log_filepath): os.remove(log_filepath) raise - fsize = os.path.getsize(deps_filepath) / (1024 * 1024) + if self.dry_run: + fsize = -1 + else: + fsize = os.path.getsize(deps_filepath) / (1024 * 1024) m.message(f'build-dep cache {deps_filepath} of size {fsize:.2f}MB generated') def run(self, config, args): @@ -294,7 +414,9 @@ class UploadCache(BaseCache): doc = N_('Build build cache to external storage.') name = 'upload-cache' - def __init__(self, args=[]): + def __init__(self, args=None): + if args is None: + args = [] BaseCache.__init__(self, args) def upload_dep(self, config, args, deps): @@ -310,8 +432,9 @@ def upload_dep(self, config, args, deps): deps_filepath = self.get_deps_filepath(config) log_filepath = self.get_log_filepath(config) - if not os.path.exists(deps_filepath) or not os.path.exists(log_filepath): - raise FatalError(_('gen-cache must be run before running upload-cache.')) + if not self.dry_run: + if not os.path.exists(deps_filepath) or not os.path.exists(log_filepath): + raise FatalError('gen-cache must be run before running upload-cache.') try: # Setup tempory private key from env @@ -326,31 +449,41 @@ def upload_dep(self, config, args, deps): scp_cmd = ['scp'] + ssh_opt # Ensure directory sturcture is in place - branch = args.branch - distro, arch = self.get_distro_and_arch(config) - base_dir = os.path.join(branch, distro, arch) - shell.new_call(ssh_cmd + ['mkdir -p %s' % base_dir], verbose=True) + base_dir = self.get_artifact_dir(config, args) + m.message(f'Making directory structure: {base_dir}') + if not self.dry_run: + shell.new_call(ssh_cmd + ['mkdir -p %s' % base_dir], verbose=True) # Upload the deps files first remote_deps_filepath = os.path.join(base_dir, '%s-%s' % (sha, self.deps_filename)) - shell.new_call(scp_cmd + [deps_filepath, '%s:%s' % (self.ssh_address, remote_deps_filepath)], verbose=True) + upload_cmd = scp_cmd + [deps_filepath, f'{self.ssh_address}:{remote_deps_filepath}'] + m.message(f'Uploading deps file: {upload_cmd!r}') + if not self.dry_run: + shell.new_call(upload_cmd, verbose=True) # Upload the new log remote_tmp_log_filepath = os.path.join(base_dir, '%s-%s' % (sha, self.log_filename)) - shell.new_call( - scp_cmd + [log_filepath, '%s:%s' % (self.ssh_address, remote_tmp_log_filepath)], verbose=True - ) + upload_cmd = scp_cmd + [log_filepath, f'{self.ssh_address}:{remote_tmp_log_filepath}'] + m.message(f'Uploading deps log: {upload_cmd!r}') + if not self.dry_run: + shell.new_call(upload_cmd, verbose=True) # Override the new log in a way that we reduce the risk of corrupted # fetch. remote_log_filepath = os.path.join(base_dir, self.log_filename) - shell.new_call(ssh_cmd + ['mv', '-f', remote_tmp_log_filepath, remote_log_filepath], verbose=True) + rename_cmd = ssh_cmd + ['mv', '-f', remote_tmp_log_filepath, remote_log_filepath] + m.message(f'Renaming deps log: {rename_cmd!r}') + if not self.dry_run: + shell.new_call(rename_cmd, verbose=True) m.message('New deps cache uploaded and deps log updated') # Now remove the obsoleted dep file if needed for dep in deps[self.log_size - 1 :]: - old_remote_deps_filepath = os.path.join(base_dir, os.path.basename(dep['url'])) - shell.new_call(ssh_cmd + ['rm', '-f', old_remote_deps_filepath], verbose=True) + old_remote_deps_filepath = os.path.relpath(dep['url'], self.base_url) + rm_cmd = ['rm', '-f', old_remote_deps_filepath] + m.message(f'Removing obsolete dep file: {rm_cmd!r}') + if not self.dry_run: + shell.new_call(ssh_cmd + rm_cmd, verbose=True) finally: shutil.rmtree(tmpdir) diff --git a/cerbero/commands/debugpackages.py b/cerbero/commands/debugpackages.py index df50c5aa5..ffa2a907b 100644 --- a/cerbero/commands/debugpackages.py +++ b/cerbero/commands/debugpackages.py @@ -58,7 +58,9 @@ def find_duplicates(self, allfiles): m.message('Found duplicates files in packages:') m.message('%r' % duplicates) - def find_orphan_files(self, allfiles, prefix, excludes=[]): + def find_orphan_files(self, allfiles, prefix, excludes=None): + if excludes is None: + excludes = [] cmd = ['find', '.', '-type', 'f'] for x in excludes: cmd += ['(', '!', '-name', x, ')'] diff --git a/cerbero/commands/deps.py b/cerbero/commands/deps.py index 91bea2224..1386370e2 100644 --- a/cerbero/commands/deps.py +++ b/cerbero/commands/deps.py @@ -66,7 +66,9 @@ def run(self, config, args): m.message(recipe.name) else: - def print_dep(cookbook, recipe, level=0, already_shown=[]): + def print_dep(cookbook, recipe, level=0, already_shown=None): + if already_shown is None: + already_shown = [] m.message('%s%s' % (' ' * 3 * level, recipe.name)) already_shown.append(recipe) for r in [cookbook.get_recipe(x) for x in recipe.list_deps()]: diff --git a/cerbero/commands/edit_cache.py b/cerbero/commands/edit_cache.py index d6d67eed9..9b742f9b1 100644 --- a/cerbero/commands/edit_cache.py +++ b/cerbero/commands/edit_cache.py @@ -50,16 +50,37 @@ def __init__(self): for attr in self.recipe_attributes: attr_nargs = '*' if isinstance(getattr(self.recipe_status, attr), list) else None attr_type = type(getattr(self.recipe_status, attr)) - arg_type = str if attr_type == bool or attr_type == list else attr_type - arguments.append(ArgparseArgument('--' + attr, nargs=attr_nargs, type=arg_type, help=_('Modify ' + attr))) + arg_type = str if attr_type is bool or attr_type is list else attr_type + arguments.append(ArgparseArgument('--' + attr, nargs=attr_nargs, type=arg_type, help=N_('Modify ' + attr))) Command.__init__(self, arguments) + def _modify(self, recipe_name, cookbook, status, args): + if args.reset: + cookbook.reset_recipe_status(recipe_name) + m.message(f'Recipe {recipe_name} reset') + return + if args.touch: + status.touch() + for attr in self.recipe_attributes: + var = getattr(args, attr) + if var is not None: + if isinstance(getattr(self.recipe_status, attr), bool): + if var.lower() == 'true': + var = True + elif var.lower() == 'false': + var = False + else: + m.error(f'Error: Attribute "{attr}" needs to be either "True" or "False"') + return + setattr(status, attr, var) + print(f'After : {recipe_name}: {status}') + def run(self, config, args): if args.bootstrap: config.cache_file = config.build_tools_cache - cookbook = CookBook(config) + cookbook = CookBook(config, reset_status=False) - is_modifying = False or args.touch or args.reset + is_modifying = args.touch or args.reset if not is_modifying: for attr in self.recipe_attributes: if getattr(args, attr) is not None: @@ -73,39 +94,19 @@ def run(self, config, args): '{} cache values for recipes: {}'.format('Showing' if not is_modifying else 'Modifying', ', '.join(recipes)) ) - for recipe in recipes: - if recipe not in global_status.keys(): - m.error('Recipe {} not in cookbook'.format(recipe)) + for recipe_name in recipes: + if recipe_name not in global_status.keys(): + m.error(f'Recipe {recipe_name} not in cookbook') continue - status = global_status[recipe] - print('[{}]'.format(recipe)) + status = global_status[recipe_name] text = '' if is_modifying: - text = 'Before\n' - print('{}{}\n'.format(text, status)) + text = 'Before: ' + print(f'{text}{recipe_name}: ', end='') + print(f'{status}') if is_modifying: - if args.reset: - cookbook.reset_recipe_status(recipe) - m.message('Recipe {} reset'.format(recipe)) - else: - if args.touch: - status.touch() - - for attr in self.recipe_attributes: - var = getattr(args, attr) - if var is not None: - if isinstance(getattr(self.recipe_status, attr), bool): - if var.lower() == 'true': - var = True - elif var.lower() == 'false': - var = False - else: - m.error('Error: Attribute "{}" needs to be either "True" or "False"'.format(attr)) - return - setattr(status, attr, var) - - cookbook.save() - print('After\n{}\n'.format(status)) + self._modify(recipe_name, cookbook, status, args) + cookbook.save() register_command(EditCache) diff --git a/cerbero/commands/fetch.py b/cerbero/commands/fetch.py index db12d6075..1a9171d85 100644 --- a/cerbero/commands/fetch.py +++ b/cerbero/commands/fetch.py @@ -40,7 +40,9 @@ class Fetch(Command): - def __init__(self, args=[]): + def __init__(self, args=None): + if args is None: + args = [] args.append( ArgparseArgument( '--reset-rdeps', diff --git a/cerbero/commands/gensdkshell.py b/cerbero/commands/gensdkshell.py index c7f6da294..c84ee5ccd 100644 --- a/cerbero/commands/gensdkshell.py +++ b/cerbero/commands/gensdkshell.py @@ -75,6 +75,7 @@ def runargs( cmd=None, env=None, prefix_env_name='GSTREAMER_ROOT', + root_from_name=False, ): if cmd is None: cmd = self.DEFAULT_CMD @@ -85,19 +86,25 @@ def runargs( self._env = env prefix_env = '${%s}' % prefix_env_name libdir = libdir.replace(prefix, prefix_env) + if isinstance(py_prefixes, str): + python_path = os.path.join(prefix_env, py_prefixes) + elif isinstance(py_prefixes, list): + python_path = os.pathsep.join(py_prefixes) + else: + python_path = '' self._putvar('PATH', '%s/bin${PATH:+:$PATH}' % prefix_env) self._putvar('LD_LIBRARY_PATH', '%s${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}' % libdir) self._putvar( 'PKG_CONFIG_PATH', - '%s/lib/pkgconfig:%s/share/pkgconfig' '${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}' % (prefix_env, prefix_env), + '%s/pkgconfig:%s/share/pkgconfig' '${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}' % (libdir, prefix_env), ) self._putvar('XDG_DATA_DIRS', '%s/share${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}' % prefix_env) self._putvar('XDG_CONFIG_DIRS', '%s/etc/xdg${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}' % prefix_env) self._putvar('GST_REGISTRY_1_0', '${HOME}/.cache/gstreamer-1.0/gstreamer-cerbero-registry', None) self._putvar('GST_PLUGIN_SCANNER_1_0', '%s/libexec/gstreamer-1.0/gst-plugin-scanner' % prefix_env) - self._putvar('GST_PLUGIN_PATH_1_0', '%s/lib/gstreamer-1.0' % prefix_env) - self._putvar('GST_PLUGIN_SYSTEM_PATH_1_0', '%s/lib/gstreamer-1.0' % prefix_env) - self._putvar('PYTHONPATH', '%s${PYTHONPATH:+:$PYTHONPATH}' % (os.pathsep.join(py_prefixes))) + self._putvar('GST_PLUGIN_PATH_1_0', '%s/gstreamer-1.0' % libdir) + self._putvar('GST_PLUGIN_SYSTEM_PATH_1_0', '%s/gstreamer-1.0' % libdir) + self._putvar('PYTHONPATH', '%s${PYTHONPATH:+:$PYTHONPATH}' % python_path) self._putvar('CFLAGS', '-I%s/include ${CFLAGS}' % prefix_env, ' ') self._putvar('CXXFLAGS', '-I%s/include ${CXXFLAGS}' % prefix_env, ' ') self._putvar('CPPFLAGS', '-I%s/include ${CPPFLAGS}' % prefix_env, ' ') @@ -105,7 +112,13 @@ def runargs( self._putvar('GIO_EXTRA_MODULES', '%s/gio/modules' % libdir) self._putvar('GI_TYPELIB_PATH', '%s/girepository-1.0' % libdir) - envstr = 'export %s="%s"\n' % (prefix_env_name, prefix) + envstr = '' + if root_from_name: + envstr += 'scriptdir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]:-${(%):-%x}}" )" &> /dev/null && pwd)\n' + envstr += 'export ' + prefix_env_name + '="${scriptdir%"/' + os.path.dirname(name) + '"}"\n' + envstr += 'unset scriptdir\n' + else: + envstr += 'export %s="%s"\n' % (prefix_env_name, prefix) for e, v in env.items(): envstr += 'export %s="%s"\n' % (e, v) try: diff --git a/cerbero/commands/genvsprops.py b/cerbero/commands/genvsprops.py index dd802954d..d0b9991ce 100644 --- a/cerbero/commands/genvsprops.py +++ b/cerbero/commands/genvsprops.py @@ -51,7 +51,7 @@ def __init__(self): def run(self, config, args): self.runargs(config, args.output_dir, args.prefix) - def runargs(self, config, output_dir, prefix=DEFAULT_PREFIX_MACRO): + def runargs(self, config, output_dir, prefix=DEFAULT_PREFIX_MACRO, logfile=None): if not os.path.exists(output_dir): os.makedirs(output_dir) @@ -60,7 +60,7 @@ def runargs(self, config, output_dir, prefix=DEFAULT_PREFIX_MACRO): pc, prefix=config.prefix, inherit_common=True, prefix_replacement='$(%s)' % prefix, env=config.env ) p2v.create(output_dir) - m.action('Created %s.props' % pc) + m.log('Created %s.props' % pc, logfile=logfile) common = CommonProps(prefix) common.create(output_dir) diff --git a/cerbero/commands/graph.py b/cerbero/commands/graph.py index 40bc59928..6f2ec3011 100644 --- a/cerbero/commands/graph.py +++ b/cerbero/commands/graph.py @@ -101,7 +101,9 @@ def run(self, config, args): shell.new_call(['dot', '-Tsvg', tmp.name, '-o', output]) m.message('Dependency graph for %s generated at %s' % (name, output)) - def _dot_gen(self, name, graph_type, already_parsed=[]): + def _dot_gen(self, name, graph_type, already_parsed=None): + if already_parsed is None: + already_parsed = [] already_parsed.append(name) if graph_type == GraphType.RECIPE: deps = self.cookbook.get_recipe(name).list_deps() diff --git a/cerbero/commands/list.py b/cerbero/commands/list.py index 80b8f5795..b5034b8ff 100644 --- a/cerbero/commands/list.py +++ b/cerbero/commands/list.py @@ -18,7 +18,7 @@ from cerbero.commands import Command, register_command from cerbero.build.cookbook import CookBook -from cerbero.utils import _, N_ +from cerbero.utils import _, N_, ArgparseArgument from cerbero.utils import messages as m from cerbero.packages.packagesstore import PackagesStore @@ -59,17 +59,37 @@ class ShowConfig(Command): name = 'show-config' def __init__(self): - Command.__init__(self, []) + arguments = [ + ArgparseArgument('--archs', action='store_true', default=False, help=_('Show also the arch config if any')), + ArgparseArgument( + '--build-tools', action='store_true', default=False, help=_('Show also the boot tools config if any') + ), + ] + Command.__init__(self, arguments) def run(self, config, args): + self._print_config(config) + if args.archs and config.arch_config and len(config.arch_config) > 0 and tuple(config.arch_config) != (None,): + archs = list(config.arch_config.keys()) + archs.sort() + print('Arch configs:', ', '.join(archs)) + for a in archs: + print(a, 'arch:') + self._print_config(config.arch_config[a]) + if args.build_tools and config.build_tools_config: + print('Build tools config:') + self._print_config(config.build_tools_config) + + def _print_config(self, config): for n in config._properties: - if n == 'variants': - print('%25s :' % (n)) - variants = getattr(config, n).__dict__ - for v in variants: - print('%30s : %s' % (v, variants[v])) - else: - print('%25s : %s' % (n, getattr(config, n))) + print('%25s : %s' % (n, getattr(config, n))) + # Now the variants + print('%25s :' % 'variants') + variants = config.variants.__dict__ + for v in variants: + if v.startswith('_'): + continue + print('%30s : %s' % (v, variants[v])) register_command(List) diff --git a/cerbero/commands/package.py b/cerbero/commands/package.py index 3fdd8b9a0..de981ad34 100644 --- a/cerbero/commands/package.py +++ b/cerbero/commands/package.py @@ -84,6 +84,14 @@ def __init__(self): 'Only build the recipes needed to ' 'create this package (conflicts with --skip-deps-build)' ), ), + ArgparseArgument( + '--exclude', + '-e', + action='append', + type=str, + default=None, + help=_('Recipes to exclude when building, only when using --only-build-deps'), + ), ArgparseArgument( '-k', '--keep-temp', action='store_true', default=False, help=_('Keep temporary files for debug') ), @@ -121,8 +129,11 @@ def run(self, config, args): if args.skip_deps_build and args.only_build_deps: raise UsageError(_('Cannot use --skip-deps-build together with ' '--only-build-deps')) + if args.exclude and not args.only_build_deps: + raise UsageError(_('Cannot use --exclude without --only-build-deps')) + if not args.skip_deps_build: - self._build_deps(config, p, args.no_devel, args.offline, args.dry_run, args.jobs) + self._build_deps(config, p, args.no_devel, args.exclude, args.offline, args.dry_run, args.jobs) if args.only_build_deps or args.dry_run: return @@ -163,11 +174,14 @@ def run(self, config, args): paths = p.post_package(paths, output_dir) or paths m.action(_('Package successfully created in %s') % ' '.join([os.path.abspath(x) for x in paths])) - def _build_deps(self, config, package, has_devel, offline, dry_run, jobs): + def _build_deps(self, config, package, has_devel, exclude, offline, dry_run, jobs): build_command = build.Build() + deps = set(package.recipes_dependencies(has_devel)) + if exclude: + deps.difference_update(exclude) build_command.runargs( config, - package.recipes_dependencies(has_devel), + deps, cookbook=self.store.cookbook, dry_run=dry_run, offline=offline, diff --git a/cerbero/config.py b/cerbero/config.py index 4adacfdad..309b23c2a 100644 --- a/cerbero/config.py +++ b/cerbero/config.py @@ -29,7 +29,7 @@ from cerbero.errors import FatalError, ConfigurationError from cerbero.utils import _, system_info, validate_packager, shell from cerbero.utils import to_unixpath, to_winepath, parse_file, detect_qt5, detect_qt6 -from cerbero.utils import EnvVar, EnvValue +from cerbero.utils import merge_str_env, merge_env_value_env from cerbero.utils import messages as m from cerbero.ide.pkgconfig import PkgConfig from cerbero.ide.vs.env import get_vs_year_version @@ -43,7 +43,7 @@ DEFAULT_ALLOW_PARALLEL_BUILD = True DEFAULT_PACKAGER = 'Default ' CERBERO_UNINSTALLED = 'CERBERO_UNINSTALLED' -DEFAULT_MIRRORS = ['https://gstreamer.freedesktop.org/src/mirror/'] +DEFAULT_MIRRORS = ['https://gstreamer.freedesktop.org/src/mirror'] RUST_TRIPLE_MAPPING = { (Platform.ANDROID, Architecture.ARM64): 'aarch64-linux-android', (Platform.ANDROID, Architecture.ARMv7): 'armv7-linux-androideabi', @@ -106,7 +106,7 @@ class Variants(object): 'rust', 'qt6', ] - __enabled_variants = ['debug', 'optimization', 'testspackage'] + __enabled_variants = ['debug', 'optimization', 'testspackage', 'assert', 'checks'] __bool_variants = __enabled_variants + __disabled_variants # Variants that are `key: (values)`, with the first value in the tuple # being the default @@ -117,29 +117,44 @@ class Variants(object): } def __init__(self, variants): + # Keeps a list of variants overriden by the user after initialization + self.__overridden_variants = set() # Set default values + self.reset() + self.override(variants) + + def reset(self): for v in self.__enabled_variants: setattr(self, v, True) for v in self.__disabled_variants: setattr(self, v, False) for v, choices in self.__mapping_variants.items(): setattr(self, v, choices[0]) - self.override(variants) + # reset after all inits + self.__overridden_variants.clear() def set_bool(self, key): + val = True if key.startswith('no'): key = key[2:] - if key not in self.__bool_variants: - m.warning('Variant {!r} is unknown or obsolete'.format(key)) - setattr(self, key, False) - else: - if key not in self.__bool_variants: - m.warning('Variant {!r} is unknown or obsolete'.format(key)) - setattr(self, key, True) + val = False + if key not in self.__bool_variants: + m.warning('Variant {!r} is unknown or obsolete'.format(key)) + setattr(self, key, val) + + def override(self, variants, force=True): + """ + Override existing variants using value (str) or values (list) from `variants`. + + If `force` is `False`, do not override those variants that are already overridden + after the object initialization. + """ - def override(self, variants): if not isinstance(variants, list): variants = [variants] + if not force: + variants = [v for v in variants if not self._is_overridden(v)] + # Set the configured values for v in variants: if '=' in v: @@ -164,10 +179,16 @@ def __setattr__(self, attr, value): if '-' in attr: raise AssertionError("Variant name {!r} must not contain '-'".format(attr)) super().__setattr__(attr, value) + if attr in ['_Variants__overridden_variants']: + return + + self.__overridden_variants.add(attr) # UWP implies Visual Studio if attr == 'uwp' and value: self.visualstudio = True + self.__overridden_variants.add('visualstudio') self.mingw = False + self.__overridden_variants.add('mingw') def __getattr__(self, name): if name.startswith('no') and name[2:] in self.bools(): @@ -185,6 +206,17 @@ def bools(self): def mappings(self): return sorted(self.__mapping_variants) + def _is_overridden(self, variant): + if not isinstance(variant, str): + return False + if variant.startswith('no'): + real_name = variant[2:] + if real_name not in self.bools(): + return False + else: + real_name = variant + return real_name in self.__overridden_variants + class Config(object): """ @@ -242,8 +274,8 @@ class Config(object): 'use_ccache', 'force_git_commit', 'universal_archs', + 'universal_prefix', 'osx_target_sdk_version', - 'variants', 'build_tools_prefix', 'build_tools_sources', 'build_tools_logs', @@ -279,6 +311,7 @@ class Config(object): 'package_tarball_compression', 'extra_mirrors', 'extra_bootstrap_packages', + 'override_bootstrap_packages', 'moltenvk_prefix', 'vs_install_path', 'vs_install_version', @@ -314,6 +347,8 @@ def __init__(self, is_build_tools_config=False): # Store raw os.environ data self._pre_environ = os.environ.copy() self.config_env = os.environ.copy() + # Initialize variants + self.variants = Variants([]) def _copy(self, arch): c = copy.deepcopy(self) @@ -329,18 +364,16 @@ def load(self, filename=None, variants_override=None): if variants_override is None: variants_override = [] - # Initialize variants - self.variants = Variants(variants_override) + # Reset variants + self.variants.reset() + self.variants.override(variants_override) # First load the default configuration self.load_defaults() # Use Visual Studio by default when building on Windows - if not self.variants.mingw and not self.variants.visualstudio: - if self.platform == Platform.WINDOWS: - self.variants.override(['visualstudio']) - else: - self.variants.override(['mingw']) + if not self.variants.mingw and not self.variants.visualstudio and self.platform == Platform.WINDOWS: + self.variants.override(['visualstudio']) # Next parse the user configuration file USER_CONFIG_FILE # which overrides the defaults @@ -396,7 +429,10 @@ def load(self, filename=None, variants_override=None): for config in list(self.arch_config.values()): if self.target_arch == Architecture.UNIVERSAL: config.sources = os.path.join(self.sources, config.target_arch) - config.prefix = os.path.join(self.prefix) + config.prefix = os.path.join(self.prefix, config.target_arch) + # A universal prefix is only available if arch-prefixes are merged during build + if self.cross_universal_type() == 'merged': + config.universal_prefix = self.prefix # qmake_path is different for each arch in android-universal, but # not in ios-universal. qtpkgdir, qmake5 = detect_qt5( @@ -417,8 +453,8 @@ def load(self, filename=None, variants_override=None): # Ensure that variants continue to override all other configuration self.variants.override(variants_override) - if not self.prefix_is_executable() and self.variants.gi: - m.warning(_('gobject introspection requires an executable ' "prefix, 'gi' variant will be removed")) + if self.variants.gi and not self.gi_supported(): + m.warning(_("gobject introspection requires an executable target, 'gi' variant will be removed")) self.variants.gi = False for c in list(self.arch_config.values()): @@ -485,10 +521,11 @@ def get_wine_runtime_env(self, prefix, env): 'GST_PLUGIN_PATH_1_0', 'GST_REGISTRY', 'GST_REGISTRY_1_0', + 'MONO_PATH', + 'MONO_GAC_PREFIX', ) for each in runtime_env: env[each] = to_winepath(env[each]) - env['WIX'] = os.path.join(self.build_tools_prefix, 'lib', 'wix') # NOTE: Ensure that whatever directory this goes into is ignored by the # .cerbero deps CI job otherwise we will tar up ~1GB of generated data. env['WINEPREFIX'] = os.path.join(self.build_tools_prefix, 'var', 'tmp', 'wine') @@ -496,31 +533,6 @@ def get_wine_runtime_env(self, prefix, env): env['WINEDEBUG'] = 'fixme-all' return env - def _merge_env(self, old_env, new_env, override_env=()): - ret_env = {} - for k in new_env.keys(): - new_v = new_env[k] - # Must not accidentally use this with EnvValue objects - if isinstance(new_v, EnvValue): - raise AssertionError('{!r}: {!r}'.format(k, new_v)) - if k not in old_env or k in override_env: - ret_env[k] = new_v - continue - old_v = old_env[k] - if new_v == old_v: - ret_env[k] = new_v - elif EnvVar.is_path(k) or EnvVar.is_arg(k) or EnvVar.is_cmd(k): - ret_env[k] = new_v - else: - raise FatalError( - "Don't know how to combine the environment " - "variable '%s' with values '%s' and '%s'" % (k, new_v, old_v) - ) - for k in old_env.keys(): - if k not in new_env: - ret_env[k] = old_env[k] - return ret_env - @lru_cache(maxsize=None) def get_env(self, prefix, libdir): # Get paths for environment variables @@ -585,6 +597,9 @@ def get_env(self, prefix, libdir): if self.toolchain_prefix is not None: ld_library_path = self._join_path(ld_library_path, os.path.join(self.toolchain_prefix, 'lib')) includedir = self._join_path(includedir, os.path.join(self.toolchain_prefix, 'include')) + if self.lib_suffix and self.variants.python: + # if there is a lib_suffix and a Python build is present it would sit "next" to the lib_suffix dir rather than in it + ld_library_path = self._join_path(os.path.join(self.prefix, 'lib'), ld_library_path) # Most of these variables are extracted from jhbuild env = { 'LD_LIBRARY_PATH': ld_library_path, @@ -626,7 +641,7 @@ def get_env(self, prefix, libdir): # merge the config env with this new env # LDFLAGS and PATH were already merged above - new_env = self._merge_env(self.config_env, env, override_env=('LDFLAGS', 'PATH')) + new_env = merge_str_env(self.config_env, env, override_env=('LDFLAGS', 'PATH')) if self.target_platform == Platform.WINDOWS and self.platform != Platform.WINDOWS: new_env = self.get_wine_runtime_env(prefix, new_env) @@ -639,7 +654,6 @@ def load_defaults(self): self.set_property('prefix', None) self.set_property('sources', None) self.set_property('local_sources', None) - self.set_property('cached_sources', self._relative_path('sources')) self.set_property('git_root', DEFAULT_GIT_ROOT) self.set_property('allow_parallel_build', DEFAULT_ALLOW_PARALLEL_BUILD) self.set_property('allow_universal_parallel_build', DEFAULT_ALLOW_PARALLEL_BUILD) @@ -669,6 +683,7 @@ def load_defaults(self): self.set_property('lib_suffix', '') self.set_property('exe_suffix', self._get_exe_suffix()) self.set_property('data_dir', self._find_data_dir()) + self.set_property('cached_sources', self._relative_path('sources')) self.set_property('environ_dir', self._relative_path('config')) self.set_property('recipes_dir', self._relative_path('recipes')) self.set_property('packages_dir', self._relative_path('packages')) @@ -677,7 +692,6 @@ def load_defaults(self): self.set_property('external_recipes', {}) self.set_property('external_packages', {}) self.set_property('universal_archs', None) - self.set_property('variants', None) self.set_property('build_tools_prefix', None) self.set_property('build_tools_sources', None) self.set_property('build_tools_cache', None) @@ -693,6 +707,7 @@ def load_defaults(self): self.set_property('extra_properties', {}) self.set_property('extra_mirrors', []) self.set_property('extra_bootstrap_packages', {}) + self.set_property('override_bootstrap_packages', {}) self.set_property('bash_completions', set()) # Increase open-files limits set_nofile_ulimit() @@ -742,15 +757,12 @@ def cross_compiling(self): ) def cross_universal_type(self): - if not self.cross_compiling(): + if not self.cross_compiling() or self.target_arch != Architecture.UNIVERSAL: return None - # cross-ios-universal, each arch prefix is merged and flattened into one prefix - if isinstance(self.universal_archs, list): - return 'flat' - # cross-android-universal, each arch prefix is separate - if isinstance(self.universal_archs, dict): - return 'normal' - return None + # cross-{macos,ios}-universal, each arch prefix is merged and flattened into one prefix + if self.target_platform in (Platform.IOS, Platform.DARWIN): + return 'merged' + return 'split' def prefix_is_executable(self): """Can the binaries from the target platform can be executed in the @@ -763,6 +775,25 @@ def prefix_is_executable(self): if self.target_arch != self.arch: if self.target_arch == Architecture.X86 and self.arch == Architecture.X86_64: return True + if self.target_platform == Platform.DARWIN and self.target_arch == Architecture.X86_64: + return True + if self.target_arch == Architecture.UNIVERSAL and self.cross_universal_type() == 'merged': + return True + return False + return True + + def gi_supported(self): + if not self.prefix_is_executable(): + return False + # When building cross-macos-universal, the merged prefix is executable + # on both arm64 and x86_64, but introspection runs executables before + # merging, so we only support it when running on arm64, where we have + # Rosetta available. + if ( + self.target_platform == Platform.DARWIN + and self.target_arch == Architecture.UNIVERSAL + and self.arch != Architecture.ARM64 + ): return False return True @@ -808,6 +839,8 @@ def _create_build_tools_config(self): self.build_tools_config.build_tools_cache = self.build_tools_cache self.build_tools_config.system_build_tools = self.system_build_tools self.build_tools_config.external_recipes = self.external_recipes + self.build_tools_config.recipes_remotes = self.recipes_remotes + self.build_tools_config.recipes_commits = self.recipes_commits self.build_tools_config.extra_mirrors = self.extra_mirrors self.build_tools_config.cached_sources = self.cached_sources self.build_tools_config.vs_install_path = self.vs_install_path @@ -829,26 +862,39 @@ def _init_python_prefixes(self): # Make sure we also include the default non-versioned path on # Windows in addition to the posix path. self.py_win_prefix = sysconfig.get_path('purelib', 'nt', vars=pyvars) + # And the system prefix for Xcode Python + # (making it relative as it's appended to the Cerbero root folder) + self.py_macos_prefix = os.path.splitdrive(sysconfig.get_path('purelib'))[1].lstrip('/') self.py_prefixes = [self.py_prefix, self.py_plat_prefix] if self.platform == Platform.WINDOWS: self.py_prefixes.append(self.py_win_prefix) self.py_prefixes = list(set(self.py_prefixes)) + if self.platform == Platform.WINDOWS: + # pythonpaths start with 'Lib' on Windows, which is extremely + # undesirable since our libdir is 'lib'. Windows APIs are + # case-preserving case-insensitive. + # Running this fix first is necessary because otherwise the WiX + # logic will enumerate lib/ first, and then Lib/ for the Python + # package, thus double defining the same artifact folder. + self.py_prefixes = [path.lower() for path in self.py_prefixes] + # Ensure python paths exists because setup.py won't create them for path in self.py_prefixes: path = os.path.join(self.prefix, path) - if self.platform == Platform.WINDOWS: - # pythonpaths start with 'Lib' on Windows, which is extremely - # undesirable since our libdir is 'lib'. Windows APIs are - # case-preserving case-insensitive. - path = path.lower() # dict universal arches do not have an active prefix if not isinstance(self.universal_archs, dict): self._create_path(path) def _parse(self, filename, reset=True): - config = {'os': os, '__file__': filename, 'env': self.config_env, 'cross': self.cross_compiling()} + config = { + 'os': os, + '__file__': filename, + 'env': self.config_env, + 'cross': self.cross_compiling(), + 'variants': self.variants, + } if not reset: for prop in self._properties: if hasattr(self, prop): @@ -918,19 +964,23 @@ def _load_platform_config(self): if os.path.exists(config_path): self._parse(config_path, reset=False) - def _get_toolchain_target_platform_arch(self): + def _get_toolchain_target_platform_arch(self, readable=False): + mingw = 'MinGW' if readable else 'mingw' + msvc = 'MSVC' if readable else 'msvc' + uwp = 'UWP' if readable else 'uwp' + debug = ' Debug' if readable else '-debug' if self.target_platform != Platform.WINDOWS or self._is_build_tools_config: return (self.target_platform, self.target_arch) if not self.variants.visualstudio: - return ('mingw', self.target_arch) + return (mingw, self.target_arch) # When building with Visual Studio, we can target (MSVC, UWP) x (debug, release) if self.variants.uwp: - target_platform = 'uwp' + target_platform = uwp else: - target_platform = 'msvc' + target_platform = msvc # Debug CRT needs a separate prefix if self.variants.vscrt == 'mdd': - target_platform += '-debug' + target_platform += debug # Check for invalid configuration of a custom Visual Studio path if self.vs_install_path and not self.vs_install_version: raise ConfigurationError('vs_install_path was set, but vs_install_version was not') @@ -958,6 +1008,13 @@ def _load_last_defaults(self): self.python_exe = Path(self.build_tools_prefix, 'bin', 'python').as_posix() else: self.python_exe = Path(sys.executable).as_posix() + if ( + self.platform == Platform.DARWIN + and self.arch == Architecture.ARM64 + and self.target_arch == Architecture.X86_64 + ): + # Created by the build-tools bootstrapper + self.python_exe = os.path.join(self.build_tools_prefix, 'bin', 'python3-x86_64') def _get_exe_suffix(self): if self.platform != Platform.WINDOWS: @@ -1066,3 +1123,72 @@ def find_toml_module(self, system_only=False): sys.path.insert(0, os.path.abspath(tomli_dir)) return importlib.import_module('tomli') return None + + def get_build_env(self, in_env=None, using_msvc=False): + """ + Override/merge toolchain env with `in_env` and return a new dict + with values as EnvValue objects + if `in_env` is empty, `self.env` is used. + """ + + # Extract toolchain config for the build system from the appropriate + # config env dict. Start with `in_env`, since it contains toolchain + # config set by the recipe and when building for target platforms other + # than Windows, it also contains build tools and the env for the + # toolchain set by config/*.config. + # + # On Windows, the toolchain config is `msvc_env_for_build_system` + # or `mingw_env_for_build_system` depending on which toolchain + # this recipe will use. + if self.target_platform == Platform.WINDOWS: + if using_msvc: + build_env = dict(self.msvc_env_for_build_system) + else: + build_env = dict(self.mingw_env_for_build_system) + else: + build_env = {} + + return merge_env_value_env(build_env, in_env or self.env) + + # config helpers for recipes with Python dependencies: + + def get_python_ext_suffix(self): + return sysconfig.get_config_vars().get('EXT_SUFFIX', '%(pext)s') + + def get_python_framework(self): + """ + Get framework prefix for RPATH + """ + return sysconfig.get_config_vars().get('PYTHONFRAMEWORKPREFIX', None) + + def get_python_version(self): + return self.extra_properties.get('python_version', sysconfig.get_python_version()) + + def get_python_name(self): + return f'python{self.get_python_version()}' + + def get_build_python_exe(self): + py_name = self.get_python_name() + path = self._get_build_python_path('scripts', py_name) + if path: + return path.joinpath(py_name) + return self.python_exe + + def get_python_prefix(self): + if self.target_platform == Platform.WINDOWS: + return Path(self.py_win_prefix) + else: + return Path(self.py_plat_prefix) + + def _get_build_python_path(self, path_name, testfile): + py_version = self.get_python_version() + py_name = f'python{py_version}' + if path_name == 'scripts': + glue = 'bin' + elif path_name in ['include', 'platinclude']: + glue = Path('include', py_name) + else: + glue = Path('lib', py_name) + if Path(self.prefix, glue, testfile).exists(): + return Path(self.prefix, glue) + return None diff --git a/cerbero/enums.py b/cerbero/enums.py index 43dfdda92..4aeb90252 100644 --- a/cerbero/enums.py +++ b/cerbero/enums.py @@ -20,7 +20,7 @@ # Safest place to define this since this file imports very few modules -CERBERO_VERSION = '1.24.8' +CERBERO_VERSION = '1.26.3' class Platform: @@ -104,31 +104,13 @@ class DistroVersion: UBUNTU_DISCO = 'ubuntu_19_04_disco' UBUNTU_EOAN = 'ubuntu_19_10_eoan' UBUNTU_FOCAL = 'ubuntu_20_04_focal' - FEDORA_16 = 'fedora_16' - FEDORA_17 = 'fedora_17' - FEDORA_18 = 'fedora_18' - FEDORA_19 = 'fedora_19' - FEDORA_20 = 'fedora_20' - FEDORA_21 = 'fedora_21' - FEDORA_22 = 'fedora_22' - FEDORA_23 = 'fedora_23' - FEDORA_24 = 'fedora_24' - FEDORA_25 = 'fedora_25' - FEDORA_26 = 'fedora_26' - FEDORA_27 = 'fedora_27' - FEDORA_28 = 'fedora_28' - FEDORA_29 = 'fedora_29' - FEDORA_30 = 'fedora_30' - FEDORA_31 = 'fedora_31' - FEDORA_32 = 'fedora_32' - # further fedora versions are generated automatically + # fedora versions are generated automatically, like: + # FEDORA_32 = 'fedora_32' REDHAT_6 = 'redhat_6' REDHAT_7 = 'redhat_7' - REDHAT_8 = 'redhat_8' - REDHAT_9 = 'redhat_9' - # Amazon Linux seems to be RedHat/CentOS-based - AMAZON_LINUX = 'amazon_linux' - AMAZON_LINUX_2 = 'amazon_linux_2' + # further RedHat versions are generated automatically, like: + # REDHAT_8_1 = 'redhat_8.1' + AMAZON_LINUX_2023 = 'amazonlinux_2023' ARCH_ROLLING = 'rolling' GENTOO_VERSION = 'gentoo-version' OPENSUSE_42_2 = 'opensuse_42_2' diff --git a/cerbero/hacks.py b/cerbero/hacks.py index daf62efc8..886e87fcd 100644 --- a/cerbero/hacks.py +++ b/cerbero/hacks.py @@ -23,45 +23,6 @@ import pathlib -### XML Hacks ### - -import re -import io -from xml.dom import minidom - -try: - import xml.etree.cElementTree as etree -except ImportError: - from lxml import etree - -oldwrite = etree.ElementTree.write - - -def pretify(string, pretty_print=True): - parsed = minidom.parseString(string) - # See:http://www.hoboes.com/Mimsy/hacks/geektool-taskpaper-and-xml/ - fix = re.compile(r'((?<=>)(\n[\t]*)(?=[^<\t]))|(?<=[^>\t])(\n[\t]*)(?=<)') - return re.sub(fix, '', parsed.toprettyxml()) - - -def write(self, file_or_filename, encoding=None, pretty_print=False): - if not pretty_print: - return oldwrite(self, file_or_filename, encoding) - tmpfile = io.BytesIO() - oldwrite(self, tmpfile, encoding) - tmpfile.seek(0) - if hasattr(file_or_filename, 'write'): - out_file = file_or_filename - else: - out_file = open(file_or_filename, 'wb') - out_file.write(pretify(tmpfile.read()).encode()) - if not hasattr(file_or_filename, 'write'): - out_file.close() - - -etree.ElementTree.write = write - - ### Windows Hacks ### # we don't want backlashes in paths as it breaks shell commands diff --git a/cerbero/ide/vs/props.py b/cerbero/ide/vs/props.py index cf5fca9a0..31b3a6318 100644 --- a/cerbero/ide/vs/props.py +++ b/cerbero/ide/vs/props.py @@ -17,7 +17,7 @@ # Boston, MA 02111-1307, USA. import os -from cerbero.utils import etree, to_winpath +from cerbero.utils import etree, to_winpath, xmlwrite class PropsBase(object): @@ -53,7 +53,7 @@ def _import_property(self, name): def create(self, outdir): el = etree.ElementTree(self.root) - el.write(os.path.join(outdir, '%s.props' % self.name), encoding='utf-8', pretty_print=True) + xmlwrite(el, os.path.join(outdir, '%s.props' % self.name)) def _add_compiler_props(self): self.compiler = etree.SubElement(self.item_definition_group, 'ClCompile') diff --git a/cerbero/ide/vs/vsprops.py b/cerbero/ide/vs/vsprops.py index 0bb47f437..6b6563a31 100644 --- a/cerbero/ide/vs/vsprops.py +++ b/cerbero/ide/vs/vsprops.py @@ -18,7 +18,7 @@ # Boston, MA 02111-1307, USA. import os -from cerbero.utils import etree, to_winpath +from cerbero.utils import etree, to_winpath, xmlwrite class VSPropsBase(object): @@ -30,7 +30,7 @@ def _add_root(self, name): def create(self, outdir): el = etree.ElementTree(self.root) - el.write(os.path.join(outdir, '%s.vsprops' % self.name), encoding='utf-8') + xmlwrite(el, os.path.join(outdir, '%s.vsprops' % self.name)) class CommonVSProps(VSPropsBase): diff --git a/cerbero/packages/__init__.py b/cerbero/packages/__init__.py index ddf23fec7..0ce7b9ec4 100644 --- a/cerbero/packages/__init__.py +++ b/cerbero/packages/__init__.py @@ -48,7 +48,7 @@ def pack(self, output_dir, devel=True, force=False, keep_temp=False): @param force: forces the creation of the package @type force: bool @param keep_temp: do not delete temporary files - @type force: bool + @type keep_temp: bool @return: list of filenames for the packages created @rtype: list diff --git a/cerbero/packages/ninja_syntax.py b/cerbero/packages/ninja_syntax.py new file mode 100644 index 000000000..3f967b1b0 --- /dev/null +++ b/cerbero/packages/ninja_syntax.py @@ -0,0 +1,233 @@ +#!/usr/bin/python + +# Copyright 2011 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Python module for generating .ninja files. + +Note that this is emphatically not a required piece of Ninja; it's +just a helpful utility for build-file-generation systems that already +use Python. +""" + +import re +import textwrap +from io import TextIOWrapper +from typing import Dict, List, Match, Optional, Tuple, Union + + +def escape_path(word: str) -> str: + return word.replace('$ ', '$$ ').replace(' ', '$ ').replace(':', '$:') + + +class Writer(object): + def __init__(self, output: TextIOWrapper, width: int = 78) -> None: + self.output = output + self.width = width + + def newline(self) -> None: + self.output.write('\n') + + def comment(self, text: str) -> None: + for line in textwrap.wrap(text, self.width - 2, break_long_words=False, break_on_hyphens=False): + self.output.write('# ' + line + '\n') + + def variable( + self, + key: str, + value: Optional[Union[bool, int, float, str, List[str]]], + indent: int = 0, + ) -> None: + if value is None: + return + if isinstance(value, list): + value = ' '.join(filter(None, value)) # Filter out empty strings. + self._line('%s = %s' % (key, value), indent) + + def pool(self, name: str, depth: int) -> None: + self._line('pool %s' % name) + self.variable('depth', depth, indent=1) + + def rule( + self, + name: str, + command: str, + description: Optional[str] = None, + depfile: Optional[str] = None, + generator: bool = False, + pool: Optional[str] = None, + restat: bool = False, + rspfile: Optional[str] = None, + rspfile_content: Optional[str] = None, + deps: Optional[Union[str, List[str]]] = None, + ) -> None: + self._line('rule %s' % name) + self.variable('command', command, indent=1) + if description: + self.variable('description', description, indent=1) + if depfile: + self.variable('depfile', depfile, indent=1) + if generator: + self.variable('generator', '1', indent=1) + if pool: + self.variable('pool', pool, indent=1) + if restat: + self.variable('restat', '1', indent=1) + if rspfile: + self.variable('rspfile', rspfile, indent=1) + if rspfile_content: + self.variable('rspfile_content', rspfile_content, indent=1) + if deps: + self.variable('deps', deps, indent=1) + + def build( + self, + outputs: Union[str, List[str]], + rule: str, + inputs: Optional[Union[str, List[str]]] = None, + implicit: Optional[Union[str, List[str]]] = None, + order_only: Optional[Union[str, List[str]]] = None, + variables: Optional[ + Union[ + List[Tuple[str, Optional[Union[str, List[str]]]]], + Dict[str, Optional[Union[str, List[str]]]], + ] + ] = None, + implicit_outputs: Optional[Union[str, List[str]]] = None, + pool: Optional[str] = None, + dyndep: Optional[str] = None, + ) -> List[str]: + outputs = as_list(outputs) + out_outputs = [escape_path(x) for x in outputs] + all_inputs = [escape_path(x) for x in as_list(inputs)] + + if implicit: + implicit = [escape_path(x) for x in as_list(implicit)] + all_inputs.append('|') + all_inputs.extend(implicit) + if order_only: + order_only = [escape_path(x) for x in as_list(order_only)] + all_inputs.append('||') + all_inputs.extend(order_only) + if implicit_outputs: + implicit_outputs = [escape_path(x) for x in as_list(implicit_outputs)] + out_outputs.append('|') + out_outputs.extend(implicit_outputs) + + self._line('build %s: %s' % (' '.join(out_outputs), ' '.join([rule] + all_inputs))) + if pool is not None: + self._line(' pool = %s' % pool) + if dyndep is not None: + self._line(' dyndep = %s' % dyndep) + + if variables: + if isinstance(variables, dict): + iterator = iter(variables.items()) + else: + iterator = iter(variables) + + for key, val in iterator: + self.variable(key, val, indent=1) + + return outputs + + def include(self, path: str) -> None: + self._line('include %s' % path) + + def subninja(self, path: str) -> None: + self._line('subninja %s' % path) + + def default(self, paths: Union[str, List[str]]) -> None: + self._line('default %s' % ' '.join(as_list(paths))) + + def _count_dollars_before_index(self, s: str, i: int) -> int: + """Returns the number of '$' characters right in front of s[i].""" + dollar_count = 0 + dollar_index = i - 1 + while dollar_index > 0 and s[dollar_index] == '$': + dollar_count += 1 + dollar_index -= 1 + return dollar_count + + def _line(self, text: str, indent: int = 0) -> None: + """Write 'text' word-wrapped at self.width characters.""" + leading_space = ' ' * indent + while len(leading_space) + len(text) > self.width: + # The text is too wide; wrap if possible. + + # Find the rightmost space that would obey our width constraint and + # that's not an escaped space. + available_space = self.width - len(leading_space) - len(' $') + space = available_space + while True: + space = text.rfind(' ', 0, space) + if space < 0 or self._count_dollars_before_index(text, space) % 2 == 0: + break + + if space < 0: + # No such space; just use the first unescaped space we can find. + space = available_space - 1 + while True: + space = text.find(' ', space + 1) + if space < 0 or self._count_dollars_before_index(text, space) % 2 == 0: + break + if space < 0: + # Give up on breaking. + break + + self.output.write(leading_space + text[0:space] + ' $\n') + text = text[space + 1 :] + + # Subsequent lines are continuations, so indent them. + leading_space = ' ' * (indent + 2) + + self.output.write(leading_space + text + '\n') + + def close(self) -> None: + self.output.close() + + +def as_list(input: Optional[Union[str, List[str]]]) -> List[str]: + if input is None: + return [] + if isinstance(input, list): + return input + return [input] + + +def escape(string: str) -> str: + """Escape a string such that it can be embedded into a Ninja file without + further interpretation.""" + assert '\n' not in string, 'Ninja syntax does not allow newlines' + # We only have one special metacharacter: '$'. + return string.replace('$', '$$') + + +def expand(string: str, vars: Dict[str, str], local_vars: Dict[str, str] = None) -> str: + """Expand a string containing $vars as Ninja would. + + Note: doesn't handle the full Ninja variable syntax, but it's enough + to make configure.py's use of it work. + """ + + if local_vars is None: + local_vars = {} + + def exp(m: Match[str]) -> str: + var = m.group(1) + if var == '$': + return '$' + return local_vars.get(var, vars.get(var, '')) + + return re.sub(r'\$(\$|\w*)', exp, string) diff --git a/cerbero/packages/osx/packager.py b/cerbero/packages/osx/packager.py index b4e24e467..21aa24eab 100644 --- a/cerbero/packages/osx/packager.py +++ b/cerbero/packages/osx/packager.py @@ -256,7 +256,13 @@ def pack(self, output_dir, devel=False, force=False, keep_temp=False): return paths def _prepare_pack(self): - self.include_dirs = PkgConfig.list_all_include_dirs(env=self.config.env) + env = self.config.env.copy() + # python3.xx-embed is a system package + if self.config.variants.python: + import sysconfig + + env['PKG_CONFIG_PATH'] = f"{env['PKG_CONFIG_PATH']}:{sysconfig.get_config_var('LIBPC')}" + self.include_dirs = PkgConfig.list_all_include_dirs(env=env) self.tmp = tempfile.mkdtemp() self.fw_path = self.tmp diff --git a/cerbero/packages/package.py b/cerbero/packages/package.py index 73d558cba..eaeaed309 100644 --- a/cerbero/packages/package.py +++ b/cerbero/packages/package.py @@ -116,6 +116,11 @@ def __init__(self, config, store): self.store = store self.package_mode = PackageType.RUNTIME + def load(self): + self.prepare() + # reload files after calling prepare + self.load_files() + def prepare(self): """ Can be overrided by subclasses to modify conditionally the package @@ -571,9 +576,9 @@ def recipes_dependencies(self, use_devel=True): return remove_list_duplicates(deps) def files_list(self): - # for each package, call the function that list files - files = Package.files_list(self) + files = super().files_list() if self.embed_deps: + # for each package, call the function that list files packages_deps = [self.store.get_package(x) for x in self.deps] for package in packages_deps: packages_deps.extend(self.store.get_package_deps(package)) @@ -650,4 +655,4 @@ def __getattribute__(self, name): ret.extend(platform_list) return ret else: - return PackageBase.__getattribute__(self, name) + return super().__getattribute__(name) diff --git a/cerbero/packages/packager.py b/cerbero/packages/packager.py index f17802087..f284458bb 100644 --- a/cerbero/packages/packager.py +++ b/cerbero/packages/packager.py @@ -68,10 +68,11 @@ def __new__(klass, config, package, store): return _packagers[d][v](config, package, store) -from cerbero.packages import wix_packager, rpm, debian, android, disttarball # noqa: E402 +from cerbero.packages import rpm, debian, android, disttarball # noqa: E402 +from cerbero.packages.windows import wix_on_ninja # noqa: E402 from cerbero.packages.osx import packager as osx_packager # noqa: E402 -wix_packager.register() +wix_on_ninja.register() osx_packager.register() rpm.register() debian.register() diff --git a/cerbero/packages/packagesstore.py b/cerbero/packages/packagesstore.py index 37f8bd3df..563ce4c51 100644 --- a/cerbero/packages/packagesstore.py +++ b/cerbero/packages/packagesstore.py @@ -120,7 +120,11 @@ def add_package(self, package): self._packages[package.name] = package def _list_metapackage_deps(self, metapackage): - def get_package_deps(package_name, visited=[], depslist=[]): + def get_package_deps(package_name, visited=None, depslist=None): + if visited is None: + visited = [] + if depslist is None: + depslist = [] if package_name in visited: return visited.append(package_name) @@ -208,6 +212,8 @@ def _load_package_from_file(self, package_cls, filepath, custom=None): p = package_cls(self._config, self, self.cookbook) elif issubclass(package_cls, package.SDKPackage): p = package_cls(self._config, self) + elif issubclass(package_cls, package.MetaPackage): + p = package_cls(self._config, self) elif issubclass(package_cls, package.InstallerPackage): p = package_cls(self._config, self) elif issubclass(package_cls, package.Package): @@ -218,10 +224,7 @@ def _load_package_from_file(self, package_cls, filepath, custom=None): # a package may need to call something that needs it # e.g. prepare() may call self.relative_path(), which uses __file__ p.__file__ = os.path.abspath(filepath) - p.prepare() - # reload files from package now that we called prepare that - # may have changed it - p.load_files() + p.load() return p def _is_package_class(self, cls): diff --git a/cerbero/packages/rpm.py b/cerbero/packages/rpm.py index ebefd4a9c..5fe002ed3 100644 --- a/cerbero/packages/rpm.py +++ b/cerbero/packages/rpm.py @@ -254,7 +254,7 @@ def _rpmbuild_support_nodebuginfo(self): if not self.config.distro == Distro.REDHAT: return False - if 'fedora' in self.config.distro_version and self.config.distro_version > DistroVersion.FEDORA_26: + if 'fedora' in self.config.distro_version and self.config.distro_version > 'fedora_26': return True if 'redhat' in self.config.distro_version and self.config.distro_version > DistroVersion.REDHAT_7: diff --git a/cerbero/packages/windows/__init__.py b/cerbero/packages/windows/__init__.py new file mode 100644 index 000000000..3034c5d04 --- /dev/null +++ b/cerbero/packages/windows/__init__.py @@ -0,0 +1,2 @@ +# SPDX-FileCopyrightText: 2024 L. E. Segovia +# SPDX-License-Ref: LGPL-2.1-or-later diff --git a/cerbero/packages/windows/wix_on_ninja.py b/cerbero/packages/windows/wix_on_ninja.py new file mode 100644 index 000000000..5b0ce880b --- /dev/null +++ b/cerbero/packages/windows/wix_on_ninja.py @@ -0,0 +1,546 @@ +# SPDX-FileCopyrightText: 2024 L. E. Segovia +# SPDX-License-Ref: LGPL-2.1-or-later + +from __future__ import annotations +from enum import Enum +from pathlib import Path +import shlex +import shutil +import tempfile +from zipfile import ZipFile + +from cerbero.config import Platform, Architecture +from cerbero.errors import EmptyPackageError +from cerbero.packages import PackagerBase, PackageType +from cerbero.packages.package import Package, App +from cerbero.packages.ninja_syntax import Writer +from cerbero.packages.wix import Fragment, MergeModule, MSI, VSFragment, VSTemplatePackage, WixConfig +from cerbero.utils import get_wix_prefix, m, shell + + +class Light(object): + """Link WiX objects with light""" + + options = {} + + Output = Enum('Output', ['MSM', 'MSI', 'WIXLIB']) + + def __init__(self, extra=None): + self.options['extra'] = [] if extra is None else extra + + def compile(self, writer: Writer, objects: list[str], msi_name: str, merge_module=Output.MSI, implicit_deps=None): + """ + Write the rules to link WiX objects together into a MSM/MSI + """ + if not objects: + raise RuntimeError('Objects cannot be empty') + wix_bin_name = f'{msi_name}.{merge_module.name.lower()}' + writer.build( + wix_bin_name, + 'light', + objects, + implicit=implicit_deps, + variables={'extra': self.options['extra']}, + ) + writer.newline() + return wix_bin_name + + def rule(writer: Writer, wix_prefix: str, with_wine: bool) -> None: + """ + The template rule for compiling Wix wxs files into Merge Modules or MSI installers + """ + command = [f'{Path(__file__).parent}/wrapper.py', 'wine'] if with_wine else [] + outobj = 'posix:$out' if with_wine else '$out' + if with_wine: + # Ninja uses a shell underneath, don't allow splitting on spaces + command.extend([f"'{(Path(wix_prefix) / 'wix.exe').as_posix()}'"]) + else: + command.extend([(Path(wix_prefix) / 'wix.exe').as_posix()]) + command.extend(['build', '-out', outobj, '$extra', '$in']) + + if with_wine: + command.extend(['&&', 'chmod', '0755', '$out']) + + writer.rule( + 'light', + ' '.join(command), + description='Compiling $out', + ) + + +class StripRule(object): + """Wrapper for the strip tool""" + + def __init__(self, config, keep_symbols=None): + self.config = config + self.keep_symbols = keep_symbols or [] + + def rule(writer: Writer, config): + if 'STRIP' not in config.env: + m.warning('Strip command is not defined for this configuration, skipping rule generation') + return + + strip_cmd = shlex.split(config.env['STRIP']) + + # This is NOT windows -- don't waste checks + strip_cmd.extend( + [ + '-o', + '$out', + '$extra', # -K goes here + '--strip-unneeded', + '$in', + ] + ) + + if config.target_platform == Platform.DARWIN: + strip_cmd.append('-x') + + writer.rule('strip', ' '.join(strip_cmd), description='Stripping $out') + writer.newline() + + copy_cmd = [ + Path(config.python).as_posix(), + '-c', + '"from sys import argv; from shutil import copy; copy(argv[1], argv[2])"', + '$in', + '$out', + ] + + writer.rule('copy', ' '.join(copy_cmd), description='Copying $out') + writer.newline() + + def copy_file(self, writer: Writer, source_dir: Path, input_filename: Path, output_dir: Path): + writer.build( + Path(output_dir / input_filename).as_posix(), + 'copy', + Path(source_dir / input_filename).as_posix(), + ) + writer.newline() + + def strip_file(self, writer: Writer, source_dir: Path, input_filename: Path, output_dir: Path): + if 'STRIP' not in self.config.env: + m.warning('Strip command is not defined for this configuration') + return + + extra = [] + + for symbol in self.keep_symbols: + extra += ['-K', symbol] + + writer.build( + Path(output_dir / input_filename).as_posix(), + 'strip', + Path(source_dir / input_filename).as_posix(), + variables={'extra': extra}, + ) + writer.newline() + + def strip_dir(self, writer: Writer, source_root, output_root): + srcd = Path(source_root) + outd = Path(output_root) + for dirpath, _, filenames in srcd.walk(follow_symlinks=True): + for f in filenames: + # Send path relative to dir_path + self.strip_file(writer, source_root, Path(dirpath) / f, outd) + + +class MergeModuleWithNinjaPackager(PackagerBase): + VS_EXT = ['-ext', 'WixToolset.VisualStudio.wixext'] + + def __init__(self, config, package, store): + PackagerBase.__init__(self, config, package, store) + self._with_wine = config.platform != Platform.WINDOWS + self.wix_prefix = get_wix_prefix(config) + + def is_strippable_file(filename: Path, package: Package): + return any([filename.parent().is_relative_to(x) for x in package.strip_dirs]) and not any( + [filename.name in path for path in package.strip_excludes] + ) + + def strip_files(self, writer: Writer, package_type, force=False): + """ + Prepare the temporary roots for stripped files + """ + tmpdir = None + if self.package.strip and 'STRIP' in self.config.env: + tmpdir = Path(f'{self.package.name}.stripped.d') + prefix = Path(self.config.prefix) + s = StripRule(self.config) + # Now we need to filter the list in two parts: + outputs = [] + + for file in self.files_list(package_type, force): + filename = Path(file) + dst: Path = tmpdir / filename + + if self.is_strippable_file(filename, self.package): + # Those with parent in strip_dirs, insert stripping rules + s.strip_file(writer, prefix, filename, tmpdir) + else: + # Those without, mkdir and copy + s.copy_file(writer, prefix, filename, tmpdir) + outputs.append(dst) + tmpdir = tmpdir + writer.build( + tmpdir, + 'phony', + outputs, + ) + return tmpdir + + def pack(self, output_dir, devel=False, force=False, keep_temp=False): + """ + Create the scroll of incantation and then call Ninja to assemble it + """ + + PackagerBase.pack(self, output_dir, devel, force, keep_temp) + # Let's make a temporary directory, that can be cleaned up in one go + # This is the directory where Ninja will run + output_dir = Path(output_dir).absolute() + self.output_dir = Path(tempfile.mkdtemp(prefix=f'merge-module-{self._package_name()}-', dir=output_dir)) + # These are the outputs of the Ninja process + # All the paths must be understood relative to self.output_dir + paths: list[Path] = [] + + # For packages that requires stripping object files, we need + # to copy all the files to a new tree and strip them there: + package_types = [PackageType.RUNTIME] + if devel: + package_types.append(PackageType.DEVEL) + + # Set Ninja build file up + m.action('Creating Ninja project for Merge Module') + with (self.output_dir / 'build.ninja').open('w', encoding='utf-8') as rules: + writer = Writer(rules, width=120) + + writer.comment(f'This is the build file for the merge module "{self._package_name()}"') + writer.comment('It is autogenerated by Cerbero.') + writer.comment('Do not edit by hand.') + writer.newline() + writer._line('ninja_required_version = 1.1') + writer.newline() + writer.newline() + + # Set Candle and Light rules up + writer.comment('Incantations for the WiX Toolkit') + writer.newline() + Light.rule(writer, self.wix_prefix, self._with_wine) + StripRule.rule(writer, self.config) + writer.newline() + + writer.comment('Incantations for stripping files') + writer.newline() + tmpdirs = {t: self.strip_files(t, force) for t in package_types} + writer.newline() + + # set rules for runtime package + writer.comment('Incantations for the runtime package generation') + writer.newline() + p = self.create_merge_module( + writer, + PackageType.RUNTIME, + force, + self.package.version, + stripped_dir=tmpdirs.get(PackageType.RUNTIME, None), + ) + if p: + paths.append(p) + writer.newline() + + # set rules for devel package + if devel: + writer.comment('Incantations for the development package generation') + writer.newline() + p = self.create_merge_module( + writer, + PackageType.DEVEL, + force, + self.package.version, + stripped_dir=tmpdirs.get(PackageType.RUNTIME, None), + ) + if p: + paths.append(p) + writer.newline() + + writer.close() + + # Execute ninja on the chosen output directory + m.action('Building Merge Module in {self.output_dir}') + + # Ensure all the WiX temporary files are reaped at the end of execution + with tempfile.TemporaryDirectory(prefix='wix-') as tmp: + env = self.config.env.copy() + env['TMP'] = tmp + shell.new_call(['ninja'], cmd_dir=self.output_dir, env=env) + + # Copy the outputs to the output directory + for p in paths: + src = self.output_dir / p + dst = output_dir / p + m.action(f'Moving {p} to {output_dir}') + shutil.move(src, dst) + + # Clean up + # We need to tally up the temporaries now + if keep_temp: + m.action(f'Temporary build directory is at {self.output_dir}') + else: + shutil.rmtree(self.output_dir) + + return paths + + def create_merge_module(self, writer: Writer, package_type: PackageType, force: bool, version, stripped_dir=None): + self.package.set_mode(package_type) + try: + files_list: list[str] = self.files_list(package_type, force) + except EmptyPackageError: + m.warning('Package %s is empty, skipping module generation' % self.package.name) + return None + + package_name = self.package.name + + args = [] + + if self.package.wix_use_fragment: + mergemodule = Fragment(self.config, files_list, self.package) + mergeoutput = Light.Output.WIXLIB + sources = f'{package_name}-fragment.wxs' + # FIXME (remove this special casing): https://github.com/wixtoolset/issues/issues/8558 + elif isinstance(self.package, VSTemplatePackage): + mergemodule = VSFragment(self.config, files_list, self.package) + args = [*self.VS_EXT] + mergeoutput = Light.Output.WIXLIB + sources = f'{package_name}-fragment.wxs' + else: + mergemodule = MergeModule(self.config, files_list, self.package) + mergeoutput = Light.Output.MSM + sources = f'{package_name}.wxs' + + # There's a ready-made stripped folder here + implicit_deps = None + if stripped_dir: + implicit_deps = [stripped_dir] + mergemodule.prefix = Path(self.output_dir / stripped_dir).as_posix() + + mergemodule_path = Path(self.output_dir / sources).absolute() + if mergemodule_path.exists(): + raise RuntimeError(f'Merge module manifest {mergemodule_path} already exists') + mergemodule.write(mergemodule_path.as_posix()) + + # Render deliverables + wixobjs = [mergemodule_path.as_posix()] + path = Light(args).compile( + writer, + wixobjs, + package_name, + implicit_deps=implicit_deps, + merge_module=mergeoutput, + ) + + return path + + def _package_name(self, version): + if self.config.variants.uwp: + platform = 'uwp' + elif self.config.variants.visualstudio: + platform = 'msvc' + else: + platform = 'mingw' + if self.config.variants.visualstudio and self.config.variants.vscrt == 'mdd': + platform += '+debug' + return '-'.join((self.package.name, platform, self.config.target_arch, version)) + + +class MSIWithNinjaPackager(PackagerBase): + UI_EXT = ['-ext', 'WiXToolset.UI.wixext'] + VS_EXT = ['-ext', 'WixToolset.VisualStudio.wixext'] + + def __init__(self, config, package, store): + PackagerBase.__init__(self, config, package, store) + self._with_wine = config.platform != Platform.WINDOWS + self.architecture = config.target_arch + self.wix_prefix = get_wix_prefix(config) + + def pack(self, output_dir, devel=False, force=False, keep_temp=False): + """ + Create the scroll of incantation and then call Ninja to assemble it + """ + + PackagerBase.pack(self, output_dir, devel, force, keep_temp) + # This is the directory where Ninja will run + output_dir = Path(output_dir).absolute() + self.output_dir = Path(tempfile.mkdtemp(prefix=f'msi-{self._package_name()}-', dir=output_dir)) + # These are the outputs of the Ninja process + # All the paths must be understood relative to self.output_dir + paths: list[Path] = [] + tmp_dirs: list[Path] = [] + + self.merge_modules: dict[str, list[str]] = {} + + # Calm Git if you're running this interactively + with (self.output_dir / '.gitignore').open('w', encoding='utf-8') as f: + f.write('*\n') + + # Set Ninja build file up + m.action(f'Creating Ninja project for MSI {self._package_name()}') + with (self.output_dir / 'build.ninja').open('w', encoding='utf-8') as rules: + writer = Writer(rules, width=120) + + writer.comment(f'This is the build file for the MSI installer "{self._package_name()}"') + writer.comment('It is autogenerated by Cerbero.') + writer.comment('Do not edit by hand.') + writer.newline() + writer._line('ninja_required_version = 1.1') + writer.newline() + + # Set Candle and Light rules up + writer.comment('Incantations for the WiX Toolkit') + Light.rule(writer, self.wix_prefix, self._with_wine) + StripRule.rule(writer, self.config) + + # set rules for runtime package + writer.comment('Incantations for the runtime package generation') + p, d = self._create_msi_installer(writer, PackageType.RUNTIME) + paths.append(p) + tmp_dirs.extend(d) + + # set rules for devel package + if devel and not isinstance(self.package, App): + writer.comment('Incantations for the development package generation') + p, d = self._create_msi_installer(writer, PackageType.DEVEL) + paths.append(p) + tmp_dirs.extend(d) + + writer.close() + + # Execute ninja on the chosen output directory + m.action(f'Building {self._package_name()} in {self.output_dir}') + + # Ensure all the WiX temporary files are reaped at the end of execution + with tempfile.TemporaryDirectory(prefix='wix-') as tmp: + env = self.config.env.copy() + env['TMP'] = tmp + shell.new_call(['ninja'], cmd_dir=self.output_dir, env=env) + + # Copy the outputs to the output directory + for p in paths: + src = self.output_dir / p + dst = output_dir / p + m.action(f'Moving {p} to {output_dir}') + shutil.move(src, dst) + + # Create zip with Merge Modules + if not self.package.wix_use_fragment: + self.package.set_mode(PackageType.RUNTIME) + zipf_path = output_dir / f'{self._package_name()}-merge-modules.zip' + with ZipFile(zipf_path, 'w') as zipf: + for p in self.merge_modules[PackageType.RUNTIME]: + zipf.write(self.output_dir / p, f'{self._package_name()}/{p}') + zipf.write(self.output_dir / 'build.ninja', f'{self._package_name()}/build.ninja') + + # Get rid of all the Merge Modules + # And clean up the relevant stripped directories + # (they're all within output_dir now) + if keep_temp: + m.action(f'Temporary build directory is at {self.output_dir}') + else: + shutil.rmtree(self.output_dir) + + return paths + + def _package_name(self): + if self.config.variants.uwp: + platform = 'uwp' + elif self.config.variants.visualstudio: + platform = 'msvc' + else: + platform = 'mingw' + if self.config.variants.visualstudio and self.config.variants.vscrt == 'mdd': + platform += '+debug' + return '-'.join((self.package.name, platform, self.config.target_arch, self.package.version)) + + def _create_msi_installer(self, writer: Writer, package_type) -> tuple[Path, list[Path]]: + self.package.set_mode(package_type) + self.packagedeps = self.store.get_package_deps(self.package, True) + if isinstance(self.package, App): + self.packagedeps = [self.package] + tmp_dirs = self._create_merge_modules(writer, package_type) + (config_path, ui_path) = self._create_config() + return (self._create_msi(writer, config_path, ui_path), tmp_dirs) + + def _create_merge_modules(self, writer: Writer, package_type: PackageType) -> list[Path]: + packagedeps = {} + tmp_dirs = [] + for package in self.packagedeps: + package.set_mode(package_type) + package.wix_use_fragment = self.package.wix_use_fragment + m.action('Creating Merge Module for %s' % package) + packager = MergeModuleWithNinjaPackager(self.config, package, self.store) + tmpdir = packager.strip_files(package_type, self.force) + # FIXME: this should be passed correctly + packager.output_dir = self.output_dir + path = packager.create_merge_module( + writer, package_type, self.force, self.package.version, stripped_dir=tmpdir + ) + if path: + packagedeps[package] = path + if tmpdir: + tmp_dirs.append(tmpdir) + self.packagedeps = packagedeps + self.merge_modules[package_type] = list(packagedeps.values()) + return tmp_dirs + + def _create_config(self): + config = WixConfig(self.config, self.package) + config_path = config.write(self.output_dir) + return config_path + + def _create_msi(self, writer: Writer, config_path, ui_path) -> Path: + wixobjs = [] + + # Make the MSI manifest relative to the Ninja root. + msi_manifest = f'{self._package_name()}.wxs' + + # Writes the manifest for the MSI installer. + MSI(self.config, self.package, self.packagedeps, config_path, self.store).write( + (self.output_dir / msi_manifest).as_posix() + ) + wixobjs.append(msi_manifest) + if ui_path: + wixobjs.append(ui_path) + + implicit_deps = [] + if self.package.wix_use_fragment: + wixobjs.extend(self.merge_modules[self.package.package_mode]) + else: + for dep in self.merge_modules[self.package.package_mode]: + if dep.endswith(Light.Output.WIXLIB.name.lower()): + wixobjs.append(dep) + else: + implicit_deps.append(dep) + + args = [*self.UI_EXT, *self.VS_EXT] + if self.architecture == Architecture.X86_64: + args += ['-arch', 'x64'] + else: + args += ['-arch', self.architecture] + + path = Light(args).compile(writer, wixobjs, self._package_name(), implicit_deps=implicit_deps) + + return path + + +class Packager(object): + def __new__(klass, config, package, store): + if isinstance(package, Package): + return MergeModuleWithNinjaPackager(config, package, store) + else: + return MSIWithNinjaPackager(config, package, store) + + +def register(): + from cerbero.packages.packager import register_packager + from cerbero.config import Distro + + register_packager(Distro.WINDOWS, Packager) diff --git a/cerbero/packages/windows/wrapper.py b/cerbero/packages/windows/wrapper.py new file mode 100755 index 000000000..9e63c32d8 --- /dev/null +++ b/cerbero/packages/windows/wrapper.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2024 L. E. Segovia +# SPDX-License-Ref: LGPL-2.1-or-later + +import subprocess +import os +from sys import stdout, stderr +from argparse import ArgumentParser, REMAINDER + +parser = ArgumentParser( + description='Convert command paths to Wine paths', + epilog="Prepend 'posix:' to any path that must be converted. Alternatively, use '--' to separate flags from positional arguments. The positional arguments will be converted wholesale without further intervention.", +) +parser.add_argument('command_or_param', nargs=REMAINDER, help='Portion of command to call') + +if __name__ == '__main__': + args = parser.parse_args() + new_argv = [] + convert_all = False + for i in args.command_or_param: + if i.startswith('posix:'): + real_i = i[6:] + if os.path.isdir(real_i): + new_argv.append(f'z:{os.path.abspath(real_i)}/') + else: + new_argv.append(f'z:{os.path.abspath(real_i)}') + elif i == '--': + convert_all = True + elif convert_all: + new_argv.append(f'z:{os.path.abspath(i)}') + else: + new_argv.append(i) + subprocess.check_call( + new_argv, + stdout=stdout, + stderr=stderr, + shell=False, # Disallow interpreting the path to WiX v5 + ) diff --git a/cerbero/packages/wix.py b/cerbero/packages/wix.py index c623c18ba..9b625c9fc 100644 --- a/cerbero/packages/wix.py +++ b/cerbero/packages/wix.py @@ -20,13 +20,20 @@ import uuid import shutil -from cerbero.utils import etree, to_winepath, shell +from cerbero.utils import etree, to_winepath, shell, xmlwrite from cerbero.errors import FatalError from cerbero.config import Platform, Architecture from cerbero.packages import PackageType from cerbero.packages.package import Package, SDKPackage, App, InstallerPackage -WIX_SCHEMA = 'http://schemas.microsoft.com/wix/2006/wi' +WIX_SCHEMA = 'http://wixtoolset.org/schemas/v4/wxs' +WIX_UI_SCHEMA = 'http://wixtoolset.org/schemas/v4/wxs/ui' +WIX_VS_SCHEMA = 'http://wixtoolset.org/schemas/v4/wxs/vs' + +NS = {'': WIX_SCHEMA, 'ui': WIX_UI_SCHEMA, 'vs': WIX_VS_SCHEMA} + +for k, v in NS.items(): + etree.register_namespace(k, v) class VSTemplatePackage(Package): @@ -76,13 +83,13 @@ def fill(self): def write(self, filepath): self.fill() tree = etree.ElementTree(self.root) - tree.write(filepath, encoding='utf-8', pretty_print=True) + xmlwrite(tree, filepath) def _format_level(self, selected): return selected and '1' or '4' def _format_absent(self, required): - return required and 'disallow' or 'allow' + return required and 'yes' or 'no' def _add_root(self): self.root = etree.Element('Wix', xmlns=WIX_SCHEMA) @@ -162,8 +169,6 @@ def __init__(self, config, files_list, package): def _fill(self): self._add_root() self._add_module() - self._add_package() - self._add_root_dir() self._add_files() def _add_module(self): @@ -172,22 +177,16 @@ def _add_module(self): 'Module', Id=self._format_id(self.package.name), Version=self._format_version(self.package.version), + Guid=self.package.uuid or self._get_uuid(), Language='1033', ) - - def _add_package(self): - self.pkg = etree.SubElement( + self.summary = etree.SubElement( self.module, - 'Package', - Id=self.package.uuid or self._get_uuid(), + 'SummaryInformation', Description=self.package.shortdesc, - Comments=self.package.longdesc, Manufacturer=self.package.vendor, ) - - def _add_root_dir(self): - self.rdir = etree.SubElement(self.module, 'Directory', Id='TARGETDIR', Name='SourceDir') - self._dirnodes[''] = self.rdir + self._dirnodes[''] = self.module def _add_files(self): for f in self.files_list: @@ -306,54 +305,98 @@ class VSMergeModule(MergeModule): def __init__(self, config, files_list, package): MergeModule.__init__(self, config, files_list, package) + self.year = self.package.year - def _add_root_dir(self): - MergeModule._add_root_dir(self) + def _add_module(self): + MergeModule._add_module(self) self._add_vs_templates() def _add_vs_templates(self): - etree.SubElement(self.module, 'PropertyRef', Id='VS_PROJECTTEMPLATES_DIR') - etree.SubElement(self.module, 'PropertyRef', Id='VS_WIZARDS_DIR') - etree.SubElement(self.module, 'CustomActionRef', Id='VS2010InstallVSTemplates') - etree.SubElement(self.module, 'CustomActionRef', Id='VC2010InstallVSTemplates') - prop = etree.SubElement( - self.module, - 'SetProperty', - Id='VSPROJECTTEMPLATESDIR', - After='AppSearch', - Value='[VS_PROJECTTEMPLATES_DIR]\\%s' % self.package.vs_template_name or '', - ) - prop.text = 'VS_PROJECTTEMPLATES_DIR' - prop = etree.SubElement( - self.module, - 'SetProperty', - Id='VSWIZARDSDIR', - After='AppSearch', - Value='[VS_WIZARDS_DIR]\\%s' % os.path.split(self.package.vs_template_dir)[1], - ) - prop.text = 'VS_WIZARDS_DIR' - - self._wizard_dir = etree.SubElement(self.rdir, 'Directory', Id='VSPROJECTTEMPLATESDIR') - self._tpl_dir = etree.SubElement(self.rdir, 'Directory', Id='VSWIZARDSDIR') + self.root.attrib['xmlns:vs'] = WIX_VS_SCHEMA + + etree.SubElement(self.module, 'CustomActionRef', Id=f'VS{self.year}InstallVSTemplates') + etree.SubElement(self.module, 'PropertyRef', Id=f'VS{self.year}_IDE_DIR') + tpl_base = etree.SubElement(self.module, 'Directory', Id=f'VS{self.year}_IDE_DIR') + tpl_base = etree.SubElement(tpl_base, 'Directory', Name='VC') + # In 2015 onwards "wizard" files go into VCProjects + self._wizard_dir = etree.SubElement(tpl_base, 'Directory', Name='VCProjects') + self._wizard_dir = etree.SubElement(self._wizard_dir, 'Directory', Name=self.package.vs_template_name) + self._dirnodes[self.package.vs_wizard_dir] = self._wizard_dir + # In 2015 onwards "template" files go into VCWizards + # **NOTE**: the end path is // + self._tpl_dir = etree.SubElement(tpl_base, 'Directory', Name='VCWizards') + self._tpl_dir = etree.SubElement(self._tpl_dir, 'Directory', Name=self.package.vs_template_name) self._dirnodes[self.package.vs_template_dir] = self._tpl_dir + + +class VSFragment(Fragment): + """ + Creates a Merge Module for Visual Studio templates + + @ivar package: package with the info to build the merge package + @type pacakge: L{cerbero.packages.package.Package} + + FIXME (remove this special casing): https://github.com/wixtoolset/issues/issues/8558 + """ + + def __init__(self, config, files_list, package): + Fragment.__init__(self, config, files_list, package) + self.year = self.package.year + + def _fill(self): + self._add_root() + self._add_fragment() + self._add_component_group() + self._add_vs_templates() + self._add_files() + + def _add_vs_templates(self): + self.root.attrib['xmlns:vs'] = WIX_VS_SCHEMA + + etree.SubElement(self.fragment, 'CustomActionRef', Id=f'VS{self.year}InstallVSTemplates') + etree.SubElement(self.fragment, 'PropertyRef', Id=f'VS{self.year}_IDE_DIR') + tpl_base = etree.SubElement(self.fragment, 'Directory', Id=f'VS{self.year}_IDE_DIR') + tpl_base = etree.SubElement(tpl_base, 'Directory', Name='VC') + dirpath = self.package.vs_template_name + dirid = self._format_dir_id(self.package.name, 'VCProjects' + dirpath) + # In 2015 onwards "wizard" files go into VCProjects + self._wizard_dir = etree.SubElement(tpl_base, 'Directory', Name='VCProjects') + self._wizard_dir = etree.SubElement(self._wizard_dir, 'Directory', Id=dirid, Name=dirpath) self._dirnodes[self.package.vs_wizard_dir] = self._wizard_dir + self._dirids[self.package.vs_wizard_dir] = dirid + # In 2015 onwards "template" files go into VCWizards + # **NOTE**: the end path is // + dirid = self._format_dir_id(self.package.name, 'VCWizards' + dirpath) + self._tpl_dir = etree.SubElement(tpl_base, 'Directory', Name='VCWizards') + self._tpl_dir = etree.SubElement(self._tpl_dir, 'Directory', Id=dirid, Name=self.package.vs_template_name) + # In 2015 onwards they all go into the same folder + self._dirnodes[self.package.vs_template_dir] = self._tpl_dir + self._dirids[self.package.vs_template_dir] = dirid class WixConfig(WixBase): wix_config = 'wix/Config.wxi' + ui_path = 'wix/wixui_Mondo_GStreamer.wxi' def __init__(self, config, package): self.config_path = os.path.join(config.data_dir, self.wix_config) + self.ui_path = os.path.join(config.data_dir, self.ui_path) self.arch = config.target_arch + self.abi_desc = ' '.join(config._get_toolchain_target_platform_arch(readable=True)) self.package = package if isinstance(self.package, App): self.ui_type = 'WixUI_InstallDir' else: - self.ui_type = 'WixUI_Mondo' + self.ui_type = 'WixUI_Mondo_GStreamer' + # Wine doesn't support other than mszip + if config.cross_compiling(): + self.compression = 'mszip' + else: + self.compression = 'high' def write(self, output_dir): - config_out_path = os.path.join(output_dir, os.path.basename(self.wix_config)) - shutil.copy(self.config_path, os.path.join(output_dir, os.path.basename(self.wix_config))) + config_out_path = os.path.join(output_dir, os.path.basename(self.wix_config) + self.package.package_mode) + shutil.copy(self.config_path, config_out_path) replacements = { '@ProductID@': '*', '@UpgradeCode@': self.package.get_wix_upgrade_code(), @@ -361,18 +404,21 @@ def write(self, output_dir): '@Manufacturer@': self.package.vendor, '@Version@': self._format_version(self.package.version), '@PackageComments@': self.package.longdesc, - '@Description@': self.package.shortdesc, - '@ProjectURL': self.package.url, - '@ProductName@': self._product_name(), + '@Description@': f'{self.package.shortdesc} ({self.abi_desc})', + '@ProjectURL@': self.package.url, + '@ProductName@': f'{self.package.shortdesc} ({self.abi_desc})', '@ProgramFilesFolder@': self._program_folder(), '@Platform@': self._platform(), '@UIType@': self.ui_type, + '@Compression@': self.compression, } shell.replace(config_out_path, replacements) - return config_out_path - - def _product_name(self): - return '%s' % self.package.shortdesc + if self.ui_type == 'WixUI_Mondo_GStreamer': + ui_out_path = os.path.join(output_dir, os.path.basename(self.ui_path)) + shutil.copy(self.ui_path, ui_out_path) + return (config_out_path, ui_out_path) + else: + return (config_out_path, None) def _program_folder(self): if self.arch == Architecture.X86: @@ -406,19 +452,18 @@ def __init__(self, config, package, packages_deps, wix_config, store): self.store = store self.wix_config = wix_config self._parse_sources() + self.product = self.root.find('Package', namespaces=NS) + if not self.product: + raise RuntimeError self._add_include() + self._add_compression(not config.cross_compiling()) self._customize_ui() - self.product = self.root.find('.//Product') self._add_vs_properties() def _parse_sources(self): sources_path = self.package.resources_wix_installer or os.path.join(self.config.data_dir, self.wix_sources) - with open(sources_path, 'r') as f: + with open(sources_path, 'r', encoding='utf-8') as f: self.root = etree.fromstring(f.read()) - for element in self.root.iter(): - element.tag = element.tag[len(WIX_SCHEMA) + 2 :] - self.root.set('xmlns', WIX_SCHEMA) - self.product = self.root.find('Product') def _add_include(self): if self._with_wine: @@ -426,6 +471,17 @@ def _add_include(self): inc = etree.PI('include %s' % self.wix_config) self.root.insert(0, inc) + def _add_compression(self, shard): + mediatemplate = etree.SubElement( + self.product, + 'MediaTemplate', + EmbedCab='yes', + CompressionLevel='$(var.Compression)', + ) + if shard: + # On Wine this yields corrupted sharded cabinets. + mediatemplate.set('MaximumUncompressedMediaSize', '50') + def _fill(self): self._add_install_dir() if isinstance(self.package, App): @@ -500,6 +556,9 @@ def _add_merge_modules(self): for package, path in self.packages_deps.items(): if self.package.wix_use_fragment: etree.SubElement(self.main_feature, 'ComponentGroupRef', Id=self._format_group_id(package.name)) + # FIXME: https://github.com/wixtoolset/issues/issues/8558 + elif isinstance(package, VSTemplatePackage): + etree.SubElement(self.main_feature, 'ComponentGroupRef', Id=self._format_group_id(package.name)) else: etree.SubElement( self.installdir, @@ -515,10 +574,9 @@ def _add_dir(self, parent, dir_id, name): return tdir def _add_install_dir(self): - self.target_dir = self._add_dir(self.product, 'TARGETDIR', 'SourceDir') - # FIXME: Add a way to install to ProgramFilesFolder + self.target_dir = etree.SubElement(self.product, 'StandardDirectory', Id='ProgramFiles6432Folder') if isinstance(self.package, App): - installdir = self._add_dir(self.target_dir, '$(var.PlatformProgramFilesFolder)', 'ProgramFilesFolder') + installdir = self.target_dir self.installdir = self._add_dir(installdir, 'INSTALLDIR', '$(var.ProductName)') self.bindir = self._add_dir(self.installdir, 'INSTALLBINDIR', 'bin') else: @@ -550,15 +608,15 @@ def _customize_ui(self): (self.LICENSE_RTF, 'LicenseRtf'), ]: path = self.package.relative_path(path) - if self._with_wine: - path = to_winepath(path) if os.path.exists(path): + if self._with_wine: + path = to_winepath(path) etree.SubElement(self.product, 'WixVariable', Id='WixUI%s' % var, Value=path) # Icon path = self.package.relative_path(self.ICON) - if self._with_wine: - path = to_winepath(path) if os.path.exists(path): + if self._with_wine: + path = to_winepath(path) etree.SubElement(self.product, 'Icon', Id='MainIcon', SourceFile=path) def _add_sdk_root_env_variable(self): @@ -584,45 +642,48 @@ def _add_registry_install_dir(self): # installation folder name = self._package_var().replace(' ', '') - # Add INSTALLDIR in the registry only for the runtime package - if self.package.package_mode == PackageType.RUNTIME: - regcomponent = etree.SubElement( - self.installdir, 'Component', Id='RegistryInstallDir', Guid=self._get_uuid() - ) - regkey = etree.SubElement( - regcomponent, - 'RegistryKey', - Id='RegistryInstallDirRoot', - ForceCreateOnInstall='yes', - ForceDeleteOnUninstall='yes', - Key=self._registry_key(name), - Root=self.REG_ROOT, - ) - etree.SubElement( - regkey, - 'RegistryValue', - Id='RegistryInstallDirValue', - Type='string', - Name='InstallDir', - Value='[INSTALLDIR]', - ) - etree.SubElement( - regkey, - 'RegistryValue', - Id='RegistryVersionValue', - Type='string', - Name='Version', - Value=self.package.version, - ) - etree.SubElement( - regkey, - 'RegistryValue', - Id='RegistrySDKVersionValue', - Type='string', - Name='SdkVersion', - Value=self.package.sdk_version, - ) - etree.SubElement(self.main_feature, 'ComponentRef', Id='RegistryInstallDir') + # Add INSTALLDIR in the registry only when missing + regcomponent = etree.SubElement( + self.installdir, + 'Component', + Id='RegistryInstallDir', + Guid=self._get_uuid(), + Condition='NOT GSTINSTALLDIR', + ) + regkey = etree.SubElement( + regcomponent, + 'RegistryKey', + Id='RegistryInstallDirRoot', + ForceCreateOnInstall='yes', + ForceDeleteOnUninstall='yes', + Key=self._registry_key(name), + Root=self.REG_ROOT, + ) + etree.SubElement( + regkey, + 'RegistryValue', + Id='RegistryInstallDirValue', + Type='string', + Name='InstallDir', + Value='[INSTALLDIR]', + ) + etree.SubElement( + regkey, + 'RegistryValue', + Id='RegistryVersionValue', + Type='string', + Name='Version', + Value=self.package.version, + ) + etree.SubElement( + regkey, + 'RegistryValue', + Id='RegistrySDKVersionValue', + Type='string', + Name='SdkVersion', + Value=self.package.sdk_version, + ) + etree.SubElement(self.main_feature, 'ComponentRef', Id='RegistryInstallDir') def _add_get_install_dir_from_registry(self): name = self._package_var().replace(' ', '') @@ -632,7 +693,7 @@ def _add_get_install_dir_from_registry(self): key = self._registry_key(name) # Get INSTALLDIR from the registry key - installdir_prop = etree.SubElement(self.product, 'Property', Id='INSTALLDIR') + installdir_prop = etree.SubElement(self.product, 'Property', Id='GSTINSTALLDIR') etree.SubElement( installdir_prop, 'RegistrySearch', Id=name, Type='raw', Root=self.REG_ROOT, Key=key, Name='InstallDir' ) @@ -646,8 +707,9 @@ def _add_merge_module(self, package, required, selected, required_packages): Title=package.shortdesc, Level=self._format_level(selected), Display='expand', - Absent=self._format_absent(required), ) + if required: + feature.set('AllowAbsent', 'no') deps = self.store.get_package_deps(package, True) # Add all the merge modules required by this package, but excluding @@ -662,10 +724,12 @@ def _add_merge_module(self, package, required, selected, required_packages): for p in mergerefs: etree.SubElement(feature, 'MergeRef', Id=self._package_id(p.name)) - etree.SubElement(feature, 'MergeRef', Id=self._package_id(package.name)) + # FIXME (remove this special casing): https://github.com/wixtoolset/issues/issues/8558 if isinstance(package, VSTemplatePackage): - c = etree.SubElement(feature, 'Condition', Level='0') - c.text = 'NOT VS2010DEVENV AND NOT VC2010EXPRESS_IDE' + etree.SubElement(feature, 'ComponentGroupRef', Id=self._format_group_id(package.name)) + etree.SubElement(feature, 'Level', Value='0', Condition=f'NOT VS{package.year}DEVENV') + else: + etree.SubElement(feature, 'MergeRef', Id=self._package_id(package.name)) def _add_start_menu_shortcuts(self): # Create a folder with the application name in the Start Menu folder @@ -700,5 +764,7 @@ def _add_start_menu_shortcuts(self): etree.SubElement(self.main_feature, 'ComponentRef', Id='ApplicationShortcut') def _add_vs_properties(self): - etree.SubElement(self.product, 'PropertyRef', Id='VS2010DEVENV') - etree.SubElement(self.product, 'PropertyRef', Id='VC2010EXPRESS_IDE') + etree.SubElement(self.product, f'{{{WIX_VS_SCHEMA}}}FindVisualStudio') + etree.SubElement(self.product, 'PropertyRef', Id='VS2017DEVENV') + etree.SubElement(self.product, 'PropertyRef', Id='VS2019DEVENV') + etree.SubElement(self.product, 'PropertyRef', Id='VS2022DEVENV') diff --git a/cerbero/packages/wix_packager.py b/cerbero/packages/wix_packager.py deleted file mode 100644 index 8c6f8ee45..000000000 --- a/cerbero/packages/wix_packager.py +++ /dev/null @@ -1,339 +0,0 @@ -# cerbero - a multi-platform build system for Open Source software -# Copyright (C) 2012 Andoni Morales Alastruey -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Library General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library 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 -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import os -import tempfile -import shutil -from zipfile import ZipFile - -from cerbero.errors import EmptyPackageError -from cerbero.packages import PackagerBase, PackageType -from cerbero.packages.package import Package, App -from cerbero.utils import messages as m -from cerbero.utils import shell, to_winepath, get_wix_prefix -from cerbero.tools import strip -from cerbero.packages.wix import MergeModule, VSMergeModule, MSI, WixConfig, Fragment -from cerbero.packages.wix import VSTemplatePackage -from cerbero.config import Platform - - -class MergeModulePackager(PackagerBase): - def __init__(self, config, package, store): - PackagerBase.__init__(self, config, package, store) - self._with_wine = config.platform != Platform.WINDOWS - self.wix_prefix = get_wix_prefix(config) - - def pack(self, output_dir, devel=False, force=False, keep_temp=False): - PackagerBase.pack(self, output_dir, devel, force, keep_temp) - - paths = [] - - # create runtime package - p = self.create_merge_module(output_dir, PackageType.RUNTIME, force, self.package.version, keep_temp) - if p: - paths.append(p) - - if devel: - p = self.create_merge_module(output_dir, PackageType.DEVEL, force, self.package.version, keep_temp) - if p: - paths.append(p) - - return paths - - def create_merge_module(self, output_dir, package_type, force, version, keep_temp, keep_strip_temp_dir=False): - self.package.set_mode(package_type) - try: - files_list = self.files_list(package_type, force) - except EmptyPackageError: - m.warning('Package %s is empty, skipping module generation' % self.package.name) - return None - if isinstance(self.package, VSTemplatePackage): - mergemodule = VSMergeModule(self.config, files_list, self.package) - else: - mergemodule = MergeModule(self.config, files_list, self.package) - tmpdir = None - # For packages that requires stripping object files, we need - # to copy all the files to a new tree and strip them there: - if self.package.strip: - tmpdir = tempfile.mkdtemp() - for f in files_list: - src = os.path.join(self.config.prefix, f) - dst = os.path.join(tmpdir, f) - if not os.path.exists(os.path.dirname(dst)): - os.makedirs(os.path.dirname(dst)) - shutil.copy(src, dst) - s = strip.Strip(self.config, self.package.strip_excludes) - for p in self.package.strip_dirs: - s.strip_dir(os.path.join(tmpdir, p)) - - package_name = self._package_name(version) - if self.package.wix_use_fragment: - mergemodule = Fragment(self.config, files_list, self.package) - sources = [os.path.join(output_dir, '%s-fragment.wxs' % package_name)] - wixobjs = [os.path.join(output_dir, '%s-fragment.wixobj' % package_name)] - else: - mergemodule = MergeModule(self.config, files_list, self.package) - sources = [os.path.join(output_dir, '%s.wxs' % package_name)] - wixobjs = [os.path.join(output_dir, '%s.wixobj' % package_name)] - - if tmpdir: - mergemodule.prefix = tmpdir - mergemodule.write(sources[0]) - - for x in ['utils']: - wixobjs.append(os.path.join(output_dir, '%s.wixobj' % x)) - sources.append(os.path.join(os.path.abspath(self.config.data_dir), 'wix/%s.wxs' % x)) - if self._with_wine: - final_wixobjs = ['"{}"'.format(to_winepath(x)) for x in wixobjs] - final_sources = ['"{}"'.format(to_winepath(x)) for x in sources] - else: - final_wixobjs = wixobjs - final_sources = sources - - candle = Candle(self.wix_prefix, self._with_wine) - candle.compile(' '.join(final_sources), output_dir, env=self.config.env) - - if self.package.wix_use_fragment: - path = wixobjs[0] - else: - light = Light(self.wix_prefix, self._with_wine) - path = light.compile(final_wixobjs, package_name, output_dir, env=self.config.env, merge_module=True) - - # Clean up - if not keep_temp: - os.remove(sources[0]) - if not self.package.wix_use_fragment: - for f in wixobjs: - os.remove(f) - try: - os.remove(f.replace('.wixobj', '.wixpdb')) - except Exception: - pass - - if keep_strip_temp_dir: - return (path, tmpdir) - elif tmpdir: - shutil.rmtree(tmpdir) - - return path - - def _package_name(self, version): - if self.config.variants.uwp: - platform = 'uwp' - elif self.config.variants.visualstudio: - platform = 'msvc' - else: - platform = 'mingw' - if self.config.variants.visualstudio and self.config.variants.vscrt == 'mdd': - platform += '+debug' - return '%s-%s-%s-%s' % (self.package.name, platform, self.config.target_arch, version) - - -class MSIPackager(PackagerBase): - UI_EXT = '-ext WixUIExtension' - UTIL_EXT = '-ext WixUtilExtension' - - def __init__(self, config, package, store): - PackagerBase.__init__(self, config, package, store) - self._with_wine = config.platform != Platform.WINDOWS - self.wix_prefix = get_wix_prefix(config) - - def pack(self, output_dir, devel=False, force=False, keep_temp=False): - self.output_dir = os.path.realpath(output_dir) - if not os.path.exists(self.output_dir): - os.makedirs(self.output_dir) - self.force = force - self.keep_temp = keep_temp - - paths = [] - self.merge_modules = {} - - # create runtime package - p = self._create_msi_installer(PackageType.RUNTIME) - paths.append(p) - - # create devel package - if devel and not isinstance(self.package, App): - p = self._create_msi_installer(PackageType.DEVEL) - paths.append(p) - - # create zip with merge modules - if not self.package.wix_use_fragment: - self.package.set_mode(PackageType.RUNTIME) - zipf = ZipFile(os.path.join(self.output_dir, '%s-merge-modules.zip' % self._package_name()), 'w') - for p in self.merge_modules[PackageType.RUNTIME]: - zipf.write(p) - zipf.close() - - if not keep_temp and not self.package.wix_use_fragment: - for msms in list(self.merge_modules.values()): - for p in msms: - os.remove(p) - - return paths - - def _package_name(self): - if self.config.variants.uwp: - platform = 'uwp' - elif self.config.variants.visualstudio: - platform = 'msvc' - else: - platform = 'mingw' - if self.config.variants.visualstudio and self.config.variants.vscrt == 'mdd': - platform += '+debug' - return '%s-%s-%s-%s' % (self.package.name, platform, self.config.target_arch, self.package.version) - - def _create_msi_installer(self, package_type): - self.package.set_mode(package_type) - self.packagedeps = self.store.get_package_deps(self.package, True) - if isinstance(self.package, App): - self.packagedeps = [self.package] - tmp_dirs = self._create_merge_modules(package_type) - config_path = self._create_config() - return self._create_msi(config_path, tmp_dirs) - - def _create_merge_modules(self, package_type): - packagedeps = {} - tmp_dirs = [] - for package in self.packagedeps: - package.set_mode(package_type) - package.wix_use_fragment = self.package.wix_use_fragment - m.action('Creating Merge Module for %s' % package) - packager = MergeModulePackager(self.config, package, self.store) - path = packager.create_merge_module( - self.output_dir, package_type, self.force, self.package.version, self.keep_temp, True - ) - if path: - packagedeps[package] = path[0] - if path[1]: - tmp_dirs.append(path[1]) - self.packagedeps = packagedeps - self.merge_modules[package_type] = list(packagedeps.values()) - return tmp_dirs - - def _create_config(self): - config = WixConfig(self.config, self.package) - config_path = config.write(self.output_dir) - return config_path - - def _create_msi(self, config_path, tmp_dirs): - sources = [os.path.join(self.output_dir, '%s.wxs' % self._package_name())] - msi = MSI(self.config, self.package, self.packagedeps, config_path, self.store) - msi.write(sources[0]) - - wixobjs = [os.path.join(self.output_dir, '%s.wixobj' % self._package_name())] - if self.package.wix_use_fragment: - wixobjs.extend(self.merge_modules[self.package.package_mode]) - - for x in ['utils']: - wixobjs.append(os.path.join(self.output_dir, '%s.wixobj' % x)) - sources.append(os.path.join(os.path.abspath(self.config.data_dir), 'wix/%s.wxs' % x)) - - if self._with_wine: - final_wixobjs = ['"{}"'.format(to_winepath(x)) for x in wixobjs] - final_sources = ['"{}"'.format(to_winepath(x)) for x in sources] - else: - final_wixobjs = wixobjs - final_sources = sources - - candle = Candle(self.wix_prefix, self._with_wine) - candle.compile(' '.join(final_sources), self.output_dir, env=self.config.env) - light = Light(self.wix_prefix, self._with_wine, '%s %s' % (self.UI_EXT, self.UTIL_EXT)) - path = light.compile(final_wixobjs, self._package_name(), self.output_dir, env=self.config.env) - - # Clean up - if not self.keep_temp: - os.remove(sources[0]) - for f in wixobjs: - os.remove(f) - try: - os.remove(f.replace('.wixobj', '.wixpdb')) - except Exception: - pass - os.remove(config_path) - - for tmp_dir in tmp_dirs: - shutil.rmtree(tmp_dir) - - return path - - -class Packager(object): - def __new__(klass, config, package, store): - if isinstance(package, Package): - return MergeModulePackager(config, package, store) - else: - return MSIPackager(config, package, store) - - -class Candle(object): - """Compile WiX objects with candle""" - - cmd = '%(wine)s %(q)s%(prefix)s/candle.exe%(q)s %(source)s' - - def __init__(self, wix_prefix, with_wine): - self.options = {} - self.options['prefix'] = wix_prefix - if with_wine: - self.options['wine'] = 'wine' - self.options['q'] = '"' - else: - self.options['wine'] = '' - self.options['q'] = '' - - def compile(self, source, output_dir, env): - self.options['source'] = source - shell.new_call(self.cmd % self.options, output_dir, env=env) - return os.path.join(output_dir, source, '.msm') - - -class Light(object): - """Compile WiX objects with light""" - - cmd = '%(wine)s %(q)s%(prefix)s/light.exe%(q)s %(objects)s -o ' '%(msi)s.%(ext)s -sval %(extra)s' - - def __init__(self, wix_prefix, with_wine, extra=''): - self.options = {} - self.options['prefix'] = wix_prefix - self.options['extra'] = extra - if with_wine: - self.options['wine'] = 'wine' - self.options['q'] = '"' - else: - self.options['wine'] = '' - self.options['q'] = '' - - def compile(self, objects, msi_file, output_dir, env, merge_module=False): - self.options['objects'] = ' '.join(objects) - self.options['msi'] = msi_file - if merge_module: - self.options['ext'] = 'msm' - else: - self.options['ext'] = 'msi' - shell.new_call(self.cmd % self.options, output_dir, env=env) - msi_file_path = os.path.join(output_dir, '%(msi)s.%(ext)s' % self.options) - if self.options['wine'] == 'wine': - shell.new_call(['chmod', '0755', msi_file_path]) - return msi_file_path - - -def register(): - from cerbero.packages.packager import register_packager - from cerbero.config import Distro - - register_packager(Distro.WINDOWS, Packager) diff --git a/cerbero/tools/depstracker.py b/cerbero/tools/depstracker.py index b7098805f..582125e48 100644 --- a/cerbero/tools/depstracker.py +++ b/cerbero/tools/depstracker.py @@ -26,7 +26,11 @@ class RecursiveLister: def list_file_deps(self, prefix, path): raise NotImplementedError() - def find_deps(self, prefix, lib, state={}, ordered=[]): + def find_deps(self, prefix, lib, state=None, ordered=None): + if state is None: + state = {} + if ordered is None: + ordered = [] if state.get(lib, 'clean') == 'processed': return if state.get(lib, 'clean') == 'in-progress': diff --git a/cerbero/tools/osxrelocator.py b/cerbero/tools/osxrelocator.py index 449b31e16..3ecf12c48 100755 --- a/cerbero/tools/osxrelocator.py +++ b/cerbero/tools/osxrelocator.py @@ -37,9 +37,9 @@ class OSXRelocator(object): ID if the file is a shared library. """ - def __init__(self, root, lib_prefix, recursive, logfile=None): + def __init__(self, root, install_prefix, recursive, logfile=None): self.root = root - self.lib_prefix = self._fix_path(lib_prefix) + self.install_prefix = self._fix_path(install_prefix) self.recursive = recursive self.use_relative_paths = True self.logfile = None @@ -59,7 +59,7 @@ def change_id(self, object_file, id=None): @object_file: Path to the object file @id: New ID; if None, it'll be `@rpath/` """ - id = id or object_file.replace(self.lib_prefix, '@rpath') + id = id or object_file.replace(self.install_prefix, '@rpath') if not self._is_mach_o_file(object_file): return cmd = [INT_CMD, '-id', id, object_file] @@ -96,7 +96,7 @@ def change_libs_path(self, object_file, original_file=None): raise FatalError(f'Cannot relocate a fixed location framework: {dylib_id}') # With that out of the way, we need to sort out how many parents # need to be navigated to reach the root of the GStreamer prefix - depth = len(original_file.split('/')) - len(self.lib_prefix.split('/')) + depth = len(os.path.dirname(original_file).split('/')) - len(self.install_prefix.split('/')) p_depth = '/..' * depth # These paths assume that the file being relocated resides within # /lib @@ -125,7 +125,9 @@ def change_libs_path(self, object_file, original_file=None): rpaths = list(set(rpaths)) # Remove absolute RPATHs, we don't want or need these existing_rpaths = list(set(self.list_rpaths(object_file))) - for p in filter(lambda p: p.startswith('/'), self.list_rpaths(object_file)): + for p in filter( + lambda p: p.startswith('/') and not p.startswith('/Applications/Xcode.app'), self.list_rpaths(object_file) + ): cmd = [INT_CMD, '-delete_rpath', p, object_file] shell.new_call(cmd, fail=False) # Add relative RPATHs @@ -134,12 +136,9 @@ def change_libs_path(self, object_file, original_file=None): shell.new_call(cmd, fail=False) # Change dependencies' paths from absolute to @rpath/ for lib in self.list_shared_libraries(object_file): - if self.lib_prefix in lib: - new_lib = lib.replace(self.lib_prefix, '@rpath') - elif '@rpath/lib/' in lib: - # These are leftovers from meson thinking RPATH == prefix - new_lib = lib.replace('@rpath/lib/', '@rpath/') - else: + new_lib = lib.replace(self.install_prefix, '@rpath').replace('@rpath/lib/', '@rpath/') + # These are leftovers from meson thinking RPATH == prefix + if new_lib == lib: continue cmd = [INT_CMD, '-change', lib, new_lib, object_file] shell.new_call(cmd, fail=False, logfile=self.logfile) diff --git a/cerbero/tools/osxuniversalgenerator.py b/cerbero/tools/osxuniversalgenerator.py index b12bc22c5..d22d3dd54 100755 --- a/cerbero/tools/osxuniversalgenerator.py +++ b/cerbero/tools/osxuniversalgenerator.py @@ -233,7 +233,6 @@ async def parse_dirs_main(): tasks.append(asyncio.ensure_future(parse_dirs_worker())) await run_tasks(tasks, queue_done()) - print('parsing dirs') run_until_complete(parse_dirs_main()) def _copy(self, src, dest): diff --git a/cerbero/tools/strip.py b/cerbero/tools/strip.py index 762111135..4777ba95e 100644 --- a/cerbero/tools/strip.py +++ b/cerbero/tools/strip.py @@ -18,23 +18,25 @@ # Boston, MA 02111-1307, USA. import os -import shlex from cerbero.config import Platform from cerbero.utils import shell, run_until_complete, messages as m class Strip(object): - """Wrapper for the strip tool""" + """ + Wrapper for the strip tool. + Warning: This wrapper should never be used for msvc-built binaries since it usually corrupts them. + Please, check using_msvc == False. + """ def __init__(self, config, excludes=None, keep_symbols=None): self.config = config self.excludes = excludes or [] self.keep_symbols = keep_symbols or [] - self.strip_cmd = [] - if 'STRIP' in config.env: - self.strip_cmd = shlex.split(config.env['STRIP']) + self.build_env = self.config.get_build_env() + self.strip_cmd = self.build_env.get('STRIP', 'strip') - async def _async_strip_file(self, path): + async def async_strip_file(self, path): if not self.strip_cmd: m.warning('Strip command is not defined') return @@ -55,12 +57,13 @@ async def _async_strip_file(self, path): cmd += ['--strip-unneeded', path] try: - await shell.async_call(cmd) + # async_call() is not adapted for EnvValues in env + await shell.async_call(cmd, env={'PATH': self.build_env['PATH'].get()}) except Exception as e: m.warning(e) def strip_file(self, path): - run_until_complete(self._async_strip_file(path)) + run_until_complete(self.async_strip_file(path)) def strip_dir(self, dir_path): if not self.strip_cmd: @@ -70,5 +73,5 @@ def strip_dir(self, dir_path): tasks = [] for dirpath, dirnames, filenames in os.walk(dir_path): for f in filenames: - tasks.append(self._async_strip_file(os.path.join(dirpath, f))) + tasks.append(self.async_strip_file(os.path.join(dirpath, f))) run_until_complete(tasks) diff --git a/cerbero/utils/__init__.py b/cerbero/utils/__init__.py index 3812099c9..ef041b00b 100644 --- a/cerbero/utils/__init__.py +++ b/cerbero/utils/__init__.py @@ -119,12 +119,28 @@ def determine_total_ram() -> int: ram_size_query = subprocess.run([shutil.which('sysctl'), '-n', 'hw.memsize'], stdout=subprocess.PIPE, text=True) if ram_size_query.returncode == 0: return int(ram_size_query.stdout.strip()) - elif platform == Platform.WINDOWS: + elif platform == Platform.WINDOWS and shutil.which('wmic'): ram_size_query = subprocess.run( [shutil.which('wmic'), 'computersystem', 'get', 'totalphysicalmemory'], stdout=subprocess.PIPE, text=True ) if ram_size_query.returncode == 0: return int(ram_size_query.stdout.strip().splitlines()[-1]) + elif platform == Platform.WINDOWS and shutil.which('powershell'): + ram_size_query = subprocess.run( + [ + shutil.which('powershell'), + '(Get-CimInstance', + '-ClassName', + 'Win32_ComputerSystem', + '-Property', + 'TotalPhysicalMemory', + ').TotalPhysicalMemory', + ], + stdout=subprocess.PIPE, + text=True, + ) + if ram_size_query.returncode == 0: + return int(ram_size_query.stdout.strip().splitlines()[-1]) elif platform == Platform.LINUX: free_exe = shutil.which('free') if free_exe: @@ -252,19 +268,16 @@ def system_info(): d = ('arch', 'Arch', 'Linux') elif os.path.exists('/etc/os-release'): with open('/etc/os-release', 'r') as f: - if 'ID="amzn"\n' in f.readlines(): - d = ('RedHat', 'amazon', '') - else: - f.seek(0, 0) - for line in f: - # skip empty lines and comment lines - if line.strip() and not line.lstrip().startswith('#'): - k, v = line.rstrip().split('=') - if k == 'NAME': - name = v.strip('"') - elif k == 'VERSION_ID': - version = v.strip('"') - d = (name, version, '') + f.seek(0, 0) + for line in f: + # skip empty lines and comment lines + if line.strip() and not line.lstrip().startswith('#'): + k, v = line.rstrip().split('=') + if k == 'NAME': + name = v.strip('"') + elif k == 'VERSION_ID': + version = v.strip('"') + d = (name, version, '') if d[0] in ['Ubuntu', 'debian', 'Debian GNU/Linux', 'LinuxMint', 'Linux Mint']: distro = Distro.DEBIAN @@ -337,69 +350,28 @@ def system_info(): distro_version = 'ubuntu_24_04_noble' else: raise FatalError("Distribution '%s' not supported" % str(d)) - elif d[0] in [ - 'RedHat', - 'Fedora', - 'Fedora Linux', - 'CentOS', - 'Red Hat Enterprise Linux Server', - 'CentOS Linux', - 'Amazon Linux', - 'Rocky Linux', - ]: + elif d[0].startswith('Fedora'): + distro = Distro.REDHAT + # str(int()) is for ensuring that the fedora version is + # actually a number + distro_version = 'fedora_' + str(int(d[1])) + elif d[0].startswith(('RedHat', 'CentOS', 'Red Hat', 'Rocky Linux', 'AlmaLinux')): distro = Distro.REDHAT - if d[1] == '16': - distro_version = DistroVersion.FEDORA_16 - elif d[1] == '17': - distro_version = DistroVersion.FEDORA_17 - elif d[1] == '18': - distro_version = DistroVersion.FEDORA_18 - elif d[1] == '19': - distro_version = DistroVersion.FEDORA_19 - elif d[1] == '20': - distro_version = DistroVersion.FEDORA_20 - elif d[1] == '21': - distro_version = DistroVersion.FEDORA_21 - elif d[1] == '22': - distro_version = DistroVersion.FEDORA_22 - elif d[1] == '23': - distro_version = DistroVersion.FEDORA_23 - elif d[1] == '24': - distro_version = DistroVersion.FEDORA_24 - elif d[1] == '25': - distro_version = DistroVersion.FEDORA_25 - elif d[1] == '26': - distro_version = DistroVersion.FEDORA_26 - elif d[1] == '27': - distro_version = DistroVersion.FEDORA_27 - elif d[1] == '28': - distro_version = DistroVersion.FEDORA_28 - elif d[1] == '29': - distro_version = DistroVersion.FEDORA_29 - elif d[1] == '30': - distro_version = DistroVersion.FEDORA_30 - elif d[1] == '31': - distro_version = DistroVersion.FEDORA_31 - elif d[1] == '32': - distro_version = DistroVersion.FEDORA_32 - elif d[0].startswith('Fedora'): - # str(int()) is for ensuring that the fedora version is - # actually a number - distro_version = 'fedora_' + str(int(d[1])) - elif d[1] == '6' or d[1].startswith('6.'): + if d[1] == '6' or d[1].startswith('6.'): distro_version = DistroVersion.REDHAT_6 elif d[1] == '7' or d[1].startswith('7.'): distro_version = DistroVersion.REDHAT_7 - elif d[1] == '8' or d[1].startswith('8.'): - distro_version = DistroVersion.REDHAT_8 - elif d[1] == '9' or d[1].startswith('9.'): - distro_version = DistroVersion.REDHAT_9 - elif d[0] == 'Amazon Linux' and d[1].startswith('2'): - distro_version = DistroVersion.AMAZON_LINUX_2 - elif d[1] == 'amazon': - distro_version = DistroVersion.AMAZON_LINUX else: - # FIXME Fill this + distro_version = 'redhat_' + d[1] + elif d[0].startswith('Amazon Linux'): + distro = Distro.REDHAT + if d[0].endswith('AMI'): + distro_version = DistroVersion.REDHAT_6 + elif d[1] == '2': + distro_version = DistroVersion.REDHAT_7 + elif d[1] == '2023': + distro_version = DistroVersion.AMAZON_LINUX_2023 + else: raise FatalError("Distribution '%s' not supported" % str(d)) elif d[0].strip() in ['openSUSE']: distro = Distro.SUSE @@ -518,26 +490,47 @@ def parse_file(filename, dict): def escape_path(path): - path = path.replace('\\', '/') - path = path.replace('(', r'\\(').replace(')', r'\\)') - path = path.replace(' ', r'\\ ') - return path + return Path(path).as_posix() + + +def decorator_escape_path(fn): + def wrapper(*args, **kwargs): + return escape_path(fn(*args, **kwargs)) + + return wrapper +@decorator_escape_path def get_wix_prefix(config): - if 'WIX' in config.env: - wix_prefix = os.path.join(config.env['WIX'], 'bin') + from cerbero.utils import shell + + if config.platform != Platform.WINDOWS: + err_msg = ', please run bootstrap again' else: - wix_prefix = 'C:/Program Files%s/Windows Installer XML v3.5/bin' - if not os.path.exists(wix_prefix): - wix_prefix = wix_prefix % ' (x86)' - if not os.path.exists(wix_prefix): - wix_prefix = 'C:/Program Files%s/Wix Toolset v3.11/bin' - if not os.path.exists(wix_prefix): - wix_prefix = wix_prefix % ' (x86)' - if not os.path.exists(wix_prefix): - raise FatalError("The required packaging tool 'WiX' was not found") - return escape_path(to_unixpath(wix_prefix)) + err_msg = ', please update it' + wix_path, found, newer = shell.check_tool_version('wix', '5.0.1', env=config.env) + if found: + if newer: + return os.path.dirname(wix_path) + raise FatalError(f'Need WiX 5.0, found {found} which is too old{err_msg}') + if config.cross_compiling(): + return 'C:/Program Files/WiX Toolset v5.0/bin' + progfiles = ('C:/Program Files/', 'C:/Program Files (x86)/') + if 'WIX5' in os.environ: + return os.environ['WIX5'] + # The hunt for WiX 5.0 + wixdir = 'WiX Toolset v5.0/bin' + for d in progfiles: + wix_prefix = d + wixdir + if os.path.exists(wix_prefix): + return wix_prefix + # If the user has WiX 3 installed, give a better error message + for d in progfiles: + for wixdir in ('Windows Installer XML v3.5/bin', 'Wix Toolset v3.11/bin'): + wix_prefix = d + wixdir + if os.path.exists(wix_prefix): + raise FatalError(f'Need WiX 5.0, found WiX 3 which is too old{err_msg}') + raise FatalError('The required packaging tool WiX 5.0 was not found') def add_system_libs(config, new_env, old_env=None): @@ -965,3 +958,83 @@ def __init__(self, *values): if len(values) == 1 and not isinstance(values[0], list): values = (values[0].split(os.pathsep),) super().__init__(os.pathsep, *values) + + +def merge_str_env(old_env, new_env, override_env=()): + """ + Returns a new env dict with the `old_env` as a base, where vars are overridden + by vars from `new_env` dict using `EnvVar.is_*(k)` checks, + or without checks if var name is in `override_env` tuple. + + Values are checked for being `str` type. + """ + ret_env = {} + for k in new_env.keys(): + new_v = new_env[k] + # Must not accidentally use this with EnvValue objects + if not isinstance(new_v, str): + raise AssertionError('new value {!r}: {!r}'.format(k, new_v)) + if k not in old_env or k in override_env: + ret_env[k] = new_v + continue + old_v = old_env[k] + if not isinstance(old_v, str): + raise AssertionError('old value {!r}: {!r}'.format(k, new_v)) + if new_v == old_v: + ret_env[k] = new_v + elif EnvVar.is_path(k) or EnvVar.is_arg(k) or EnvVar.is_cmd(k): + ret_env[k] = new_v + else: + raise FatalError( + "Don't know how to combine the environment " + "variable '%s' with values '%s' and '%s'" % (k, new_v, old_v) + ) + for k in old_env.keys(): + if k not in new_env: + ret_env[k] = old_env[k] + return ret_env + + +def merge_env_value_env(old_env, new_env): + """ + Returns a new env dict with the `old_env` as a base, where vars are overridden + by vars from `new_env` dict if they are not `EnvValuePath` or `EnvValueArg`, + otherwise, values are concatenated. + + Changed values from `old_env` are checked for being `EnvValue` type. + + Values from `new_env` are converted to `EnvValue` using `EnvValue.from_key(k, new_v)`. + """ + ret_env = {} + # Set/merge new values + for k, new_v in new_env.items(): + new_v = EnvValue.from_key(k, new_v) + if k not in old_env: + ret_env[k] = new_v + continue + old_v = old_env[k] + assert isinstance(old_v, EnvValue) + if isinstance(old_v, (EnvValueSingle, EnvValueCmd)) or (new_v == old_v): + ret_env[k] = new_v + elif isinstance(old_v, (EnvValuePath, EnvValueArg)): + ret_env[k] = new_v + old_v + else: + raise FatalError( + "Don't know how to combine the environment " + "variable '%s' with values '%s' and '%s'" % (k, new_v, old_v) + ) + # Set remaining old values + for k in old_env.keys(): + if k not in new_env: + ret_env[k] = old_env[k] + return ret_env + + +### XML Hacks ### +def xmlwrite(tree: etree.ElementTree, filepath, encoding='utf-8'): + import xml + from xml.dom import minidom + + xmlstr = xml.etree.ElementTree.tostring(tree.getroot()) + xmlstr = minidom.parseString(xmlstr).toprettyxml(indent='\t') + open(filepath, 'w', encoding=encoding).write(xmlstr) diff --git a/cerbero/utils/git.py b/cerbero/utils/git.py index 195d68fdd..9223c519b 100644 --- a/cerbero/utils/git.py +++ b/cerbero/utils/git.py @@ -17,6 +17,7 @@ # Boston, MA 02111-1307, USA. import os +import shutil import time import cerbero.utils.messages as m @@ -24,8 +25,11 @@ from cerbero.utils import shell, _ from cerbero.errors import FatalError - -GIT = 'git' +if shell.PLATFORM == Platform.WINDOWS: + # We do not want the MSYS2 Git because it mucks consumption by Cargo + GIT = shutil.which('git', path=shell.get_path_minus_msys(os.environ['PATH'])) +else: + GIT = 'git' def ensure_user_is_set(git_dir, logfile=None): diff --git a/cerbero/utils/messages.py b/cerbero/utils/messages.py index 5b825d22c..54bcdf88e 100644 --- a/cerbero/utils/messages.py +++ b/cerbero/utils/messages.py @@ -16,6 +16,7 @@ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. +import io import sys import os import time @@ -49,8 +50,12 @@ def enable_vt100(): def console_is_interactive(): - if not os.isatty(sys.stdout.fileno()): + try: + if not os.isatty(sys.stdout.fileno()): + return False + except io.UnsupportedOperation: return False + if os.environ.get('TERM') == 'dumb': return False return True diff --git a/cerbero/utils/shell.py b/cerbero/utils/shell.py index dc290d5f8..d7c363a26 100644 --- a/cerbero/utils/shell.py +++ b/cerbero/utils/shell.py @@ -29,9 +29,6 @@ import glob import shutil import hashlib -import urllib.request -import urllib.error -import urllib.parse import collections from pathlib import Path, PurePath @@ -197,23 +194,40 @@ def check_output(cmd, cmd_dir=None, fail=True, logfile=None, env=None, quiet=Fal if sys.stdout.encoding: o = o.decode(sys.stdout.encoding, errors='replace') + elif isinstance(o, bytes): + o = o.decode() return o -def new_call(cmd, cmd_dir=None, fail=True, logfile=None, env=None, verbose=False, interactive=False, shell=False): +def new_call( + cmd, cmd_dir=None, fail=True, logfile=None, env=None, verbose=False, interactive=False, shell=False, input=None +): cmd = _cmd_string_to_array(cmd, env) if logfile: - logfile.write(f'Running command {cmd!r} in {cmd_dir}\n') + if input: + logfile.write(f'Running command {cmd!r} with stdin {input} in {cmd_dir}\n') + else: + logfile.write(f'Running command {cmd!r} in {cmd_dir}\n') logfile.flush() if verbose: m.message('Running {!r}\n'.format(cmd)) - if not interactive: + if input: + stdin = None + elif not interactive: stdin = subprocess.DEVNULL else: stdin = None try: subprocess.run( - cmd, cwd=cmd_dir, env=env, stdout=logfile, stderr=subprocess.STDOUT, stdin=stdin, shell=shell, check=True + cmd, + cwd=cmd_dir, + env=env, + stdout=logfile, + stderr=subprocess.STDOUT, + stdin=stdin, + input=input, + shell=shell, + check=True, ) except SUBPROCESS_EXCEPTIONS as e: returncode = getattr(e, 'returncode', -1) @@ -383,7 +397,7 @@ async def unpack(filepath, output_dir, logfile=None, force_tarfile=False): raise FatalError('Unknown tarball format %s' % filepath) -async def download(url, dest, check_cert=True, overwrite=False, logfile=None, mirrors=None): +async def download(url, dest, check_cert=True, overwrite=False, logfile=None, fallback_urls=None): """ Downloads a file @@ -397,10 +411,11 @@ async def download(url, dest, check_cert=True, overwrite=False, logfile=None, mi @type check_cert: bool @param logfile: path to the file to log instead of stdout @type logfile: str - @param mirrors: list of mirrors to use as fallback - @type logfile: list """ user_agent = 'GStreamerCerbero/' + CERBERO_VERSION + urls = [url] + if fallback_urls: + urls += fallback_urls if not overwrite and os.path.exists(dest): if logfile is None: @@ -411,13 +426,6 @@ async def download(url, dest, check_cert=True, overwrite=False, logfile=None, mi os.makedirs(os.path.dirname(dest)) m.log('Downloading {}'.format(url), logfile) - urls = [url] - if mirrors is not None: - filename = os.path.basename(url) - # Add a traling '/' the url so that urljoin joins correctly urls - # in case users provided it without the trailing '/' - urls += [urllib.parse.urljoin(u + '/', filename) for u in mirrors] - if sys.platform.startswith('win'): cmd = [ 'powershell', @@ -427,16 +435,6 @@ async def download(url, dest, check_cert=True, overwrite=False, logfile=None, mi f'Invoke-WebRequest -UserAgent {user_agent} -OutFile {dest} ' '-Method Get -Uri %s', ] - elif shutil.which('wget2'): - cmd = ['wget2', '--user-agent', user_agent, '--tries=2', '--timeout=20', '-O', dest] - if not check_cert: - cmd += ['--no-check-certificate'] - cmd += ['%s'] - elif shutil.which('wget'): - cmd = ['wget', '--user-agent', user_agent, '--tries=2', '--timeout=20', '--progress=dot:giga', '-O', dest] - if not check_cert: - cmd += ['--no-check-certificate'] - cmd += ['%s'] elif shutil.which('curl'): cmd = [ 'curl', @@ -455,6 +453,16 @@ async def download(url, dest, check_cert=True, overwrite=False, logfile=None, mi if not check_cert: cmd += ['-k'] cmd += ['%s'] + elif shutil.which('wget2'): + cmd = ['wget2', '--user-agent', user_agent, '--tries=2', '--timeout=20', '-O', dest] + if not check_cert: + cmd += ['--no-check-certificate'] + cmd += ['%s'] + elif shutil.which('wget'): + cmd = ['wget', '--user-agent', user_agent, '--tries=2', '--timeout=20', '--progress=dot:giga', '-O', dest] + if not check_cert: + cmd += ['--no-check-certificate'] + cmd += ['%s'] else: raise FatalError('Need either wget or curl to download things') @@ -526,8 +534,10 @@ def find_files(pattern, prefix): return glob.glob(os.path.join(prefix, pattern)) -def prompt(message, options=[]): +def prompt(message, options=None): """Prompts the user for input with the message and options""" + if options is None: + options = [] if len(options) != 0: message = '%s [%s] ' % (message, '/'.join(options)) res = input(message) @@ -653,23 +663,24 @@ def enter_build_environment(platform, arch, distro, sourcedir=None, bash_complet bat_tpl = MSYSBAT else: bat_tpl = MSYS2BAT - msysbatdir = tempfile.mkdtemp() - msysbat = os.path.join(msysbatdir, 'msys.bat') - bashrc = os.path.join(msysbatdir, 'bash.rc') - with open(msysbat, 'w+') as f: - f.write(bat_tpl % bashrc) - with open(bashrc, 'w+') as f: - f.write(shellrc) - subprocess.check_call(msysbat, shell=True, env=env) - # We should remove the temporary directory - # but there is a race with the bash process + with tempfile.TemporaryDirectory() as msysbatdir: + bashrc = os.path.join(msysbatdir, 'bash.rc') + with open(bashrc, 'w+') as f: + f.write(shellrc) + if os.environ['MSYSTEM'] == 'UCRT64': + subprocess.check_call([os.environ['SHELL'], '--rcfile', bashrc], shell=False, env=env) + else: + msysbat = os.path.join(msysbatdir, 'msys.bat') + with open(msysbat, 'w+') as f: + f.write(bat_tpl % bashrc) + subprocess.check_call(msysbat, shell=True, env=env) else: with tempfile.TemporaryDirectory() as tmp: rc_tmp = open(os.path.join(tmp, rc_file), 'w+') rc_tmp.write(shellrc) rc_tmp.flush() if 'zsh' in shell: - env['ZDOTDIR'] = tmp.name + env['ZDOTDIR'] = tmp os.execlpe(shell, shell, env) else: # Check if the shell supports passing the rcfile diff --git a/ci/cerbero_setup.sh b/ci/cerbero_setup.sh index 509e1bd61..d21a2a37c 100755 --- a/ci/cerbero_setup.sh +++ b/ci/cerbero_setup.sh @@ -28,22 +28,26 @@ fix_build_tools() { fi } +user_branch_exists_in() { + ./ci/exists_branch_in_user_repo.sh "$1" "$2" +} + # Produces runtime and devel tarball packages for linux/android or .pkg for macos cerbero_package_and_check() { # Plugins that dlopen libs and will have 0 features on the CI, and hence # won't be listed in `gst-inspect-1.0` output, and have to be inspected # explicitly - local dlopen_plugins=(jack soup) + local dlopen_plugins=(jack soup adaptivedemux2) if [[ $CONFIG = win* ]]; then dlopen_plugins+=(amfcodec mediafoundation msdk nvcodec qsv) elif [[ $CONFIG = linux* ]]; then dlopen_plugins+=(msdk nvcodec qsv va vaapi) fi - $CERBERO $CERBERO_ARGS package --offline ${CERBERO_PACKAGE_ARGS} -o "$(pwd_native)" gstreamer-1.0 + ./ci/run_retry.sh $CERBERO $CERBERO_ARGS package --offline ${CERBERO_PACKAGE_ARGS} -o "$(pwd_native)" gstreamer-1.0 # Run gst-inspect-1.0 for some basic checks. Can't do this for cross-(android|ios)-universal, of course. - if [[ $CONFIG != *universal* ]] && [[ $CONFIG != *cross-win* ]]; then + if [[ $CONFIG != *ios-universal* ]] && [[ $CONFIG != *android-universal* ]] && [[ $CONFIG != *cross-win* ]]; then $CERBERO $CERBERO_ARGS run gst-inspect-1.0$CERBERO_RUN_SUFFIX --version $CERBERO $CERBERO_ARGS run gst-inspect-1.0$CERBERO_RUN_SUFFIX for plugin in $dlopen_plugins; do @@ -54,10 +58,96 @@ cerbero_package_and_check() { show_ccache_sum } +# Using "main" as the branch name in the Cerbero PR's fork is valid, +# and in that case we should NOT look for a branch by the same name in +# the user's gstreamer / gst-plugins-rs forks because those will always +# exist and the user doesn't intend for us to use that outdated branch +# +# We also don't want to search for a stable branch name, such as 1.24 +can_search_branch_name() { + [[ $1 != main ]] && [[ $1 != ${GST_UPSTREAM_BRANCH} ]] +} + cerbero_before_script() { + # Default: unset, use recipe defaults + local gst_commit + local gst_remote + local gstpluginsrs_commit + local gstpluginsrs_remote + local user_branch + local user_ns + local job_type="other" pwd ls -lha + + # Three special cases in which we should build against a user-specific + # branch of gstreamer or gst-plugins-rs: + # 1. We have been triggered by gstreamer monorepo MR CI + # - ci/gitlab/trigger_cerbero_pipeline.py + # - job_type=gstreamer-mr + # 2. We have been triggered by gst-plugins-rs MR CI + # - ci/cerbero/trigger_cerbero_pipeline.py + # - job_type=gstpluginsrs-mr + # 3. We are running as part of CI for a cerbero merge request + # - job_type=cerbero-mr + # + # We should skip that logic when: + # * We are running in post-merge CI pipeline + # * We are running in a scheduled pipeline + # job_type=other + if [[ -n ${CI_GSTREAMER_PATH} ]]; then + echo "gstreamer MR trigger CI" + job_type="gstreamer-mr" + if can_search_branch_name ${CI_GSTREAMER_REF_NAME}; then + echo "Using gstreamer MR user branch" + gst_commit="${CI_GSTREAMER_REF_NAME}" + gst_remote="${CI_SERVER_URL}/${CI_GSTREAMER_PATH}" + user_branch="${CI_GSTREAMER_REF_NAME}" + user_ns=$(dirname ${CI_GSTREAMER_PATH}) + fi + elif [[ -n ${CI_GST_PLUGINS_RS_PATH} ]]; then + echo "gst-plugins-rs MR trigger CI" + job_type="gstpluginsrs-mr" + if can_search_branch_name ${CI_GST_PLUGINS_RS_REF_NAME}; then + echo "Using gst-plugins-rs MR user branch" + gstpluginsrs_commit="${CI_GST_PLUGINS_RS_REF_NAME}" + gstpluginsrs_remote="${CI_SERVER_URL}/${CI_GST_PLUGINS_RS_PATH}" + user_branch="${CI_GST_PLUGINS_RS_REF_NAME}" + user_ns=$(dirname ${CI_GST_PLUGINS_RS_PATH}) + fi + elif [[ ${CI_PROJECT_NAMESPACE} != gstreamer ]]; then + echo "Cerbero merge request" + job_type="cerbero-mr" + if can_search_branch_name ${CI_COMMIT_REF_NAME}; then + echo "Using cerbero MR user branch" + user_branch=${CI_COMMIT_REF_NAME} + user_ns=${CI_PROJECT_NAMESPACE} + fi + fi + + # Search for the specific branch in the user's forks + if [[ -n $user_branch ]]; then + # If we're in a gst-plugins-rs MR or a cerbero MR, look for a matching + # monorepo branch in the user's fork + if [[ $job_type = "gstpluginsrs-mr" ]] || [[ $job_type = "cerbero-mr" ]]; then + if user_branch_exists_in "${user_ns}/gstreamer" "${user_branch}"; then + gst_commit="${user_branch}" + gst_remote="${CI_SERVER_URL}/${user_ns}/gstreamer" + echo "Found gstreamer branch ${gst_commit} in ${gst_remote}" + fi + fi + # If we're in a gstreamer monorepo MR or a cerbero MR, look for + # a matching gst-plugins-rs branch in the user's fork + if [[ $job_type = "gstreamer-mr" ]] || [[ $job_type = "cerbero-mr" ]]; then + if user_branch_exists_in "${user_ns}/gst-plugins-rs" "${user_branch}"; then + gstpluginsrs_commit="${user_branch}" + gstpluginsrs_remote="${CI_SERVER_URL}/${user_ns}/gst-plugins-rs" + echo "Found gst-plugins-rs branch ${gstpluginsrs_commit} in ${gstpluginsrs_remote}" + fi + fi + fi + # If there's no cerbero-sources directory in the runner cache, copy it from # the image cache if ! [[ -d ${CERBERO_SOURCES} ]]; then @@ -76,8 +166,25 @@ cerbero_before_script() { if [[ "x${FDO_CI_CONCURRENT}" != "x" ]]; then echo "num_of_cpus = ${FDO_CI_CONCURRENT}" >> localconf.cbc fi - echo "recipes_commits = {'gstreamer-1.0': 'ci/${CI_GSTREAMER_REF_NAME}'}" >> localconf.cbc - echo "recipes_remotes = {'gstreamer-1.0': {'ci': '${CI_GSTREAMER_URL}'}}" >> localconf.cbc + + echo "recipes_commits = {" >> localconf.cbc + if [[ -n $gst_commit ]]; then + echo " 'gstreamer-1.0': 'ci/${gst_commit}'," >> localconf.cbc + fi + if [[ -n $gstpluginsrs_commit ]]; then + echo " 'gst-plugins-rs': 'ci/${gstpluginsrs_commit}'," >> localconf.cbc + fi + echo "}" >> localconf.cbc + + echo "recipes_remotes = {" >> localconf.cbc + if [[ -n $gst_remote ]]; then + echo " 'gstreamer-1.0': {'ci': '${gst_remote}'}," >> localconf.cbc + fi + if [[ -n $gstpluginsrs_remote ]]; then + echo " 'gst-plugins-rs': {'ci': '${gstpluginsrs_remote}'}," >> localconf.cbc + fi + echo "}" >> localconf.cbc + cat localconf.cbc # GitLab runner does not always wipe the image after each job, so do that @@ -90,24 +197,45 @@ cerbero_before_script() { cerbero_script() { show_ccache_sum - $CERBERO $CERBERO_ARGS show-config + $CERBERO $CERBERO_ARGS show-config | tee config.txt + if [[ -n $CI_GST_PLUGINS_RS_REF_NAME ]] && grep -q '\' config.txt; then + echo "gst-plugins-rs trigger CI, but Rust variant is disabled. Skipping job." + return 0 + fi + $CERBERO $CERBERO_ARGS fetch-bootstrap --jobs=4 $CERBERO $CERBERO_ARGS fetch-package --jobs=4 --deps gstreamer-1.0 du -sch "${CERBERO_SOURCES}" || true - $CERBERO $CERBERO_ARGS fetch-cache --branch "${GST_UPSTREAM_BRANCH}" - - if [[ -n ${CERBERO_OVERRIDDEN_DIST_DIR} && -d "${CERBERO_HOME}/dist/${ARCH}" ]]; then - mkdir -p "${CERBERO_OVERRIDDEN_DIST_DIR}" - time rsync -aH "${CERBERO_HOME}/dist/${ARCH}/" "${CERBERO_OVERRIDDEN_DIST_DIR}" + local project + if [[ -n $CI_GST_PLUGINS_RS_REF_NAME ]]; then + project="gst-plugins-rs" + else + project="gstreamer" fi + $CERBERO $CERBERO_ARGS fetch-cache --branch "${GST_UPSTREAM_BRANCH}" --project "${project}" - $CERBERO $CERBERO_ARGS bootstrap --offline --system=$CERBERO_BOOTSTRAP_SYSTEM + ./ci/run_retry.sh $CERBERO $CERBERO_ARGS bootstrap --offline --system=$CERBERO_BOOTSTRAP_SYSTEM --assume-yes fix_build_tools cerbero_package_and_check } +upload_cache() { + # Check that the env var is set. Don't expand this protected variable by + # doing something silly like [[ -n ${CERBERO_...} ]] because it will get + # printed in the CI logs due to set -x + if env | grep -q -e CERBERO_PRIVATE_SSH_KEY; then + # Don't generate and upload caches for scheduled pipelines on main branch + if [[ "x${CI_PIPELINE_SOURCE}" != "xschedule" ]]; then + time $CERBERO $CERBERO_ARGS gen-cache \ + --project="$1" --branch "${GST_UPSTREAM_BRANCH}" + time $CERBERO $CERBERO_ARGS upload-cache \ + --project="$1" --branch "${GST_UPSTREAM_BRANCH}" + fi + fi +} + cerbero_deps_script() { # Build deps for all gstreamer recipes and any recipes that build gstreamer # plugins (and hence compile against gstreamer) @@ -132,25 +260,18 @@ cerbero_deps_script() { $CERBERO $CERBERO_ARGS show-config $CERBERO $CERBERO_ARGS fetch-bootstrap --jobs=4 $CERBERO $CERBERO_ARGS fetch-package --jobs=4 --deps gstreamer-1.0 - $CERBERO $CERBERO_ARGS bootstrap --offline --system=$CERBERO_BOOTSTRAP_SYSTEM - $CERBERO $CERBERO_ARGS build-deps --offline $build_deps - $CERBERO $CERBERO_ARGS build --offline $more_deps - - if [[ -n ${CERBERO_OVERRIDDEN_DIST_DIR} ]]; then - mkdir -p "${CERBERO_HOME}/dist/${ARCH}" - time rsync -aH "${CERBERO_OVERRIDDEN_DIST_DIR}/" "${CERBERO_HOME}/dist/${ARCH}" - fi + ./ci/run_retry.sh $CERBERO $CERBERO_ARGS bootstrap --offline --system=$CERBERO_BOOTSTRAP_SYSTEM --assume-yes + ./ci/run_retry.sh $CERBERO $CERBERO_ARGS build-deps --offline $build_deps + ./ci/run_retry.sh $CERBERO $CERBERO_ARGS build --offline $more_deps + # All external deps have been built, upload the cache for the cerbero CI + # triggered by the gstreamer monorepo + upload_cache gstreamer - # Check that the env var is set. Don't expand this protected variable by - # doing something silly like [[ -n ${CERBERO_...} ]] because it will get - # printed in the CI logs due to set -x - if env | grep -q -e CERBERO_PRIVATE_SSH_KEY; then - # Don't generate and upload caches for scheduled pipelines on main branch - if [[ "x${CI_PIPELINE_SOURCE}" != "xschedule" ]]; then - time $CERBERO $CERBERO_ARGS gen-cache --branch "${GST_UPSTREAM_BRANCH}" - time $CERBERO $CERBERO_ARGS upload-cache --branch "${GST_UPSTREAM_BRANCH}" - fi - fi + # Now, build everything except gst-plugins-rs and gst-android-1.0 since + # that also pulls gst-plugins-rs in + ./ci/run_retry.sh $CERBERO $CERBERO_ARGS package --offline gstreamer-1.0 --only-build-deps \ + --exclude gst-plugins-rs --exclude gst-android-1.0 --exclude gstreamer-ios-templates + upload_cache gst-plugins-rs cerbero_package_and_check } diff --git a/ci/docker_android_setup.sh b/ci/docker_android_setup.sh index 1a53b024e..714a62b0d 100755 --- a/ci/docker_android_setup.sh +++ b/ci/docker_android_setup.sh @@ -28,7 +28,7 @@ echo "e9acab5b5fbb560a72cfaecce8946896ff6aab9d" > ${ANDROID_HOME}/licenses/mips- # pre-cache deps export GSTREAMER_ROOT_ANDROID=/android/sources/gstreamer-android -curl -o /android/sources/gstreamer-android.tar.xz https://gstreamer.freedesktop.org/data/pkg/android/1.22.0/gstreamer-1.0-android-universal-1.22.0.tar.xz +curl -o /android/sources/gstreamer-android.tar.xz https://gstreamer.freedesktop.org/data/pkg/android/1.26.2/gstreamer-1.0-android-universal-1.26.2.tar.xz mkdir $GSTREAMER_ROOT_ANDROID tar -xvf /android/sources/gstreamer-android.tar.xz -C $GSTREAMER_ROOT_ANDROID ls $GSTREAMER_ROOT_ANDROID diff --git a/ci/examples_setup.sh b/ci/examples_setup.sh new file mode 100755 index 000000000..feb9812f8 --- /dev/null +++ b/ci/examples_setup.sh @@ -0,0 +1,120 @@ +#!/bin/bash +# vim: set sts=4 sw=4 et : + +set -ex + +user_branch_exists_in() { + ./ci/exists_branch_in_user_repo.sh "$1" "$2" +} + +clone_gstreamer() { + local gst_commit="$GST_UPSTREAM_BRANCH" + local gst_remote="${CI_SERVER_URL}/gstreamer/gstreamer" + + # Two special cases in which we should build examples against + # a user-specific branch of gstreamer: + # 1. We have been triggered by gstreamer monorepo CI + # - ci/gitlab/trigger_cerbero_pipeline.py + # 2. We are running as part of CI for a cerbero merge request + if [[ -n ${CI_GSTREAMER_PATH} ]]; then + gst_commit="${CI_GSTREAMER_REF_NAME}" + gst_remote="${CI_SERVER_URL}/${CI_GSTREAMER_PATH}" + echo "gstreamer trigger CI, using ${gst_commit} in ${gst_remote}" + elif [[ -n ${CI_GST_PLUGINS_RS_PATH} ]]; then + echo "gst-plugins-rs trigger CI, using ${gst_commit} in ${gst_remote}" + elif [[ ${CI_PROJECT_NAMESPACE} != gstreamer ]]; then + echo "Cerbero merge request, checking for matching branch in user fork of gstreamer" + if user_branch_exists_in "${CI_PROJECT_NAMESPACE}/gstreamer" "${CI_COMMIT_REF_NAME}"; then + gst_commit="${CI_COMMIT_REF_NAME}" + gst_remote="${CI_SERVER_URL}/${CI_PROJECT_NAMESPACE}/gstreamer" + echo "Found branch ${gst_commit} in ${gst_remote}" + else + gst_remote="${CI_SERVER_URL}/gstreamer/gstreamer" + fi + fi + + # Clone gstreamer repository to get gst-examples and gst-docs + rm -rf gstreamer + git clone "${gst_remote}" -b "${gst_commit}" --depth 1 gstreamer/ +} + +find_textrels() { + set +x + local apks + local libs + + mapfile -t apks < <(find ${EXAMPLES_HOME} -iname '*.apk') + echo "${apks[@]}" + if [[ "${#apks[@]}" -eq 0 ]]; then + echo "No APKs found in ${EXAMPLES_HOME}" + return 1 + fi + + local ret=0 + for apk in "${apks[@]}"; do + echo "Checking $apk" + d=$(basename "${apk}_CONTENTS") + mkdir "$d" + unzip -qd "$d" "$apk" + mapfile -t libs < <(find "$d" -iname libgstreamer_android.so) + for lib in "${libs[@]}"; do + echo $lib + if readelf --dynamic "$lib" | grep TEXTREL; then + echo "Text relocations found in $lib:" + scanelf -qT "$lib" + ret=1 + fi + done + done + + if [[ $ret != 0 ]]; then + echo "ERROR: Text relocations found! See above for details." + fi + return $ret +} + +build_android_examples() { + clone_gstreamer + mkdir -p ${OUTPUT_DIR} + + # extract our binaries + rm -f gstreamer-1.0-android-universal-*-runtime.tar.* + mkdir ${GSTREAMER_ROOT_ANDROID} + time tar -C ${GSTREAMER_ROOT_ANDROID} -xf gstreamer-1.0-android-universal-*.tar.* + + # install tools + ./ci/run_retry.sh ${ANDROID_HOME}/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_HOME} "cmake;3.18.1" "build-tools;30.0.3" "ndk;25.2.9519653" "platforms;android-32" + + # build the examples + ./ci/generate_rules.py + CI_BASE_DIR=$PWD + mv build.ninja ${OUTPUT_DIR}/ + pushd ${OUTPUT_DIR} + ${CI_BASE_DIR}/ci/run_retry.sh ${ANDROID_HOME}/cmake/3.18.1/bin/ninja + + find_textrels +} + +build_ios_examples() { + # install the binaries + installer -pkg gstreamer-1.0-devel-*-ios-universal.pkg -target CurrentUserHomeDirectory -verbose + + # Clone gstreamer repository to get gst-examples and gst-docs + clone_gstreamer + + # dump some useful information + xcodebuild -version + xcodebuild -showsdks + echo ${XCODE_BUILD_ARGS} > xcode_buildargs + + # gst-docs ios tutorials + ./ci/run_retry.sh xcodebuild -showBuildSettings -alltargets -project ${EXAMPLES_HOME}/gst-docs/examples/tutorials/xcode\ iOS/GStreamer\ iOS\ Tutorials.xcodeproj $(cat xcode_buildargs) + ./ci/run_retry.sh xcodebuild -alltargets -destination generic/platform=iOS -project ${EXAMPLES_HOME}/gst-docs/examples/tutorials/xcode\ iOS/GStreamer\ iOS\ Tutorials.xcodeproj $(cat xcode_buildargs) + + # gst-examples + ./ci/run_retry.sh xcodebuild -showBuildSettings -alltargets -project ${EXAMPLES_HOME}/gst-examples/playback/player/ios/GstPlay.xcodeproj $(cat xcode_buildargs) + ./ci/run_retry.sh xcodebuild -alltargets -destination generic/platform=iOS -project ${EXAMPLES_HOME}/gst-examples/playback/player/ios/GstPlay.xcodeproj $(cat xcode_buildargs) +} + +# Run whichever function is asked of us +eval "$1" diff --git a/ci/exists_branch_in_user_repo.sh b/ci/exists_branch_in_user_repo.sh new file mode 100755 index 000000000..ba6789b60 --- /dev/null +++ b/ci/exists_branch_in_user_repo.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# vim: set sts=2 sw=2 et : +# +# Takes a branch name and a repo name, and returns 0 if that branch exists in +# a fork of the repo in the user's namespace, else returns non-zero. + +quoted() { + python3 -c "import urllib.parse; print(urllib.parse.quote('$1', safe=''))" +} + +PROJECT_PATH=$(quoted "$1") +BRANCH_NAME=$(quoted "$2") + +if [[ -z ${PROJECT_PATH} ]] || [[ -z ${BRANCH_NAME} ]]; then + echo "Usage: $0 " + exit 1 +fi + +curl --fail-with-body -s "${CI_API_V4_URL}/projects/${PROJECT_PATH}/repository/branches/${BRANCH_NAME}" diff --git a/ci/generate_rules.py b/ci/generate_rules.py new file mode 100755 index 000000000..837c3bb32 --- /dev/null +++ b/ci/generate_rules.py @@ -0,0 +1,306 @@ +#!/usr/bin/env python3 + +### BEGIN NINJA-BUILD CODE ### + +# Copyright 2011 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Python module for generating .ninja files. + +Note that this is emphatically not a required piece of Ninja; it's +just a helpful utility for build-file-generation systems that already +use Python. +""" + +# ruff: noqa: E402 +import re +import textwrap +from io import TextIOWrapper +from typing import Dict, List, Match, Optional, Tuple, Union + + +def escape_path(word: str) -> str: + return word.replace('$ ', '$$ ').replace(' ', '$ ').replace(':', '$:') + + +class Writer(object): + def __init__(self, output: TextIOWrapper, width: int = 78) -> None: + self.output = output + self.width = width + + def newline(self) -> None: + self.output.write('\n') + + def comment(self, text: str) -> None: + for line in textwrap.wrap(text, self.width - 2, break_long_words=False, break_on_hyphens=False): + self.output.write('# ' + line + '\n') + + def variable( + self, + key: str, + value: Optional[Union[bool, int, float, str, List[str]]], + indent: int = 0, + ) -> None: + if value is None: + return + if isinstance(value, list): + value = ' '.join(filter(None, value)) # Filter out empty strings. + self._line('%s = %s' % (key, value), indent) + + def pool(self, name: str, depth: int) -> None: + self._line('pool %s' % name) + self.variable('depth', depth, indent=1) + + def rule( + self, + name: str, + command: str, + description: Optional[str] = None, + depfile: Optional[str] = None, + generator: bool = False, + pool: Optional[str] = None, + restat: bool = False, + rspfile: Optional[str] = None, + rspfile_content: Optional[str] = None, + deps: Optional[Union[str, List[str]]] = None, + ) -> None: + self._line('rule %s' % name) + self.variable('command', command, indent=1) + if description: + self.variable('description', description, indent=1) + if depfile: + self.variable('depfile', depfile, indent=1) + if generator: + self.variable('generator', '1', indent=1) + if pool: + self.variable('pool', pool, indent=1) + if restat: + self.variable('restat', '1', indent=1) + if rspfile: + self.variable('rspfile', rspfile, indent=1) + if rspfile_content: + self.variable('rspfile_content', rspfile_content, indent=1) + if deps: + self.variable('deps', deps, indent=1) + + def build( + self, + outputs: Union[str, List[str]], + rule: str, + inputs: Optional[Union[str, List[str]]] = None, + implicit: Optional[Union[str, List[str]]] = None, + order_only: Optional[Union[str, List[str]]] = None, + variables: Optional[ + Union[ + List[Tuple[str, Optional[Union[str, List[str]]]]], + Dict[str, Optional[Union[str, List[str]]]], + ] + ] = None, + implicit_outputs: Optional[Union[str, List[str]]] = None, + pool: Optional[str] = None, + dyndep: Optional[str] = None, + ) -> List[str]: + outputs = as_list(outputs) + out_outputs = [escape_path(x) for x in outputs] + all_inputs = [escape_path(x) for x in as_list(inputs)] + + if implicit: + implicit = [escape_path(x) for x in as_list(implicit)] + all_inputs.append('|') + all_inputs.extend(implicit) + if order_only: + order_only = [escape_path(x) for x in as_list(order_only)] + all_inputs.append('||') + all_inputs.extend(order_only) + if implicit_outputs: + implicit_outputs = [escape_path(x) for x in as_list(implicit_outputs)] + out_outputs.append('|') + out_outputs.extend(implicit_outputs) + + self._line('build %s: %s' % (' '.join(out_outputs), ' '.join([rule] + all_inputs))) + if pool is not None: + self._line(' pool = %s' % pool) + if dyndep is not None: + self._line(' dyndep = %s' % dyndep) + + if variables: + if isinstance(variables, dict): + iterator = iter(variables.items()) + else: + iterator = iter(variables) + + for key, val in iterator: + self.variable(key, val, indent=1) + + return outputs + + def include(self, path: str) -> None: + self._line('include %s' % path) + + def subninja(self, path: str) -> None: + self._line('subninja %s' % path) + + def default(self, paths: Union[str, List[str]]) -> None: + self._line('default %s' % ' '.join(as_list(paths))) + + def _count_dollars_before_index(self, s: str, i: int) -> int: + """Returns the number of '$' characters right in front of s[i].""" + dollar_count = 0 + dollar_index = i - 1 + while dollar_index > 0 and s[dollar_index] == '$': + dollar_count += 1 + dollar_index -= 1 + return dollar_count + + def _line(self, text: str, indent: int = 0) -> None: + """Write 'text' word-wrapped at self.width characters.""" + leading_space = ' ' * indent + while len(leading_space) + len(text) > self.width: + # The text is too wide; wrap if possible. + + # Find the rightmost space that would obey our width constraint and + # that's not an escaped space. + available_space = self.width - len(leading_space) - len(' $') + space = available_space + while True: + space = text.rfind(' ', 0, space) + if space < 0 or self._count_dollars_before_index(text, space) % 2 == 0: + break + + if space < 0: + # No such space; just use the first unescaped space we can find. + space = available_space - 1 + while True: + space = text.find(' ', space + 1) + if space < 0 or self._count_dollars_before_index(text, space) % 2 == 0: + break + if space < 0: + # Give up on breaking. + break + + self.output.write(leading_space + text[0:space] + ' $\n') + text = text[space + 1 :] + + # Subsequent lines are continuations, so indent them. + leading_space = ' ' * (indent + 2) + + self.output.write(leading_space + text + '\n') + + def close(self) -> None: + self.output.close() + + +def as_list(input: Optional[Union[str, List[str]]]) -> List[str]: + if input is None: + return [] + if isinstance(input, list): + return input + return [input] + + +def escape(string: str) -> str: + """Escape a string such that it can be embedded into a Ninja file without + further interpretation.""" + assert '\n' not in string, 'Ninja syntax does not allow newlines' + # We only have one special metacharacter: '$'. + return string.replace('$', '$$') + + +def expand(string: str, vars: Dict[str, str], local_vars: Dict[str, str] = None) -> str: + """Expand a string containing $vars as Ninja would. + + Note: doesn't handle the full Ninja variable syntax, but it's enough + to make configure.py's use of it work. + """ + + if local_vars is None: + local_vars = {} + + def exp(m: Match[str]) -> str: + var = m.group(1) + if var == '$': + return '$' + return local_vars.get(var, vars.get(var, '')) + + return re.sub(r'\$(\$|\w*)', exp, string) + + +### END NINJA-BUILD CODE ### + +# ruff: noqa: E402 +import os + +if __name__ == '__main__': + rules = open('build.ninja', 'w', encoding='utf-8') + writer = Writer(rules, width=120) + + writer.comment('This is the build file for the Android examples CI.') + writer.comment('It is autogenerated by Cerbero.') + writer.comment('Do not edit by hand.') + writer.newline() + writer._line('ninja_required_version = 1.1') + writer.newline() + writer.newline() + writer.rule( + 'run_retry', + '$in --project-dir $projectdir --no-daemon --parallel --profile $target && cp $artifact ./', + description='Building Gradle target $target in $projectdir', + ) + + writer.newline() + writer.newline() + projectdir = f"{os.environ['EXAMPLES_HOME']}/gst-examples/playback/player/android" + writer.build( + 'app-debug.apk', + 'run_retry', + f'{projectdir}/gradlew', + variables={ + 'projectdir': projectdir, + 'target': 'assembleDebug', + 'artifact': f'{projectdir}/app/build/outputs/apk/debug/*.apk', + }, + ) + + writer.newline() + projectdir = f"{os.environ['EXAMPLES_HOME']}/gst-examples/vulkan/android" + writer.build( + 'org.freedesktop.gstreamer.vulkan.vulkan_1-v1-debug.apk', + 'run_retry', + f'{projectdir}/gradlew', + variables={ + 'projectdir': projectdir, + 'target': 'assembleDebug', + 'artifact': f'{projectdir}/build/outputs/apk/debug/*.apk', + }, + ) + + out = [ + 'android-tutorial-1-debug.apk', + 'android-tutorial-2-debug.apk', + 'android-tutorial-3-debug.apk', + 'android-tutorial-4-debug.apk', + 'android-tutorial-5-debug.apk', + ] + writer.newline() + projectdir = f"{os.environ['EXAMPLES_HOME']}/gst-docs/examples/tutorials/android" + writer.build( + out, + 'run_retry', + f'{projectdir}/gradlew', + variables={ + 'projectdir': projectdir, + 'target': 'assembleDebug', + 'artifact': f'{projectdir}/android-tutorial-*/build/outputs/apk/debug/*.apk', + }, + ) diff --git a/ci/run_retry.sh b/ci/run_retry.sh index 9105c9cc6..fa6c18942 100755 --- a/ci/run_retry.sh +++ b/ci/run_retry.sh @@ -6,6 +6,12 @@ set -o pipefail ERRORS=( "Warning: An error occurred while preparing SDK package Android SDK Tools: Connection reset." "The Xcode build system has crashed. Build again to continue." + "libc++abi: terminating with uncaught exception" + # https://github.com/rust-lang/rust/issues/127883#issuecomment-2290594194 + "Access is denied (os error 5)" + "LINK : fatal error LNK1104: cannot open file" + # Mono on Wine is flaky + "ShellExecuteEx failed" ) RETRIES=3 LOGFILE="/tmp/logfile.txt" diff --git a/config/android.config b/config/android.config index bbe043759..d375ce558 100644 --- a/config/android.config +++ b/config/android.config @@ -26,7 +26,7 @@ import cerbero.utils.messages as m # sysroot: location of the API-level libraries (no headers) # isysroot: location of the headers -variants.override(['nopython', 'notestspackage', 'rust']) +variants.override(['nopython', 'notestspackage', 'rust'], False) # We don't want anything from linux system to be used on android :) allow_system_libs=False @@ -111,19 +111,11 @@ env.pop('RUSTFLAGS', None) env['ANDROID_NDK_HOME'] = toolchain_prefix env['ANDROID_NDK_TOOLCHAIN_BIN'] = llvm_toolchain_path -# 'universal' is set by cerbero itself when building under a universal regime -# so that we can construct different paths to include/lib directories to where -# they actually are. Without this we don't know where the headers/libs will -# actually end up -if universal_archs: - incl_dir = os.path.join(prefix, _cerbero_arch, 'include') - lib_dir = os.path.join(prefix, _cerbero_arch, 'lib') -else: - incl_dir = os.path.join(prefix, 'include') - lib_dir = os.path.join(prefix, 'lib') -if target_arch != Architecture.UNIVERSAL and not os.path.exists(incl_dir): +incl_dir = os.path.join(prefix, 'include') +lib_dir = os.path.join(prefix, 'lib') +if not os.path.exists(incl_dir): os.makedirs(incl_dir) -if target_arch != Architecture.UNIVERSAL and not os.path.exists(lib_dir): +if not os.path.exists(lib_dir): os.makedirs(lib_dir) # Most of the compiler/linker specific flags are taken from @@ -142,7 +134,7 @@ if target_arch == Architecture.X86: if v < 24: cflags += ' -mstackrealign' -ldflags = f'-fPIC -no-canonical-prefixes -Wl,-no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--gc-sections -Wl,--warn-shared-textrel,--undefined-version ' +ldflags = f'-fPIC -no-canonical-prefixes -Wl,-no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,-z,text -Wl,--gc-sections -Wl,--warn-shared-textrel,--undefined-version ' if target_arch == Architecture.ARMv7: defines += ' -D__ARM_ARCH_7A__ ' diff --git a/config/cross-win32.cbc b/config/cross-win32.cbc index 9c99cd404..6db7554e3 100644 --- a/config/cross-win32.cbc +++ b/config/cross-win32.cbc @@ -4,5 +4,8 @@ from cerbero.config import Platform, Architecture, Distro, DistroVersion target_platform=Platform.WINDOWS target_arch=Architecture.X86 target_distro=Distro.WINDOWS -target_distro_version=DistroVersion.WINDOWS_7 -build = 'x86_64-pc-linux' +target_distro_version=DistroVersion.WINDOWS_10 +build = 'x86_64-linux-gnu' + +# Needs GCC with DWARF2 +variants.override(['norust', 'mingw']) diff --git a/config/cross-win64.cbc b/config/cross-win64.cbc index 403e9c04c..625aae552 100644 --- a/config/cross-win64.cbc +++ b/config/cross-win64.cbc @@ -4,5 +4,7 @@ from cerbero.config import Platform, Architecture, Distro, DistroVersion target_platform=Platform.WINDOWS target_arch=Architecture.X86_64 target_distro=Distro.WINDOWS -target_distro_version=DistroVersion.WINDOWS_7 -build = 'x86_64-pc-linux' +target_distro_version=DistroVersion.WINDOWS_10 +build = 'x86_64-linux-gnu' + +variants.override(['mingw']) diff --git a/config/darwin.config b/config/darwin.config index cf0f0f99c..201a66888 100644 --- a/config/darwin.config +++ b/config/darwin.config @@ -13,7 +13,7 @@ from cerbero.errors import FatalError allow_system_libs=False # Enable introspection by default -variants.override(['gi', 'rust']) +variants.override(['gi', 'rust', 'python'], False) if arch == Architecture.X86_64: build = 'x86_64-apple-darwin12' diff --git a/config/ios.config b/config/ios.config index cddc1d430..54a3ef8f5 100644 --- a/config/ios.config +++ b/config/ios.config @@ -9,7 +9,7 @@ from cerbero.utils import shell from cerbero.config import Architecture, DistroVersion from cerbero.errors import FatalError -variants.override(['nopython', 'notestspackage', 'rust']) +variants.override(['nopython', 'notestspackage', 'rust'], False) # We don't want anything from macports detected in configure and # used later. System libs are passed through the -isysroot option @@ -99,10 +99,7 @@ else: raise FatalError("Arch %s not supported" % target_arch) includedir = os.path.join(prefix, 'include') -if universal_archs: - lib_dir = os.path.join(prefix, target_arch, 'lib') -else: - lib_dir = os.path.join(prefix, 'lib') +lib_dir = os.path.join(prefix, 'lib') # Toolchain environment env['CC']= 'clang' diff --git a/config/linux.config b/config/linux.config index f786bee5b..236aa15f0 100644 --- a/config/linux.config +++ b/config/linux.config @@ -4,17 +4,22 @@ # PLEASE, DO NOT EDIT THIS FILE import os +import shutil from cerbero.utils import shell from cerbero.utils import messages as m -from cerbero.config import Architecture, Distro +from cerbero.config import Architecture, Distro, Platform -vlist = ['alsa', 'x11', 'pulse', 'cdparanoia', 'v4l2', 'gi', 'unwind'] -if '--export-dynamic-symbol' in shell.check_output(['ld', '--help']): - vlist += ['rust'] -elif prefix != build_tools_prefix: - m.warning('Disabling rust variant: binutils is too old, need >=2.36') +vlist = ['alsa', 'x11', 'pulse', 'cdparanoia', 'v4l2', 'gi', 'unwind', 'rust'] +is_cross_build = target_platform != platform or target_arch != arch or target_distro_version != distro_version +if not is_cross_build and shutil.which('ld'): + if '--export-dynamic-symbol' not in shell.check_output(['ld', '--help']): + vlist.remove('rust') + if prefix != build_tools_prefix: + m.warning('Disabling rust variant: binutils is too old, need >=2.36') # Set default values for some optional variants -variants.override(vlist) +if not is_cross_build: + vlist.append('python') +variants.override(vlist, False) for f in ['CPPFLAGS', 'CFLAGS', 'CCASFLAGS', 'CXXFLAGS', 'LDFLAGS', 'OBJCFLAGS']: diff --git a/config/mingw-multilib-win.cbc b/config/mingw-multilib-win.cbc index eb5f58a02..c24558521 100644 --- a/config/mingw-multilib-win.cbc +++ b/config/mingw-multilib-win.cbc @@ -10,4 +10,4 @@ prefix=os.path.expanduser('~/mingw/windows/multilib') sources=os.path.join(home_dir, 'sources', 'mingw-multilib-win') toolchain_prefix=os.path.expanduser('~/mingw/linux/multilib/') recipes_dir = os.path.join(recipes_dir, '..', 'recipes-toolchain') -build='x86_64-pc-linux-gnu' +build='x86_64-linux-gnu' diff --git a/config/windows.config b/config/windows.config index e86e8c068..6cd24d93c 100644 --- a/config/windows.config +++ b/config/windows.config @@ -6,10 +6,19 @@ from cerbero.config import Architecture, Platform, Distro, FatalError from cerbero.utils import EnvValue, EnvValueArg, EnvValueCmd, EnvValuePath -# Enable rust support by default only when building with MSVC -# https://gitlab.freedesktop.org/gstreamer/cerbero/-/issues/381 -if not variants.mingw and not variants.uwp: - variants.override('rust') +# MinGW x86 requires changing GCC's exception model to DWARF2 +# See https://fedoraproject.org/wiki/Changes/Mingw32GccDwarf2 +mingw_incompatible_sjlj = variants.mingw and target_arch == Architecture.X86 + +# Tracking bug: https://gitlab.freedesktop.org/gstreamer/cerbero/-/issues/381 +if not variants.uwp and not mingw_incompatible_sjlj: + variants.override(['rust'], False) + # FIXME: Detect the corresponding Python for cross-build of x86 bindings + is_cross_build = target_platform != platform or target_arch != arch + # FIXME: Should use a MinGW Python to build python bindings with the MinGW + # toolchain; same problem as x86 builds on Windows + if target_arch == Architecture.X86_64 and not is_cross_build and not variants.mingw: + variants.override(['gi', 'python'], False) # We don't want anything from mingw or msys detected in configure and # used later. @@ -76,19 +85,11 @@ def cmd(command, args=None, wrapper=None): wrapper = [] return EnvValueCmd(wrapper + ['%s%s' % (tools_prefix, command)] + args) -# 'universal' is set by cerbero itself when building under a universal regime -# so that we can construct different paths to include/lib directories to where -# they actually are. Without this we don't know where the headers/libs will -# actually end up -if universal_archs: - incl_dir = os.path.join(prefix, target_arch, 'include') - lib_dir = os.path.join(prefix, target_arch, 'lib') -else: - incl_dir = os.path.join(prefix, 'include') - lib_dir = os.path.join(prefix, 'lib') -if target_arch != Architecture.UNIVERSAL and not os.path.exists(incl_dir): +incl_dir = os.path.join(prefix, 'include') +lib_dir = os.path.join(prefix, 'lib') +if not os.path.exists(incl_dir): os.makedirs(incl_dir) -if target_arch != Architecture.UNIVERSAL and not os.path.exists(lib_dir): +if not os.path.exists(lib_dir): os.makedirs(lib_dir) # Default GCC compiler flags @@ -126,8 +127,8 @@ if cross: ccache = use_ccache and ['ccache'] or [] -# By default the target Windows 7, but for UWP it's Windows 10 -target_winver = '0x0A00' if variants.uwp else '0x0601' +# By default the target is Windows 10 +target_winver = '0x0A00' winver_flags = ['-DWINVER=' + target_winver, '-D_WIN32_WINNT=' + target_winver] # MinGW and MSVC build system config env @@ -154,6 +155,10 @@ msvc_env_for_build_system['CC'] = EnvValueCmd('cl') msvc_env_for_build_system['CXX'] = EnvValueCmd('cl') msvc_env_for_build_system['AR'] = EnvValueCmd('lib') +# Rust +mingw_env_for_toolchain['RUSTC_LDFLAGS'] = EnvValueArg(arch_flags + [f'-Wl,-m,i386pe']) +mingw_env_for_toolchain['RUSTC_LINKER'] = cmd('gcc') + # MinGW toolchain config env mingw_env_for_toolchain['LIBRARY_PATH'] = EnvValuePath([lib_dir]) @@ -173,7 +178,7 @@ if distro == Distro.MSYS: toolchainbin = os.path.join(toolchain_prefix, 'bin') if toolchainbin not in env['PATH']: env['PATH'] = '%s%s%s' % (toolchainbin, os.pathsep, env['PATH']) - libexecdir = os.path.join(toolchain_prefix, "libexec/gcc/x86_64-w64-mingw32/8.2.0/") + libexecdir = os.path.join(toolchain_prefix, "libexec/gcc/x86_64-w64-mingw32/14.2.0/") env['PATH'] = '%s%s%s' % (libexecdir, os.pathsep, env['PATH']) # These only have meaning for autotools, so let's just leave it in the general env diff --git a/data/mobile/FindGStreamerMobile.cmake b/data/mobile/FindGStreamerMobile.cmake new file mode 100644 index 000000000..b58b96440 --- /dev/null +++ b/data/mobile/FindGStreamerMobile.cmake @@ -0,0 +1,611 @@ +# SPDX-FileCopyrightText: 2024 L. E. Segovia +# SPDX-License-Ref: LGPL-2.1-or-later + +#[=======================================================================[.rst: +FindGStreamerMobile +------- + +Creates additional mobile targets to install fonts and the CA certificate +bundle. Android and iOS only. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module defines the following :prop_tgt:`INTERFACE` targets: + +``GStreamer::fonts`` + A target that will install GStreamer's default fonts into the app. + +``GStreamer::ca_certificates`` + A target that will install the NSS CA certificate bundle into the app. + +This module defines the following :prop_tgt:`SHARED` targets: + +``GStreamer::mobile`` + A target that will build the shared library consisting of GStreamer plus all the selected plugin components. (Android/iOS only) + +Result Variables +^^^^^^^^^^^^^^^^ + +This will define the following variables: + +``GStreamer_Mobile_FOUND`` + ON if the system has the GStreamer library. + +Cache Variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``GStreamer_CA_BUNDLE`` + Path to /etc/ssl/certs/ca-certificates.crt. +``GStreamer_UBUNTU_R_TTF`` + Path to the TrueType font Ubuntu R. +``GStreamer_FONTS_CONF`` + Path to /etc/fonts.conf. + +Configuration Variables +^^^^^^^^^^^^^^^ + +Like with the main GStreamer library, setting the following variables is +required, depending on the operating system: + +``GStreamer_ROOT_DIR`` + Installation prefix of the GStreamer SDK. + +``GStreamer_JAVA_SRC_DIR`` + Target directory for deploying the selected plugins' Java classfiles to. (Android only) + +``GStreamer_Mobile_MODULE_NAME`` + Name for the GStreamer::mobile shared library. Default is ``gstreamer_android`` (Android) or ``gstreamer_mobile`` (iOS). + +``GStreamer_ASSETS_DIR`` + Target directory for deploying assets to. + +``G_IO_MODULES`` + Set this to the GIO modules you need, additional to any GStreamer plugins. (Usually set to ``gnutls`` or ``openssl``) + +``G_IO_MODULES_PATH`` + Path for the static GIO modules. + +#]=======================================================================] + +if (GStreamer_Mobile_FOUND) + return() +endif() + +##################### +# Setup variables # +##################### + +if (NOT DEFINED GStreamer_ROOT_DIR AND DEFINED GSTREAMER_ROOT) + set(GStreamer_ROOT_DIR ${GSTREAMER_ROOT}) +endif() + +if (NOT GStreamer_ROOT_DIR) + set(GStreamer_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/../../") +endif() + +if (NOT EXISTS "${GStreamer_ROOT_DIR}") + message(FATAL_ERROR "The directory GStreamer_ROOT_DIR=${GStreamer_ROOT_DIR} does not exist") +endif() + +set(_gst_required_vars) + +if (ca_certificates IN_LIST GStreamerMobile_FIND_COMPONENTS) + # for setting the default GTlsDatabase + list(APPEND GStreamer_EXTRA_DEPS gio-2.0) +endif() + +if (ANDROID) + list(APPEND GStreamer_EXTRA_DEPS zlib) +endif() + +# Prepare Android hotfixes for x264 +if(ANDROID_ABI MATCHES "^armeabi") + set(NEEDS_TEXTREL_ERROR TRUE) + set(NEEDS_BSYMBOLIC_FIX TRUE) +elseif(ANDROID_ABI STREQUAL "x86") + set(NEEDS_TEXTREL_ERROR TRUE) + set(NEEDS_BSYMBOLIC_FIX TRUE) +# arm64: https://ffmpeg.org/pipermail/ffmpeg-devel/2022-July/298734.html +elseif(ANDROID_ABI STREQUAL "x86_64" OR ANDROID_ABI STREQUAL "arm64-v8a") + set(NEEDS_BSYMBOLIC_FIX TRUE) +endif() + +# Set up output variables for Android +if(ANDROID) + if (NOT DEFINED GStreamer_JAVA_SRC_DIR AND DEFINED GSTREAMER_JAVA_SRC_DIR) + set(GStreamer_JAVA_SRC_DIR ${GSTREAMER_JAVA_SRC_DIR}) + elseif(NOT DEFINED GStreamer_JAVA_SRC_DIR) + set(GStreamer_JAVA_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../src/") + else() + # Gradle does not let us access the root of the subproject + # so we implement the ndk-build assumption ourselves + set(GStreamer_JAVA_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../${GStreamer_JAVA_SRC_DIR}") + endif() + + if(NOT DEFINED GStreamer_NDK_BUILD_PATH AND DEFINED GSTREAMER_NDK_BUILD_PATH) + set(GStreamer_NDK_BUILD_PATH "${GSTREAMER_NDK_BUILD_PATH}") + elseif(NOT DEFINED GStreamer_NDK_BUILD_PATH) + set(GStreamer_NDK_BUILD_PATH "${GStreamer_ROOT_DIR}/share/gst-android/ndk-build/") + endif() +endif() + +if(NOT DEFINED GStreamer_Mobile_MODULE_NAME) + if (DEFINED GSTREAMER_ANDROID_MODULE_NAME) + set(GStreamer_Mobile_MODULE_NAME "${GSTREAMER_ANDROID_MODULE_NAME}") + elseif(ANDROID) + set(GStreamer_Mobile_MODULE_NAME gstreamer_android) + else() + set(GStreamer_Mobile_MODULE_NAME gstreamer_mobile) + endif() +endif() + +if(ANDROID) + if(NOT DEFINED GStreamer_ASSETS_DIR AND DEFINED GSTREAMER_ASSETS_DIR) + set(GStreamer_ASSETS_DIR "${GSTREAMER_ASSETS_DIR}") + elseif(NOT DEFINED GStreamer_ASSETS_DIR) + set(GStreamer_ASSETS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../src/assets/") + else() + # Same as above + set(GStreamer_ASSETS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../${GStreamer_ASSETS_DIR}") + endif() + + if(NOT DEFINED GStreamer_NDK_BUILD_PATH AND DEFINED GSTREAMER_NDK_BUILD_PATH) + set(GStreamer_NDK_BUILD_PATH "${GSTREAMER_NDK_BUILD_PATH}") + elseif(NOT DEFINED GStreamer_NDK_BUILD_PATH) + set(GStreamer_NDK_BUILD_PATH "${GStreamer_ROOT_DIR}/share/gst-android/ndk-build/") + endif() +elseif(IOS) + if(NOT DEFINED GStreamer_ASSETS_DIR AND DEFINED GStreamer_ASSETS_DIR) + set(GStreamer_ASSETS_DIR ${GStreamer_ASSETS_DIR}) + elseif(NOT DEFINED GStreamer_ASSETS_DIR) + set(GStreamer_ASSETS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/assets") + else() + # Same as above + set(GStreamer_ASSETS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../${GStreamer_ASSETS_DIR}") + endif() +endif() + +if (ANDROID AND CMAKE_HOST_WIN32) + set(PKG_CONFIG_EXECUTABLE "${GStreamer_NDK_BUILD_PATH}/tools/windows/pkg-config.exe") +endif() + +if (ANDROID) + file(READ "${GStreamer_NDK_BUILD_PATH}/GStreamer.java" JAVA_INPUT) +endif() + +if (ANDROID OR APPLE) + set(GSTREAMER_IS_MOBILE ON) +else() + set(GSTREAMER_IS_MOBILE OFF) +endif() + +# Block shared GStreamer on mobile +if (GSTREAMER_IS_MOBILE) + if (NOT DEFINED GStreamer_USE_STATIC_LIBS) + set(GStreamer_USE_STATIC_LIBS ON) + endif() + if (NOT GStreamer_USE_STATIC_LIBS) + message(FATAL_ERROR "Shared library GStreamer is not supported on mobile platforms") + endif() +endif() + +# Now, let's set up targets for each of the components supplied +# These are the required plugins +set(_gst_plugins ${GStreamerMobile_FIND_COMPONENTS}) +# These are custom handled targets, and must be skipped from the loop +list(REMOVE_ITEM _gst_plugins fonts ca_certificates mobile) +list(REMOVE_DUPLICATES _gst_plugins) + +set(GSTREAMER_PLUGINS ${_gst_plugins}) +# These are the API packages +set(GSTREAMER_APIS ${GSTREAMER_PLUGINS}) +list(FILTER GSTREAMER_APIS INCLUDE REGEX "^api_") +# Filter them out, although they're handled the same +# they cannot be considered for the purposes of initialization +list(FILTER GSTREAMER_PLUGINS EXCLUDE REGEX "^api_") + +if (GSTREAMER_IS_MOBILE AND (NOT TARGET GStreamer::mobile)) + # Generate the plugins' declaration strings + # (don't append a semicolon, CMake does it as part of the list) + list(TRANSFORM GSTREAMER_PLUGINS + PREPEND "\nGST_PLUGIN_STATIC_DECLARE\(" + OUTPUT_VARIABLE PLUGINS_DECLARATION + ) + list(TRANSFORM PLUGINS_DECLARATION + APPEND "\)" + OUTPUT_VARIABLE PLUGINS_DECLARATION + ) + if(PLUGINS_DECLARATION) + set(PLUGINS_DECLARATION "${PLUGINS_DECLARATION};") + endif() + + # Generate the plugins' registration strings + list(TRANSFORM GSTREAMER_PLUGINS + PREPEND "\nGST_PLUGIN_STATIC_REGISTER\(" + OUTPUT_VARIABLE PLUGINS_REGISTRATION + ) + list(TRANSFORM PLUGINS_REGISTRATION + APPEND "\)" + OUTPUT_VARIABLE PLUGINS_REGISTRATION + ) + if(PLUGINS_REGISTRATION) + set(PLUGINS_REGISTRATION "${PLUGINS_REGISTRATION};") + endif() + + # Generate list of gio modules + if (NOT G_IO_MODULES) + set(G_IO_MODULES) + endif() + list(TRANSFORM G_IO_MODULES + PREPEND "gio" + OUTPUT_VARIABLE G_IO_MODULES_LIBS + ) + list(TRANSFORM G_IO_MODULES + PREPEND "\nGST_G_IO_MODULE_DECLARE\(" + OUTPUT_VARIABLE G_IO_MODULES_DECLARE + ) + list(TRANSFORM G_IO_MODULES_DECLARE + APPEND "\);" + OUTPUT_VARIABLE G_IO_MODULES_DECLARE + ) + if(G_IO_MODULES_DECLARE) + set(G_IO_MODULES_DECLARE "${G_IO_MODULES_DECLARE};") + endif() + list(TRANSFORM G_IO_MODULES + PREPEND "\nGST_G_IO_MODULE_LOAD\(" + OUTPUT_VARIABLE G_IO_MODULES_LOAD + ) + list(TRANSFORM G_IO_MODULES_LOAD + APPEND "\)" + OUTPUT_VARIABLE G_IO_MODULES_LOAD + ) + if(G_IO_MODULES_LOAD) + set(G_IO_MODULES_LOAD "${G_IO_MODULES_LOAD};") + endif() + + # Generates a source file that declares and registers all the required plugins + if (ANDROID) + configure_file( + "${CMAKE_CURRENT_LIST_DIR}/GStreamer/gstreamer_android-1.0.c.in" + "${GStreamer_Mobile_MODULE_NAME}.c" + ) + else() + configure_file( + "${CMAKE_CURRENT_LIST_DIR}/GStreamer/gst_ios_init.m.in" + "${GStreamer_Mobile_MODULE_NAME}.m" + ) + endif() + + # Creates a shared library including gstreamer, its plugins and all the dependencies + if (ANDROID) + add_library(GStreamerMobile + SHARED + "${GStreamer_Mobile_MODULE_NAME}.c" + ) + else() + add_library(GStreamerMobile SHARED) + enable_language(OBJC OBJCXX) + target_sources(GStreamerMobile + PRIVATE + "${GStreamer_Mobile_MODULE_NAME}.m" + ) + set_source_files_properties("${GStreamer_Mobile_MODULE_NAME}.m" + PROPERTIES + LANGUAGE OBJC + ) + find_library(Foundation_LIB Foundation REQUIRED) + target_link_libraries(GStreamerMobile + PRIVATE + ${Foundation_LIB} + ) + endif() + add_library(GStreamer::mobile ALIAS GStreamerMobile) + + # Assume it's C++ for the sake of gstsoundtouch + set_target_properties( + GStreamerMobile + PROPERTIES + LIBRARY_OUTPUT_NAME ${GStreamer_Mobile_MODULE_NAME} + ) + if (APPLE) + set_target_properties( + GStreamerMobile + PROPERTIES + LINKER_LANGUAGE OBJCXX + FRAMEWORK TRUE + FRAMEWORK_VERSION A + MACOSX_FRAMEWORK_IDENTIFIER org.gstreamer.GStreamerMobile + ) + else() + set_target_properties( + GStreamerMobile + PROPERTIES + LINKER_LANGUAGE CXX + ) + endif() +endif() + +if (GStreamerMobile_FIND_REQUIRED) +find_package(GStreamer COMPONENTS ${_gst_plugins} REQUIRED) +else() +find_package(GStreamer COMPONENTS ${_gst_plugins}) +endif() + +# Path for the static GIO modules +pkg_get_variable(G_IO_MODULES_PATH gio-2.0 giomoduledir) +if (NOT G_IO_MODULES_PATH) + set(G_IO_MODULES_PATH "${GStreamer_ROOT_DIR}/lib/gio/modules") +endif() + +if (GSTREAMER_IS_MOBILE) + set_target_properties( + GStreamerMobile + PROPERTIES + VERSION ${PC_GStreamer_VERSION} + SOVERSION ${PC_GStreamer_VERSION} + ) + + # Handle all libraries, even those specified with -l:libfoo.a (srt) + # Due to the unavailability of pkgconf's `--maximum-traverse-depth` + # on stock pkg-config, I attempt to simulate it through the shared + # libraries listing. + # If pkgconf is available, replace all PC_GStreamer_ entries with + # PC_GStreamer_NoDeps and uncomment the code block above. + if (ANDROID AND CMAKE_HOST_WIN32) + # Prevent visibility inconsistencies between glib and others wrt. + # libintl + list(REMOVE_DUPLICATES PC_GStreamer_LIBRARIES) + endif() + foreach(LOCAL_LIB IN LISTS PC_GStreamer_LIBRARIES) + # list(TRANSFORM REPLACE) is of no use here + # https://gitlab.kitware.com/cmake/cmake/-/issues/16899 + if (LOCAL_LIB MATCHES "${_gst_SRT_REGEX_PATCH}") + string(REGEX REPLACE "${_gst_SRT_REGEX_PATCH}" "\\1" LOCAL_LIB "${LOCAL_LIB}") + endif() + string(MAKE_C_IDENTIFIER "_gst_${LOCAL_LIB}" GST_LOCAL_LIB) + # These have already been found by FindGStreamer + if ("${${GST_LOCAL_LIB}}" IN_LIST _gst_IGNORED_SYSTEM_LIBRARIES) + target_link_libraries(GStreamerMobile PRIVATE + "${${GST_LOCAL_LIB}}" + ) + elseif (MSVC) + target_link_libraries(GStreamerMobile PRIVATE + "/WHOLEARCHIVE:${${GST_LOCAL_LIB}}" + ) + elseif(APPLE) + target_link_libraries(GStreamerMobile PRIVATE + "-Wl,-force_load,${${GST_LOCAL_LIB}}" + ) + else() + target_link_libraries(GStreamerMobile PRIVATE + "-Wl,--whole-archive,${${GST_LOCAL_LIB}},--no-whole-archive" + ) + endif() + endforeach() + + target_link_libraries( + GStreamerMobile + PRIVATE + GStreamer::deps + ) + + target_link_options( + GStreamerMobile + INTERFACE + $ + ) + + target_include_directories( + GStreamerMobile + INTERFACE + $ + ) + + # text relocations are strictly forbidden, error out if we encounter any + if(DEFINED NEEDS_TEXTREL_ERROR) + target_link_options( + GStreamerMobile + PRIVATE + "-Wl,-z,text" + ) + endif() + + # resolve textrels in the x86 asm + if(DEFINED NEEDS_BSYMBOLIC_FIX) + target_link_options( + GStreamerMobile + PRIVATE + "-Wl,-Bsymbolic" + ) + endif() + + if (ANDROID) + # Collect all Java-based initializer classes + set(GSTREAMER_PLUGINS_CLASSES) + foreach(LOCAL_PLUGIN IN LISTS GSTREAMER_PLUGINS) + file(GLOB_RECURSE + LOCAL_PLUGIN_CLASS + FOLLOW_SYMLINKS + RELATIVE "${GStreamer_NDK_BUILD_PATH}" + "${GStreamer_NDK_BUILD_PATH}/${LOCAL_PLUGIN}/*.java" + ) + list(APPEND GSTREAMER_PLUGINS_CLASSES ${LOCAL_PLUGIN_CLASS}) + endforeach() + + # Same as above, but collect the plugins themselves + set(GSTREAMER_PLUGINS_WITH_CLASSES) + foreach(LOCAL_PLUGIN IN LISTS GSTREAMER_PLUGINS) + if(EXISTS "${GStreamer_NDK_BUILD_PATH}/${LOCAL_PLUGIN}/") + list(APPEND GSTREAMER_PLUGINS_WITH_CLASSES ${LOCAL_PLUGIN}) + endif() + endforeach() + + add_custom_target( + "copyjavasource_${ANDROID_ABI}" + ) + + foreach(LOCAL_FILE IN LISTS GSTREAMER_PLUGINS_CLASSES) + string(MAKE_C_IDENTIFIER "cp_${LOCAL_FILE}" COPYJAVASOURCE_TGT) + add_custom_target( + ${COPYJAVASOURCE_TGT} + COMMAND + "${CMAKE_COMMAND}" -E make_directory + "${GStreamer_JAVA_SRC_DIR}/org/freedesktop/gstreamer/" + COMMAND + "${CMAKE_COMMAND}" -E copy + "${GStreamer_NDK_BUILD_PATH}/${LOCAL_FILE}" + "${GStreamer_JAVA_SRC_DIR}/org/freedesktop/gstreamer/" + BYPRODUCTS + "${GStreamer_JAVA_SRC_DIR}/org/freedesktop/gstreamer/${LOCAL_FILE}" + ) + add_dependencies(copyjavasource_${ANDROID_ABI} ${COPYJAVASOURCE_TGT}) + endforeach() + endif() + + # And, finally, set the GIO modules up + if (G_IO_MODULES_LIBS) + add_library(GStreamer::gio_modules INTERFACE IMPORTED) + + _gst_apply_link_libraries(OFF G_IO_MODULES_LIBS G_IO_MODULES_PATH GStreamer::gio_modules) + target_link_libraries( + GStreamerMobile + PRIVATE + GStreamer::gio_modules + ) + endif() + set(GStreamer_mobile_FOUND TRUE) +endif() + +if(fonts IN_LIST GStreamerMobile_FIND_COMPONENTS) + set(GStreamer_UBUNTU_R_TTF "${GStreamer_NDK_BUILD_PATH}/fontconfig/fonts/Ubuntu-R.ttf" + CACHE FILEPATH "Path to Ubuntu-R.ttf" + ) + set(GStreamer_FONTS_CONF + "${GStreamer_NDK_BUILD_PATH}/fontconfig/fonts.conf" + CACHE FILEPATH "Path to fonts.conf" + ) + if (EXISTS "${GStreamer_UBUNTU_R_TTF}" AND EXISTS "${GStreamer_FONTS_CONF}") + set(GStreamerMobile_fonts_FOUND ON) + set(_gst_required_vars "GStreamer_UBUNTU_R_TTF GStreamer_FONTS_CONF ${gst_required_vars}") + + if (ANDROID) + string(REPLACE "//copyFonts" "copyFonts" JAVA_INPUT "${JAVA_INPUT}") + add_custom_target( + copyfontsres_${ANDROID_ABI} + COMMAND + "${CMAKE_COMMAND}" -E make_directory + "${GStreamer_ASSETS_DIR}/fontconfig/fonts/truetype/" + COMMAND + "${CMAKE_COMMAND}" -E copy + "${GStreamer_UBUNTU_R_TTF}" + "${GStreamer_ASSETS_DIR}/fontconfig/fonts/truetype/" + COMMAND + "${CMAKE_COMMAND}" -E copy + "${GStreamer_FONTS_CONF}" + "${GStreamer_ASSETS_DIR}/fontconfig/" + BYPRODUCTS + "${GStreamer_ASSETS_DIR}/fontconfig/fonts/truetype/Ubuntu-R.ttf" + "${GStreamer_ASSETS_DIR}/fontconfig/fonts.conf" + ) + + if (TARGET GStreamerMobile) + add_dependencies(GStreamerMobile copyfontsres_${ANDROID_ABI}) + endif() + elseif(APPLE) + set(GStreamerMobile_fonts_FOUND ON) + list(APPEND GSTREAMER_RESOURCES "${GStreamer_FONTS_CONF}" "${GStreamer_UBUNTU_R_TTF}") + else() + message(FATAL_ERROR "No fonts assets available for this operating system.") + endif() + else() + set(GStreamerMobile_fonts_FOUND OFF) + endif() +endif() + +if(ca_certificates IN_LIST GStreamerMobile_FIND_COMPONENTS) + set(GStreamer_CA_BUNDLE "${GStreamer_ROOT_DIR}/etc/ssl/certs/ca-certificates.crt" + CACHE FILEPATH "Path to ca-certificates bundle" + ) + if (EXISTS "${GStreamer_CA_BUNDLE}") + set(GStreamerMobile_ca_certificates_FOUND ON) + string(REPLACE "//copyCaCertificates" "copyCaCertificates" JAVA_INPUT "${JAVA_INPUT}") + set(_gst_required_vars "GStreamer_CA_BUNDLE ${_gst_required_vars}") + + if (ANDROID) + add_custom_target( + copycacertificatesres_${ANDROID_ABI} + COMMAND + "${CMAKE_COMMAND}" -E make_directory + "${GStreamer_ASSETS_DIR}/ssl/certs/" + COMMAND + "${CMAKE_COMMAND}" -E copy + "${GStreamer_CA_BUNDLE}" + "${GStreamer_ASSETS_DIR}/ssl/certs/" + BYPRODUCTS "${GStreamer_ASSETS_DIR}/ssl/certs/ca-certificates.crt" + ) + + if (TARGET GStreamerMobile) + add_dependencies(GStreamerMobile copycacertificatesres_${ANDROID_ABI}) + target_compile_definitions(GStreamerMobile + PRIVATE + GSTREAMER_INCLUDE_CA_CERTIFICATES + ) + endif() + elseif (APPLE) + list(APPEND GSTREAMER_RESOURCES "${GStreamer_CA_BUNDLE}") + else() + message(FATAL_ERROR "No certificate bundle available for this operating system.") + endif() + else() + set(GStreamerMobile_ca_certificates_FOUND OFF) + endif() +endif() + +if (ANDROID) + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/GStreamer.java" "${JAVA_INPUT}") + add_custom_target( + enable_includes_in_gstreamer_java + COMMAND + "${CMAKE_COMMAND}" -E make_directory + "${GStreamer_JAVA_SRC_DIR}/org/freedesktop/gstreamer/" + COMMAND + "${CMAKE_COMMAND}" -E copy + "${CMAKE_CURRENT_BINARY_DIR}/GStreamer.java" + "${GStreamer_JAVA_SRC_DIR}/org/freedesktop/gstreamer/GStreamer.java" + BYPRODUCTS + "${GStreamer_JAVA_SRC_DIR}/org/freedesktop/gstreamer/GStreamer.java" + ) + if (TARGET GStreamerMobile) + add_dependencies(copyjavasource_${ANDROID_ABI} enable_includes_in_gstreamer_java) + add_dependencies(GStreamerMobile copyjavasource_${ANDROID_ABI}) + endif() +endif() + +if (TARGET GStreamerMobile AND GSTREAMER_RESOURCES) + set_target_properties( + GStreamerMobile + PROPERTIES + RESOURCE "${GSTREAMER_RESOURCES}" + ) +endif() + +# Perform final validation +include(FindPackageHandleStandardArgs) +foreach(_gst_PLUGIN IN LISTS _gst_plugins) + set(GStreamerMobile_${_gst_PLUGIN}_FOUND "${GStreamer_${_gst_PLUGIN}_FOUND}") + + if (GStreamer_${_gst_PLUGIN}_FOUND) + target_link_libraries( + GStreamerMobile + PRIVATE + GStreamer::${_gst_PLUGIN} + ) + endif() +endforeach() +# FIXME: CMake does not tolerate interpolation of REQUIRED_VARS +find_package_handle_standard_args(GStreamerMobile + HANDLE_COMPONENTS +) diff --git a/data/mobile/gst_ios_init.m.in b/data/mobile/gst_ios_init.m.in new file mode 100644 index 000000000..638744391 --- /dev/null +++ b/data/mobile/gst_ios_init.m.in @@ -0,0 +1,80 @@ +#include +#include +#include + +/* Declaration of static plugins */ + @PLUGINS_DECLARATION@ + +/* Declaration of static gio modules */ + @G_IO_MODULES_DECLARE@ + +#ifdef GSTREAMER_INCLUDE_CA_CERTIFICATES +static void +gst_ios_load_certificates (const gchar *resources_dir) +{ + gchar *ca_certificates; + + ca_certificates = g_build_filename (resources_dir, "ssl", "certs", "ca-certificates.crt", NULL); + g_setenv ("CA_CERTIFICATES", ca_certificates, TRUE); + + if (ca_certificates) { + GTlsBackend *backend = g_tls_backend_get_default (); + if (backend) { + GTlsDatabase *db = g_tls_file_database_new (ca_certificates, NULL); + if (db) + g_tls_backend_set_default_database (backend, db); + } + } + g_free (ca_certificates); +} + +#endif + +void +gst_ios_init (void) +{ + GstPluginFeature *plugin; + GstRegistry *reg; + NSString *resources = [[NSBundle mainBundle] resourcePath]; + NSString *tmp = NSTemporaryDirectory(); + NSString *cache = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"]; + NSString *docs = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; + + const gchar *resources_dir = [resources UTF8String]; + const gchar *tmp_dir = [tmp UTF8String]; + const gchar *cache_dir = [cache UTF8String]; + const gchar *docs_dir = [docs UTF8String]; + + g_setenv ("TMP", tmp_dir, TRUE); + g_setenv ("TEMP", tmp_dir, TRUE); + g_setenv ("TMPDIR", tmp_dir, TRUE); + g_setenv ("XDG_RUNTIME_DIR", resources_dir, TRUE); + g_setenv ("XDG_CACHE_HOME", cache_dir, TRUE); + + g_setenv ("HOME", docs_dir, TRUE); + g_setenv ("XDG_DATA_DIRS", resources_dir, TRUE); + g_setenv ("XDG_CONFIG_DIRS", resources_dir, TRUE); + g_setenv ("XDG_CONFIG_HOME", cache_dir, TRUE); + g_setenv ("XDG_DATA_HOME", resources_dir, TRUE); + g_setenv ("FONTCONFIG_PATH", resources_dir, TRUE); + + @G_IO_MODULES_LOAD@ + +#ifdef GSTREAMER_INCLUDE_CA_CERTIFICATES + gst_ios_load_certificates (resources_dir); +#endif + + gst_init (NULL, NULL); + + @PLUGINS_REGISTRATION@ + + /* Lower the ranks of filesrc and giosrc so iosavassetsrc is + * tried first in gst_element_make_from_uri() for file:// */ + reg = gst_registry_get(); + plugin = gst_registry_lookup_feature(reg, "filesrc"); + if (plugin) + gst_plugin_feature_set_rank(plugin, GST_RANK_SECONDARY); + plugin = gst_registry_lookup_feature(reg, "giosrc"); + if (plugin) + gst_plugin_feature_set_rank(plugin, GST_RANK_SECONDARY-1); +} diff --git a/data/mobile/gstreamer_android-1.0.c.in b/data/mobile/gstreamer_android-1.0.c.in new file mode 100644 index 000000000..6a3a5cde4 --- /dev/null +++ b/data/mobile/gstreamer_android-1.0.c.in @@ -0,0 +1,59 @@ +#include +#include + +#define GST_G_IO_MODULE_DECLARE(name) \ +extern void G_PASTE(g_io_, G_PASTE(name, _load)) (gpointer module) + +#define GST_G_IO_MODULE_LOAD(name) \ +G_PASTE(g_io_, G_PASTE(name, _load)) (NULL) + +/* Declaration of static plugins */ + @PLUGINS_DECLARATION@ + +/* Declaration of static gio modules */ + @G_IO_MODULES_DECLARE@ + +#ifdef GSTREAMER_INCLUDE_CA_CERTIFICATES +static void +gst_android_load_certificates (void) +{ + GTlsBackend *backend; + const gchar *ca_certs; + + ca_certs = g_getenv ("CA_CERTIFICATES"); + + backend = g_tls_backend_get_default (); + if (backend && ca_certs) { + GTlsDatabase *db; + GError *error = NULL; + + db = g_tls_file_database_new (ca_certs, &error); + if (db) { + g_tls_backend_set_default_database (backend, db); + g_object_unref (db); + } else { + g_warning ("Failed to create a database from file: %s", + error ? error->message : "Unknown"); + } + } +} +#endif + +/* Call this function to load GIO modules */ +static void +gst_android_load_gio_modules (void) +{ + @G_IO_MODULES_LOAD@ + +#ifdef GSTREAMER_INCLUDE_CA_CERTIFICATES + gst_android_load_certificates (); +#endif +} + +/* This is called by gst_init() */ +void +gst_init_static_plugins (void) +{ + @PLUGINS_REGISTRATION@ + gst_android_load_gio_modules (); +} diff --git a/data/ndk-build/gstreamer-1.0.mk b/data/ndk-build/gstreamer-1.0.mk index 04539d5c6..253f628fa 100644 --- a/data/ndk-build/gstreamer-1.0.mk +++ b/data/ndk-build/gstreamer-1.0.mk @@ -83,6 +83,32 @@ ifeq ($(GSTREAMER_INCLUDE_CA_CERTIFICATES),yes) GSTREAMER_DEPS += gio-2.0 endif +NEEDS_TEXTREL_ERROR := no +NEEDS_BSYMBOLIC_FIX := no +ifeq ($(TARGET_ARCH_ABI),armeabi) +NEEDS_TEXTREL_ERROR := yes +NEEDS_BSYMBOLIC_FIX := yes +else ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) +NEEDS_TEXTREL_ERROR := yes +NEEDS_BSYMBOLIC_FIX := yes +else ifeq ($(TARGET_ARCH_ABI),x86) +NEEDS_TEXTREL_ERROR := yes +NEEDS_BSYMBOLIC_FIX := yes +else ifeq ($(TARGET_ARCH_ABI),x86_64) +NEEDS_BSYMBOLIC_FIX := yes +endif + +# text relocations are strictly forbidden, error out if we encounter any +ifeq ($(NEEDS_TEXTREL_ERROR),yes) +GSTREAMER_LD := $(GSTREAMER_LD) -Wl,-z,text +endif + +# resolve textrels in the x86 asm +ifeq ($(NEEDS_BSYMBOLIC_FIX),yes) +GSTREAMER_LD := $(GSTREAMER_LD) -Wl,-Bsymbolic +endif + + ################################ # NDK Build Prebuilt library # ################################ diff --git a/data/vs-1.0/gst-sdk-template/Scripts/1033/default.js b/data/vs-1.0/gst-sdk-template/Scripts/1033/default.js new file mode 100644 index 000000000..b2f63add5 --- /dev/null +++ b/data/vs-1.0/gst-sdk-template/Scripts/1033/default.js @@ -0,0 +1,102 @@ +function OnFinish(selProj, selObj) +{ + try + { + var strProjectPath = wizard.FindSymbol('PROJECT_PATH'); + var strProjectName = wizard.FindSymbol('PROJECT_NAME'); + + selProj = CreateCustomProject(strProjectName, strProjectPath); + AddFilters(selProj); + + selProj.Object.Save(); + } + catch(e) + { + if (e.description.length != 0) + SetErrorInfo(e); + return e.number + } +} + +function CreateCustomProject(strProjectName, strProjectPath) +{ + try + { + var strProjTemplatePath = wizard.FindSymbol('PROJECT_TEMPLATE_PATH'); + var strProjTemplate = strProjTemplatePath + '\\gst-sdk-template\\gst-template.vcxproj'; + + var Solution = dte.Solution; + var strSolutionName = ""; + if (wizard.FindSymbol("CLOSE_SOLUTION")) + { + Solution.Close(); + strSolutionName = wizard.FindSymbol("VS_SOLUTION_NAME"); + if (strSolutionName.length) + { + var strSolutionPath = strProjectPath.substr(0, strProjectPath.length - strProjectName.length); + Solution.Create(strSolutionPath, strSolutionName); + } + } + + var strProjectNameWithExt = strProjectName + '.vcxproj'; + + var oTarget = wizard.FindSymbol("TARGET"); + var prj; + if (wizard.FindSymbol("WIZARD_TYPE") == vsWizardAddSubProject) // vsWizardAddSubProject + { + var prjItem = oTarget.AddFromTemplate(strProjTemplate, strProjectNameWithExt); + prj = prjItem.SubProject; + } + else + { + prj = oTarget.AddFromTemplate(strProjTemplate, strProjectPath, strProjectNameWithExt); + } + return prj; + } + catch(e) + { + throw e; + } +} + +function AddFilters(proj) +{ + try + { + var group = proj.Object.AddFilter('Source Files'); + group.Filter = "cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx"; + group.UniqueIdentifier = "{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"; + group = proj.Object.AddFilter('Header Files'); + group.Filter = "h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd"; + group.UniqueIdentifier = "{93995380-89BD-4b04-88EB-625FBE52EBFB}"; + group = proj.Object.AddFilter('Resource Files'); + group.Filter = "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms"; + group.UniqueIdentifier = "{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"; + } + catch(e) + { + throw e; + } +} + + +function GetTargetName(strName, strProjectName) +{ + try + { + // TODO: set the name of the rendered file based on the template filename + var strTarget = strName; + + if (strName == 'readme.txt') + strTarget = 'ReadMe.txt'; + + if (strName == 'sample.txt') + strTarget = 'Sample.txt'; + + return strTarget; + } + catch(e) + { + throw e; + } +} diff --git a/data/vs-1.0/gst-template/gst-template.vcxproj b/data/vs-1.0/gst-sdk-template/gst-template.vcxproj similarity index 100% rename from data/vs-1.0/gst-template/gst-template.vcxproj rename to data/vs-1.0/gst-sdk-template/gst-template.vcxproj diff --git a/data/vs-1.0/gst-template/Scripts/1033/default.js b/data/vs-1.0/gst-template/Scripts/1033/default.js deleted file mode 100644 index 7eabdde10..000000000 --- a/data/vs-1.0/gst-template/Scripts/1033/default.js +++ /dev/null @@ -1,332 +0,0 @@ - -function OnFinish(selProj, selObj) -{ - try - { - var strProjectPath = wizard.FindSymbol('PROJECT_PATH'); - var strProjectName = wizard.FindSymbol('PROJECT_NAME'); - - selProj = CreateCustomProject(strProjectName, strProjectPath); - AddFilters(selProj); - - selProj.Object.Save(); - } - catch(e) - { - if (e.description.length != 0) - SetErrorInfo(e); - return e.number - } -} - -function CreateCustomProject(strProjectName, strProjectPath) -{ - try - { - var strProjTemplatePath = wizard.FindSymbol('PROJECT_TEMPLATE_PATH'); - var strProjTemplate = ''; - strProjTemplate = strProjTemplatePath + '\\gst-template\\gst-template.vcxproj'; - - var Solution = dte.Solution; - var strSolutionName = ""; - if (wizard.FindSymbol("CLOSE_SOLUTION")) - { - Solution.Close(); - strSolutionName = wizard.FindSymbol("VS_SOLUTION_NAME"); - if (strSolutionName.length) - { - var strSolutionPath = strProjectPath.substr(0, strProjectPath.length - strProjectName.length); - Solution.Create(strSolutionPath, strSolutionName); - } - } - - var strProjectNameWithExt = ''; - strProjectNameWithExt = strProjectName + '.vcxproj'; - - var oTarget = wizard.FindSymbol("TARGET"); - var prj; - if (wizard.FindSymbol("WIZARD_TYPE") == vsWizardAddSubProject) // vsWizardAddSubProject - { - var prjItem = oTarget.AddFromTemplate(strProjTemplate, strProjectNameWithExt); - prj = prjItem.SubProject; - } - else - { - prj = oTarget.AddFromTemplate(strProjTemplate, strProjectPath, strProjectNameWithExt); - } - var fxtarget = wizard.FindSymbol("TARGET_FRAMEWORK_VERSION"); - if (fxtarget != null && fxtarget != "") - { - fxtarget = fxtarget.split('.', 2); - if (fxtarget.length == 2) - prj.Object.TargetFrameworkVersion = parseInt(fxtarget[0]) * 0x10000 + parseInt(fxtarget[1]) - } - return prj; - } - catch(e) - { - throw e; - } -} - -function AddFilters(proj) -{ - try - { - var group = proj.Object.AddFilter('Source Files'); - group.Filter = "cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"; - group = proj.Object.AddFilter('Header Files'); - group.Filter = "h;hpp;hxx;hm;inl;inc;xsd"; - group = proj.Object.AddFilter('Resource Files'); - group.Filter = "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"; - } - catch(e) - { - throw e; - } -} - - -function GetTargetName(strName, strProjectName) -{ - try - { - // TODO: set the name of the rendered file based on the template filename - var strTarget = strName; - - if (strName == 'readme.txt') - strTarget = 'ReadMe.txt'; - - if (strName == 'sample.txt') - strTarget = 'Sample.txt'; - - return strTarget; - } - catch(e) - { - throw e; - } -} - -function AddFilesToCustomProj(proj, strProjectName, strProjectPath, InfFile) -{ - try - { - var projItems = proj.ProjectItems - - var strTemplatePath = wizard.FindSymbol('TEMPLATES_PATH'); - - var strTpl = ''; - var strName = ''; - - var strTextStream = InfFile.OpenAsTextStream(1, -2); - while (!strTextStream.AtEndOfStream) - { - strTpl = strTextStream.ReadLine(); - if (strTpl != '') - { - strName = strTpl; - var strTarget = GetTargetName(strName, strProjectName); - var strTemplate = strTemplatePath + '\\' + strTpl; - var strFile = strProjectPath + '\\' + strTarget; - - var bCopyOnly = false; //"true" will only copy the file from strTemplate to strTarget without rendering/adding to the project - var strExt = strName.substr(strName.lastIndexOf(".")); - if(strExt==".bmp" || strExt==".ico" || strExt==".gif" || strExt==".rtf" || strExt==".css") - bCopyOnly = true; - wizard.RenderTemplate(strTemplate, strFile, bCopyOnly); - proj.Object.AddFile(strFile); - } - } - strTextStream.Close(); - } - catch(e) - { - throw e; - } -} - - -// SIG // Begin signature block -// SIG // MIIXPgYJKoZIhvcNAQcCoIIXLzCCFysCAQExCzAJBgUr -// SIG // DgMCGgUAMGcGCisGAQQBgjcCAQSgWTBXMDIGCisGAQQB -// SIG // gjcCAR4wJAIBAQQQEODJBs441BGiowAQS9NQkAIBAAIB -// SIG // AAIBAAIBAAIBADAhMAkGBSsOAwIaBQAEFP9REkc7iEsy -// SIG // MTaCMZhRfDelVKKzoIISMTCCBGAwggNMoAMCAQICCi6r -// SIG // EdxQ/1ydy8AwCQYFKw4DAh0FADBwMSswKQYDVQQLEyJD -// SIG // b3B5cmlnaHQgKGMpIDE5OTcgTWljcm9zb2Z0IENvcnAu -// SIG // MR4wHAYDVQQLExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x -// SIG // ITAfBgNVBAMTGE1pY3Jvc29mdCBSb290IEF1dGhvcml0 -// SIG // eTAeFw0wNzA4MjIyMjMxMDJaFw0xMjA4MjUwNzAwMDBa -// SIG // MHkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n -// SIG // dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN -// SIG // aWNyb3NvZnQgQ29ycG9yYXRpb24xIzAhBgNVBAMTGk1p -// SIG // Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBMIIBIjANBgkq -// SIG // hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt3l91l2zRTmo -// SIG // NKwx2vklNUl3wPsfnsdFce/RRujUjMNrTFJi9JkCw03Y -// SIG // SWwvJD5lv84jtwtIt3913UW9qo8OUMUlK/Kg5w0jH9FB -// SIG // JPpimc8ZRaWTSh+ZzbMvIsNKLXxv2RUeO4w5EDndvSn0 -// SIG // ZjstATL//idIprVsAYec+7qyY3+C+VyggYSFjrDyuJSj -// SIG // zzimUIUXJ4dO3TD2AD30xvk9gb6G7Ww5py409rQurwp9 -// SIG // YpF4ZpyYcw2Gr/LE8yC5TxKNY8ss2TJFGe67SpY7UFMY -// SIG // zmZReaqth8hWPp+CUIhuBbE1wXskvVJmPZlOzCt+M26E -// SIG // RwbRntBKhgJuhgCkwIffUwIDAQABo4H6MIH3MBMGA1Ud -// SIG // JQQMMAoGCCsGAQUFBwMDMIGiBgNVHQEEgZowgZeAEFvQ -// SIG // cO9pcp4jUX4Usk2O/8uhcjBwMSswKQYDVQQLEyJDb3B5 -// SIG // cmlnaHQgKGMpIDE5OTcgTWljcm9zb2Z0IENvcnAuMR4w -// SIG // HAYDVQQLExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xITAf -// SIG // BgNVBAMTGE1pY3Jvc29mdCBSb290IEF1dGhvcml0eYIP -// SIG // AMEAizw8iBHRPvZj7N9AMA8GA1UdEwEB/wQFMAMBAf8w -// SIG // HQYDVR0OBBYEFMwdznYAcFuv8drETppRRC6jRGPwMAsG -// SIG // A1UdDwQEAwIBhjAJBgUrDgMCHQUAA4IBAQB7q65+Siby -// SIG // zrxOdKJYJ3QqdbOG/atMlHgATenK6xjcacUOonzzAkPG -// SIG // yofM+FPMwp+9Vm/wY0SpRADulsia1Ry4C58ZDZTX2h6t -// SIG // KX3v7aZzrI/eOY49mGq8OG3SiK8j/d/p1mkJkYi9/uEA -// SIG // uzTz93z5EBIuBesplpNCayhxtziP4AcNyV1ozb2AQWtm -// SIG // qLu3u440yvIDEHx69dLgQt97/uHhrP7239UNs3DWkuNP -// SIG // tjiifC3UPds0C2I3Ap+BaiOJ9lxjj7BauznXYIxVhBoz -// SIG // 9TuYoIIMol+Lsyy3oaXLq9ogtr8wGYUgFA0qvFL0QeBe -// SIG // MOOSKGmHwXDi86erzoBCcnYOMIIEejCCA2KgAwIBAgIK -// SIG // YQHPPgAAAAAADzANBgkqhkiG9w0BAQUFADB5MQswCQYD -// SIG // VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G -// SIG // A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 -// SIG // IENvcnBvcmF0aW9uMSMwIQYDVQQDExpNaWNyb3NvZnQg -// SIG // Q29kZSBTaWduaW5nIFBDQTAeFw0wOTEyMDcyMjQwMjla -// SIG // Fw0xMTAzMDcyMjQwMjlaMIGDMQswCQYDVQQGEwJVUzET -// SIG // MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk -// SIG // bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 -// SIG // aW9uMQ0wCwYDVQQLEwRNT1BSMR4wHAYDVQQDExVNaWNy -// SIG // b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEB -// SIG // AQUAA4IBDwAwggEKAoIBAQC9MIn7RXKoU2ueiU8AI8C+ -// SIG // 1B09sVlAOPNzkYIm5pYSAFPZHIIOPM4du733Qo2X1Pw4 -// SIG // GuS5+ePs02EDv6DT1nVNXEap7V7w0uJpWxpz6rMcjQTN -// SIG // KUSgZFkvHphdbserGDmCZcSnvKt1iBnqh5cUJrN/Jnak -// SIG // 1Dg5hOOzJtUY+Svp0skWWlQh8peNh4Yp/vRJLOaL+AQ/ -// SIG // fc3NlpKGDXED4tD+DEI1/9e4P92ORQp99tdLrVvwdnId -// SIG // dyN9iTXEHF2yUANLR20Hp1WImAaApoGtVE7Ygdb6v0LA -// SIG // Mb5VDZnVU0kSMOvlpYh8XsR6WhSHCLQ3aaDrMiSMCOv5 -// SIG // 1BS64PzN6qQVAgMBAAGjgfgwgfUwEwYDVR0lBAwwCgYI -// SIG // KwYBBQUHAwMwHQYDVR0OBBYEFDh4BXPIGzKbX5KGVa+J -// SIG // usaZsXSOMA4GA1UdDwEB/wQEAwIHgDAfBgNVHSMEGDAW -// SIG // gBTMHc52AHBbr/HaxE6aUUQuo0Rj8DBEBgNVHR8EPTA7 -// SIG // MDmgN6A1hjNodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v -// SIG // cGtpL2NybC9wcm9kdWN0cy9DU1BDQS5jcmwwSAYIKwYB -// SIG // BQUHAQEEPDA6MDgGCCsGAQUFBzAChixodHRwOi8vd3d3 -// SIG // Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL0NTUENBLmNy -// SIG // dDANBgkqhkiG9w0BAQUFAAOCAQEAKAODqxMN8f4Rb0J2 -// SIG // 2EOruMZC+iRlNK51sHEwjpa2g/py5P7NN+c6cJhRIA66 -// SIG // cbTJ9NXkiugocHPV7eHCe+7xVjRagILrENdyA+oSTuzd -// SIG // DYx7RE8MYXX9bpwH3c4rWhgNObBg/dr/BKoCo9j6jqO7 -// SIG // vcFqVDsxX+QsbsvxTSoc8h52e4avxofWsSrtrMwOwOSf -// SIG // f+jP6IRyVIIYbirInpW0Gh7Bb5PbYqbBS2utye09kuOy -// SIG // L6t6dzlnagB7gp0DEN5jlUkmQt6VIsGHC9AUo1/cczJy -// SIG // Nh7/yCnFJFJPZkjJHR2pxSY5aVBOp+zCBmwuchvxIdpt -// SIG // JEiAgRVAfJ/MdDhKTzCCBJ0wggOFoAMCAQICEGoLmU/A -// SIG // ACWrEdtFH1h6Z6IwDQYJKoZIhvcNAQEFBQAwcDErMCkG -// SIG // A1UECxMiQ29weXJpZ2h0IChjKSAxOTk3IE1pY3Jvc29m -// SIG // dCBDb3JwLjEeMBwGA1UECxMVTWljcm9zb2Z0IENvcnBv -// SIG // cmF0aW9uMSEwHwYDVQQDExhNaWNyb3NvZnQgUm9vdCBB -// SIG // dXRob3JpdHkwHhcNMDYwOTE2MDEwNDQ3WhcNMTkwOTE1 -// SIG // MDcwMDAwWjB5MQswCQYDVQQGEwJVUzETMBEGA1UECBMK -// SIG // V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG -// SIG // A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSMwIQYD -// SIG // VQQDExpNaWNyb3NvZnQgVGltZXN0YW1waW5nIFBDQTCC -// SIG // ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANw3 -// SIG // bvuvyEJKcRjIzkg+U8D6qxS6LDK7Ek9SyIPtPjPZSTGS -// SIG // KLaRZOAfUIS6wkvRfwX473W+i8eo1a5pcGZ4J2botrfv -// SIG // hbnN7qr9EqQLWSIpL89A2VYEG3a1bWRtSlTb3fHev5+D -// SIG // x4Dff0wCN5T1wJ4IVh5oR83ZwHZcL322JQS0VltqHGP/ -// SIG // gHw87tUEJU05d3QHXcJc2IY3LHXJDuoeOQl8dv6dbG56 -// SIG // 4Ow+j5eecQ5fKk8YYmAyntKDTisiXGhFi94vhBBQsvm1 -// SIG // Go1s7iWbE/jLENeFDvSCdnM2xpV6osxgBuwFsIYzt/iU -// SIG // W4RBhFiFlG6wHyxIzG+cQ+Bq6H8mjmsCAwEAAaOCASgw -// SIG // ggEkMBMGA1UdJQQMMAoGCCsGAQUFBwMIMIGiBgNVHQEE -// SIG // gZowgZeAEFvQcO9pcp4jUX4Usk2O/8uhcjBwMSswKQYD -// SIG // VQQLEyJDb3B5cmlnaHQgKGMpIDE5OTcgTWljcm9zb2Z0 -// SIG // IENvcnAuMR4wHAYDVQQLExVNaWNyb3NvZnQgQ29ycG9y -// SIG // YXRpb24xITAfBgNVBAMTGE1pY3Jvc29mdCBSb290IEF1 -// SIG // dGhvcml0eYIPAMEAizw8iBHRPvZj7N9AMBAGCSsGAQQB -// SIG // gjcVAQQDAgEAMB0GA1UdDgQWBBRv6E4/l7k0q0uGj7yc -// SIG // 6qw7QUPG0DAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMA -// SIG // QTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAN -// SIG // BgkqhkiG9w0BAQUFAAOCAQEAlE0RMcJ8ULsRjqFhBwEO -// SIG // jHBFje9zVL0/CQUt/7hRU4Uc7TmRt6NWC96Mtjsb0fus -// SIG // p8m3sVEhG28IaX5rA6IiRu1stG18IrhG04TzjQ++B4o2 -// SIG // wet+6XBdRZ+S0szO3Y7A4b8qzXzsya4y1Ye5y2PENtEY -// SIG // Ib923juasxtzniGI2LS0ElSM9JzCZUqaKCacYIoPO8cT -// SIG // ZXhIu8+tgzpPsGJY3jDp6Tkd44ny2jmB+RMhjGSAYwYE -// SIG // lvKaAkMve0aIuv8C2WX5St7aA3STswVuDMyd3ChhfEjx -// SIG // F5wRITgCHIesBsWWMrjlQMZTPb2pid7oZjeN9CKWnMyw -// SIG // d1RROtZyRLIj9jCCBKowggOSoAMCAQICCmEFojAAAAAA -// SIG // AAgwDQYJKoZIhvcNAQEFBQAweTELMAkGA1UEBhMCVVMx -// SIG // EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl -// SIG // ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh -// SIG // dGlvbjEjMCEGA1UEAxMaTWljcm9zb2Z0IFRpbWVzdGFt -// SIG // cGluZyBQQ0EwHhcNMDgwNzI1MTkwMTE1WhcNMTMwNzI1 -// SIG // MTkxMTE1WjCBszELMAkGA1UEBhMCVVMxEzARBgNVBAgT -// SIG // Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc -// SIG // BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsG -// SIG // A1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0Ug -// SIG // RVNOOjg1RDMtMzA1Qy01QkNGMSUwIwYDVQQDExxNaWNy -// SIG // b3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIBIjANBgkq -// SIG // hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8AQtspbAGoFn -// SIG // JbEmYrMTS84wusASOPyBZTQHxDayJGj2BwTAB5f0t/F7 -// SIG // HmIsRtlLpFE0t9Ns7Vo7tIOhRz0RCC41a0XmwjyMAmYC -// SIG // qRhp60rtJyzuPHdbpNRwmUtXhBDQry34iR3m6im058+e -// SIG // BmKnclTCO8bPP7jhsFgQbOWl18PCdTe99IXhgego2Bvx -// SIG // 8q7xgqPW1wOinxWE+z36q+G2MsigAmTz5v8aJnEIU4oV -// SIG // AvKDJ3ZJgnGn760yeMbXbBZPImWXYk1GL/8jr4XspnC9 -// SIG // A8va2DIFxSuQQLae1SyGbLfLEzJ9jcZ+rhcvMvxmux2w -// SIG // RVX4rfotZ4NnKZOE0lqhIwIDAQABo4H4MIH1MB0GA1Ud -// SIG // DgQWBBTol/b374zx5mnjWWhO95iKet2bLjAfBgNVHSME -// SIG // GDAWgBRv6E4/l7k0q0uGj7yc6qw7QUPG0DBEBgNVHR8E -// SIG // PTA7MDmgN6A1hjNodHRwOi8vY3JsLm1pY3Jvc29mdC5j -// SIG // b20vcGtpL2NybC9wcm9kdWN0cy90c3BjYS5jcmwwSAYI -// SIG // KwYBBQUHAQEEPDA6MDgGCCsGAQUFBzAChixodHRwOi8v -// SIG // d3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL3RzcGNh -// SIG // LmNydDATBgNVHSUEDDAKBggrBgEFBQcDCDAOBgNVHQ8B -// SIG // Af8EBAMCBsAwDQYJKoZIhvcNAQEFBQADggEBAA0/d1+R -// SIG // PL6lNaTbBQWEH1by75mmxwiNL7PNP3HVhnx3H93rF7K9 -// SIG // fOP5mfIKRUitFLtpLPI+Z2JU8u5/JxGSOezO2YdOiPdg -// SIG // RyN7JxVACJ+/DTEEgtg1tgycANOLqnhhxbWIQZ0+NtxY -// SIG // pCebOtq9Bl0UprIPTMGOPIvyYpn4Zu3V8xwosDLbyjEJ -// SIG // vPsiaEZM+tNzIucpjiIA+1a/Bq6BoBW6NPkojh9KYgWh -// SIG // ifWBR+kNkQjXWDuPHmsJaanASHxVgj9fADhDnAbMP9gv -// SIG // v09zCT39ul70x+w3wmRhoE3UPXDMW7ATgcHUozEavWTW -// SIG // ltJ6PypbRlMJPM0D+T9ZAMyJU2ExggR5MIIEdQIBATCB -// SIG // hzB5MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu -// SIG // Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV -// SIG // TWljcm9zb2Z0IENvcnBvcmF0aW9uMSMwIQYDVQQDExpN -// SIG // aWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQQIKYQHPPgAA -// SIG // AAAADzAJBgUrDgMCGgUAoIGkMBkGCSqGSIb3DQEJAzEM -// SIG // BgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgor -// SIG // BgEEAYI3AgEVMCMGCSqGSIb3DQEJBDEWBBRD573odGht -// SIG // DuvZD+9oREp/ubzpsDBEBgorBgEEAYI3AgEMMTYwNKAa -// SIG // gBgAYwB1AHMAdABvAG0AdwBpAHoALgBqAHOhFoAUaHR0 -// SIG // cDovL21pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEBBQAE -// SIG // ggEARB6u45hpHcw9dJ1kVqrdxQKIDXpHqE5ug51VwhkY -// SIG // KUgWTmI5ra0+ufLmKXYQOLNPSnNgWonKeG0w8K5QD4UW -// SIG // J9C0JG5nAqlyfJIaaq6htLw2cz5Ke453xiNP1LNuwWtP -// SIG // VdKQLmdPul5VW/SYXkxJ4VKZ/eUM6WoXanYD+NiLvcWj -// SIG // uSoQhohdvXnN8f6z6Xxzta7xQ+GdVShJFPa1a9IQDmLd -// SIG // g3KbK8pvBzCWZLp7XuF9OsxlNd6iFxZU78FPbN5YtGnR -// SIG // cLxR4MzBxavVh9pyEHscP4EwPkeaetMYIh2ufrbEr98R -// SIG // SL/gEjT4hsxwiwE04QkgQqNcRKTPC047gbeYqqGCAh8w -// SIG // ggIbBgkqhkiG9w0BCQYxggIMMIICCAIBATCBhzB5MQsw -// SIG // CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ -// SIG // MA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z -// SIG // b2Z0IENvcnBvcmF0aW9uMSMwIQYDVQQDExpNaWNyb3Nv -// SIG // ZnQgVGltZXN0YW1waW5nIFBDQQIKYQWiMAAAAAAACDAH -// SIG // BgUrDgMCGqBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0B -// SIG // BwEwHAYJKoZIhvcNAQkFMQ8XDTEwMDMxOTEzMDA1OFow -// SIG // IwYJKoZIhvcNAQkEMRYEFI2my6oEaZuQ5u31IF2xpaLt -// SIG // 0zomMA0GCSqGSIb3DQEBBQUABIIBABZaWeWNnLDWxt8t -// SIG // t0w1E1e+LMEzC1oELO1CyyPJ/z4mYrbtJkEjVO4n9Qrh -// SIG // WRCwiFVMEbBnb0fqvXncDMwBvuu7ODjLhXDAsaZgHOof -// SIG // IWhvUTgFb+iJmq3E9wd/9xAwppwHemW8xXy76cT1BH3G -// SIG // O5F/PlW/DVeMau1E0QmCdWGR3Y648/p9p2v2cwPWGy/z -// SIG // Sry8HYjS2ZfSapOtqJ3WQnEmu5YEhwq6++o9IWROK76I -// SIG // cT3oZoK/097drHGC/LTC+L4NRxRv22MgH16QtBhCWVOd -// SIG // cu0pTmQwz2DjlkcxKF2/pBGnNAWs05oEqr4WLasds3IH -// SIG // pD24xF79NyE/6vam6LQ= -// SIG // End signature block diff --git a/data/vs-1.0/wizard/gst-sdk-template.vsdir b/data/vs-1.0/wizard/gst-sdk-template.vsdir index 2ac7cf676..36132153c 100644 --- a/data/vs-1.0/wizard/gst-sdk-template.vsdir +++ b/data/vs-1.0/wizard/gst-sdk-template.vsdir @@ -1 +1 @@ -gst-template.vsz| |GStreamer Project|1|Create GStreamer projects easily.| |6777| |GstProject +gst-sdk-template.vsz| |GStreamer Project|1|Create GStreamer projects easily.| |6777| |GstProject diff --git a/data/vs-1.0/wizard/gst-sdk-template.vsz b/data/vs-1.0/wizard/gst-sdk-template.vsz index 3d340f201..475a55776 100644 --- a/data/vs-1.0/wizard/gst-sdk-template.vsz +++ b/data/vs-1.0/wizard/gst-sdk-template.vsz @@ -1,8 +1,7 @@ VSWIZARD 7.0 Wizard=VsWizard.VsWizardEngine.10.0 -Param="WIZARD_NAME = gst-template" +Param="WIZARD_NAME = gst-sdk-template" Param="RELATIVE_PATH = VCWizards" Param="FALLBACK_LCID = 1033" Param="WIZARD_UI = FALSE" -Param="SOURCE_FILTER = txt" diff --git a/data/wix/Config.wxi b/data/wix/Config.wxi index 45c47476d..7de2a96ca 100644 --- a/data/wix/Config.wxi +++ b/data/wix/Config.wxi @@ -6,12 +6,10 @@ - - + - - + diff --git a/data/wix/installer.wxs b/data/wix/installer.wxs index 8847d6897..b272bda59 100644 --- a/data/wix/installer.wxs +++ b/data/wix/installer.wxs @@ -1,15 +1,6 @@ - - - - - - - - + + + @@ -18,15 +9,9 @@ - 1 - - - - - - - - + + + diff --git a/data/wix/properties.wxi b/data/wix/properties.wxi deleted file mode 100644 index 6820d2a43..000000000 --- a/data/wix/properties.wxi +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/data/wix/ui.wxs b/data/wix/ui.wxs deleted file mode 100644 index 585e2565e..000000000 --- a/data/wix/ui.wxs +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - 1 - "1"]]> - - 1 - - 1 - - 1 - LicenseAccepted = "1" - - 1 - 1 - NOT WIXUI_DONTVALIDATEPATH - "1"]]> - WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1" - 1 - 1 - - NOT Installed - Installed - - 1 - - 1 - 1 - 1 - - - - - - - - - - diff --git a/data/wix/utils.wxs b/data/wix/utils.wxs deleted file mode 100644 index 951ba8ca2..000000000 --- a/data/wix/utils.wxs +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VS2010DEVENV - - - - - - - - - VC2010EXPRESS_IDE - - - diff --git a/data/wix/wixui_Mondo_GStreamer.wxi b/data/wix/wixui_Mondo_GStreamer.wxi new file mode 100644 index 000000000..5805ca669 --- /dev/null +++ b/data/wix/wixui_Mondo_GStreamer.wxi @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/toolchains.md b/docs/toolchains.md index 519154ddd..08dffd5fd 100644 --- a/docs/toolchains.md +++ b/docs/toolchains.md @@ -30,8 +30,8 @@ The final goal on Windows is to use the Visual Studio studio toolchain for all t The GCC + MinGW toolchain is a multilib toolchain that can generate 32 and 64 bits binaries. It uses the following versions and configurations: - * GCC: 8.2.0 - * MinGW: 6.0.0 + * GCC: 14.1.0 + * MinGW: 12.0.0 * Threads: posix * Exception handling: * 32 bits: SJLJ @@ -52,4 +52,4 @@ The toolchain recipes are kept in a different folder `recipes-toolchain` so that After building a new toolchain, to make it available to all users the tarballs should be uploaded to `freedesktop.org:/srv/gstreamer.freedesktop.org/www/data/cerbero/toolchain/windows/` and the new sha256 should be updated in `cerbero/bootstrap/windows.py` ## Visual Studio -FIXME: add documentation \ No newline at end of file +FIXME: add documentation diff --git a/packages/base-system-1.0.package b/packages/base-system-1.0.package index f9801954a..76f815ccd 100644 --- a/packages/base-system-1.0.package +++ b/packages/base-system-1.0.package @@ -12,8 +12,8 @@ class Package(custom.GStreamer, package.Package): files = ['cairo:libs', 'expat:libs', 'fontconfig:libs:etc', 'libffi:libs', 'freetype:libs', 'glib:libs:lang:bins:schemas', 'orc:libs', 'pango:libs:modules', 'libpng:libs', 'libjpeg-turbo:libs', - 'tiff:libs', 'gdk-pixbuf:bins:libs:modules:lang', 'libcroco:libs', - 'librsvg:libs', 'libxml2:libs', 'pixman:libs', 'fribidi:libs', + 'tiff:libs', 'gdk-pixbuf:bins:libs:modules:lang', + 'libxml2:libs', 'pixman:libs', 'fribidi:libs', 'zlib:libs', 'bzip2:libs', 'harfbuzz:libs', 'json-glib:bins:libs', 'pcre2:libs'] @@ -29,6 +29,9 @@ class Package(custom.GStreamer, package.Package): if self.config.variants.gi: self.files.append('gobject-introspection:libs:typelibs') + if self.config.variants.rust: + self.files.append('librsvg:libs') + if self.config.variants.uwp: self.platform_files[Platform.WINDOWS] = ['proxy-libintl:libs:lang'] self.files = [ diff --git a/packages/custom.py b/packages/custom.py index 526d10355..c2590a99a 100644 --- a/packages/custom.py +++ b/packages/custom.py @@ -5,7 +5,7 @@ class GStreamer: url = 'http://gstreamer.freedesktop.org' - version = '1.24.8' + version = '1.26.3' vendor = 'GStreamer Project' licenses = [License.LGPLv2Plus] org = 'org.freedesktop.gstreamer' diff --git a/packages/gstreamer-1.0-codecs-restricted.package b/packages/gstreamer-1.0-codecs-restricted.package index 58556ff8f..431ffa8cf 100644 --- a/packages/gstreamer-1.0-codecs-restricted.package +++ b/packages/gstreamer-1.0-codecs-restricted.package @@ -10,8 +10,8 @@ class Package(custom.GStreamer, package.Package): uuid = '0a4e77e8-3c8c-4e7d-890b-1538d36f1816' deps = ['gstreamer-1.0-core'] - files = ['a52dec:libs', 'opencore-amr:libs', - 'libdca:libs', 'vo-aacenc:libs', 'x264:libs', + files = ['a52dec:libs', 'libdca:libs', 'opencore-amr:libs', + 'vo-aacenc:libs', 'x264:libs', 'x265:libs', 'x265-src:libs', 'gst-plugins-ugly-1.0:plugins_codecs_restricted', 'gst-plugins-bad-1.0:plugins_codecs_restricted'] files_devel = ['gst-plugins-ugly-1.0:plugins_codecs_restricted_devel', diff --git a/packages/gstreamer-1.0-codecs.package b/packages/gstreamer-1.0-codecs.package index 6a59da3e7..ace10bcff 100644 --- a/packages/gstreamer-1.0-codecs.package +++ b/packages/gstreamer-1.0-codecs.package @@ -15,7 +15,7 @@ class Package(custom.GStreamer, package.Package): 'libtheora:libs', 'wavpack:libs', 'libvpx:libs', 'opus:libs', 'libvorbis:libs', 'openjpeg:libs', 'openh264:libs', 'taglib:libs', 'tiff:libs', 'spandsp:libs', - 'sbc:libs', 'mpg123:libs', 'lame:libs', 'zbar:libs', + 'sbc:libs', 'mpg123:libs', 'lame:libs', 'zbar:libs', 'svt-av1:libs', 'gst-plugins-base-1.0:plugins_codecs', 'gst-plugins-good-1.0:plugins_codecs', 'gst-plugins-bad-1.0:plugins_codecs', 'gst-plugins-ugly-1.0:plugins_codecs', ] @@ -50,3 +50,6 @@ class Package(custom.GStreamer, package.Package): 'gst-plugins-base-1.0:plugins_codecs', 'gst-plugins-good-1.0:plugins_codecs', 'gst-plugins-bad-1.0:plugins_codecs', 'gst-plugins-ugly-1.0:plugins_codecs', ] + + if self.config.target_arch == Architecture.X86_64: + self.files.append('svt-jpeg-xs:libs') diff --git a/packages/gstreamer-1.0-effects.package b/packages/gstreamer-1.0-effects.package index d9f8a24b3..913aeadd0 100644 --- a/packages/gstreamer-1.0-effects.package +++ b/packages/gstreamer-1.0-effects.package @@ -13,6 +13,8 @@ class Package(custom.GStreamer, package.Package): files = ['ladspa:libs', 'libltc:libs', 'soundtouch:libs', + 'qrencode:libs', + 'json-glib:libs', 'webrtc-audio-processing:libs', 'gst-plugins-base-1.0:plugins_effects', 'gst-plugins-good-1.0:plugins_effects', @@ -31,3 +33,6 @@ class Package(custom.GStreamer, package.Package): if self.config.variants.rust: self.files.append('gst-plugins-rs:plugins_effects') self.files_devel.append('gst-plugins-rs:plugins_effects_devel') + + if self.config.target_platform not in [Platform.IOS, Platform.ANDROID]: + self.files.append('frei0r-plugins:plugins') diff --git a/packages/gstreamer-1.0-python.package b/packages/gstreamer-1.0-python.package new file mode 100644 index 000000000..686c80a9b --- /dev/null +++ b/packages/gstreamer-1.0-python.package @@ -0,0 +1,25 @@ +# -*- Mode: Python -*- vi:si:et:sw=4:sts=4:ts=4:syntax=python + +class Package(custom.GStreamer, package.Package): + name = 'gstreamer-1.0-python' + shortdesc = 'GStreamer 1.0 Python bindings' + longdesc = 'GStreamer 1.0 Python bindings' + uuid = 'fde33a12-887c-48b5-ae65-52f7379ba863' + deps = ['gstreamer-1.0-core'] + + files = [ + 'gobject-introspection:python', + 'gst-python-1.0:python:plugins:libs', + 'gst-editing-services-1.0:python', + 'pycairo:python:libs', + 'pygobject:python:libs', + 'json-glib:typelibs', + 'harfbuzz:typelibs', + 'pango:typelibs', + 'libsoup:typelibs', + 'gdk-pixbuf:typelibs', + ] + + def prepare(self): + self.shortdesc += f" (Python {self.config.get_python_version()})" + self.longdesc += f" (Python {self.config.get_python_version()})" diff --git a/packages/gstreamer-1.0-system.package b/packages/gstreamer-1.0-system.package index c611b9135..7ee113f7a 100644 --- a/packages/gstreamer-1.0-system.package +++ b/packages/gstreamer-1.0-system.package @@ -36,3 +36,14 @@ class Package(custom.GStreamer, package.Package): if self.config.variants.rust: self.files.append('gst-plugins-rs:plugins_sys') self.files_devel.append('gst-plugins-rs:plugins_sys_devel') + + if self.config.target_platform == Platform.ANDROID: + self.files += ['tinyalsa:libs'] + self.files_devel += ['tinyalsa:files_devel'] + + # webview2 is linked statically into the corresponding plugin, so we + # don't want to distribute any files belonging to the package. However, + # we must include an empty file category here so that fetch-package + # works correctly. + if self.config.target_platform == Platform.WINDOWS: + self.files_devel += ['webview2:files_devel'] diff --git a/packages/gstreamer-1.0-vs-templates.package b/packages/gstreamer-1.0-vs-templates.package index 45742f14b..3fb4ae1cb 100644 --- a/packages/gstreamer-1.0-vs-templates.package +++ b/packages/gstreamer-1.0-vs-templates.package @@ -2,13 +2,37 @@ # -*- Mode: Python -*- from cerbero.packages.wix import VSTemplatePackage +# IDE_DIR support starts only with VS 2017 onwards +# vs_template_name must match the wizard name -class Package(custom.GStreamer, VSTemplatePackage): +class Package2017(custom.GStreamer, VSTemplatePackage): + year = '2017' + name = 'gstreamer-1.0-vs-templates-2017' + shortdesc = 'GStreamer 1.0 Visual Studio 2017 templates' + vs_template_dir = 'share/vs/2010/gst-sdk-template' + vs_template_name = 'gst-sdk-template' + + def prepare(self): + self.vs_wizard_dir = f'share/vs/{self.year}/wizard' + + +class Package2019(custom.GStreamer, VSTemplatePackage): + year = '2019' + name = 'gstreamer-1.0-vs-templates-2019' + shortdesc = 'GStreamer 1.0 Visual Studio 2019 templates' + vs_template_dir = 'share/vs/2010/gst-sdk-template' + vs_template_name = 'gst-sdk-template' + + def prepare(self): + self.vs_wizard_dir = f'share/vs/{self.year}/wizard' - name = 'gstreamer-1.0-vs-templates' - shortdesc = 'GStreamer 1.0 VS templates' - longdesc = 'GStreamer 1.0 Visual Studio templates' - uuid = '42b3ba90-bd6a-4d94-a40d-5f2adf7ce441' + +class Package2022(custom.GStreamer, VSTemplatePackage): + year = '2022' + name = 'gstreamer-1.0-vs-templates-2022' + shortdesc = 'GStreamer 1.0 Visual Studio 2022 templates' vs_template_dir = 'share/vs/2010/gst-sdk-template' - vs_wizard_dir = 'share/vs/2010/wizard' - vs_template_name = 'GStreamer' + vs_template_name = 'gst-sdk-template' + + def prepare(self): + self.vs_wizard_dir = f'share/vs/{self.year}/wizard' diff --git a/packages/gstreamer-1.0/gstreamer-1.0.package b/packages/gstreamer-1.0/gstreamer-1.0.package index fd6e9f060..d1b268b68 100644 --- a/packages/gstreamer-1.0/gstreamer-1.0.package +++ b/packages/gstreamer-1.0/gstreamer-1.0.package @@ -34,7 +34,9 @@ class SDKPackage(custom.GStreamer, package.SDKPackage): platform_packages = { Platform.WINDOWS: [ ('vsintegration-1.0', True, False), - ('gstreamer-1.0-vs-templates', True, False), + ('gstreamer-1.0-vs-templates-2017', True, False), + ('gstreamer-1.0-vs-templates-2019', True, False), + ('gstreamer-1.0-vs-templates-2022', True, False), ], } @@ -81,3 +83,5 @@ class SDKPackage(custom.GStreamer, package.SDKPackage): if self.config.target_platform == Platform.IOS: self.resources_postinstall = 'post_install_ios' #self.user_resources = ['share/gst-sdk/tutorials/xcode iOS'] + if self.config.variants.python and self.config.variants.gi: + self.packages += [('gstreamer-1.0-python', False, True)] diff --git a/recipes-toolchain/binutils.recipe b/recipes-toolchain/binutils.recipe index 2a3e047dd..6925c88bc 100644 --- a/recipes-toolchain/binutils.recipe +++ b/recipes-toolchain/binutils.recipe @@ -3,11 +3,11 @@ import shutil class Recipe(recipe.Recipe): name = 'binutils' - version = '2.31.1' + version = '2.42' licenses = [License.LGPLv2Plus] licenses_bins = [License.GPLv2Plus] url = 'https://ftpmirror.gnu.org/gnu/binutils/binutils-%(version)s.tar.bz2' - tarball_checksum = 'ffcc382695bf947da6135e7436b8ed52d991cf270db897190f19d6f9838564d0' + tarball_checksum = 'aa54850ebda5064c72cd4ec2d9b056c294252991486350d9a97ab2a6dfdfaf12' stype = SourceType.TARBALL autoreconf = True configure_options = '--enable-ld=yes ' \ @@ -47,12 +47,25 @@ class Recipe(recipe.Recipe): files_lang = ['bfd', 'binutils', 'gas', 'gprof', 'ld', 'opcodes'] + patches = [ + f'{name}/0002-check-for-unusual-file-harder.patch', + f'{name}/0010-bfd-Increase-_bfd_coff_max_nscns-to-65279.patch', + f'{name}/0110-binutils-mingw-gnu-print.patch', + f'{name}/2001-ld-option-to-move-default-bases-under-4GB.patch', + f'{name}/2003-Restore-old-behaviour-of-windres-so-that-options-con.patch', + f'{name}/reproducible-import-libraries.patch', + f'{name}/libiberty-unlink-handle-windows-nul.patch', + f'{name}/3001-hack-libiberty-link-order.patch', + ] + can_msvc = False + override_libtool = False + def prepare(self): if self.config.target_arch == Architecture.X86: raise InvalidRecipeError(self) self.target = 'x86_64-w64-mingw32' self.configure_options += ' --target=%s ' % self.target - self.configure_options += '--with-sysroot=$CERBERO_PREFIX/%s/sysroot ' % self.target + self.configure_options += f' --with-sysroot={self.config.prefix}/{self.target}/sysroot' if self.config.target_platform == Platform.WINDOWS: self.configure_options += ' --host=%s' % self.target @@ -66,15 +79,12 @@ class Recipe(recipe.Recipe): self.files_binutils]) self.files_binutils = files - async def configure(self): - for d in ['bfd', 'opcodes', 'gas', 'binutils', 'gprof', 'ld']: - shell.new_call(['autoreconf', '-ivf'], os.path.join(self.build_dir, d)) - await super().configure() + async def install(self): + await super().install() - def post_install(self): # Prefix binaries with the host triplet if self.config.target_platform == Platform.WINDOWS: - for f in self.files_list_by_category('bins'): + for f in self.files_list_by_category('bins', only_existing=False): f = os.path.join(self.config.prefix, f) shutil.copy(f.replace(self.target + '-', ''), f) # libtool m4 macros uses non-prefixed 'strings' command. @@ -84,4 +94,3 @@ class Recipe(recipe.Recipe): if os.path.exists(strings): os.remove(strings) shell.symlink('%s-strings' % self.target, 'strings', bindir) - super().post_install() diff --git a/recipes-toolchain/binutils/0002-check-for-unusual-file-harder.patch b/recipes-toolchain/binutils/0002-check-for-unusual-file-harder.patch new file mode 100644 index 000000000..6e04e1c70 --- /dev/null +++ b/recipes-toolchain/binutils/0002-check-for-unusual-file-harder.patch @@ -0,0 +1,98 @@ +From 6feec2cc68d4fbf6eb12e44e9381d1c0ae37524b Mon Sep 17 00:00:00 2001 +From: Alexey Pavlov +Date: Tue, 26 Sep 2017 10:39:03 +0300 +Subject: [PATCH] binutils: Update to 2.29.1 + +Configure scripts tend to do things like this: +nm -B /dev/null +which, on Windows, turn into: +nm -B nul +and nul here acts like a normal file with 0 size as far as stat() is +concerned. +Check harder for the file in question being unusual (isatty() does see +that). +And since configure script expects /dev/nul, do report it that way. + +Last updated at: + +https://github.com/msys2/MINGW-packages/commit/3b7171c0cec4efee59bab8d028ee68a3c1eab0a5 +--- + binutils/bucomm.c | 20 ++++++++++++++++++-- + binutils/elfedit.c | 15 ++++++++++++++- + 2 files changed, 32 insertions(+), 3 deletions(-) + +diff --git a/binutils/bucomm.c b/binutils/bucomm.c +index d51d1349..e005e0aa 100644 +--- a/binutils/bucomm.c ++++ b/binutils/bucomm.c +@@ -620,6 +620,15 @@ get_file_size (const char * file_name) + if (file_name == NULL) + return (off_t) -1; + ++ int f, t; ++ t = -1; ++ f = open (file_name, O_RDONLY | O_BINARY); ++ if (f != 0) ++ { ++ t = isatty (f); ++ close (f); ++ } ++ + if (stat (file_name, &statbuf) < 0) + { + if (errno == ENOENT) +@@ -630,8 +639,15 @@ get_file_size (const char * file_name) + } + else if (S_ISDIR (statbuf.st_mode)) + non_fatal (_("Warning: '%s' is a directory"), file_name); +- else if (! S_ISREG (statbuf.st_mode)) +- non_fatal (_("Warning: '%s' is not an ordinary file"), file_name); ++ else if (! S_ISREG (statbuf.st_mode) || t > 0) ++ { ++#ifdef _WIN32 ++ /* libtool passes /dev/null and checks for /dev/null in the output */ ++ if (stricmp (file_name, "nul") == 0) ++ file_name = "/dev/null"; ++#endif ++ non_fatal (_("Warning: '%s' is not an ordinary file"), file_name); ++ } + else if (statbuf.st_size < 0) + non_fatal (_("Warning: '%s' has negative size, probably it is too large"), + file_name); +diff --git a/binutils/elfedit.c b/binutils/elfedit.c +index 76316365..075ce8d8 100644 +--- a/binutils/elfedit.c ++++ b/binutils/elfedit.c +@@ -725,6 +725,14 @@ static int + check_file (const char *file_name, struct stat *statbuf_p) + { + struct stat statbuf; ++ int f, t; ++ t = -1; ++ f = open (file_name, O_RDONLY | O_BINARY); ++ if (f != 0) ++ { ++ t = isatty (f); ++ close (f); ++ } + + if (statbuf_p == NULL) + statbuf_p = &statbuf; +@@ -753,8 +761,13 @@ check_file (const char *file_name, struct stat *statbuf_p) + } + #endif + +- if (! S_ISREG (statbuf_p->st_mode)) ++ if (! S_ISREG (statbuf_p->st_mode) || t > 0) + { ++#ifdef _WIN32 ++ /* libtool passes /dev/null and checks for /dev/null in the output */ ++ if (stricmp (file_name, "nul") == 0) ++ file_name = "/dev/null"; ++#endif + error (_("'%s' is not an ordinary file\n"), file_name); + return 1; + } +-- +2.44.0.windows.1 + diff --git a/recipes-toolchain/binutils/0010-bfd-Increase-_bfd_coff_max_nscns-to-65279.patch b/recipes-toolchain/binutils/0010-bfd-Increase-_bfd_coff_max_nscns-to-65279.patch new file mode 100644 index 000000000..707082247 --- /dev/null +++ b/recipes-toolchain/binutils/0010-bfd-Increase-_bfd_coff_max_nscns-to-65279.patch @@ -0,0 +1,82 @@ +From 520d5017366ff334c8a866aa15abb8cce22fb952 Mon Sep 17 00:00:00 2001 +From: Ray Donnelly +Date: Mon, 23 Nov 2015 22:42:53 +0000 +Subject: [PATCH] bfd: Increase _bfd_coff_max_nscns to 65279 + +.. from 32768. This is the value that llvm uses. There's no +indication in the PECOFF specs that 32768 is the limit. +--- + bfd/coff-alpha.c | 2 +- + bfd/coff-mips.c | 2 +- + bfd/coff-rs6000.c | 2 +- + bfd/coff-sh.c | 2 +- + bfd/coffcode.h | 2 +- + 5 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c +index 15fea1fde34..c5547259956 100644 +--- a/bfd/coff-alpha.c ++++ b/bfd/coff-alpha.c +@@ -2304,7 +2304,7 @@ static const struct ecoff_backend_data alpha_ecoff_backend_data = + alpha_ecoff_swap_filehdr_out, alpha_ecoff_swap_aouthdr_out, + alpha_ecoff_swap_scnhdr_out, + FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, true, +- ECOFF_NO_LONG_SECTION_NAMES, 4, false, 2, 32768, ++ ECOFF_NO_LONG_SECTION_NAMES, 4, false, 2, 65279, + alpha_ecoff_swap_filehdr_in, alpha_ecoff_swap_aouthdr_in, + alpha_ecoff_swap_scnhdr_in, NULL, + alpha_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook, +diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c +index 963ab249119..935bb0c5702 100644 +--- a/bfd/coff-mips.c ++++ b/bfd/coff-mips.c +@@ -1314,7 +1314,7 @@ static const struct ecoff_backend_data mips_ecoff_backend_data = + mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out, + mips_ecoff_swap_scnhdr_out, + FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, true, +- ECOFF_NO_LONG_SECTION_NAMES, 4, false, 2, 32768, ++ ECOFF_NO_LONG_SECTION_NAMES, 4, false, 2, 65279, + mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in, + mips_ecoff_swap_scnhdr_in, NULL, + mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook, +diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c +index 45ba9b3cb00..744c61bafb9 100644 +--- a/bfd/coff-rs6000.c ++++ b/bfd/coff-rs6000.c +@@ -4382,7 +4382,7 @@ static const struct xcoff_backend_data_rec bfd_xcoff_backend_data = + 3, /* _bfd_coff_default_section_alignment_power */ + false, /* _bfd_coff_force_symnames_in_strings */ + 2, /* _bfd_coff_debug_string_prefix_length */ +- 32768, /* _bfd_coff_max_nscns */ ++ 65279, /* _bfd_coff_max_nscns */ + coff_swap_filehdr_in, + coff_swap_aouthdr_in, + coff_swap_scnhdr_in, +diff --git a/bfd/coff-sh.c b/bfd/coff-sh.c +index 10d203f5280..ef793612bf7 100644 +--- a/bfd/coff-sh.c ++++ b/bfd/coff-sh.c +@@ -3094,7 +3094,7 @@ static bfd_coff_backend_data bfd_coff_small_swap_table = + #else + 2, + #endif +- 32768, ++ 65279, + coff_swap_filehdr_in, coff_swap_aouthdr_in, coff_swap_scnhdr_in, + coff_swap_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook, + coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook, +diff --git a/bfd/coffcode.h b/bfd/coffcode.h +index f65f3352e46..25384adfde8 100644 +--- a/bfd/coffcode.h ++++ b/bfd/coffcode.h +@@ -5415,7 +5415,7 @@ static bfd_coff_backend_data bfd_coff_std_swap_table ATTRIBUTE_UNUSED = + #else + 2, + #endif +- 32768, ++ 65279, + coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in, + coff_SWAP_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook, + coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook, +-- +2.32.0 diff --git a/recipes-toolchain/binutils/0110-binutils-mingw-gnu-print.patch b/recipes-toolchain/binutils/0110-binutils-mingw-gnu-print.patch new file mode 100644 index 000000000..fe38436e3 --- /dev/null +++ b/recipes-toolchain/binutils/0110-binutils-mingw-gnu-print.patch @@ -0,0 +1,121 @@ +From f5673d679c7327fb4defea83ed5fe102dc76da5f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=D9=85=D9=87=D8=AF=D9=8A=20=D8=B4=D9=8A=D9=86=D9=88=D9=86?= + =?UTF-8?q?=20=28Mehdi=20Chinoune=29?= +Date: Sat, 14 Jan 2023 20:59:56 +0100 +Subject: [PATCH] binutils: update to 2.40 + +Last updated at: + +https://github.com/msys2/MINGW-packages/commit/594c064fd4150f4fad50e1ec19f86af58e5357fd +--- + binutils/strings.c | 6 +++--- + gas/as.h | 6 +++--- + gold/configure | 2 +- + gold/configure.ac | 2 +- + include/ansidecl.h | 4 ++-- + 5 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/binutils/strings.c b/binutils/strings.c +index ec02e1d5..b410a726 100644 +--- a/binutils/strings.c ++++ b/binutils/strings.c +@@ -633,7 +633,7 @@ print_filename_and_address (const char * filename, file_ptr address) + case 8: + if (sizeof (address) > sizeof (long)) + { +-#ifndef __MSVCRT__ ++#if !defined(__MSVCRT__) || defined(__USE_MINGW_ANSI_STDIO) + printf ("%7llo ", (unsigned long long) address); + #else + printf ("%7I64o ", (unsigned long long) address); +@@ -646,7 +646,7 @@ print_filename_and_address (const char * filename, file_ptr address) + case 10: + if (sizeof (address) > sizeof (long)) + { +-#ifndef __MSVCRT__ ++#if !defined(__MSVCRT__) || defined(__USE_MINGW_ANSI_STDIO) + printf ("%7llu ", (unsigned long long) address); + #else + printf ("%7I64d ", (unsigned long long) address); +@@ -659,7 +659,7 @@ print_filename_and_address (const char * filename, file_ptr address) + case 16: + if (sizeof (address) > sizeof (long)) + { +-#ifndef __MSVCRT__ ++#if !defined(__MSVCRT__) || defined(__USE_MINGW_ANSI_STDIO) + printf ("%7llx ", (unsigned long long) address); + #else + printf ("%7I64x ", (unsigned long long) address); +diff --git a/gas/as.h b/gas/as.h +index 69d7ae2c..2926cee2 100644 +--- a/gas/as.h ++++ b/gas/as.h +@@ -443,14 +443,14 @@ typedef struct _pseudo_type pseudo_typeS; + + #define PRINTF_LIKE(FCN) \ + void FCN (const char *format, ...) \ +- __attribute__ ((__format__ (__printf__, 1, 2))) ++ __attribute__ ((__format__ (gnu_printf, 1, 2))) + #define PRINTF_WHERE_LIKE(FCN) \ + void FCN (const char *file, unsigned int line, const char *format, ...) \ +- __attribute__ ((__format__ (__printf__, 3, 4))) ++ __attribute__ ((__format__ (gnu_printf, 3, 4))) + #define PRINTF_INDENT_LIKE(FCN) \ + void FCN (const char *file, unsigned int line, unsigned int indent, \ + const char *format, ...) \ +- __attribute__ ((__format__ (__printf__, 4, 5))) ++ __attribute__ ((__format__ (gnu_printf, 4, 5))) + + #else /* __GNUC__ < 2 || defined(VMS) */ + +diff --git a/gold/configure b/gold/configure +index c92f4478..6396c082 100644 +--- a/gold/configure ++++ b/gold/configure +@@ -13635,7 +13635,7 @@ else + /* end confdefs.h. */ + + template extern void foo(const char*, ...) +- __attribute__ ((__format__ (__printf__, 1, 2))); ++ __attribute__ ((__format__ (gnu_printf, 1, 2))); + template void foo(const char* format, ...) {} + void bar() { foo("%s\n", "foo"); } + +diff --git a/gold/configure.ac b/gold/configure.ac +index 2c7a969b..ddcb2c4a 100644 +--- a/gold/configure.ac ++++ b/gold/configure.ac +@@ -711,7 +711,7 @@ AC_CACHE_CHECK([whether we can use attributes with template functions], + [gold_cv_template_attribute], + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + template extern void foo(const char*, ...) +- __attribute__ ((__format__ (__printf__, 1, 2))); ++ __attribute__ ((__format__ (gnu_printf, 1, 2))); + template void foo(const char* format, ...) {} + void bar() { foo("%s\n", "foo"); } + ])], [gold_cv_template_attribute=yes], [gold_cv_template_attribute=no])]) +diff --git a/include/ansidecl.h b/include/ansidecl.h +index 653d9186..e78c9687 100644 +--- a/include/ansidecl.h ++++ b/include/ansidecl.h +@@ -154,7 +154,7 @@ So instead we use the macro below and test it against specific values. */ + before GCC 3.3, but as of 3.3 we need to add the `nonnull' + attribute to retain this behavior. */ + #ifndef ATTRIBUTE_PRINTF +-#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m) ++#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (gnu_printf, m, n))) ATTRIBUTE_NONNULL(m) + #define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2) + #define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3) + #define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4) +@@ -182,7 +182,7 @@ So instead we use the macro below and test it against specific values. */ + NULL format specifier was allowed as of gcc 3.3. */ + #ifndef ATTRIBUTE_NULL_PRINTF + # if (GCC_VERSION >= 3003) +-# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ++# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (gnu_printf, m, n))) + # else + # define ATTRIBUTE_NULL_PRINTF(m, n) + # endif /* GNUC >= 3.3 */ +-- +2.44.0.windows.1 + diff --git a/recipes-toolchain/binutils/0410-windres-handle-spaces.patch b/recipes-toolchain/binutils/0410-windres-handle-spaces.patch new file mode 100644 index 000000000..5a6071938 --- /dev/null +++ b/recipes-toolchain/binutils/0410-windres-handle-spaces.patch @@ -0,0 +1,66 @@ +From cc3edc52747fd8b184ee48f1b0cc1ac0aca7832e Mon Sep 17 00:00:00 2001 +From: Eli Zaretskii +Date: Thu, 28 Jan 2021 14:57:33 +0000 +Subject: [PATCH] Improve windres's handling of pathnames containing special + characters on Windows platforms. + + PR 4356 + * windres.c (quot): Use double quotes to protect strings on + Windows platforms. +--- + binutils/ChangeLog | 6 ++++++ + binutils/windres.c | 31 ++++++++++++++++++++++++++++--- + 2 files changed, 34 insertions(+), 3 deletions(-) + +diff --git a/binutils/windres.c b/binutils/windres.c +index 41d1e928a54..b35661cb9f5 100644 +--- a/binutils/windres.c ++++ b/binutils/windres.c +@@ -703,19 +703,44 @@ quot (const char *string) + const char *src; + char *dest; + +- if ((buflen < slen * 2 + 2) || ! buf) ++ if ((buflen < slen * 2 + 3) || ! buf) + { +- buflen = slen * 2 + 2; ++ buflen = slen * 2 + 3; + free (buf); + buf = (char *) xmalloc (buflen); + } + +- for (src=string, dest=buf; *src; src++, dest++) ++#if defined (_WIN32) && !defined (__CYGWIN__) ++ /* For Windows shells, quote "like this". */ ++ { ++ bfd_boolean quoted = FALSE; ++ ++ dest = buf; ++ if (strchr (string, ' ')) ++ { ++ quoted = TRUE; ++ *dest++ = '"'; ++ } ++ ++ for (src = string; *src; src++, dest++) ++ { ++ /* Escape-protect embedded double quotes. */ ++ if (quoted && *src == '"') ++ *dest++ = '\\'; ++ *dest = *src; ++ } ++ ++ if (quoted) ++ *dest++ = '"'; ++ } ++#else ++ for (src = string, dest = buf; *src; src++, dest++) + { + if (*src == '(' || *src == ')' || *src == ' ') + *dest++ = '\\'; + *dest = *src; + } ++#endif + *dest = 0; + return buf; + } diff --git a/recipes-toolchain/binutils/0500-fix-weak-undef-symbols-after-image-base-change.patch b/recipes-toolchain/binutils/0500-fix-weak-undef-symbols-after-image-base-change.patch new file mode 100644 index 000000000..0b03383e4 --- /dev/null +++ b/recipes-toolchain/binutils/0500-fix-weak-undef-symbols-after-image-base-change.patch @@ -0,0 +1,189 @@ +From 74edb473c9ecf5e2053ecf8e429ee608feafb9e1 Mon Sep 17 00:00:00 2001 +From: Tamar Christina +Date: Thu, 1 Apr 2021 17:10:38 +0100 +Subject: [PATCH] PE/Windows x86_64: Fix weak undef symbols after image base + change + +The change in PR19011 changed the image load address from being in the lower +32-bit address space to the higher 64-bit address space. + +However when you have a weak undef symbol which stays undef at the end of +linking the linker has to resolve this (Windows loader does not support undef +symbols). As such typically these would resolve to 0. + +The relocation used for these weak symbols are the normal 32-bit PC_REL call +relocs. So when doing the overflow check LD checks if the distance between the +symbol and the call is within range. However now that the load address is +> 32-bits and the symbol val is 0 this overflow check will always fail. + +As such the linker gives a bogus error. This patch makes the linker not emit +the overflow failure but chooses to still let the check be performed (as it's +mid-end code). + +One down side of this is that it does break the common convention that the call +be to sym at 0x0. i.e. before you'd get + + 401015: 74 05 je 40101c + 401017: e8 e4 ef bf ff callq 0 + +and now you get + + 140001015: 74 05 je 14000101c + 140001017: e8 e4 ef ff bf call 100000000 + +since the call is PC_REL there's no way to get the range large enough to +resolve to 0. As such I have chosen to leave it as the furthest simple range +that we can still represent. + +By only ignoring the error we leave the symbol value itself to still be 0 +such that the if() checks still work correctly. + +bfd/ChangeLog: + +2021-04-01 Tamar Christina + + PR ld/26659 + * cofflink.c (_bfd_coff_generic_relocate_section): Ignore overflow. + +ld/ChangeLog: + +2021-04-01 Tamar Christina + + PR ld/26659 + * testsuite/ld-pe/pe.exp: Add test. + * testsuite/ld-pe/pr26659-weak-undef-sym.d: New test. + * testsuite/ld-pe/pr26659-weak-undef-sym.s: New test. +--- + bfd/ChangeLog | 5 +++ + bfd/cofflink.c | 15 ++++++++ + ld/ChangeLog | 7 ++++ + ld/testsuite/ld-pe/pe.exp | 1 + + ld/testsuite/ld-pe/pr26659-weak-undef-sym.d | 32 +++++++++++++++++ + ld/testsuite/ld-pe/pr26659-weak-undef-sym.s | 38 +++++++++++++++++++++ + 6 files changed, 98 insertions(+) + create mode 100644 ld/testsuite/ld-pe/pr26659-weak-undef-sym.d + create mode 100644 ld/testsuite/ld-pe/pr26659-weak-undef-sym.s + +diff --git a/bfd/cofflink.c b/bfd/cofflink.c +index c6b65c761d7..dd3e8dd4bf6 100644 +--- a/bfd/cofflink.c ++++ b/bfd/cofflink.c +@@ -3129,6 +3129,21 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd, + return false; + case bfd_reloc_overflow: + { ++ ++ /* Ignore any weak undef symbols that may have overflowed. Due to ++ PR ld/19011 the base address is now in the upper 64-bit address ++ range. This means that when _bfd_final_link_relocate calculates ++ the overlow it takes the distance between the symbol and the VMA ++ which will now always overflow as 0 - 64-bit addr > 32-bit range ++ of the relocation. This ends up creating PR ld/26659. */ ++ if (val == 0 ++ /* Reverse the hack where 4 is subtracted from the addend. */ ++ && (addend + 4) == 0 ++ && sym->n_sclass == C_NT_WEAK ++ && bfd_coff_classify_symbol (output_bfd, sym) ++ == COFF_SYMBOL_UNDEFINED) ++ break; ++ + const char *name; + char buf[SYMNMLEN + 1]; + +diff --git a/ld/testsuite/ld-pe/pe.exp b/ld/testsuite/ld-pe/pe.exp +index b1a200180be..a536b51c3e6 100644 +--- a/ld/testsuite/ld-pe/pe.exp ++++ b/ld/testsuite/ld-pe/pe.exp +@@ -81,6 +81,7 @@ run_dump_test "reloc" + run_dump_test "weakdef-1" + + run_dump_test "pr19803" ++run_dump_test "pr26659-weak-undef-sym" + set pr19803_dll { + { "PR 19803: not exporting swept symbols" + "-shared --out-implib dx.dll --gc-sections" +diff --git a/ld/testsuite/ld-pe/pr26659-weak-undef-sym.d b/ld/testsuite/ld-pe/pr26659-weak-undef-sym.d +new file mode 100644 +index 00000000000..0b48994877d +--- /dev/null ++++ b/ld/testsuite/ld-pe/pr26659-weak-undef-sym.d +@@ -0,0 +1,32 @@ ++#source: pr26659-weak-undef-sym.s ++#target: x86_64-*-cygwin* x86_64-*-pe x86_64-*-mingw* ++#ld: -e0 ++#objdump: -d ++ ++#... ++0000000140001000 : ++ 140001000: 55 push %rbp ++ 140001001: 48 89 e5 mov %rsp,%rbp ++ 140001004: 48 83 ec 20 sub \$0x20,%rsp ++ 140001008: 89 4d 10 mov %ecx,0x10\(%rbp\) ++ 14000100b: 48 8b 05 ee 0f 00 00 mov 0xfee\(%rip\),%rax # 140002000 <__data_end__> ++ 140001012: 48 85 c0 test %rax,%rax ++ 140001015: 74 05 je 14000101c ++ 140001017: e8 e4 ef ff bf call 100000000 <__size_of_stack_reserve__\+0xffe00000> ++ 14000101c: 48 8b 05 ed 0f 00 00 mov 0xfed\(%rip\),%rax # 140002010 <.refptr.bar2> ++ 140001023: 48 85 c0 test %rax,%rax ++ 140001026: 74 05 je 14000102d ++ 140001028: e8 d3 ef ff bf call 100000000 <__size_of_stack_reserve__\+0xffe00000> ++ 14000102d: 8b 45 10 mov 0x10\(%rbp\),%eax ++ 140001030: 0f af c0 imul %eax,%eax ++ 140001033: 48 83 c4 20 add \$0x20,%rsp ++ 140001037: 5d pop %rbp ++ 140001038: c3 ret ++ 140001039: 90 nop ++ 14000103a: 90 nop ++ 14000103b: 90 nop ++ 14000103c: 90 nop ++ 14000103d: 90 nop ++ 14000103e: 90 nop ++ 14000103f: 90 nop ++#pass +diff --git a/ld/testsuite/ld-pe/pr26659-weak-undef-sym.s b/ld/testsuite/ld-pe/pr26659-weak-undef-sym.s +new file mode 100644 +index 00000000000..7a42759e752 +--- /dev/null ++++ b/ld/testsuite/ld-pe/pr26659-weak-undef-sym.s +@@ -0,0 +1,38 @@ ++ .text ++ .globl foo ++ .def foo; .scl 2; .type 32; .endef ++foo: ++ pushq %rbp ++ movq %rsp, %rbp ++ subq $32, %rsp ++ movl %ecx, 16(%rbp) ++ movq .refptr.bar1(%rip), %rax ++ testq %rax, %rax ++ je .L2 ++ call bar1 ++.L2: ++ movq .refptr.bar2(%rip), %rax ++ testq %rax, %rax ++ je .L3 ++ call bar2 ++.L3: ++ movl 16(%rbp), %eax ++ imull %eax, %eax ++ addq $32, %rsp ++ popq %rbp ++ ret ++ .weak bar2 ++ .weak bar1 ++ .def bar1; .scl 2; .type 32; .endef ++ .def bar2; .scl 2; .type 32; .endef ++ .section .rdata$.refptr.bar2, "dr" ++ .globl .refptr.bar2 ++ .linkonce discard ++.refptr.bar2: ++ .quad bar2 ++ .section .rdata$.refptr.bar1, "dr" ++ .globl .refptr.bar1 ++ .linkonce discard ++.refptr.bar1: ++ .quad bar1 ++ +-- +2.27.0 + diff --git a/recipes-toolchain/binutils/2001-ld-option-to-move-default-bases-under-4GB.patch b/recipes-toolchain/binutils/2001-ld-option-to-move-default-bases-under-4GB.patch new file mode 100644 index 000000000..1594cc69f --- /dev/null +++ b/recipes-toolchain/binutils/2001-ld-option-to-move-default-bases-under-4GB.patch @@ -0,0 +1,142 @@ +From 613f4ee841ab6932a7c900d770765e42458d4d46 Mon Sep 17 00:00:00 2001 +From: Jeremy Drake +Date: Thu, 10 Sep 2020 10:28:28 -0700 +Subject: [PATCH] ld option to move default bases under 4GB. + +Some (buggy) programs have 'latent pointer truncation' issues, and +setting the ImageBase below 4GB indicates to Windows that it's not safe +to relocate these using ASLR in such a way as to trigger them. +--- + ld/emultempl/pep.em | 50 ++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 47 insertions(+), 3 deletions(-) + +diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em +index c6fd8b8f8d9..312f8d6d566 100644 +--- a/ld/emultempl/pep.em ++++ b/ld/emultempl/pep.em +@@ -132,18 +132,26 @@ fragment < +Date: Mon, 10 May 2021 11:28:15 +0100 +Subject: [PATCH] Restore old behaviour of windres so that options containing + spaces are not enclosed in double quotes. + + PR 4356 + PR 26865 + PR 27594 + * windres.c (quot): Revert previous delta. Do not use double + quotes when spaces are detected in options. + * doc/binutils.texi (windres): Remove suggestion that the + --preprocessor option can take arguments. + +Source (replayed to apply patch -R aftereffects): +https://github.com/msys2/MINGW-packages/commit/04805c092970de7f4b41b5aef6eece2723a56052 + +--- + binutils/doc/binutils.texi | 7 ++++--- + binutils/windres.c | 26 +++++++++++++++++++++++++- + 2 files changed, 29 insertions(+), 4 deletions(-) + +diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi +index e0028ee0..b506a020 100644 +--- a/binutils/doc/binutils.texi ++++ b/binutils/doc/binutils.texi +@@ -4450,7 +4450,8 @@ format, which is the first one listed by the @option{--help} option. + @item --preprocessor @var{program} + When @command{windres} reads an @code{rc} file, it runs it through the C + preprocessor first. This option may be used to specify the preprocessor +-to use. The default preprocessor is @code{gcc}. ++to use, including any leading arguments. The default preprocessor ++argument is @code{gcc}. + + @item --preprocessor-arg @var{option} + When @command{windres} reads an @code{rc} file, it runs it through +@@ -4461,8 +4462,8 @@ preprocessor command line. + If the @option{--preprocessor} option has not been specified then a + default set of preprocessor arguments will be used, with any + @option{--preprocessor-arg} options being placed after them on the +-command line. These default arguments are @code{-E}, +-@code{-xc-header} and @code{-DRC_INVOKED}. ++command line. These default arguments are @code{-E -xc-header ++-DRC_INVOKED}. + + @item -I @var{directory} + @itemx --include-dir @var{directory} +diff --git a/binutils/windres.c b/binutils/windres.c +index 3f691d3e..1e65e341 100644 +--- a/binutils/windres.c ++++ b/binutils/windres.c +@@ -710,13 +710,37 @@ quot (const char *string) + buf = (char *) xmalloc (buflen); + } + ++#if defined (_WIN32) && !defined (__CYGWIN__) ++ /* For Windows shells, quote "like this". */ ++ { ++ bool quoted = false; ++ ++ dest = buf; ++ if (strchr (string, ' ')) ++ { ++ quoted = true; ++ *dest++ = '"'; ++ } ++ ++ for (src = string; *src; src++, dest++) ++ { ++ /* Escape-protect embedded double quotes. */ ++ if (quoted && *src == '"') ++ *dest++ = '\\'; ++ *dest = *src; ++ } ++ ++ if (quoted) ++ *dest++ = '"'; ++ } ++#else + for (src = string, dest = buf; *src; src++, dest++) + { + if (*src == '(' || *src == ')' || *src == ' ') + *dest++ = '\\'; + *dest = *src; + } +- ++#endif + *dest = 0; + return buf; + } +-- +2.44.0.windows.1 + diff --git a/recipes-toolchain/binutils/3001-hack-libiberty-link-order.patch b/recipes-toolchain/binutils/3001-hack-libiberty-link-order.patch new file mode 100644 index 000000000..44a3dba1a --- /dev/null +++ b/recipes-toolchain/binutils/3001-hack-libiberty-link-order.patch @@ -0,0 +1,40 @@ +From a58851f8b6dbc5708349d08fc5216db5bd9466ae Mon Sep 17 00:00:00 2001 +From: Christoph Reiter +Date: Tue, 30 Jan 2024 08:16:34 +0100 +Subject: [PATCH] binutils: Update to 2.42 + +Remove all backports which are included in this new release. + +Remove specify-timestamp.patch, looks like this was implemented upstream +in: +https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=6badd1020f5bebd3f +and it seems to work here. + +Work around binutils linking against the system libiberty instead of +the included one. + +Also binutils now links against libintl, so add gettext as a dependency + +See: https://github.com/msys2/MINGW-packages/commit/ffc97b98c28d074f697561fdadcd3798a5caca3a +--- + ld/Makefile.in | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/ld/Makefile.in b/ld/Makefile.in +index abb05657..cb082c8a 100644 +--- a/ld/Makefile.in ++++ b/ld/Makefile.in +@@ -1038,8 +1038,8 @@ ld_new_SOURCES = ldgram.y ldlex-wrapper.c lexsup.c ldlang.c mri.c ldctor.c ldmai + ld_new_DEPENDENCIES = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) \ + $(BFDLIB) $(LIBCTF) $(LIBIBERTY) $(LIBINTL_DEP) $(JANSSON_LIBS) + +-ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBCTF) \ +- $(LIBIBERTY) $(LIBINTL) $(ZLIB) $(ZSTD_LIBS) $(JANSSON_LIBS) ++ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(LIBIBERTY) $(BFDLIB) $(LIBCTF) \ ++ $(LIBINTL) $(ZLIB) $(ZSTD_LIBS) $(JANSSON_LIBS) + + # + # +-- +2.44.0.windows.1 + diff --git a/recipes-toolchain/binutils/libiberty-unlink-handle-windows-nul.patch b/recipes-toolchain/binutils/libiberty-unlink-handle-windows-nul.patch new file mode 100644 index 000000000..b4edfd2d5 --- /dev/null +++ b/recipes-toolchain/binutils/libiberty-unlink-handle-windows-nul.patch @@ -0,0 +1,32 @@ +From 1a5d638ff6179dbddaf02f381d8e2b55d47deeb9 Mon Sep 17 00:00:00 2001 +From: Himal <1590311+himalr@users.noreply.github.com> +Date: Mon, 9 Jan 2023 08:48:42 +0530 +Subject: [PATCH] binutils-handle-windows-nul + +Source: + +https://github.com/msys2/MINGW-packages/pull/14775 +--- + libiberty/unlink-if-ordinary.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/libiberty/unlink-if-ordinary.c b/libiberty/unlink-if-ordinary.c +index 0816ceb8..31cfca2b 100644 +--- a/libiberty/unlink-if-ordinary.c ++++ b/libiberty/unlink-if-ordinary.c +@@ -62,6 +62,12 @@ was made to unlink the file because it is special. + int + unlink_if_ordinary (const char *name) + { ++/* MS-Windows 'stat' function (and in turn, S_ISREG) ++ reports the null device as a regular file. */ ++#ifdef _WIN32 ++ if (stricmp (name, "nul") == 0) ++ return 1; ++#endif + struct stat st; + + if (lstat (name, &st) == 0 +-- +2.44.0.windows.1 + diff --git a/recipes-toolchain/binutils/reproducible-import-libraries.patch b/recipes-toolchain/binutils/reproducible-import-libraries.patch new file mode 100644 index 000000000..343f0fac0 --- /dev/null +++ b/recipes-toolchain/binutils/reproducible-import-libraries.patch @@ -0,0 +1,40 @@ +From ee527dfc08ba380c781564dd8b874b60f91694d5 Mon Sep 17 00:00:00 2001 +From: Christoph Reiter +Date: Mon, 16 Aug 2021 08:17:06 +0200 +Subject: [PATCH] binutils: take reproducibility patches from debian + +It's a nice property to have. + +They also use --enable-deterministic-archives, so do that too. + +---- + +Description: Make DLL import libraries reproducible +Author: Benjamin Moody +Bug-Debian: https://bugs.debian.org/915055 + +Index: binutils-mingw-w64/upstream/ld/pe-dll.c + +---- + +Source: +https://github.com/msys2/MINGW-packages/commit/c24c06db7bb7f19b9420a27bb77ba37ceeb4dffd +--- + ld/pe-dll.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ld/pe-dll.c b/ld/pe-dll.c +index 95eef84f..c55f4412 100644 +--- a/ld/pe-dll.c ++++ b/ld/pe-dll.c +@@ -2945,6 +2945,7 @@ pe_dll_generate_implib (def_file *def, const char *impfilename, struct bfd_link_ + + bfd_set_format (outarch, bfd_archive); + outarch->has_armap = 1; ++ outarch->flags |= BFD_DETERMINISTIC_OUTPUT; + + /* Work out a reasonable size of things to put onto one line. */ + ar_head = make_head (outarch); +-- +2.44.0.windows.1 + diff --git a/recipes-toolchain/gcc-bootstrap.recipe b/recipes-toolchain/gcc-bootstrap.recipe index d1727553f..c37ad7270 100644 --- a/recipes-toolchain/gcc-bootstrap.recipe +++ b/recipes-toolchain/gcc-bootstrap.recipe @@ -1,15 +1,15 @@ -from cerbero.utils import shell +from pathlib import Path # This recipe bootstraps an initial compiler that is used # for the cross-toolchain to compile the CRT before the # real final compiler. class Recipe(recipe.Recipe): name = 'gcc-bootstrap' - version = '8.2.0' + version = '14.2.0' stype = SourceType.CUSTOM licenses = [License.GPLv3Plus] - configure_options = '--with-newlib ' \ - '--disable-maintainer-mode ' \ + override_libtool = False + configure_options = '--disable-maintainer-mode ' \ '--with-host-libstdcxx=\'-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm\' ' \ '--disable-shared ' \ '--disable-libgomp ' \ @@ -22,17 +22,10 @@ class Recipe(recipe.Recipe): '--enable-threads=no ' \ '--enable-__cxa_atexit ' \ '--enable-lto ' \ - '--enable-languages=c ' \ + '--enable-languages=c,c++,lto ' \ '--enable-multiarch ' \ '' - make = 'make configure-gcc configure-libcpp configure-build-libiberty &&' \ - 'make all-libcpp all-build-libiberty && '\ - 'make configure-libdecnumber && '\ - 'make -C libdecnumber libdecnumber.a && '\ - 'make configure-libbacktrace && '\ - 'make -C libbacktrace && '\ - 'make all-gcc all-target-libgcc' - make_install = 'make install-gcc install-target-libgcc' + requires_non_src_build = True use_system_libs = True add_host_build_target = False deps = ['gcc-sources', 'mingw-w64-headers', 'gmp', 'mpfr', 'mpc', 'isl'] @@ -40,25 +33,23 @@ class Recipe(recipe.Recipe): def prepare(self): if self.config.target_arch == Architecture.X86: raise InvalidRecipeError(self) - self.set_env('CPP') self._target = 'x86_64-w64-mingw32' - sysroot = os.path.join(self.config.prefix, self._target, 'sysroot') - self.configure_options += ' --with-sysroot=%s ' % sysroot - self.configure_options += ' --with-local-prefix=%s ' % sysroot + self.sysroot = f'{self.config.prefix}/{self._target}/sysroot' + self.configure_options += f' --with-sysroot={self.sysroot} ' + self.configure_options += f' --with-local-prefix={self.sysroot} ' + self.configure_options += f' --with-native-system-header-dir=/usr/{self._target}/include ' self.configure_options += ' --target=%s' % self._target if self.config.target_platform == Platform.WINDOWS: self.configure_options += ' --host=%s' % self._target - if self.config.target_platform == Platform.WINDOWS: - self.allow_parallel_build = False - self.build_dir = os.path.join(self.config.sources, - 'gcc-%s' % self.version) - self.make_dir = os.path.join(self.build_dir, 'gcc_build_core') - self.config_sh = os.path.join(self.config.sources, - 'gcc-%s' % self.version, 'configure') + self.config_src_dir = os.path.join(self.config.sources, f'gcc-sources-{self.version}') + self.build_dir = os.path.join(self.config_src_dir, 'gcc_build_core') + self.make_dir = self.build_dir + self.make += ['all-gcc'] + self.make_install = ['install-strip-gcc' if i == 'install' else i for i in self.make_install] async def configure(self): - try: - os.mkdir(self.make_dir) - except: - pass + # https://github.com/msys2/MINGW-packages/commit/54101537025a9a3a381a1e292fb9bc967e374bd2 + header = os.path.join(self.config_src_dir, 'gcc/config/i386/mingw32.h') + shell.replace(header, {'/mingw': f'/usr/{self._target}'}) + Path(self.make_dir).mkdir(exist_ok=True) await super(Recipe, self).configure() diff --git a/recipes-toolchain/gcc-sources.recipe b/recipes-toolchain/gcc-sources.recipe index e0715ca52..6c38cef9e 100644 --- a/recipes-toolchain/gcc-sources.recipe +++ b/recipes-toolchain/gcc-sources.recipe @@ -4,16 +4,31 @@ from cerbero.utils import shell # will be used by gcc-bootstrap and gcc recipes class Recipe(recipe.Recipe): name = 'gcc-sources' - version = '8.2.0' - url = 'https://ftpmirror.gnu.org/gnu/gcc/gcc-8.2.0/gcc-%(version)s.tar.xz' - tarball_checksum = '196c3c04ba2613f893283977e6011b2345d1cd1af9abeac58e916b1aab3e0080' + version = '14.2.0' + url = 'https://ftpmirror.gnu.org/gnu/gcc/gcc-%(version)s/gcc-%(version)s.tar.xz' + tarball_checksum = 'a7b39bc69cbf9e25826c5a60ab26477001f7c08d85cec04bc0e29cabed6f3cc9' stype = SourceType.TARBALL btype = BuildType.CUSTOM licenses = [License.GPLv3Plus] - patches = ['gcc/0001-Fix-graphite-build-with-isl-0.20.patch', - 'gcc/0002-Disable-split-stack-for-non-thread-builds.patch', - 'gcc/0003-Force-SEH-SJLJ.patch', - ] + autoreconf = True + patches = [ + f'{name}/0003-Windows-Follow-Posix-dir-exists-semantics-more-close.patch', + f'{name}/0005-Windows-Don-t-ignore-native-system-header-dir.patch', + f'{name}/0007-Build-EXTRA_GNATTOOLS-for-Ada.patch', + f'{name}/0008-Prettify-linking-no-undefined.patch', + f'{name}/0011-Enable-shared-gnat-implib.patch', + f'{name}/0012-Handle-spaces-in-path-for-default-manifest.patch', + f'{name}/0014-gcc-9-branch-clone_function_name_1-Retain-any-stdcall-suffix.patch', + f'{name}/0020-libgomp-Don-t-hard-code-MS-printf-attributes.patch', + f'{name}/0021-PR14940-Allow-a-PCH-to-be-mapped-to-a-different-addr.patch', + f'{name}/0140-gcc-Enable-diagnostic-colors-under-mintty.patch', + f'{name}/0200-add-m-no-align-vector-insn-option-for-i386.patch', + f'{name}/2001-gcc-update-to-14.1.0.patch', + f'{name}/9999-gcc-build-without-sysroot-hack.patch', + f'{name}/10000-gcc-cp-Make-lang.in-Fix-spurious-directory-separator.patch', + ] + tarball_dirname = 'gcc-%(version)s' + override_libtool = False def prepare(self): if self.config.target_arch == Architecture.X86: diff --git a/recipes-toolchain/gcc-sources/0003-Windows-Follow-Posix-dir-exists-semantics-more-close.patch b/recipes-toolchain/gcc-sources/0003-Windows-Follow-Posix-dir-exists-semantics-more-close.patch new file mode 100644 index 000000000..8d5c2dd73 --- /dev/null +++ b/recipes-toolchain/gcc-sources/0003-Windows-Follow-Posix-dir-exists-semantics-more-close.patch @@ -0,0 +1,131 @@ +From 45ca3b9cdd964ec448c2ca56d5258983aef2722b Mon Sep 17 00:00:00 2001 +From: Ray Donnelly +Date: Wed, 5 Aug 2015 23:36:07 +0100 +Subject: [PATCH 02/16] Windows: Follow Posix dir-exists semantics more closely + +Make Windows behave the same as Posix in the consideration +of whether folder "/doesnt-exist/.." is a valid +path. In Posix, it isn't. + +A concrete instance of when this matters is when cross +compiling GNU/Linux glibc on Windows. +--- + libcpp/files.cc | 87 +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 87 insertions(+) + +diff --git a/libcpp/files.cc b/libcpp/files.cc +index 24208f7b0f8..a740d7a778c 100644 +--- a/libcpp/files.cc ++++ b/libcpp/files.cc +@@ -30,6 +30,14 @@ along with this program; see the file COPYING3. If not see + #include "md5.h" + #include + ++/* Needed for stat_st_mode_symlink below */ ++#if defined(_WIN32) ++# define WIN32_LEAN_AND_MEAN ++# include ++# define S_IFLNK 0xF000 ++# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) ++#endif ++ + /* Variable length record files on VMS will have a stat size that includes + record control characters that won't be included in the read size. */ + #ifdef VMS +@@ -200,6 +207,49 @@ static int pchf_save_compare (const void *e1, const void *e2); + static int pchf_compare (const void *d_p, const void *e_p); + static bool check_file_against_entries (cpp_reader *, _cpp_file *, bool); + ++#if defined(_WIN32) ++ ++static int stat_st_mode_symlink (char const* path, struct stat* buf) ++{ ++ WIN32_FILE_ATTRIBUTE_DATA attr; ++ memset(buf,0,sizeof(*buf)); ++ int err = GetFileAttributesExA (path, GetFileExInfoStandard, &attr) ? 0 : 1; ++ if (!err) ++ { ++ WIN32_FIND_DATAA finddata; ++ HANDLE h = FindFirstFileA (path, &finddata); ++ if (h != INVALID_HANDLE_VALUE) ++ { ++ FindClose (h); ++ if ((finddata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) && ++ (finddata.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) ++ buf->st_mode = S_IFLNK; ++ else if (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ++ buf->st_mode = S_IFDIR; ++ else if (finddata.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) ++ buf->st_mode = S_IFDIR; ++ else ++ buf->st_mode = S_IFREG; ++ buf->st_mode |= S_IREAD; ++ if (!(finddata.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) ++ buf->st_mode |= S_IWRITE; ++ } ++ else ++ { ++ buf->st_mode = S_IFDIR; ++ } ++ return 0; ++ } ++ return -1; ++} ++ ++#else ++ ++#define stat_st_mode_symlink (_name, _buf) stat ((_name), (_buf)) ++ ++#endif ++ ++ + /* Given a filename in FILE->PATH, with the empty string interpreted + as , open it. + +@@ -229,6 +279,43 @@ open_file (_cpp_file *file) + } + else + file->fd = open (file->path, O_RDONLY | O_NOCTTY | O_BINARY, 0666); ++#if defined(_WIN32) || defined(__CYGWIN__) ++ /* Windows and Posix differ in the face of paths of the form: ++ nonexistantdir/.. in that Posix will return ENOENT whereas ++ Windows won't care that we stepped into a non-existant dir ++ Only do these slow checks if ".." appears in file->path. ++ Cygwin also suffers from the same problem (but doesn't need ++ a new stat function): ++ http://cygwin.com/ml/cygwin/2013-05/msg00222.html ++ */ ++ if (file->fd > 0) ++ { ++ char filepath[MAX_PATH]; ++ strncpy (filepath, file->path, sizeof(filepath) - 1); ++ char* dirsep = &filepath[0]; ++ while ( (dirsep = strchr (dirsep, '\\')) != NULL) ++ *dirsep = '/'; ++ if (strstr(file->path, "/../")) ++ { ++ dirsep = &filepath[0]; ++ char dirsepc; ++ /* Check each directory in the chain. */ ++ while ( (dirsep = strpbrk (dirsep, "\\/")) != NULL) ++ { ++ dirsepc = *(++dirsep); ++ *dirsep = '\0'; ++ if (stat_st_mode_symlink (filepath, &file->st) == -1) ++ { ++ *dirsep = dirsepc; ++ close (file->fd); ++ file->fd = -1; ++ return false; ++ } ++ *dirsep++ = dirsepc; ++ } ++ } ++ } ++#endif + + if (file->fd != -1) + { +-- +2.38.1 + diff --git a/recipes-toolchain/gcc-sources/0005-Windows-Don-t-ignore-native-system-header-dir.patch b/recipes-toolchain/gcc-sources/0005-Windows-Don-t-ignore-native-system-header-dir.patch new file mode 100644 index 000000000..4e30623ad --- /dev/null +++ b/recipes-toolchain/gcc-sources/0005-Windows-Don-t-ignore-native-system-header-dir.patch @@ -0,0 +1,28 @@ +From 7b42c392145bfebc79a5a8dce77dc61f09290a32 Mon Sep 17 00:00:00 2001 +From: Ray Donnelly +Date: Wed, 5 Aug 2015 23:36:11 +0100 +Subject: [PATCH 04/16] Windows: Don't ignore native system header dir + +--- + gcc/config.gcc | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/gcc/config.gcc b/gcc/config.gcc +index 2fbf2e6fa69..f950ba56edc 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -2138,7 +2138,10 @@ i[34567]86-*-mingw* | x86_64-*-mingw*) + tmake_file="${tmake_file} i386/t-mingw-w32" + ;; + esac +- native_system_header_dir=/mingw/include ++ # Don't ignore values passed in to configure via --native-system-header-dir ++ if test x$native_system_header_dir = x ; then ++ native_system_header_dir=/mingw/include ++ fi + target_gtfiles="$target_gtfiles \$(srcdir)/config/i386/winnt.cc" + extra_options="${extra_options} i386/cygming.opt i386/mingw.opt" + case ${target} in +-- +2.38.1 + diff --git a/recipes-toolchain/gcc-sources/0007-Build-EXTRA_GNATTOOLS-for-Ada.patch b/recipes-toolchain/gcc-sources/0007-Build-EXTRA_GNATTOOLS-for-Ada.patch new file mode 100644 index 000000000..6450d9597 --- /dev/null +++ b/recipes-toolchain/gcc-sources/0007-Build-EXTRA_GNATTOOLS-for-Ada.patch @@ -0,0 +1,34 @@ +From a7c1041c3138dba8fa811490852f37b236a7f368 Mon Sep 17 00:00:00 2001 +From: Alexey Pavlov +Date: Wed, 5 Aug 2015 23:36:17 +0100 +Subject: [PATCH 06/16] Build EXTRA_GNATTOOLS for Ada + +--- + gnattools/Makefile.in | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gnattools/Makefile.in b/gnattools/Makefile.in +index e8fc4af0788..f0daadbc1d7 100644 +--- a/gnattools/Makefile.in ++++ b/gnattools/Makefile.in +@@ -201,7 +201,7 @@ gnattools-native: $(GCC_DIR)/stamp-tools $(GCC_DIR)/stamp-gnatlib-rts + ../../gnatmake$(exeext) ../../gnatlink$(exeext) + # gnattools2 + $(MAKE) -C $(GCC_DIR)/ada/tools -f ../Makefile \ +- $(TOOLS_FLAGS_TO_PASS_NATIVE) common-tools ++ $(TOOLS_FLAGS_TO_PASS_NATIVE) common-tools $(EXTRA_GNATTOOLS) + + # gnatmake/link can be built with recent gnatmake/link if they are available. + # This is especially convenient for building cross tools or for rebuilding +@@ -213,7 +213,7 @@ regnattools: $(GCC_DIR)/stamp-gnatlib-rts + gnatmake-re gnatlink-re + # gnattools2 + $(MAKE) -C $(GCC_DIR)/ada/tools -f ../Makefile \ +- $(TOOLS_FLAGS_TO_PASS_NATIVE) common-tools ++ $(TOOLS_FLAGS_TO_PASS_NATIVE) common-tools $(EXTRA_GNATTOOLS) + + gnattools-cross: $(GCC_DIR)/stamp-tools + # gnattools1-re +-- +2.38.1 + diff --git a/recipes-toolchain/gcc-sources/0008-Prettify-linking-no-undefined.patch b/recipes-toolchain/gcc-sources/0008-Prettify-linking-no-undefined.patch new file mode 100644 index 000000000..dec5f82b3 --- /dev/null +++ b/recipes-toolchain/gcc-sources/0008-Prettify-linking-no-undefined.patch @@ -0,0 +1,41 @@ +From e3d18c5f5b7ffb28146d7d7efef480ccedc4be26 Mon Sep 17 00:00:00 2001 +From: Alexey Pavlov +Date: Wed, 5 Aug 2015 23:36:19 +0100 +Subject: [PATCH 07/16] Prettify linking -no-undefined + +It might be better to put this change in a +conditional block for Windows only? +--- + libgfortran/Makefile.am | 2 +- + libgfortran/Makefile.in | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am +index 454ad12e701..cb02b417e6b 100644 +--- a/libgfortran/Makefile.am ++++ b/libgfortran/Makefile.am +@@ -57,7 +57,7 @@ libgfortran_la_DEPENDENCIES = $(version_dep) libgfortran.spec $(LIBQUADLIB_DEP) + cafexeclib_LTLIBRARIES = libcaf_single.la + cafexeclibdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR) + libcaf_single_la_SOURCES = caf/single.c +-libcaf_single_la_LDFLAGS = -static ++libcaf_single_la_LDFLAGS = -static -no-undefined + libcaf_single_la_DEPENDENCIES = caf/libcaf.h + libcaf_single_la_LINK = $(LINK) $(libcaf_single_la_LDFLAGS) + +diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in +index 23df0761096..14b78ed3569 100644 +--- a/libgfortran/Makefile.in ++++ b/libgfortran/Makefile.in +@@ -767,7 +767,7 @@ libgfortran_la_DEPENDENCIES = $(version_dep) libgfortran.spec $(LIBQUADLIB_DEP) + cafexeclib_LTLIBRARIES = libcaf_single.la + cafexeclibdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR) + libcaf_single_la_SOURCES = caf/single.c +-libcaf_single_la_LDFLAGS = -static ++libcaf_single_la_LDFLAGS = -static -no-undefined + libcaf_single_la_DEPENDENCIES = caf/libcaf.h + libcaf_single_la_LINK = $(LINK) $(libcaf_single_la_LDFLAGS) + @IEEE_SUPPORT_TRUE@fincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR)/finclude +-- +2.38.1 + diff --git a/recipes-toolchain/gcc-sources/0011-Enable-shared-gnat-implib.patch b/recipes-toolchain/gcc-sources/0011-Enable-shared-gnat-implib.patch new file mode 100644 index 000000000..3a953c8cd --- /dev/null +++ b/recipes-toolchain/gcc-sources/0011-Enable-shared-gnat-implib.patch @@ -0,0 +1,38 @@ +From c0af45f4c4b03154ea5ade26d02e1561223b63d4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=BCrgen=20Pfeifer?= +Date: Wed, 5 Aug 2015 23:36:27 +0100 +Subject: [PATCH 09/16] Enable shared gnat implib + +Provide GNAT runtime import libraries to +allow to link against shared runtime + +Original commit: +https://github.com/Alexpux/MINGW-packages/commit/51b4eb3b702fdb38df0460180c2f8209a686aaec +--- + gcc/ada/gcc-interface/Makefile.in | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in +index 6b19b8be58e..7a7d4eeb18f 100644 +--- a/gcc/ada/gcc-interface/Makefile.in ++++ b/gcc/ada/gcc-interface/Makefile.in +@@ -764,12 +764,15 @@ gnatlib-shared-win32: + $(PICFLAG_FOR_TARGET) \ + -o libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) \ + $(GNATRTL_NONTASKING_OBJS) $(LIBGNAT_OBJS) \ +- $(SO_OPTS)libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) $(MISCLIB) ++ $(SO_OPTS)libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) \ ++ -Wl,-out-implib,libgnat$(hyphen)$(LIBRARY_VERSION).dll.a \ ++ $(MISCLIB) + cd $(RTSDIR); $(GCC_FOR_ADA_RTS) -shared -shared-libgcc \ + $(PICFLAG_FOR_TARGET) \ + -o libgnarl$(hyphen)$(LIBRARY_VERSION)$(soext) \ + $(GNATRTL_TASKING_OBJS) \ + $(SO_OPTS)libgnarl$(hyphen)$(LIBRARY_VERSION)$(soext) \ ++ -Wl,-out-implib,libgnarl$(hyphen)$(LIBRARY_VERSION).dll.a \ + $(THREADSLIB) -Wl,libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) + + gnatlib-shared-darwin: +-- +2.38.1 + diff --git a/recipes-toolchain/gcc-sources/0012-Handle-spaces-in-path-for-default-manifest.patch b/recipes-toolchain/gcc-sources/0012-Handle-spaces-in-path-for-default-manifest.patch new file mode 100644 index 000000000..adc926b35 --- /dev/null +++ b/recipes-toolchain/gcc-sources/0012-Handle-spaces-in-path-for-default-manifest.patch @@ -0,0 +1,60 @@ +From 7bb1c4dfb29899729c13376cbae8393f201f1e83 Mon Sep 17 00:00:00 2001 +From: Olivier Michel +Date: Fri, 31 May 2019 15:07:06 +0200 +Subject: [PATCH 10/16] Handle spaces in path for default manifest + +--- + gcc/gcc.cc | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/gcc/gcc.cc b/gcc/gcc.cc +index afb23cd07b0..8eee9345afe 100644 +--- a/gcc/gcc.cc ++++ b/gcc/gcc.cc +@@ -6829,7 +6829,6 @@ eval_spec_function (const char *func, const char *args, + int save_arg_going; + int save_delete_this_arg; + int save_this_is_output_file; +- int save_this_is_library_file; + int save_input_from_pipe; + int save_this_is_linker_script; + const char *save_suffix_subst; +@@ -6847,7 +6846,6 @@ eval_spec_function (const char *func, const char *args, + save_arg_going = arg_going; + save_delete_this_arg = delete_this_arg; + save_this_is_output_file = this_is_output_file; +- save_this_is_library_file = this_is_library_file; + save_this_is_linker_script = this_is_linker_script; + save_input_from_pipe = input_from_pipe; + save_suffix_subst = suffix_subst; +@@ -6879,13 +6877,15 @@ eval_spec_function (const char *func, const char *args, + argbuf.address ()); + + /* Pop the spec processing context. */ ++ const char *saved_library_file = this_is_library_file ? argbuf.address()[0] : NULL; + argbuf.release (); + argbuf = save_argbuf; ++ if (saved_library_file) ++ argbuf.safe_push (saved_library_file); + + arg_going = save_arg_going; + delete_this_arg = save_delete_this_arg; + this_is_output_file = save_this_is_output_file; +- this_is_library_file = save_this_is_library_file; + this_is_linker_script = save_this_is_linker_script; + input_from_pipe = save_input_from_pipe; + suffix_subst = save_suffix_subst; +@@ -6957,8 +6957,9 @@ handle_spec_function (const char *p, bool *retval_nonnull, + /* p now points to just past the end of the spec function expression. */ + + funcval = eval_spec_function (func, args, soft_matched_part); +- if (funcval != NULL && do_spec_1 (funcval, 0, NULL) < 0) ++ if (funcval != NULL && this_is_library_file == 0 && do_spec_1 (funcval, 0, NULL) < 0) + p = NULL; ++ + if (retval_nonnull) + *retval_nonnull = funcval != NULL; + +-- +2.38.1 + diff --git a/recipes-toolchain/gcc-sources/0014-gcc-9-branch-clone_function_name_1-Retain-any-stdcall-suffix.patch b/recipes-toolchain/gcc-sources/0014-gcc-9-branch-clone_function_name_1-Retain-any-stdcall-suffix.patch new file mode 100644 index 000000000..cbb82d017 --- /dev/null +++ b/recipes-toolchain/gcc-sources/0014-gcc-9-branch-clone_function_name_1-Retain-any-stdcall-suffix.patch @@ -0,0 +1,108 @@ +From 8b5e94ebdce49fc8f7a0926a695110e83cc408ad Mon Sep 17 00:00:00 2001 +From: Ray Donnelly +Date: Mon, 17 Aug 2015 22:57:46 +0100 +Subject: [PATCH 11/16] clone_function_name_1: Retain any stdcall suffix + +Previously, clone_function_name_1 would add a suffix after +any existing stdcall suffix, for example ipa-split.c would +clone test@4 as test@4.part.0. + +Later, i386_pe_strip_name_encoding_full would come along +and strip off everything from the last @ onwards which had +the effect of generating incorrect section names which +would then fall over with errors such as: + +error: void test() causes a section type conflict with \ + void test@4.part.0() + +The following testcase, reduced from Firefox can be used +to reproduce this. + +test.ii: +class ClassA { +public: + virtual int __attribute__((__stdcall__)) Dispatch() = 0; +}; +class ClassB { +public: + ClassA* __attribute__((__stdcall__)) operator->(); +}; +class ClassC : ClassA { + int *some_int_ptr_variable; + int __attribute__((__stdcall__)) Dispatch() { + return some_int_ptr_variable + ? 42 + : m_ClassInstanceB->Dispatch(); + } + ClassB m_ClassInstanceB; +}; +ClassC ClassInstanceC; + +Compile for i686-w64-mingw32 with: +cc1plus -O -fpartial-inlining -fdevirtualize \ + -fdevirtualize-speculatively test.ii + +Outputs: +test.ii: In member function 'virtual int ClassC::Dispatch()': +test.ii:11:36: error: virtual int ClassC::Dispatch() causes \ + a section type conflict with int ClassC::_ZN6ClassC8DispatchEv@4.part.0() + int __attribute__((CALLTYPE)) Dispatch() { + ^ +test.ii:11:36: note: \ + 'int ClassC::_ZN6ClassC8DispatchEv@4.part.0()' was declared here +--- + gcc/cgraphclones.cc | 13 ++++++++++++- + gcc/defaults.h | 2 +- + 2 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc +index eb0fa87b554..3bde7e6957e 100644 +--- a/gcc/cgraphclones.cc ++++ b/gcc/cgraphclones.cc +@@ -470,7 +470,8 @@ static GTY(()) hash_map *clone_fn_ids; + each NAME) unspecified number. If clone numbering is not needed + then the two argument clone_function_name should be used instead. + Should not be called directly except for by +- lto-partition.cc:privatize_symbol_name_1. */ ++ lto-partition.cc:privatize_symbol_name_1. Final stdcall @N suffixes ++ are maintained. */ + + tree + clone_function_name_numbered (const char *name, const char *suffix) +@@ -511,10 +512,20 @@ clone_function_name (const char *name, const char *suffix, + char *tmp_name, *prefix; + + prefix = XALLOCAVEC (char, len + strlen (suffix) + 2); ++ /* name + 1 to skip fastcall which begins with '@' */ ++ const char *at_suffix = strchr (name + 1, '@'); ++ size_t at_suffix_len = 0; ++ if (at_suffix) ++ { ++ at_suffix_len = strlen (at_suffix); ++ len -= at_suffix_len; ++ } + memcpy (prefix, name, len); + strcpy (prefix + len + 1, suffix); + prefix[len] = symbol_table::symbol_suffix_separator (); + ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, number); ++ if (at_suffix) ++ strcat (tmp_name, at_suffix); + return get_identifier (tmp_name); + } + +diff --git a/gcc/defaults.h b/gcc/defaults.h +index 376687d91b1..be29e4b7c60 100644 +--- a/gcc/defaults.h ++++ b/gcc/defaults.h +@@ -51,7 +51,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + # define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ + do { const char *const name_ = (NAME); \ + char *const output_ = (OUTPUT) = \ +- (char *) alloca (strlen (name_) + 32); \ ++ (char *) alloca (strlen (name_) + 35); \ + sprintf (output_, ASM_PN_FORMAT, name_, (unsigned long)(LABELNO)); \ + } while (0) + #endif +-- +2.38.1 + diff --git a/recipes-toolchain/gcc-sources/0020-libgomp-Don-t-hard-code-MS-printf-attributes.patch b/recipes-toolchain/gcc-sources/0020-libgomp-Don-t-hard-code-MS-printf-attributes.patch new file mode 100644 index 000000000..08034b2f1 --- /dev/null +++ b/recipes-toolchain/gcc-sources/0020-libgomp-Don-t-hard-code-MS-printf-attributes.patch @@ -0,0 +1,53 @@ +From f00621c645ca24f8d228bac7b1dbb5763d1f4db3 Mon Sep 17 00:00:00 2001 +From: Liu Hao +Date: Wed, 6 May 2020 21:49:18 +0800 +Subject: [PATCH 12/16] libgomp: Don't hard-code MS printf attributes + +--- + libgomp/libgomp.h | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h +index 75192749dc7..add858d2cd3 100644 +--- a/libgomp/libgomp.h ++++ b/libgomp/libgomp.h +@@ -69,6 +69,13 @@ + # endif + #endif + ++#include ++#ifdef __MINGW_PRINTF_FORMAT ++#define PRINTF_FORMAT __MINGW_PRINTF_FORMAT ++#else ++#define PRINTF_FORMAT printf ++#endif ++ + #ifdef HAVE_ATTRIBUTE_VISIBILITY + # pragma GCC visibility push(hidden) + #endif +@@ -176,7 +183,7 @@ team_free (void *ptr) + + extern void gomp_vdebug (int, const char *, va_list); + extern void gomp_debug (int, const char *, ...) +- __attribute__ ((format (printf, 2, 3))); ++ __attribute__ ((format (PRINTF_FORMAT, 2, 3))); + #define gomp_vdebug(KIND, FMT, VALIST) \ + do { \ + if (__builtin_expect (gomp_debug_var, 0)) \ +@@ -189,11 +196,11 @@ extern void gomp_debug (int, const char *, ...) + } while (0) + extern void gomp_verror (const char *, va_list); + extern void gomp_error (const char *, ...) +- __attribute__ ((format (printf, 1, 2))); ++ __attribute__ ((format (PRINTF_FORMAT, 1, 2))); + extern void gomp_vfatal (const char *, va_list) + __attribute__ ((noreturn)); + extern void gomp_fatal (const char *, ...) +- __attribute__ ((noreturn, format (printf, 1, 2))); ++ __attribute__ ((noreturn, format (PRINTF_FORMAT, 1, 2))); + + struct gomp_task; + struct gomp_taskgroup; +-- +2.38.1 + diff --git a/recipes-toolchain/gcc-sources/0021-PR14940-Allow-a-PCH-to-be-mapped-to-a-different-addr.patch b/recipes-toolchain/gcc-sources/0021-PR14940-Allow-a-PCH-to-be-mapped-to-a-different-addr.patch new file mode 100644 index 000000000..d0269a9c5 --- /dev/null +++ b/recipes-toolchain/gcc-sources/0021-PR14940-Allow-a-PCH-to-be-mapped-to-a-different-addr.patch @@ -0,0 +1,76 @@ +From cbe91a182184704e76eeac8d47cad7aaff5c9f24 Mon Sep 17 00:00:00 2001 +From: LIU Hao +Date: Wed, 11 May 2022 22:42:53 +0800 +Subject: [PATCH 13/16] Allow a PCH to be mapped to a different address + +First, try mapping the PCH to its original address. If that fails, try +letting the system choose one; the PCH can be relocated thereafter. + +Reference: https://gcc.gnu.org/pipermail/gcc-patches/2022-May/594556.html + +2022-05-11 LIU Hao + + PR pch/14940 + * config/i386/host-mingw32.cc (mingw32_gt_pch_use_address): + Replace the loop that attempted to map the PCH only to its + original address with more adaptive operations +--- + gcc/config/i386/host-mingw32.cc | 32 +++++++++++++++----------------- + 1 file changed, 15 insertions(+), 17 deletions(-) + +diff --git a/gcc/config/i386/host-mingw32.cc b/gcc/config/i386/host-mingw32.cc +index f915b85abd0..cb254629029 100644 +--- a/gcc/config/i386/host-mingw32.cc ++++ b/gcc/config/i386/host-mingw32.cc +@@ -135,7 +135,6 @@ mingw32_gt_pch_use_address (void *&addr, size_t size, int fd, + and earlier, backslashes are invalid in object name. So, we need + to check if we are on Windows2000 or higher. */ + OSVERSIONINFO version_info; +- int r; + + version_info.dwOSVersionInfoSize = sizeof (version_info); + +@@ -169,25 +168,24 @@ mingw32_gt_pch_use_address (void *&addr, size_t size, int fd, + return -1; + } + +- /* Retry five times, as here might occure a race with multiple gcc's +- instances at same time. */ +- for (r = 0; r < 5; r++) +- { +- mmap_addr = MapViewOfFileEx (mmap_handle, FILE_MAP_COPY, 0, offset, +- size, addr); +- if (mmap_addr == addr) +- break; +- if (r != 4) +- Sleep (500); +- } +- +- if (mmap_addr != addr) ++ /* Try mapping the file at `addr`. */ ++ mmap_addr = MapViewOfFileEx (mmap_handle, FILE_MAP_COPY, 0, offset, ++ size, addr); ++ if (mmap_addr == NULL) + { +- w32_error (__FUNCTION__, __FILE__, __LINE__, "MapViewOfFileEx"); +- CloseHandle(mmap_handle); +- return -1; ++ /* We could not map the file at its original address, so let the ++ system choose a different one. The PCH can be relocated later. */ ++ mmap_addr = MapViewOfFileEx (mmap_handle, FILE_MAP_COPY, 0, offset, ++ size, NULL); ++ if (mmap_addr == NULL) ++ { ++ w32_error (__FUNCTION__, __FILE__, __LINE__, "MapViewOfFileEx"); ++ CloseHandle(mmap_handle); ++ return -1; ++ } + } + ++ addr = mmap_addr; + return 1; + } + +-- +2.38.1 + diff --git a/recipes-toolchain/gcc-sources/0140-gcc-Enable-diagnostic-colors-under-mintty.patch b/recipes-toolchain/gcc-sources/0140-gcc-Enable-diagnostic-colors-under-mintty.patch new file mode 100644 index 000000000..17dc6d4e8 --- /dev/null +++ b/recipes-toolchain/gcc-sources/0140-gcc-Enable-diagnostic-colors-under-mintty.patch @@ -0,0 +1,59 @@ +From 3cbc5bbb464dd6e205559ce19f8e21643e614300 Mon Sep 17 00:00:00 2001 +From: Alexey Pavlov +Date: Sat, 4 Aug 2018 08:38:11 +0300 +Subject: [PATCH 11/15] gcc: Enable diagnostic colors under mintty + +(updated with proper crediting) + +Source: https://github.com/msys2/MINGW-packages/commit/f1072aa1542c49d6d938974194393b03dee9dc31 +--- + gcc/diagnostic-color.cc | 31 ++++++++++++++++++++++++++++++- + 1 file changed, 30 insertions(+), 1 deletion(-) + +diff --git a/gcc/diagnostic-color.cc b/gcc/diagnostic-color.cc +index f01a0fc2e..1dccf6993 100644 +--- a/gcc/diagnostic-color.cc ++++ b/gcc/diagnostic-color.cc +@@ -211,9 +211,38 @@ should_colorize (void) + HANDLE h; + DWORD m; + ++ bool ret = false; + h = GetStdHandle (STD_ERROR_HANDLE); +- return (h != INVALID_HANDLE_VALUE) && (h != NULL) ++ ret = (h != INVALID_HANDLE_VALUE) && (h != NULL) + && GetConsoleMode (h, &m); ++ ++ if (!ret) ++ { ++ ULONG size = sizeof (FILE_NAME_INFO) + (MAX_PATH * sizeof (wchar_t)); ++ FILE_NAME_INFO *fni = (FILE_NAME_INFO*) xmalloc (size); ++ if (GetFileInformationByHandleEx (h, FileNameInfo, fni, size)) ++ { ++ wchar_t name_msys[] = L"\\msys"; ++ size_t len_msys = sizeof (name_msys) - sizeof (wchar_t); ++ wchar_t name_cyg[] = L"\\cygwin"; ++ size_t len_cyg = sizeof (name_cyg) - sizeof (wchar_t); ++ wchar_t name_dir[] = L"-to-master"; ++ size_t len_dir = sizeof (name_dir) - sizeof (wchar_t); ++ ++ if (fni->FileNameLength >= len_cyg + len_dir) ++ { ++ size_t offset = 0; ++ if (!memcmp (fni->FileName, name_msys, len_msys)) ++ offset = len_msys / sizeof (wchar_t); ++ else if (!memcmp (fni->FileName, name_cyg, len_cyg)) ++ offset = len_cyg / sizeof (wchar_t); ++ ++ ret = (offset > 0) && (wcsstr (fni->FileName + offset, name_dir) != NULL); ++ } ++ } ++ free (fni); ++ } ++ return ret; + #else + char const *t = getenv ("TERM"); + /* emacs M-x shell sets TERM="dumb". */ +-- +2.44.0.windows.1 + diff --git a/recipes-toolchain/gcc-sources/0200-add-m-no-align-vector-insn-option-for-i386.patch b/recipes-toolchain/gcc-sources/0200-add-m-no-align-vector-insn-option-for-i386.patch new file mode 100644 index 000000000..b30b636e1 --- /dev/null +++ b/recipes-toolchain/gcc-sources/0200-add-m-no-align-vector-insn-option-for-i386.patch @@ -0,0 +1,191 @@ +From 0deafca3ea0d75a062681f14ad1502a29ec30e28 Mon Sep 17 00:00:00 2001 +From: Kai Tietz +Date: Wed, 21 Apr 2021 07:54:59 +0200 +Subject: [PATCH 15/16] add -m(no-)align-vector-insn option for i386 + +--- + gcc/config/i386/i386-options.cc | 9 +++++-- + gcc/config/i386/i386.opt | 8 ++++++ + gcc/config/i386/mingw32.h | 2 +- + gcc/config/i386/predicates.md | 2 +- + gcc/config/i386/sse.md | 43 +++++++++++++++++++++++++++++---- + 5 files changed, 55 insertions(+), 9 deletions(-) + +diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc +index acb2291e70f..2de64ed5cde 100644 +--- a/gcc/config/i386/i386-options.cc ++++ b/gcc/config/i386/i386-options.cc +@@ -419,6 +419,7 @@ ix86_target_string (HOST_WIDE_INT isa, HOST_WIDE_INT isa2, + { "-minline-stringops-dynamically", MASK_INLINE_STRINGOPS_DYNAMICALLY }, + { "-mms-bitfields", MASK_MS_BITFIELD_LAYOUT }, + { "-mno-align-stringops", MASK_NO_ALIGN_STRINGOPS }, ++ { "-mno-align-vector-insn", MASK_NO_ALIGN_VECTOR_INSN }, + { "-mno-fancy-math-387", MASK_NO_FANCY_MATH_387 }, + { "-mno-push-args", MASK_NO_PUSH_ARGS }, + { "-mno-red-zone", MASK_NO_RED_ZONE }, +@@ -1169,8 +1170,12 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[], + MASK_INLINE_STRINGOPS_DYNAMICALLY), + + IX86_ATTR_NO ("align-stringops", +- OPT_mno_align_stringops, +- MASK_NO_ALIGN_STRINGOPS), ++ OPT_mno_align_stringops, ++ MASK_NO_ALIGN_STRINGOPS), ++ ++ IX86_ATTR_NO ("align-vector-insn", ++ OPT_mno_align_vector_insn, ++ MASK_NO_ALIGN_VECTOR_INSN), + + IX86_ATTR_YES ("recip", + OPT_mrecip, +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt +index 0dbaacb57ed..3b1a644e2b6 100644 +--- a/gcc/config/i386/i386.opt ++++ b/gcc/config/i386/i386.opt +@@ -256,6 +256,10 @@ malign-stringops + Target RejectNegative InverseMask(NO_ALIGN_STRINGOPS, ALIGN_STRINGOPS) Save + Align destination of the string operations. + ++malign-vector-insn ++Target RejectNegative InverseMask(NO_ALIGN_VECTOR_INSN, ALIGN_VECTOR_INSN) Save ++Use aligned vector instruction ++ + malign-data= + Target RejectNegative Joined Var(ix86_align_data_type) Enum(ix86_align_data) Init(ix86_align_data_type_compat) + Use the given data alignment. +@@ -439,6 +443,10 @@ mdaz-ftz + Target + Set the FTZ and DAZ Flags. + ++mno-align-vector-insn ++Target Mask(NO_ALIGN_VECTOR_INSN) Save ++Uses unaligned over aligned vector instruction memonics ++ + mpreferred-stack-boundary= + Target RejectNegative Joined UInteger Var(ix86_preferred_stack_boundary_arg) + Attempt to keep stack aligned to this power of 2. +diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h +index baf80400862..2ff2a99e31b 100644 +--- a/gcc/config/i386/mingw32.h ++++ b/gcc/config/i386/mingw32.h +@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see + #define TARGET_SUBTARGET_DEFAULT \ + (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS \ + | MASK_STACK_PROBE | MASK_ALIGN_DOUBLE \ +- | MASK_MS_BITFIELD_LAYOUT) ++ | MASK_MS_BITFIELD_LAYOUT | MASK_NO_ALIGN_VECTOR_INSN) + + #ifndef TARGET_USING_MCFGTHREAD + #define TARGET_USING_MCFGTHREAD 0 +diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md +index c4141a96735..0ee5a9054ee 100644 +--- a/gcc/config/i386/predicates.md ++++ b/gcc/config/i386/predicates.md +@@ -1694,7 +1694,7 @@ + ;; less than its natural alignment. + (define_predicate "misaligned_operand" + (and (match_code "mem") +- (match_test "MEM_ALIGN (op) < GET_MODE_BITSIZE (mode)"))) ++ (match_test "TARGET_NO_ALIGN_VECTOR_INSN || MEM_ALIGN (op) < GET_MODE_BITSIZE (mode)"))) + + ;; Return true if OP is a parallel for an mov{d,q,dqa,ps,pd} vec_select, + ;; where one of the two operands of the vec_concat is const0_operand. +diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md +index 076064f97e6..b224b578676 100644 +--- a/gcc/config/i386/sse.md ++++ b/gcc/config/i386/sse.md +@@ -1847,7 +1847,8 @@ + (vec_concat:V2DF (vec_select:DF (match_dup 2) + (parallel [(const_int 0)])) + (match_operand:DF 3 "memory_operand")))] +- "TARGET_SSE2 && TARGET_SSE_UNALIGNED_LOAD_OPTIMAL ++ "TARGET_SSE2 ++ && (TARGET_SSE_UNALIGNED_LOAD_OPTIMAL || TARGET_NO_ALIGN_VECTOR_INSN) + && ix86_operands_ok_for_move_multiple (operands, true, DFmode)" + [(set (match_dup 2) (match_dup 5))] + "operands[5] = adjust_address (operands[1], V2DFmode, 0);") +@@ -1858,7 +1859,8 @@ + (set (match_operand:V2DF 2 "sse_reg_operand") + (vec_concat:V2DF (match_operand:DF 4 "sse_reg_operand") + (match_operand:DF 3 "memory_operand")))] +- "TARGET_SSE2 && TARGET_SSE_UNALIGNED_LOAD_OPTIMAL ++ "TARGET_SSE2 ++ && (TARGET_SSE_UNALIGNED_LOAD_OPTIMAL || TARGET_NO_ALIGN_VECTOR_INSN) + && REGNO (operands[4]) == REGNO (operands[2]) + && ix86_operands_ok_for_move_multiple (operands, true, DFmode)" + [(set (match_dup 2) (match_dup 5))] +@@ -1872,7 +1874,8 @@ + (set (match_operand:DF 2 "memory_operand") + (vec_select:DF (match_operand:V2DF 3 "sse_reg_operand") + (parallel [(const_int 1)])))] +- "TARGET_SSE2 && TARGET_SSE_UNALIGNED_STORE_OPTIMAL ++ "TARGET_SSE2 ++ && (TARGET_SSE_UNALIGNED_STORE_OPTIMAL || TARGET_NO_ALIGN_VECTOR_INSN) + && ix86_operands_ok_for_move_multiple (operands, false, DFmode)" + [(set (match_dup 4) (match_dup 1))] + "operands[4] = adjust_address (operands[0], V2DFmode, 0);") +@@ -10873,7 +10876,8 @@ + (vec_select:V2SF + (match_operand:V4SF 1 "nonimmediate_operand" " v,v,m") + (parallel [(const_int 0) (const_int 1)])))] +- "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))" ++ "TARGET_SSE && TARGET_ALIGN_VECTOR_INSN ++ && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "@ + %vmovlps\t{%1, %0|%q0, %1} + %vmovaps\t{%1, %0|%0, %1} +@@ -10882,6 +10886,21 @@ + (set_attr "prefix" "maybe_vex") + (set_attr "mode" "V2SF,V4SF,V2SF")]) + ++(define_insn "sse_storelps_unalign" ++ [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,v,v") ++ (vec_select:V2SF ++ (match_operand:V4SF 1 "nonimmediate_operand" " v,v,m") ++ (parallel [(const_int 0) (const_int 1)])))] ++ "TARGET_SSE && TARGET_NO_ALIGN_VECTOR_INSN ++ && !(MEM_P (operands[0]) && MEM_P (operands[1]))" ++ "@ ++ %vmovlps\t{%1, %0|%q0, %1} ++ %vmovups\t{%1, %0|%0, %1} ++ %vmovlps\t{%1, %d0|%d0, %q1}" ++ [(set_attr "type" "ssemov") ++ (set_attr "prefix" "maybe_vex") ++ (set_attr "mode" "V2SF,V4SF,V2SF")]) ++ + (define_expand "sse_loadlps_exp" + [(set (match_operand:V4SF 0 "nonimmediate_operand") + (vec_concat:V4SF +@@ -13829,7 +13848,7 @@ + (vec_select:DF + (match_operand:V2DF 1 "nonimmediate_operand" "x,x,m") + (parallel [(const_int 0)])))] +- "!TARGET_SSE2 && TARGET_SSE ++ "!TARGET_SSE2 && TARGET_SSE && TARGET_ALIGN_VECTOR_INSN + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "@ + movlps\t{%1, %0|%0, %1} +@@ -13846,6 +13865,20 @@ + [(set (match_dup 0) + (vec_select:DF (match_dup 1) (parallel [(const_int 0)])))]) + ++(define_insn "*vec_extractv2df_0_sse_unalign" ++ [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x") ++ (vec_select:DF ++ (match_operand:V2DF 1 "nonimmediate_operand" "x,x,m") ++ (parallel [(const_int 0)])))] ++ "!TARGET_SSE2 && TARGET_SSE && TARGET_NO_ALIGN_VECTOR_INSN ++ && !(MEM_P (operands[0]) && MEM_P (operands[1]))" ++ "@ ++ movlps\t{%1, %0|%0, %1} ++ movups\t{%1, %0|%0, %1} ++ movlps\t{%1, %0|%0, %q1}" ++ [(set_attr "type" "ssemov") ++ (set_attr "mode" "V2SF,V4SF,V2SF")]) ++ + (define_expand "sse2_loadhpd_exp" + [(set (match_operand:V2DF 0 "nonimmediate_operand") + (vec_concat:V2DF +-- +2.46.0 + diff --git a/recipes-toolchain/gcc-sources/10000-gcc-cp-Make-lang.in-Fix-spurious-directory-separator.patch b/recipes-toolchain/gcc-sources/10000-gcc-cp-Make-lang.in-Fix-spurious-directory-separator.patch new file mode 100644 index 000000000..123d11b1e --- /dev/null +++ b/recipes-toolchain/gcc-sources/10000-gcc-cp-Make-lang.in-Fix-spurious-directory-separator.patch @@ -0,0 +1,28 @@ +From 384f0c850f88ea16db7724dbc9e2c6d9bd5cbd09 Mon Sep 17 00:00:00 2001 +From: "L. E. Segovia" +Date: Wed, 26 Jun 2024 15:12:48 -0300 +Subject: [PATCH 16/16] gcc: cp: Make-lang.in: Fix spurious directory separator + on DESTDIR + +If someone attempts a sysrooted build on Windows with this file, they'll +end up with /drive:/.... which is an invalid path. +--- + gcc/cp/Make-lang.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in +index f153891a1..a893f1d71 100644 +--- a/gcc/cp/Make-lang.in ++++ b/gcc/cp/Make-lang.in +@@ -344,7 +344,7 @@ c++.install-plugin: installdirs + # Install import library. + ifeq ($(plugin_implib),yes) + $(mkinstalldirs) $(DESTDIR)$(plugin_resourcesdir) +- $(INSTALL_DATA) cc1plus$(exeext).a $(DESTDIR)/$(plugin_resourcesdir)/cc1plus$(exeext).a ++ $(INSTALL_DATA) cc1plus$(exeext).a $(DESTDIR)$(plugin_resourcesdir)/cc1plus$(exeext).a + endif + + c++.uninstall: +-- +2.44.0.windows.1 + diff --git a/recipes-toolchain/gcc-sources/2001-gcc-update-to-14.1.0.patch b/recipes-toolchain/gcc-sources/2001-gcc-update-to-14.1.0.patch new file mode 100644 index 000000000..ff1e33bf4 --- /dev/null +++ b/recipes-toolchain/gcc-sources/2001-gcc-update-to-14.1.0.patch @@ -0,0 +1,143 @@ +From 958ca23ed6acbbf2f9487f484426d0af4954521a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=D9=85=D9=87=D8=AF=D9=8A=20=D8=B4=D9=8A=D9=86=D9=88=D9=86?= + =?UTF-8?q?=20=28Mehdi=20Chinoune=29?= +Date: Sat, 3 Feb 2024 09:42:22 +0100 +Subject: [PATCH 13/15] gcc: update to 14.1.0 + +Source: https://github.com/msys2/MINGW-packages/commit/5e812a2f380196140cef890d317e0547a6ba9617 +--- + .../errors/borrowck/rust-borrow-checker.cc | 16 +-------- + gcc/rust/expand/rust-proc-macro.cc | 35 ++++++++++++++----- + gcc/rust/parse/rust-parse.cc | 2 +- + 3 files changed, 29 insertions(+), 24 deletions(-) + +diff --git a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc +index 5daa7eb8d..9991e4b14 100644 +--- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc ++++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc +@@ -24,20 +24,6 @@ + namespace Rust { + namespace HIR { + +-void +-mkdir_wrapped (const std::string &dirname) +-{ +- int ret; +-#ifdef _WIN32 +- ret = _mkdir (dirname.c_str ()); +-#elif unix +- ret = mkdir (dirname.c_str (), 0775); +-#elif __APPLE__ +- ret = mkdir (dirname.c_str (), 0775); +-#endif +- (void) ret; +-} +- + void + dump_function_bir (const std::string &filename, BIR::Function &func, + const std::string &name) +@@ -61,7 +47,7 @@ BorrowChecker::go (HIR::Crate &crate) + + if (enable_dump_bir) + { +- mkdir_wrapped ("bir_dump"); ++ mkdir ("bir_dump", 0755); + auto mappings = Analysis::Mappings::get (); + bool ok + = mappings->get_crate_name (crate.get_mappings ().get_crate_num (), +diff --git a/gcc/rust/expand/rust-proc-macro.cc b/gcc/rust/expand/rust-proc-macro.cc +index 09680733e..d658b4d10 100644 +--- a/gcc/rust/expand/rust-proc-macro.cc ++++ b/gcc/rust/expand/rust-proc-macro.cc +@@ -22,7 +22,10 @@ + #include "rust-token-converter.h" + #include "rust-attributes.h" + +-#ifndef _WIN32 ++#ifdef _WIN32 ++#define WIN32_LEAN_AND_MEAN ++#include ++#else + #include + #endif + +@@ -102,12 +105,16 @@ static_assert ( + + } // namespace + +-template ++template + bool +-register_callback (void *handle, Symbol, std::string symbol_name, ++register_callback (Handle handle, Symbol, std::string symbol_name, + Callback callback) + { ++#ifdef _WIN32 ++ FARPROC addr = GetProcAddress (handle, symbol_name.c_str ()); ++#else + void *addr = dlsym (handle, symbol_name.c_str ()); ++#endif + if (addr == nullptr) + { + rust_error_at (UNDEF_LOCATION, +@@ -129,7 +136,18 @@ register_callback (void *handle, Symbol, std::string symbol_name, + const ProcMacro::ProcmacroArray * + load_macros_array (std::string path) + { +-#ifndef _WIN32 ++#ifdef _WIN32 ++ HMODULE handle = LoadLibraryA (path.c_str ()); ++ // We're leaking the handle since we can't ever unload it ++ if (!handle) ++ { ++ char msg[300]; ++ FormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, ++ nullptr, GetLastError (), 0, msg, sizeof msg, nullptr); ++ rust_debug ("Error whilst opening procedural macro: %s", msg); ++ return nullptr; ++ } ++#else + void *handle = dlopen (path.c_str (), RTLD_LAZY | RTLD_LOCAL); + // We're leaking the handle since we can't ever unload it + if (!handle) +@@ -137,6 +155,7 @@ load_macros_array (std::string path) + rust_debug ("Error whilst opening procedural macro: %s", dlerror ()); + return nullptr; + } ++#endif + + if (!REGISTER_CALLBACK (handle, __gccrs_proc_macro_ts_from_str_, + tokenstream_from_string)) +@@ -153,12 +172,12 @@ load_macros_array (std::string path) + auto symbol_name = generate_proc_macro_decls_symbol (0 /* FIXME */); + + return *reinterpret_cast ( +- dlsym (handle, symbol_name.c_str ())); ++#ifdef _WIN32 ++ GetProcAddress (handle, symbol_name.c_str ()) + #else +- rust_sorry_at (UNDEF_LOCATION, +- "Procedural macros are not yet supported on windows host"); +- rust_unreachable (); ++ dlsym (handle, symbol_name.c_str ()) + #endif ++ ); + } + + #undef REGISTER_CALLBACK +diff --git a/gcc/rust/parse/rust-parse.cc b/gcc/rust/parse/rust-parse.cc +index 504a409cc..acae52c25 100644 +--- a/gcc/rust/parse/rust-parse.cc ++++ b/gcc/rust/parse/rust-parse.cc +@@ -89,7 +89,7 @@ extract_module_path (const AST::AttrVec &inner_attrs, + // Source: rustc compiler + // (https://github.com/rust-lang/rust/blob/9863bf51a52b8e61bcad312f81b5193d53099f9f/compiler/rustc_expand/src/module.rs#L174) + #if defined(HAVE_DOS_BASED_FILE_SYSTEM) +- path.replace ('/', '\\'); ++ std::replace (path.begin(), path.end(), '/', '\\'); + #endif /* HAVE_DOS_BASED_FILE_SYSTEM */ + + return path; +-- +2.44.0.windows.1 + diff --git a/recipes-toolchain/gcc-sources/9999-gcc-build-without-sysroot-hack.patch b/recipes-toolchain/gcc-sources/9999-gcc-build-without-sysroot-hack.patch new file mode 100644 index 000000000..652e72c13 --- /dev/null +++ b/recipes-toolchain/gcc-sources/9999-gcc-build-without-sysroot-hack.patch @@ -0,0 +1,26 @@ +From 0f9a92cb8149382ab23b1f9f5e1de0b1f3f27431 Mon Sep 17 00:00:00 2001 +From: Alexey Borzenkov +Date: Mon, 13 Jan 2014 17:39:53 +0400 +Subject: [PATCH 15/15] gcc: build without sysroot hack + +Source: https://github.com/msys2/MINGW-packages/commit/fd87286156cc41c693c0d44f6a1a7722f051b1d7 +--- + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index 042681c27..b16ab8e43 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3608,7 +3608,7 @@ case "$target" in + x86_64-*mingw* | *-w64-mingw*) + # MinGW-w64 does not use newlib, nor does it use winsup. It may, + # however, use a symlink named 'mingw' in ${prefix} . +- FLAGS_FOR_TARGET=$FLAGS_FOR_TARGET' -L${prefix}/${target}/lib -L${prefix}/mingw/lib -isystem ${prefix}/${target}/include -isystem ${prefix}/mingw/include' ++ FLAGS_FOR_TARGET=$FLAGS_FOR_TARGET' -L${prefix}/${target}/lib -L${prefix}/lib -isystem ${prefix}/${target}/include -isystem ${prefix}/include' + ;; + *-mingw*) + # MinGW can't be handled as Cygwin above since it does not use newlib. +-- +2.44.0.windows.1 + diff --git a/recipes-toolchain/gcc.recipe b/recipes-toolchain/gcc.recipe index de616a9a4..ef7c15709 100644 --- a/recipes-toolchain/gcc.recipe +++ b/recipes-toolchain/gcc.recipe @@ -1,60 +1,80 @@ +from pathlib import Path import shutil +from cerbero.utils.git import GIT +from cerbero.utils import shell + class Recipe(recipe.Recipe): name = 'gcc' - version = '8.2.0' + version = '14.2.0' licenses = [License.GPLv3Plus] stype = SourceType.CUSTOM - make = 'make all' - make_install = 'make install-strip' add_host_build_target = False override_libtool = False + requires_non_src_build = True deps = ['gcc-sources', 'mingw-w64-crt', 'winpthreads', 'gmp', 'mpc', 'mpfr', - 'isl'] + 'isl', 'windows-default-manifest'] + # Note: on 8.2.0, the --disable-maintainer-mode flag was improperly + # spaced, that meant we've been shipping --enable-shared all along! + # For consistency I'm explicitly enabling it with 14.1.0+ configure_options = '--with-host-libstdcxx=\'-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm\' ' \ - '--disable-maintainer-mode' \ - '--disable-shared ' \ + '--disable-maintainer-mode ' \ + '--enable-shared ' \ '--disable-libgomp ' \ '--disable-libquadmath ' \ '--disable-libquadmath-support ' \ '--disable-libmudflap ' \ '--disable-libmpx ' \ '--disable-libssp ' \ + '--disable-libstdcxx-pch ' \ + '--disable-rpath ' \ + '--disable-win32-registry ' \ '--disable-nls ' \ + '--disable-werror ' \ + '--disable-symvers ' \ + '--enable-bootstrap' \ + '--enable-checking=release ' \ + '--enable-static ' \ + '--enable-libatomic ' \ '--enable-threads=posix ' \ '--enable-__cxa_atexit ' \ + '--enable-graphite ' \ + '--enable-fully-dynamic-string ' \ + '--enable-libstdcxx-filesystem-ts ' \ + '--enable-libstdcxx-time ' \ '--enable-lto ' \ '--enable-plugin ' \ '--enable-multiarch ' \ - '--enable-languages=c,c++ ' \ - '--enable-long-long ' \ + '--enable-languages=c,c++,lto ' \ + '--with-pkgversion="Built by GStreamer" ' \ + '--with-bugurl="https://gitlab.freedesktop.org/gstreamer/cerbero/-/issues" ' \ '' def prepare(self): if self.config.target_arch == Architecture.X86: raise InvalidRecipeError(self) - # The configure checks are failing on this function - # which ends in a double definition, so let's override it. - self.set_env ('ac_cv_func_powf', 'yes') self.set_env ('CPP') self._target = 'x86_64-w64-mingw32' - sysroot = os.path.join(self.config.prefix, self._target, 'sysroot') - self.configure_options += ' --with-sysroot=%s ' % sysroot - self.configure_options += ' --with-local-prefix=%s ' % sysroot + self.sysroot = f'{self.config.prefix}/{self._target}/sysroot' + self.configure_options += f' --with-sysroot={self.sysroot} ' + self.configure_options += f' --with-local-prefix={self.sysroot} ' self.configure_options += ' --target=%s' % self._target if self.config.target_platform == Platform.WINDOWS: self.configure_options += ' --host=%s' % self._target - self.build_dir = os.path.join(self.config.sources, - 'gcc-%s' % self.version) - self.make_dir = os.path.join(self.build_dir, 'gcc_build_final') - self.config_sh = '../configure' + # Point to mingw-w64-headers's sysroot (see configure_tpl) + self.configure_options += f' --with-native-system-header-dir=/usr/{self._target}/include ' + self.config_src_dir = os.path.join(self.config.sources, f'gcc-sources-{self.version}') + self.build_dir = os.path.join(self.config_src_dir, 'gcc_build_final') + self.make_dir = self.build_dir + self.make += ['all'] + self.make_install = ['install-strip' if i == 'install' else i for i in self.make_install] + # Describe version for future reference + version = shell.check_output([GIT, 'describe'], cmd_dir=Path(__file__).parent, logfile=self.logfile, env=self.env, quiet=True).strip() + self.configure_options = self.configure_options.replace('GStreamer', f'GStreamer ({version})') async def configure(self): - try: - os.mkdir(self.make_dir) - except: - pass + Path(self.make_dir).mkdir(exist_ok=True) await super(Recipe, self).configure() def post_install(self): diff --git a/recipes-toolchain/gcc/0001-Fix-graphite-build-with-isl-0.20.patch b/recipes-toolchain/gcc/0001-Fix-graphite-build-with-isl-0.20.patch deleted file mode 100644 index d182ed26a..000000000 --- a/recipes-toolchain/gcc/0001-Fix-graphite-build-with-isl-0.20.patch +++ /dev/null @@ -1,26 +0,0 @@ -From f4be86ae6d774aa4df3666ff6f55232b92fbc475 Mon Sep 17 00:00:00 2001 -From: Andoni Morales Alastruey -Date: Thu, 27 Dec 2018 23:51:16 +0100 -Subject: [PATCH] Fix graphite build with isl-0.20 - ---- - gcc/graphite.h | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/gcc/graphite.h b/gcc/graphite.h -index 4e0e58c..1398668 100644 ---- a/gcc/graphite.h -+++ b/gcc/graphite.h -@@ -37,6 +37,9 @@ along with GCC; see the file COPYING3. If not see - #include - #include - #include -+#include -+#include -+ - - typedef struct poly_dr *poly_dr_p; - --- -2.7.4 - diff --git a/recipes-toolchain/gcc/0002-Disable-split-stack-for-non-thread-builds.patch b/recipes-toolchain/gcc/0002-Disable-split-stack-for-non-thread-builds.patch deleted file mode 100644 index 59d5e4e1e..000000000 --- a/recipes-toolchain/gcc/0002-Disable-split-stack-for-non-thread-builds.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 1776d9054e428d1e6ab7aee79cb05474355fdbbf Mon Sep 17 00:00:00 2001 -From: Andoni Morales Alastruey -Date: Fri, 4 Jan 2019 15:32:34 +0100 -Subject: [PATCH 2/2] Disable split-stack for non-thread builds - ---- - libgcc/config/t-stack | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/libgcc/config/t-stack b/libgcc/config/t-stack -index cc0366b..f3f97e8 100644 ---- a/libgcc/config/t-stack -+++ b/libgcc/config/t-stack -@@ -1,4 +1,6 @@ - # Makefile fragment to provide generic support for -fsplit-stack. - # This should be used in config.host for any host which supports - # -fsplit-stack. -+ifeq ($(enable_threads),yes) - LIB2ADD_ST += $(srcdir)/generic-morestack.c $(srcdir)/generic-morestack-thread.c -+endif --- -2.7.4 - diff --git a/recipes-toolchain/gcc/0003-Force-SEH-SJLJ.patch b/recipes-toolchain/gcc/0003-Force-SEH-SJLJ.patch deleted file mode 100644 index a261b3fc3..000000000 --- a/recipes-toolchain/gcc/0003-Force-SEH-SJLJ.patch +++ /dev/null @@ -1,27 +0,0 @@ -From aec9c53549c9a755890114ccaacf5f15ed978dd9 Mon Sep 17 00:00:00 2001 -From: Andoni Morales Alastruey -Date: Wed, 9 Jan 2019 14:56:22 +0100 -Subject: [PATCH 3/3] Force SEH+SJLJ - ---- - libgcc/config.host | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/libgcc/config.host b/libgcc/config.host -index 11b4aca..c76712c 100644 ---- a/libgcc/config.host -+++ b/libgcc/config.host -@@ -765,10 +765,6 @@ x86_64-*-mingw*) - # This has to match the logic for DWARF2_UNWIND_INFO in gcc/config/i386/cygming.h - if test x$ac_cv_sjlj_exceptions = xyes; then - tmake_eh_file="i386/t-sjlj-eh" -- elif test "${host_address}" = 32; then -- # biarch -m32 with --disable-sjlj-exceptions -- tmake_eh_file="i386/t-dw2-eh" -- md_unwind_header=i386/w32-unwind.h - else - tmake_eh_file="i386/t-seh-eh" - fi --- -2.7.4 - diff --git a/recipes-toolchain/gendef.recipe b/recipes-toolchain/gendef.recipe index 3ce54a39c..aef9c6404 100644 --- a/recipes-toolchain/gendef.recipe +++ b/recipes-toolchain/gendef.recipe @@ -1,10 +1,12 @@ class Recipe(recipe.Recipe): name = 'gendef' - version = 'v6.0.0' - licenses = [License.LGPLv2Plus] + version = 'v12.0.0' + licenses = [License.GPLv3Plus] stype = SourceType.CUSTOM - files_bin = ['bin/gendef.exe'] + requires_non_src_build = True + deps = ['mingw-w64-sources'] def prepare(self): - self.build_dir = self.config_src_dir = os.path.join(self.config.sources, 'mingw-w64-%s' % self.version) - self.make_dir = os.path.join(self.build_dir, 'mingw-w64-tools', 'gendef') + self.config_src_dir = os.path.join(self.config.sources, f'mingw-w64-sources-{self.version}', 'mingw-w64-tools', 'gendef') + self.build_dir = os.path.join(self.config_src_dir, 'cerbero-build-dir') + self.make_dir = self.build_dir diff --git a/recipes-toolchain/gmp.recipe b/recipes-toolchain/gmp.recipe index f493b2f06..46de165cc 100644 --- a/recipes-toolchain/gmp.recipe +++ b/recipes-toolchain/gmp.recipe @@ -1,12 +1,11 @@ # -*- Mode: Python -*- vi:si:et:sw=4:sts=4:ts=4:syntax=python - class Recipe(recipe.Recipe): name = 'gmp' - version = '6.1.2' + version = '6.3.0' url = 'https://gmplib.org/download/gmp/gmp-%(version)s.tar.bz2' tarball_dirname = 'gmp-%(version)s' - tarball_checksum = '5275bb04f4863a13516b2f39392ac5e272f5e1bb8057b18aec1c9b79d73d8fb2' + tarball_checksum = 'ac28211a7cfb609bae2e2c8d6058d66c8fe96434f740cf6fe2e47b000d1c20cb' stype = SourceType.TARBALL licenses = [License.LGPLv3Plus] configure_options = "--disable-shared --enable-static" @@ -14,5 +13,17 @@ class Recipe(recipe.Recipe): files_libs = ['libgmp'] files_devel = ['include/gmp.h'] + patches = [ + f'{name}/0001-gmp-Do-not-declare-functions-as-dllimport.patch', + f'{name}/0002-gmp-add-macro-to-let-applications-link-static.patch', + ] + can_msvc = False + + def prepare(self): + # https://github.com/crosstool-ng/crosstool-ng/pull/1751 + if self.config.platform != self.config.target_platform: + self.set_env('CC_FOR_BUILD', f'{self.config.build}-gcc') + self.set_env('CPP_FOR_BUILD', f'{self.config.build}-cpp') + def gen_library_file(self, output_dir=None): return diff --git a/recipes-toolchain/gmp/0001-gmp-Do-not-declare-functions-as-dllimport.patch b/recipes-toolchain/gmp/0001-gmp-Do-not-declare-functions-as-dllimport.patch new file mode 100644 index 000000000..5fb8d99c5 --- /dev/null +++ b/recipes-toolchain/gmp/0001-gmp-Do-not-declare-functions-as-dllimport.patch @@ -0,0 +1,34 @@ +From dcd758480d1c6a61b66b983a900b7ac1e9415c74 Mon Sep 17 00:00:00 2001 +From: LIU Hao +Date: Fri, 6 Jan 2023 22:16:45 +0800 +Subject: [PATCH 1/2] gmp: Do not declare functions as `dllimport` + +GNU toolchains do not require `dllimport` when calling functions from +DLLs. Having `dllimport` by default causes static linking to fail, +observed when building GDB. + +Signed-off-by: LIU Hao + +Source: + +https://github.com/msys2/MINGW-packages/commit/00f2f6c12a969e729c1fc111f5f11e071602677e +--- + gmp-h.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gmp-h.in b/gmp-h.in +index 8598e97..340dd9e 100644 +--- a/gmp-h.in ++++ b/gmp-h.in +@@ -102,7 +102,7 @@ see https://www.gnu.org/licenses/. */ + + #if defined (__GNUC__) + #define __GMP_DECLSPEC_EXPORT __declspec(__dllexport__) +-#define __GMP_DECLSPEC_IMPORT __declspec(__dllimport__) ++#define __GMP_DECLSPEC_IMPORT + #endif + #if defined (_MSC_VER) || defined (__BORLANDC__) + #define __GMP_DECLSPEC_EXPORT __declspec(dllexport) +-- +2.44.0.windows.1 + diff --git a/recipes-toolchain/gmp/0002-gmp-add-macro-to-let-applications-link-static.patch b/recipes-toolchain/gmp/0002-gmp-add-macro-to-let-applications-link-static.patch new file mode 100644 index 000000000..6f1e9cd36 --- /dev/null +++ b/recipes-toolchain/gmp/0002-gmp-add-macro-to-let-applications-link-static.patch @@ -0,0 +1,43 @@ +From 71d12888f2f0db29028f2a51662e8a902ab5d106 Mon Sep 17 00:00:00 2001 +From: Jeroen Ooms +Date: Wed, 13 Sep 2023 19:36:46 +0200 +Subject: [PATCH 2/2] gmp: add macro to let applications link static + +Source: + +https://github.com/msys2/MINGW-packages/commit/19a497b647dea2939e4fe9cc2ad5818f83b1632f +--- + gmp-h.in | 4 ++++ + gmp.pc.in | 1 + + 2 files changed, 5 insertions(+) + +diff --git a/gmp-h.in b/gmp-h.in +index 340dd9e..42594cd 100644 +--- a/gmp-h.in ++++ b/gmp-h.in +@@ -59,8 +59,12 @@ see https://www.gnu.org/licenses/. */ + /* Instantiated by configure. */ + #if ! defined (__GMP_WITHIN_CONFIGURE) + @DEFN_LONG_LONG_LIMB@ ++#ifdef GMP_STATICLIB ++#define __GMP_LIBGMP_DLL 0 ++#else + #define __GMP_LIBGMP_DLL @LIBGMP_DLL@ + #endif ++#endif + + + /* __GMP_DECLSPEC supports Windows DLL versions of libgmp, and is empty in +diff --git a/gmp.pc.in b/gmp.pc.in +index bf1c799..0aa509e 100644 +--- a/gmp.pc.in ++++ b/gmp.pc.in +@@ -8,4 +8,5 @@ Description: GNU Multiple Precision Arithmetic Library + URL: https://gmplib.org + Version: @PACKAGE_VERSION@ + Cflags: -I${includedir} ++Cflags.private: -DGMP_STATICLIB + Libs: -L${libdir} -lgmp +-- +2.44.0.windows.1 + diff --git a/recipes-toolchain/isl.recipe b/recipes-toolchain/isl.recipe index 460b55663..7626f3a04 100644 --- a/recipes-toolchain/isl.recipe +++ b/recipes-toolchain/isl.recipe @@ -3,15 +3,20 @@ class Recipe(recipe.Recipe): name = 'isl' - version = '0.20' - url = 'https://deb.debian.org/debian/pool/main/i/isl/isl_0.20.orig.tar.xz' - tarball_checksum = 'a5596a9fb8a5b365cb612e4b9628735d6e67e9178fae134a816ae195017e77aa' + version = '0.26' + url = 'https://libisl.sourceforge.io/%(name)s-%(version)s.tar.xz' + tarball_checksum = 'a0b5cb06d24f9fa9e77b55fabbe9a3c94a336190345c2555f9915bb38e976504' stype = SourceType.TARBALL licenses = [License.LGPLv3Plus] + autoreconf = True configure_options = '--disable-shared '\ '--enable-static ' \ '--with-gmp=system '\ - '--with-clang=no '\ - '--with-sysroot=$CERBERO_PREFIX' + '--with-clang=no ' deps = ['gmp'] + patches = [ + f'{name}/isl-0.14.1-no-undefined.patch', + ] + + can_msvc = False diff --git a/recipes-toolchain/isl/isl-0.14.1-no-undefined.patch b/recipes-toolchain/isl/isl-0.14.1-no-undefined.patch new file mode 100644 index 000000000..a2ffd582a --- /dev/null +++ b/recipes-toolchain/isl/isl-0.14.1-no-undefined.patch @@ -0,0 +1,27 @@ +From 5af89c67817cccca3bcfde2b6dbad06da9f926dd Mon Sep 17 00:00:00 2001 +From: Alexpux +Date: Tue, 9 Jun 2015 14:30:31 +0300 +Subject: [PATCH] isl: Update to 0.14.1 + +Source: +https://github.com/msys2/MINGW-packages/blob/b194e5fa2d87e8b43ab82674036b7c40e634a0dc/mingw-w64-isl/isl-0.14.1-no-undefined.patch +--- + Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.am b/Makefile.am +index 35da88f..b5c0d9b 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -234,7 +234,7 @@ libisl_la_SOURCES = \ + isl_vertices.c \ + isl_yaml.h + libisl_la_LIBADD = @MP_LIBS@ +-libisl_la_LDFLAGS = -version-info @versioninfo@ \ ++libisl_la_LDFLAGS = -version-info @versioninfo@ -no-undefined \ + @MP_LDFLAGS@ + + isl_test_LDFLAGS = @MP_LDFLAGS@ +-- +2.44.0.windows.1 + diff --git a/recipes-toolchain/mingw-w64-crt.recipe b/recipes-toolchain/mingw-w64-crt.recipe index 31db80135..25392116a 100644 --- a/recipes-toolchain/mingw-w64-crt.recipe +++ b/recipes-toolchain/mingw-w64-crt.recipe @@ -1,11 +1,15 @@ class Recipe(recipe.Recipe): name = 'mingw-w64-crt' - version = 'v6.0.0' - licenses = [License.LGPLv2Plus] + version = 'v12.0.0' + licenses = [{License.BSD_like: ['../COPYING']}] stype = SourceType.CUSTOM add_host_build_target = False - configure_options = ' --with-default-msvcrt=ucrtbase ' + configure_options = ' --with-default-msvcrt=ucrt ' deps = ['mingw-w64-sources', 'binutils'] + requires_non_src_build = True + # Race condition in onecoreuap + allow_parallel_build = False + can_msvc = False def prepare(self): if self.config.target_arch == Architecture.X86: @@ -15,16 +19,18 @@ class Recipe(recipe.Recipe): # Since we are cross-compiling we have to reset all the env # variables set by cerbero (eg: we don't want -m64 overriding # a i386 build or gcc being used instead of x86_64-mingw32-w64-gcc) - for v in ['CC', 'LD', 'CPP', 'AS', 'RC', 'CXX','CFLAGS', 'LDFLAGS', - 'CXXFLAGS', 'CCASFLAGS']: + for v in ['CC', 'LD', 'CPP', 'AS', 'RC', 'CXX', 'RANLIB', 'AR', 'STRIP', + 'WINDRES', 'NM', 'CFLAGS', 'CXXFLAGS', 'CCASFLAGS', 'CPPFLAGS']: self.set_env(v) self.host = 'x86_64-w64-mingw32' - sysroot = os.path.join(self.config.prefix, self.host, 'sysroot') + self.sysroot = f'{self.config.prefix}/{self.host}/sysroot' + self.configure_options += f' --with-sysroot={self.sysroot} ' + self.make_install += [f'DESTDIR={self.sysroot}'] self.configure_options += ' --host=%s' % self.host - self.configure_options += ' --with-sysroot=%s ' % sysroot - self.make_install = ['make', 'install', 'DESTDIR=' + sysroot] - self.build_dir = os.path.join(self.config.sources, - 'mingw-w64-%s' % self.version) - self.make_dir = os.path.join(self.build_dir, 'mingw-w64-crt') + if self.config.platform == self.config.target_platform: + self.configure_options += ' --build=%s' % self.host self.configure_tpl = "%%(config-sh)s --prefix /usr/%(host)s "\ "--libdir /usr/%(host)s/lib %%(options)s" % {'host': self.host} + self.config_src_dir = os.path.join(self.config.sources, f'mingw-w64-sources-{self.version}', self.name) + self.build_dir = os.path.join(self.config_src_dir, 'cerbero-build-dir') + self.make_dir = self.build_dir diff --git a/recipes-toolchain/mingw-w64-headers.recipe b/recipes-toolchain/mingw-w64-headers.recipe index a80904ade..cc44e8a4a 100644 --- a/recipes-toolchain/mingw-w64-headers.recipe +++ b/recipes-toolchain/mingw-w64-headers.recipe @@ -1,28 +1,40 @@ +import os + class Recipe(recipe.Recipe): name = 'mingw-w64-headers' - version = 'v6.0.0' - licenses = [License.LGPLv2Plus] + version = 'v12.0.0' + licenses = [{License.BSD_like: ['../COPYING']}] stype = SourceType.CUSTOM - srcdir = 'mingw-w64-headers' - configure_options='--enable-sdk=all --enable-secure-api \ - --with-default-msvcrt=ucrtbase ' + configure_options=' --enable-sdk=all --with-default-msvcrt=ucrt ' add_host_build_target = False deps = ['mingw-w64-sources'] + can_msvc = False + requires_non_src_build = True def prepare(self): if self.config.target_arch == Architecture.X86: raise InvalidRecipeError(self) self.host = 'x86_64-w64-mingw32' - self._sysroot = os.path.join(self.config.prefix, self.host, 'sysroot') - self.configure_options += ' --host=%s' % self.host - self.configure_options += ' --with-sysroot=%s ' % self._sysroot - self.make_install = ['make', 'install', 'DESTDIR=' + self._sysroot] - self.build_dir = os.path.join(self.config.sources, - 'mingw-w64-%s' % self.version) - self.make_dir = os.path.join(self.build_dir, 'mingw-w64-headers') + self._sysroot = f'{self.config.prefix}/{self.host}/sysroot' + self.configure_options += f' --with-sysroot={self._sysroot}' + if self.config.target_platform != self.config.platform: + self.configure_options += ' --host=%s' % self.host + self.configure_options += ' --target=%s' % self.host + self.config_src_dir = os.path.join(self.config.sources, f'mingw-w64-sources-{self.version}', self.name) + self.make_install += [f'DESTDIR={self._sysroot}'] + self.build_dir = os.path.join(self.config_src_dir, "cerbero-build-dir") + self.make_dir = self.build_dir self.configure_tpl = "%%(config-sh)s --prefix /usr/%(host)s "\ "--libdir /usr/%(host)s %%(options)s" % {'host': self.host} + # NOTE: PLEASE BE VERY CAREFUL WITH THIS SYMLINK! + # If you don't specify it, you need to execute the below lines + # in the gcc-bootstrap recipe: + # header = os.path.join(self.config_src_dir, 'gcc/config/i386/mingw32.h') + # shell.replace(header, {'/mingw': f'/usr/{self._target}'}) + # Otherwise https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70936 happens ! + # For further information, see: + # https://github.com/msys2/MINGW-packages/commit/54101537025a9a3a381a1e292fb9bc967e374bd2 def post_install(self): if not os.path.exists(os.path.join(self._sysroot, 'mingw')): shell.symlink('usr/%(host)s' % {'host': self.host}, 'mingw', self._sysroot) diff --git a/recipes-toolchain/mingw-w64-sources.recipe b/recipes-toolchain/mingw-w64-sources.recipe index d7a60b53f..bd9b15af4 100644 --- a/recipes-toolchain/mingw-w64-sources.recipe +++ b/recipes-toolchain/mingw-w64-sources.recipe @@ -1,16 +1,16 @@ class Recipe(recipe.Recipe): name = 'mingw-w64-sources' - version = 'v6.0.0' - licenses = [License.LGPLv2Plus] + version = 'v12.0.0' + licenses = [{License.BSD_like: ['COPYING']}] url = 'https://downloads.sourceforge.net/project/mingw-w64/mingw-w64/mingw-w64-release/mingw-w64-%(version)s.tar.bz2' - tarball_checksum = '805e11101e26d7897fce7d49cbb140d7bac15f3e085a91e0001e80b2adaf48f0' + tarball_checksum = 'cc41898aac4b6e8dd5cffd7331b9d9515b912df4420a3a612b5ea2955bbeed2f' stype = SourceType.TARBALL btype = BuildType.CUSTOM patches = [ - 'mingw-w64/0001-timeb.h-declare-_ftime32-function-define-_ftime-acco.patch', - 'mingw-w64/0002-Add-_ftime-aliases-for-all-msvcr-versions.patch', - 'mingw-w64/0003-move-_fseeki64-and-_ftelli64-functions-from-libmingw.patch', - ] + 'mingw-w64/0001-Allow-to-use-bessel-and-complex-functions-without-un.patch', + 'mingw-w64/0002-Bug-1829971-Update-to-MinGW-trunk-r-firefox-build-sy.patch' + ] + tarball_dirname = 'mingw-w64-%(version)s' def prepare(self): if self.config.target_arch == Architecture.X86: diff --git a/recipes-toolchain/mingw-w64/0001-Allow-to-use-bessel-and-complex-functions-without-un.patch b/recipes-toolchain/mingw-w64/0001-Allow-to-use-bessel-and-complex-functions-without-un.patch new file mode 100644 index 000000000..93c9bb4d0 --- /dev/null +++ b/recipes-toolchain/mingw-w64/0001-Allow-to-use-bessel-and-complex-functions-without-un.patch @@ -0,0 +1,26 @@ +From 7e98084e6bd440a912727103c452bbc39a368094 Mon Sep 17 00:00:00 2001 +From: Alexey Pavlov +Date: Thu, 14 Sep 2017 11:13:45 +0300 +Subject: [PATCH 1/2] Allow to use bessel and complex functions without + undefining + +--- + mingw-w64-headers/crt/math.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mingw-w64-headers/crt/math.h b/mingw-w64-headers/crt/math.h +index b3e0408..e29102a 100644 +--- a/mingw-w64-headers/crt/math.h ++++ b/mingw-w64-headers/crt/math.h +@@ -258,7 +258,7 @@ extern "C" { + #define EDOM 33 + #define ERANGE 34 + +-#ifndef __STRICT_ANSI__ ++#if !defined(__STRICT_ANSI__) || defined(_POSIX_C_SOURCE) || defined(_POSIX_SOURCE) || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) + + #ifndef _COMPLEX_DEFINED + #define _COMPLEX_DEFINED +-- +2.45.1 + diff --git a/recipes-toolchain/mingw-w64/0001-timeb.h-declare-_ftime32-function-define-_ftime-acco.patch b/recipes-toolchain/mingw-w64/0001-timeb.h-declare-_ftime32-function-define-_ftime-acco.patch deleted file mode 100644 index 1c78fc8ec..000000000 --- a/recipes-toolchain/mingw-w64/0001-timeb.h-declare-_ftime32-function-define-_ftime-acco.patch +++ /dev/null @@ -1,83 +0,0 @@ -From f1537152d336cd072fa4fe00ffe775e45d4df8d9 Mon Sep 17 00:00:00 2001 -From: Mateusz -Date: Sun, 4 Nov 2018 17:39:10 +0100 -Subject: [PATCH 1/3] timeb.h: declare _ftime32 function, define _ftime - according to _USE_32BIT_TIME_T - -Signed-off-by: Mateusz Brzostek -Signed-off-by: Liu Hao -(cherry picked from commit 38496499910a580ddc449a7d09f3bc0302767f31) -Signed-off-by: Jonathan Yong <10walls@gmail.com> ---- - mingw-w64-crt/lib-common/msvcrt.def.in | 3 ++- - mingw-w64-headers/crt/sec_api/sys/timeb_s.h | 4 +++- - mingw-w64-headers/crt/sys/timeb.h | 9 +++++---- - 3 files changed, 10 insertions(+), 6 deletions(-) - -diff --git a/mingw-w64-crt/lib-common/msvcrt.def.in b/mingw-w64-crt/lib-common/msvcrt.def.in -index 1a1db2b4..13115412 100644 ---- a/mingw-w64-crt/lib-common/msvcrt.def.in -+++ b/mingw-w64-crt/lib-common/msvcrt.def.in -@@ -532,7 +532,8 @@ _fstat64 - _fstati64 - F64(_fstat64i32 == _fstat) - _ftime --F_ARM_ANY(_ftime32) -+F_I386(_ftime32 == _ftime) -+F_NON_I386(_ftime32) - _ftime32_s - _ftime64 - _ftime64_s -diff --git a/mingw-w64-headers/crt/sec_api/sys/timeb_s.h b/mingw-w64-headers/crt/sec_api/sys/timeb_s.h -index f635d32b..ed92946e 100644 ---- a/mingw-w64-headers/crt/sec_api/sys/timeb_s.h -+++ b/mingw-w64-headers/crt/sec_api/sys/timeb_s.h -@@ -15,11 +15,13 @@ extern "C" { - - #if defined(MINGW_HAS_SECURE_API) - -- _CRTIMP errno_t __cdecl _ftime_s(struct __timeb32 *_Time); -+ _CRTIMP errno_t __cdecl _ftime32_s(struct __timeb32 *_Time); - _CRTIMP errno_t __cdecl _ftime64_s(struct __timeb64 *_Time); - - #ifndef _USE_32BIT_TIME_T - #define _ftime_s _ftime64_s -+#else -+#define _ftime_s _ftime32_s - #endif - #endif - -diff --git a/mingw-w64-headers/crt/sys/timeb.h b/mingw-w64-headers/crt/sys/timeb.h -index c92c8e01..7bfe98e0 100644 ---- a/mingw-w64-headers/crt/sys/timeb.h -+++ b/mingw-w64-headers/crt/sys/timeb.h -@@ -76,13 +76,14 @@ extern "C" { - #endif - - _CRTIMP void __cdecl _ftime64(struct __timeb64 *_Time); -+ _CRTIMP void __cdecl _ftime32(struct __timeb32 *_Time); - --#ifdef _WIN64 -+#ifndef _USE_32BIT_TIME_T - #define _timeb __timeb64 -- _CRTIMP void __cdecl _ftime(struct __timeb64 *); -+#define _ftime _ftime64 - #else - #define _timeb __timeb32 -- _CRTIMP void __cdecl _ftime(struct __timeb32 *); -+#define _ftime _ftime32 - #endif - - #ifndef _TIMESPEC_DEFINED -@@ -109,7 +110,7 @@ struct itimerspec { - } - #else - __CRT_INLINE void __cdecl ftime(struct timeb *_Tmb) { -- _ftime((struct __timeb32 *)_Tmb); -+ _ftime32((struct __timeb32 *)_Tmb); - } - #endif /* _USE_32BIT_TIME_T */ - #endif /* !__CRT__NO_INLINE */ --- -2.14.1 - diff --git a/recipes-toolchain/mingw-w64/0002-Add-_ftime-aliases-for-all-msvcr-versions.patch b/recipes-toolchain/mingw-w64/0002-Add-_ftime-aliases-for-all-msvcr-versions.patch deleted file mode 100644 index a4ce33c4a..000000000 --- a/recipes-toolchain/mingw-w64/0002-Add-_ftime-aliases-for-all-msvcr-versions.patch +++ /dev/null @@ -1,223 +0,0 @@ -From ade3f5ad8ec5686d0acdff3986619e0469434104 Mon Sep 17 00:00:00 2001 -From: Johannes Pfau -Date: Wed, 2 Jan 2019 14:10:59 +0100 -Subject: [PATCH 2/3] Add _ftime aliases for all msvcr versions. - -Signed-off-by: Johannes Pfau -Signed-off-by: Jacek Caban -(cherry picked from commit 6a5c1535fb22d94797dcc75a4b4b9109d8360058) -Signed-off-by: Jonathan Yong <10walls@gmail.com> ---- - mingw-w64-crt/lib32/msvcr100.def.in | 1 + - mingw-w64-crt/lib32/msvcr110.def.in | 1 + - mingw-w64-crt/lib32/msvcr120.def.in | 1 + - mingw-w64-crt/lib32/msvcr120_app.def.in | 1 + - mingw-w64-crt/lib32/msvcr120d.def.in | 1 + - mingw-w64-crt/lib32/msvcr90.def.in | 1 + - mingw-w64-crt/lib32/msvcr90d.def.in | 1 + - mingw-w64-crt/lib64/msvcr100.def.in | 1 + - mingw-w64-crt/lib64/msvcr110.def.in | 1 + - mingw-w64-crt/lib64/msvcr120.def.in | 1 + - mingw-w64-crt/lib64/msvcr120_app.def.in | 1 + - mingw-w64-crt/lib64/msvcr120d.def.in | 1 + - mingw-w64-crt/lib64/msvcr90.def.in | 1 + - mingw-w64-crt/lib64/msvcr90d.def.in | 1 + - mingw-w64-crt/libarm32/msvcr110.def | 1 + - mingw-w64-crt/libarm32/msvcr120_clr0400.def | 1 + - 16 files changed, 16 insertions(+) - -diff --git a/mingw-w64-crt/lib32/msvcr100.def.in b/mingw-w64-crt/lib32/msvcr100.def.in -index d103a2b0..53ccd37b 100644 ---- a/mingw-w64-crt/lib32/msvcr100.def.in -+++ b/mingw-w64-crt/lib32/msvcr100.def.in -@@ -896,6 +896,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime32 - _ftol - _fullpath - _futime32 -diff --git a/mingw-w64-crt/lib32/msvcr110.def.in b/mingw-w64-crt/lib32/msvcr110.def.in -index 7296955b..920677bc 100644 ---- a/mingw-w64-crt/lib32/msvcr110.def.in -+++ b/mingw-w64-crt/lib32/msvcr110.def.in -@@ -1019,6 +1019,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime32 - _ftol - _fullpath - _futime32 -diff --git a/mingw-w64-crt/lib32/msvcr120.def.in b/mingw-w64-crt/lib32/msvcr120.def.in -index 57122cbf..c1e2af84 100644 ---- a/mingw-w64-crt/lib32/msvcr120.def.in -+++ b/mingw-w64-crt/lib32/msvcr120.def.in -@@ -1042,6 +1042,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime32 - _ftol - _fullpath - _futime32 -diff --git a/mingw-w64-crt/lib32/msvcr120_app.def.in b/mingw-w64-crt/lib32/msvcr120_app.def.in -index 0c5aaff9..b13d9a66 100644 ---- a/mingw-w64-crt/lib32/msvcr120_app.def.in -+++ b/mingw-w64-crt/lib32/msvcr120_app.def.in -@@ -654,6 +654,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime32 - _ftol - _fullpath - _futime32 -diff --git a/mingw-w64-crt/lib32/msvcr120d.def.in b/mingw-w64-crt/lib32/msvcr120d.def.in -index 194a0d24..385d4913 100644 ---- a/mingw-w64-crt/lib32/msvcr120d.def.in -+++ b/mingw-w64-crt/lib32/msvcr120d.def.in -@@ -1098,6 +1098,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime32 - _ftol - _fullpath - _fullpath_dbg -diff --git a/mingw-w64-crt/lib32/msvcr90.def.in b/mingw-w64-crt/lib32/msvcr90.def.in -index 861ce56c..69765e53 100644 ---- a/mingw-w64-crt/lib32/msvcr90.def.in -+++ b/mingw-w64-crt/lib32/msvcr90.def.in -@@ -523,6 +523,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime32 - _ftol - _fullpath - _futime32 -diff --git a/mingw-w64-crt/lib32/msvcr90d.def.in b/mingw-w64-crt/lib32/msvcr90d.def.in -index 419c65ce..2fe211dd 100644 ---- a/mingw-w64-crt/lib32/msvcr90d.def.in -+++ b/mingw-w64-crt/lib32/msvcr90d.def.in -@@ -583,6 +583,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime32 - _ftol - _fullpath - _fullpath_dbg -diff --git a/mingw-w64-crt/lib64/msvcr100.def.in b/mingw-w64-crt/lib64/msvcr100.def.in -index b3be3024..b1e3e073 100644 ---- a/mingw-w64-crt/lib64/msvcr100.def.in -+++ b/mingw-w64-crt/lib64/msvcr100.def.in -@@ -853,6 +853,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime64 - _fullpath - _futime32 - _futime64 -diff --git a/mingw-w64-crt/lib64/msvcr110.def.in b/mingw-w64-crt/lib64/msvcr110.def.in -index 59868920..a4129975 100644 ---- a/mingw-w64-crt/lib64/msvcr110.def.in -+++ b/mingw-w64-crt/lib64/msvcr110.def.in -@@ -978,6 +978,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime64 - _fullpath - _futime32 - _futime64 -diff --git a/mingw-w64-crt/lib64/msvcr120.def.in b/mingw-w64-crt/lib64/msvcr120.def.in -index 0ec1dc48..38d5af29 100644 ---- a/mingw-w64-crt/lib64/msvcr120.def.in -+++ b/mingw-w64-crt/lib64/msvcr120.def.in -@@ -998,6 +998,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime64 - _fullpath - _futime32 - _futime64 -diff --git a/mingw-w64-crt/lib64/msvcr120_app.def.in b/mingw-w64-crt/lib64/msvcr120_app.def.in -index b829b841..a5f6f777 100644 ---- a/mingw-w64-crt/lib64/msvcr120_app.def.in -+++ b/mingw-w64-crt/lib64/msvcr120_app.def.in -@@ -611,6 +611,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime64 - _fullpath - _futime32 - _futime64 -diff --git a/mingw-w64-crt/lib64/msvcr120d.def.in b/mingw-w64-crt/lib64/msvcr120d.def.in -index f5304d45..df0425af 100644 ---- a/mingw-w64-crt/lib64/msvcr120d.def.in -+++ b/mingw-w64-crt/lib64/msvcr120d.def.in -@@ -1052,6 +1052,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime64 - _fullpath - _fullpath_dbg - _futime32 -diff --git a/mingw-w64-crt/lib64/msvcr90.def.in b/mingw-w64-crt/lib64/msvcr90.def.in -index f18166aa..72f30700 100644 ---- a/mingw-w64-crt/lib64/msvcr90.def.in -+++ b/mingw-w64-crt/lib64/msvcr90.def.in -@@ -470,6 +470,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime64 - _fullpath - _futime32 - _futime64 -diff --git a/mingw-w64-crt/lib64/msvcr90d.def.in b/mingw-w64-crt/lib64/msvcr90d.def.in -index 07755389..99b167ee 100644 ---- a/mingw-w64-crt/lib64/msvcr90d.def.in -+++ b/mingw-w64-crt/lib64/msvcr90d.def.in -@@ -524,6 +524,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime64 - _fullpath - _fullpath_dbg - _futime32 -diff --git a/mingw-w64-crt/libarm32/msvcr110.def b/mingw-w64-crt/libarm32/msvcr110.def -index 40a40937..9ce6a8ac 100644 ---- a/mingw-w64-crt/libarm32/msvcr110.def -+++ b/mingw-w64-crt/libarm32/msvcr110.def -@@ -635,6 +635,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime32 - _fullpath - _futime32 - _futime64 -diff --git a/mingw-w64-crt/libarm32/msvcr120_clr0400.def b/mingw-w64-crt/libarm32/msvcr120_clr0400.def -index 32d7965f..84f768a5 100644 ---- a/mingw-w64-crt/libarm32/msvcr120_clr0400.def -+++ b/mingw-w64-crt/libarm32/msvcr120_clr0400.def -@@ -634,6 +634,7 @@ _ftime32 - _ftime32_s - _ftime64 - _ftime64_s -+_ftime == _ftime32 - _fullpath - _futime32 - _futime64 --- -2.14.1 - diff --git a/recipes-toolchain/mingw-w64/0002-Bug-1829971-Update-to-MinGW-trunk-r-firefox-build-sy.patch b/recipes-toolchain/mingw-w64/0002-Bug-1829971-Update-to-MinGW-trunk-r-firefox-build-sy.patch new file mode 100644 index 000000000..b202db683 --- /dev/null +++ b/recipes-toolchain/mingw-w64/0002-Bug-1829971-Update-to-MinGW-trunk-r-firefox-build-sy.patch @@ -0,0 +1,68 @@ +From af4d05963320fd819005efa1da1af028134afe9c Mon Sep 17 00:00:00 2001 +From: Tom Ritter +Date: Tue, 2 May 2023 17:08:08 +0000 +Subject: [PATCH 2/2] Bug 1829971: Update to MinGW trunk + r=firefox-build-system-reviewers,andi + +Differential Revision: https://phabricator.services.mozilla.com/D176730 + +Source: https://hg.mozilla.org/mozilla-central/rev/60bf7328d740548c440deabc9ef1be9fc5783e74 + +Signed-off-by: L. E. Segovia +--- + mingw-w64-headers/include/windows.ui.composition.h | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/mingw-w64-headers/include/windows.ui.composition.h b/mingw-w64-headers/include/windows.ui.composition.h +index 7c2066d..7561057 100644 +--- a/mingw-w64-headers/include/windows.ui.composition.h ++++ b/mingw-w64-headers/include/windows.ui.composition.h +@@ -4916,13 +4916,13 @@ namespace ABI { + ICompositionDrawingSurface : public IInspectable + { + virtual HRESULT STDMETHODCALLTYPE get_AlphaMode( +- enum DirectXAlphaMode *value) = 0; ++ ABI::Windows::Graphics::DirectX::DirectXAlphaMode *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_PixelFormat( +- enum DirectXPixelFormat *value) = 0; ++ ABI::Windows::Graphics::DirectX::DirectXPixelFormat *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_Size( +- struct Size *value) = 0; ++ ABI::Windows::Foundation::Size *value) = 0; + + }; + } +@@ -5704,8 +5704,8 @@ namespace ABI { + { + virtual HRESULT STDMETHODCALLTYPE CreateDrawingSurface( + struct Size pixels, +- enum DirectXPixelFormat format, +- enum DirectXAlphaMode mode, ++ ABI::Windows::Graphics::DirectX::DirectXPixelFormat format, ++ ABI::Windows::Graphics::DirectX::DirectXAlphaMode mode, + ABI::Windows::UI::Composition::ICompositionDrawingSurface **result) = 0; + + virtual HRESULT STDMETHODCALLTYPE add_RenderingDeviceReplaced( +@@ -9338,7 +9338,7 @@ namespace ABI { + boolean value) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_Offset( +- struct Vector3 *value) = 0; ++ ABI::Windows::Foundation::Numerics::Vector3 *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE put_Offset( + struct Vector3 value) = 0; +@@ -9383,7 +9383,7 @@ namespace ABI { + struct Vector3 value) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_Size( +- struct Vector2 *value) = 0; ++ ABI::Windows::Foundation::Numerics::Vector2 *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE put_Size( + struct Vector2 value) = 0; +-- +2.45.1 + diff --git a/recipes-toolchain/mingw-w64/0003-move-_fseeki64-and-_ftelli64-functions-from-libmingw.patch b/recipes-toolchain/mingw-w64/0003-move-_fseeki64-and-_ftelli64-functions-from-libmingw.patch deleted file mode 100644 index 9a10b1d2e..000000000 --- a/recipes-toolchain/mingw-w64/0003-move-_fseeki64-and-_ftelli64-functions-from-libmingw.patch +++ /dev/null @@ -1,733 +0,0 @@ -From 71276530be885bd3558d5f351a7bd0fb3bcb88d6 Mon Sep 17 00:00:00 2001 -From: Mateusz Brzostek -Date: Tue, 27 Nov 2018 09:21:36 +0100 -Subject: [PATCH 3/3] move _fseeki64 and _ftelli64 functions from libmingwex to - libmsvcrt - -_fseeki64 and _ftelli64 functions are already in libmsvcr90 and newer, -so we need to provide these functions only for libmsvcrt. In addition, -_ftelli64 function implementation is not compatible with ucrt. - -Signed-off-by: Mateusz Brzostek -Signed-off-by: Jacek Caban ---- - mingw-w64-crt/Makefile.am | 1 + - mingw-w64-crt/Makefile.in | 96 ++++++++++++++++--- - mingw-w64-crt/lib32/msvcr100.def.in | 4 +- - mingw-w64-crt/lib32/msvcr90.def.in | 4 +- - mingw-w64-crt/lib64/msvcr100.def.in | 4 +- - mingw-w64-crt/lib64/msvcr90.def.in | 4 +- - mingw-w64-crt/stdio/fseeki64.c | 177 ++++++++++++++++++++++++++++++++++++ - mingw-w64-crt/stdio/fseeko64.c | 131 -------------------------- - mingw-w64-headers/crt/stdio.h | 5 +- - 9 files changed, 272 insertions(+), 154 deletions(-) - create mode 100644 mingw-w64-crt/stdio/fseeki64.c - -diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am -index 30f9f7fc..c4b19beb 100644 ---- a/mingw-w64-crt/Makefile.am -+++ b/mingw-w64-crt/Makefile.am -@@ -210,6 +210,7 @@ src_msvcrt=\ - secapi/vsprintf_s.c \ - secapi/wmemcpy_s.c \ - secapi/wmemmove_s.c \ -+ stdio/fseeki64.c \ - stdio/mingw_lock.c - - src_ucrtbase=\ -diff --git a/mingw-w64-crt/Makefile.in b/mingw-w64-crt/Makefile.in -index 4952edde..aea778a5 100644 ---- a/mingw-w64-crt/Makefile.in -+++ b/mingw-w64-crt/Makefile.in -@@ -1341,8 +1341,9 @@ am__lib32_libmsvcrt_os_a_SOURCES_DIST = misc/onexit_table.c \ - secapi/_wmktemp_s.c secapi/_wstrdate_s.c secapi/asctime_s.c \ - secapi/memcpy_s.c secapi/memmove_s.c secapi/rand_s.c \ - secapi/sprintf_s.c secapi/strerror_s.c secapi/vsprintf_s.c \ -- secapi/wmemcpy_s.c secapi/wmemmove_s.c stdio/mingw_lock.c \ -- misc/lc_locale_func.c lib-common/msvcrt.def.in -+ secapi/wmemcpy_s.c secapi/wmemmove_s.c stdio/fseeki64.c \ -+ stdio/mingw_lock.c misc/lc_locale_func.c \ -+ lib-common/msvcrt.def.in - am__objects_33 = misc/lib32_libmsvcrt_os_a-onexit_table.$(OBJEXT) \ - misc/lib32_libmsvcrt_os_a-register_tls_atexit.$(OBJEXT) \ - stdio/lib32_libmsvcrt_os_a-acrt_iob_func.$(OBJEXT) -@@ -1395,6 +1396,7 @@ am__objects_34 = $(am__objects_33) \ - secapi/lib32_libmsvcrt_os_a-vsprintf_s.$(OBJEXT) \ - secapi/lib32_libmsvcrt_os_a-wmemcpy_s.$(OBJEXT) \ - secapi/lib32_libmsvcrt_os_a-wmemmove_s.$(OBJEXT) \ -+ stdio/lib32_libmsvcrt_os_a-fseeki64.$(OBJEXT) \ - stdio/lib32_libmsvcrt_os_a-mingw_lock.$(OBJEXT) - am__objects_35 = $(am__objects_34) \ - misc/lib32_libmsvcrt_os_a-lc_locale_func.$(OBJEXT) -@@ -2669,9 +2671,9 @@ am__lib64_libmsvcrt_os_a_SOURCES_DIST = misc/onexit_table.c \ - secapi/_wmktemp_s.c secapi/_wstrdate_s.c secapi/asctime_s.c \ - secapi/memcpy_s.c secapi/memmove_s.c secapi/rand_s.c \ - secapi/sprintf_s.c secapi/strerror_s.c secapi/vsprintf_s.c \ -- secapi/wmemcpy_s.c secapi/wmemmove_s.c stdio/mingw_lock.c \ -- misc/__p___argv.c misc/__p__acmdln.c misc/__p__fmode.c \ -- misc/__p__wcmdln.c lib-common/msvcrt.def.in -+ secapi/wmemcpy_s.c secapi/wmemmove_s.c stdio/fseeki64.c \ -+ stdio/mingw_lock.c misc/__p___argv.c misc/__p__acmdln.c \ -+ misc/__p__fmode.c misc/__p__wcmdln.c lib-common/msvcrt.def.in - am__objects_84 = misc/lib64_libmsvcrt_os_a-onexit_table.$(OBJEXT) \ - misc/lib64_libmsvcrt_os_a-register_tls_atexit.$(OBJEXT) \ - stdio/lib64_libmsvcrt_os_a-acrt_iob_func.$(OBJEXT) -@@ -2724,6 +2726,7 @@ am__objects_85 = $(am__objects_84) \ - secapi/lib64_libmsvcrt_os_a-vsprintf_s.$(OBJEXT) \ - secapi/lib64_libmsvcrt_os_a-wmemcpy_s.$(OBJEXT) \ - secapi/lib64_libmsvcrt_os_a-wmemmove_s.$(OBJEXT) \ -+ stdio/lib64_libmsvcrt_os_a-fseeki64.$(OBJEXT) \ - stdio/lib64_libmsvcrt_os_a-mingw_lock.$(OBJEXT) - am__objects_86 = $(am__objects_85) \ - misc/lib64_libmsvcrt_os_a-__p___argv.$(OBJEXT) \ -@@ -3863,9 +3866,9 @@ am__libarm32_libmsvcrt_os_a_SOURCES_DIST = misc/onexit_table.c \ - secapi/_wmktemp_s.c secapi/_wstrdate_s.c secapi/asctime_s.c \ - secapi/memcpy_s.c secapi/memmove_s.c secapi/rand_s.c \ - secapi/sprintf_s.c secapi/strerror_s.c secapi/vsprintf_s.c \ -- secapi/wmemcpy_s.c secapi/wmemmove_s.c stdio/mingw_lock.c \ -- misc/__p___argv.c misc/__p__acmdln.c misc/__p__fmode.c \ -- misc/__p__wcmdln.c lib-common/msvcrt.def.in -+ secapi/wmemcpy_s.c secapi/wmemmove_s.c stdio/fseeki64.c \ -+ stdio/mingw_lock.c misc/__p___argv.c misc/__p__acmdln.c \ -+ misc/__p__fmode.c misc/__p__wcmdln.c lib-common/msvcrt.def.in - am__objects_124 = misc/libarm32_libmsvcrt_os_a-onexit_table.$(OBJEXT) \ - misc/libarm32_libmsvcrt_os_a-register_tls_atexit.$(OBJEXT) \ - stdio/libarm32_libmsvcrt_os_a-acrt_iob_func.$(OBJEXT) -@@ -3918,6 +3921,7 @@ am__objects_125 = $(am__objects_124) \ - secapi/libarm32_libmsvcrt_os_a-vsprintf_s.$(OBJEXT) \ - secapi/libarm32_libmsvcrt_os_a-wmemcpy_s.$(OBJEXT) \ - secapi/libarm32_libmsvcrt_os_a-wmemmove_s.$(OBJEXT) \ -+ stdio/libarm32_libmsvcrt_os_a-fseeki64.$(OBJEXT) \ - stdio/libarm32_libmsvcrt_os_a-mingw_lock.$(OBJEXT) - am__objects_126 = $(am__objects_125) \ - misc/libarm32_libmsvcrt_os_a-__p___argv.$(OBJEXT) \ -@@ -4948,9 +4952,9 @@ am__libarm64_libmsvcrt_os_a_SOURCES_DIST = misc/onexit_table.c \ - secapi/_wmktemp_s.c secapi/_wstrdate_s.c secapi/asctime_s.c \ - secapi/memcpy_s.c secapi/memmove_s.c secapi/rand_s.c \ - secapi/sprintf_s.c secapi/strerror_s.c secapi/vsprintf_s.c \ -- secapi/wmemcpy_s.c secapi/wmemmove_s.c stdio/mingw_lock.c \ -- misc/__p___argv.c misc/__p__acmdln.c misc/__p__fmode.c \ -- misc/__p__wcmdln.c lib-common/msvcrt.def.in -+ secapi/wmemcpy_s.c secapi/wmemmove_s.c stdio/fseeki64.c \ -+ stdio/mingw_lock.c misc/__p___argv.c misc/__p__acmdln.c \ -+ misc/__p__fmode.c misc/__p__wcmdln.c lib-common/msvcrt.def.in - am__objects_160 = misc/libarm64_libmsvcrt_os_a-onexit_table.$(OBJEXT) \ - misc/libarm64_libmsvcrt_os_a-register_tls_atexit.$(OBJEXT) \ - stdio/libarm64_libmsvcrt_os_a-acrt_iob_func.$(OBJEXT) -@@ -5003,6 +5007,7 @@ am__objects_161 = $(am__objects_160) \ - secapi/libarm64_libmsvcrt_os_a-vsprintf_s.$(OBJEXT) \ - secapi/libarm64_libmsvcrt_os_a-wmemcpy_s.$(OBJEXT) \ - secapi/libarm64_libmsvcrt_os_a-wmemmove_s.$(OBJEXT) \ -+ stdio/libarm64_libmsvcrt_os_a-fseeki64.$(OBJEXT) \ - stdio/libarm64_libmsvcrt_os_a-mingw_lock.$(OBJEXT) - am__objects_162 = $(am__objects_161) \ - misc/libarm64_libmsvcrt_os_a-__p___argv.$(OBJEXT) \ -@@ -6925,6 +6930,7 @@ src_msvcrt = \ - secapi/vsprintf_s.c \ - secapi/wmemcpy_s.c \ - secapi/wmemmove_s.c \ -+ stdio/fseeki64.c \ - stdio/mingw_lock.c - - src_ucrtbase = \ -@@ -11079,6 +11085,8 @@ secapi/lib32_libmsvcrt_os_a-wmemcpy_s.$(OBJEXT): \ - secapi/$(am__dirstamp) secapi/$(DEPDIR)/$(am__dirstamp) - secapi/lib32_libmsvcrt_os_a-wmemmove_s.$(OBJEXT): \ - secapi/$(am__dirstamp) secapi/$(DEPDIR)/$(am__dirstamp) -+stdio/lib32_libmsvcrt_os_a-fseeki64.$(OBJEXT): stdio/$(am__dirstamp) \ -+ stdio/$(DEPDIR)/$(am__dirstamp) - stdio/lib32_libmsvcrt_os_a-mingw_lock.$(OBJEXT): \ - stdio/$(am__dirstamp) stdio/$(DEPDIR)/$(am__dirstamp) - misc/lib32_libmsvcrt_os_a-lc_locale_func.$(OBJEXT): \ -@@ -12926,6 +12934,8 @@ secapi/lib64_libmsvcrt_os_a-wmemcpy_s.$(OBJEXT): \ - secapi/$(am__dirstamp) secapi/$(DEPDIR)/$(am__dirstamp) - secapi/lib64_libmsvcrt_os_a-wmemmove_s.$(OBJEXT): \ - secapi/$(am__dirstamp) secapi/$(DEPDIR)/$(am__dirstamp) -+stdio/lib64_libmsvcrt_os_a-fseeki64.$(OBJEXT): stdio/$(am__dirstamp) \ -+ stdio/$(DEPDIR)/$(am__dirstamp) - stdio/lib64_libmsvcrt_os_a-mingw_lock.$(OBJEXT): \ - stdio/$(am__dirstamp) stdio/$(DEPDIR)/$(am__dirstamp) - misc/lib64_libmsvcrt_os_a-__p___argv.$(OBJEXT): misc/$(am__dirstamp) \ -@@ -14664,6 +14674,8 @@ secapi/libarm32_libmsvcrt_os_a-wmemcpy_s.$(OBJEXT): \ - secapi/$(am__dirstamp) secapi/$(DEPDIR)/$(am__dirstamp) - secapi/libarm32_libmsvcrt_os_a-wmemmove_s.$(OBJEXT): \ - secapi/$(am__dirstamp) secapi/$(DEPDIR)/$(am__dirstamp) -+stdio/libarm32_libmsvcrt_os_a-fseeki64.$(OBJEXT): \ -+ stdio/$(am__dirstamp) stdio/$(DEPDIR)/$(am__dirstamp) - stdio/libarm32_libmsvcrt_os_a-mingw_lock.$(OBJEXT): \ - stdio/$(am__dirstamp) stdio/$(DEPDIR)/$(am__dirstamp) - misc/libarm32_libmsvcrt_os_a-__p___argv.$(OBJEXT): \ -@@ -16183,6 +16195,8 @@ secapi/libarm64_libmsvcrt_os_a-wmemcpy_s.$(OBJEXT): \ - secapi/$(am__dirstamp) secapi/$(DEPDIR)/$(am__dirstamp) - secapi/libarm64_libmsvcrt_os_a-wmemmove_s.$(OBJEXT): \ - secapi/$(am__dirstamp) secapi/$(DEPDIR)/$(am__dirstamp) -+stdio/libarm64_libmsvcrt_os_a-fseeki64.$(OBJEXT): \ -+ stdio/$(am__dirstamp) stdio/$(DEPDIR)/$(am__dirstamp) - stdio/libarm64_libmsvcrt_os_a-mingw_lock.$(OBJEXT): \ - stdio/$(am__dirstamp) stdio/$(DEPDIR)/$(am__dirstamp) - misc/libarm64_libmsvcrt_os_a-__p___argv.$(OBJEXT): \ -@@ -20029,6 +20043,7 @@ distclean-compile: - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/lib32_libmsvcr90_a-acrt_iob_func.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/lib32_libmsvcr90d_a-acrt_iob_func.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/lib32_libmsvcrt_os_a-acrt_iob_func.Po@am__quote@ -+@AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/lib32_libmsvcrt_os_a-fseeki64.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/lib32_libmsvcrt_os_a-mingw_lock.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/lib32_libucrt_extra_a-ucrt__vsnprintf.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/lib32_libucrt_extra_a-ucrt__vsnwprintf.Po@am__quote@ -@@ -20141,6 +20156,7 @@ distclean-compile: - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/lib64_libmsvcr90_a-acrt_iob_func.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/lib64_libmsvcr90d_a-acrt_iob_func.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/lib64_libmsvcrt_os_a-acrt_iob_func.Po@am__quote@ -+@AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/lib64_libmsvcrt_os_a-fseeki64.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/lib64_libmsvcrt_os_a-mingw_lock.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/lib64_libucrt_extra_a-ucrt__vsnprintf.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/lib64_libucrt_extra_a-ucrt__vsnwprintf.Po@am__quote@ -@@ -20245,6 +20261,7 @@ distclean-compile: - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/libarm32_libmingwex_a-wtoll.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/libarm32_libmsvcr110_a-acrt_iob_func.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/libarm32_libmsvcrt_os_a-acrt_iob_func.Po@am__quote@ -+@AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/libarm32_libmsvcrt_os_a-fseeki64.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/libarm32_libmsvcrt_os_a-mingw_lock.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/libarm32_libucrt_extra_a-ucrt__vsnprintf.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/libarm32_libucrt_extra_a-ucrt__vsnwprintf.Po@am__quote@ -@@ -20348,6 +20365,7 @@ distclean-compile: - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/libarm64_libmingwex_a-vwscanf2.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/libarm64_libmingwex_a-wtoll.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/libarm64_libmsvcrt_os_a-acrt_iob_func.Po@am__quote@ -+@AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/libarm64_libmsvcrt_os_a-fseeki64.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/libarm64_libmsvcrt_os_a-mingw_lock.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/libarm64_libucrt_extra_a-ucrt__vsnprintf.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@stdio/$(DEPDIR)/libarm64_libucrt_extra_a-ucrt__vsnwprintf.Po@am__quote@ -@@ -30851,6 +30869,20 @@ secapi/lib32_libmsvcrt_os_a-wmemmove_s.obj: secapi/wmemmove_s.c - @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib32_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o secapi/lib32_libmsvcrt_os_a-wmemmove_s.obj `if test -f 'secapi/wmemmove_s.c'; then $(CYGPATH_W) 'secapi/wmemmove_s.c'; else $(CYGPATH_W) '$(srcdir)/secapi/wmemmove_s.c'; fi` - -+stdio/lib32_libmsvcrt_os_a-fseeki64.o: stdio/fseeki64.c -+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib32_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stdio/lib32_libmsvcrt_os_a-fseeki64.o -MD -MP -MF stdio/$(DEPDIR)/lib32_libmsvcrt_os_a-fseeki64.Tpo -c -o stdio/lib32_libmsvcrt_os_a-fseeki64.o `test -f 'stdio/fseeki64.c' || echo '$(srcdir)/'`stdio/fseeki64.c -+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) stdio/$(DEPDIR)/lib32_libmsvcrt_os_a-fseeki64.Tpo stdio/$(DEPDIR)/lib32_libmsvcrt_os_a-fseeki64.Po -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stdio/fseeki64.c' object='stdio/lib32_libmsvcrt_os_a-fseeki64.o' libtool=no @AMDEPBACKSLASH@ -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib32_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stdio/lib32_libmsvcrt_os_a-fseeki64.o `test -f 'stdio/fseeki64.c' || echo '$(srcdir)/'`stdio/fseeki64.c -+ -+stdio/lib32_libmsvcrt_os_a-fseeki64.obj: stdio/fseeki64.c -+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib32_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stdio/lib32_libmsvcrt_os_a-fseeki64.obj -MD -MP -MF stdio/$(DEPDIR)/lib32_libmsvcrt_os_a-fseeki64.Tpo -c -o stdio/lib32_libmsvcrt_os_a-fseeki64.obj `if test -f 'stdio/fseeki64.c'; then $(CYGPATH_W) 'stdio/fseeki64.c'; else $(CYGPATH_W) '$(srcdir)/stdio/fseeki64.c'; fi` -+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) stdio/$(DEPDIR)/lib32_libmsvcrt_os_a-fseeki64.Tpo stdio/$(DEPDIR)/lib32_libmsvcrt_os_a-fseeki64.Po -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stdio/fseeki64.c' object='stdio/lib32_libmsvcrt_os_a-fseeki64.obj' libtool=no @AMDEPBACKSLASH@ -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib32_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stdio/lib32_libmsvcrt_os_a-fseeki64.obj `if test -f 'stdio/fseeki64.c'; then $(CYGPATH_W) 'stdio/fseeki64.c'; else $(CYGPATH_W) '$(srcdir)/stdio/fseeki64.c'; fi` -+ - stdio/lib32_libmsvcrt_os_a-mingw_lock.o: stdio/mingw_lock.c - @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib32_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stdio/lib32_libmsvcrt_os_a-mingw_lock.o -MD -MP -MF stdio/$(DEPDIR)/lib32_libmsvcrt_os_a-mingw_lock.Tpo -c -o stdio/lib32_libmsvcrt_os_a-mingw_lock.o `test -f 'stdio/mingw_lock.c' || echo '$(srcdir)/'`stdio/mingw_lock.c - @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) stdio/$(DEPDIR)/lib32_libmsvcrt_os_a-mingw_lock.Tpo stdio/$(DEPDIR)/lib32_libmsvcrt_os_a-mingw_lock.Po -@@ -41099,6 +41131,20 @@ secapi/lib64_libmsvcrt_os_a-wmemmove_s.obj: secapi/wmemmove_s.c - @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib64_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o secapi/lib64_libmsvcrt_os_a-wmemmove_s.obj `if test -f 'secapi/wmemmove_s.c'; then $(CYGPATH_W) 'secapi/wmemmove_s.c'; else $(CYGPATH_W) '$(srcdir)/secapi/wmemmove_s.c'; fi` - -+stdio/lib64_libmsvcrt_os_a-fseeki64.o: stdio/fseeki64.c -+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib64_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stdio/lib64_libmsvcrt_os_a-fseeki64.o -MD -MP -MF stdio/$(DEPDIR)/lib64_libmsvcrt_os_a-fseeki64.Tpo -c -o stdio/lib64_libmsvcrt_os_a-fseeki64.o `test -f 'stdio/fseeki64.c' || echo '$(srcdir)/'`stdio/fseeki64.c -+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) stdio/$(DEPDIR)/lib64_libmsvcrt_os_a-fseeki64.Tpo stdio/$(DEPDIR)/lib64_libmsvcrt_os_a-fseeki64.Po -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stdio/fseeki64.c' object='stdio/lib64_libmsvcrt_os_a-fseeki64.o' libtool=no @AMDEPBACKSLASH@ -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib64_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stdio/lib64_libmsvcrt_os_a-fseeki64.o `test -f 'stdio/fseeki64.c' || echo '$(srcdir)/'`stdio/fseeki64.c -+ -+stdio/lib64_libmsvcrt_os_a-fseeki64.obj: stdio/fseeki64.c -+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib64_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stdio/lib64_libmsvcrt_os_a-fseeki64.obj -MD -MP -MF stdio/$(DEPDIR)/lib64_libmsvcrt_os_a-fseeki64.Tpo -c -o stdio/lib64_libmsvcrt_os_a-fseeki64.obj `if test -f 'stdio/fseeki64.c'; then $(CYGPATH_W) 'stdio/fseeki64.c'; else $(CYGPATH_W) '$(srcdir)/stdio/fseeki64.c'; fi` -+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) stdio/$(DEPDIR)/lib64_libmsvcrt_os_a-fseeki64.Tpo stdio/$(DEPDIR)/lib64_libmsvcrt_os_a-fseeki64.Po -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stdio/fseeki64.c' object='stdio/lib64_libmsvcrt_os_a-fseeki64.obj' libtool=no @AMDEPBACKSLASH@ -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib64_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stdio/lib64_libmsvcrt_os_a-fseeki64.obj `if test -f 'stdio/fseeki64.c'; then $(CYGPATH_W) 'stdio/fseeki64.c'; else $(CYGPATH_W) '$(srcdir)/stdio/fseeki64.c'; fi` -+ - stdio/lib64_libmsvcrt_os_a-mingw_lock.o: stdio/mingw_lock.c - @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib64_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stdio/lib64_libmsvcrt_os_a-mingw_lock.o -MD -MP -MF stdio/$(DEPDIR)/lib64_libmsvcrt_os_a-mingw_lock.Tpo -c -o stdio/lib64_libmsvcrt_os_a-mingw_lock.o `test -f 'stdio/mingw_lock.c' || echo '$(srcdir)/'`stdio/mingw_lock.c - @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) stdio/$(DEPDIR)/lib64_libmsvcrt_os_a-mingw_lock.Tpo stdio/$(DEPDIR)/lib64_libmsvcrt_os_a-mingw_lock.Po -@@ -50871,6 +50917,20 @@ secapi/libarm32_libmsvcrt_os_a-wmemmove_s.obj: secapi/wmemmove_s.c - @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarm32_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o secapi/libarm32_libmsvcrt_os_a-wmemmove_s.obj `if test -f 'secapi/wmemmove_s.c'; then $(CYGPATH_W) 'secapi/wmemmove_s.c'; else $(CYGPATH_W) '$(srcdir)/secapi/wmemmove_s.c'; fi` - -+stdio/libarm32_libmsvcrt_os_a-fseeki64.o: stdio/fseeki64.c -+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarm32_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stdio/libarm32_libmsvcrt_os_a-fseeki64.o -MD -MP -MF stdio/$(DEPDIR)/libarm32_libmsvcrt_os_a-fseeki64.Tpo -c -o stdio/libarm32_libmsvcrt_os_a-fseeki64.o `test -f 'stdio/fseeki64.c' || echo '$(srcdir)/'`stdio/fseeki64.c -+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) stdio/$(DEPDIR)/libarm32_libmsvcrt_os_a-fseeki64.Tpo stdio/$(DEPDIR)/libarm32_libmsvcrt_os_a-fseeki64.Po -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stdio/fseeki64.c' object='stdio/libarm32_libmsvcrt_os_a-fseeki64.o' libtool=no @AMDEPBACKSLASH@ -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarm32_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stdio/libarm32_libmsvcrt_os_a-fseeki64.o `test -f 'stdio/fseeki64.c' || echo '$(srcdir)/'`stdio/fseeki64.c -+ -+stdio/libarm32_libmsvcrt_os_a-fseeki64.obj: stdio/fseeki64.c -+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarm32_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stdio/libarm32_libmsvcrt_os_a-fseeki64.obj -MD -MP -MF stdio/$(DEPDIR)/libarm32_libmsvcrt_os_a-fseeki64.Tpo -c -o stdio/libarm32_libmsvcrt_os_a-fseeki64.obj `if test -f 'stdio/fseeki64.c'; then $(CYGPATH_W) 'stdio/fseeki64.c'; else $(CYGPATH_W) '$(srcdir)/stdio/fseeki64.c'; fi` -+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) stdio/$(DEPDIR)/libarm32_libmsvcrt_os_a-fseeki64.Tpo stdio/$(DEPDIR)/libarm32_libmsvcrt_os_a-fseeki64.Po -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stdio/fseeki64.c' object='stdio/libarm32_libmsvcrt_os_a-fseeki64.obj' libtool=no @AMDEPBACKSLASH@ -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarm32_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stdio/libarm32_libmsvcrt_os_a-fseeki64.obj `if test -f 'stdio/fseeki64.c'; then $(CYGPATH_W) 'stdio/fseeki64.c'; else $(CYGPATH_W) '$(srcdir)/stdio/fseeki64.c'; fi` -+ - stdio/libarm32_libmsvcrt_os_a-mingw_lock.o: stdio/mingw_lock.c - @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarm32_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stdio/libarm32_libmsvcrt_os_a-mingw_lock.o -MD -MP -MF stdio/$(DEPDIR)/libarm32_libmsvcrt_os_a-mingw_lock.Tpo -c -o stdio/libarm32_libmsvcrt_os_a-mingw_lock.o `test -f 'stdio/mingw_lock.c' || echo '$(srcdir)/'`stdio/mingw_lock.c - @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) stdio/$(DEPDIR)/libarm32_libmsvcrt_os_a-mingw_lock.Tpo stdio/$(DEPDIR)/libarm32_libmsvcrt_os_a-mingw_lock.Po -@@ -59565,6 +59625,20 @@ secapi/libarm64_libmsvcrt_os_a-wmemmove_s.obj: secapi/wmemmove_s.c - @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ - @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarm64_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o secapi/libarm64_libmsvcrt_os_a-wmemmove_s.obj `if test -f 'secapi/wmemmove_s.c'; then $(CYGPATH_W) 'secapi/wmemmove_s.c'; else $(CYGPATH_W) '$(srcdir)/secapi/wmemmove_s.c'; fi` - -+stdio/libarm64_libmsvcrt_os_a-fseeki64.o: stdio/fseeki64.c -+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarm64_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stdio/libarm64_libmsvcrt_os_a-fseeki64.o -MD -MP -MF stdio/$(DEPDIR)/libarm64_libmsvcrt_os_a-fseeki64.Tpo -c -o stdio/libarm64_libmsvcrt_os_a-fseeki64.o `test -f 'stdio/fseeki64.c' || echo '$(srcdir)/'`stdio/fseeki64.c -+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) stdio/$(DEPDIR)/libarm64_libmsvcrt_os_a-fseeki64.Tpo stdio/$(DEPDIR)/libarm64_libmsvcrt_os_a-fseeki64.Po -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stdio/fseeki64.c' object='stdio/libarm64_libmsvcrt_os_a-fseeki64.o' libtool=no @AMDEPBACKSLASH@ -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarm64_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stdio/libarm64_libmsvcrt_os_a-fseeki64.o `test -f 'stdio/fseeki64.c' || echo '$(srcdir)/'`stdio/fseeki64.c -+ -+stdio/libarm64_libmsvcrt_os_a-fseeki64.obj: stdio/fseeki64.c -+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarm64_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stdio/libarm64_libmsvcrt_os_a-fseeki64.obj -MD -MP -MF stdio/$(DEPDIR)/libarm64_libmsvcrt_os_a-fseeki64.Tpo -c -o stdio/libarm64_libmsvcrt_os_a-fseeki64.obj `if test -f 'stdio/fseeki64.c'; then $(CYGPATH_W) 'stdio/fseeki64.c'; else $(CYGPATH_W) '$(srcdir)/stdio/fseeki64.c'; fi` -+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) stdio/$(DEPDIR)/libarm64_libmsvcrt_os_a-fseeki64.Tpo stdio/$(DEPDIR)/libarm64_libmsvcrt_os_a-fseeki64.Po -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stdio/fseeki64.c' object='stdio/libarm64_libmsvcrt_os_a-fseeki64.obj' libtool=no @AMDEPBACKSLASH@ -+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarm64_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stdio/libarm64_libmsvcrt_os_a-fseeki64.obj `if test -f 'stdio/fseeki64.c'; then $(CYGPATH_W) 'stdio/fseeki64.c'; else $(CYGPATH_W) '$(srcdir)/stdio/fseeki64.c'; fi` -+ - stdio/libarm64_libmsvcrt_os_a-mingw_lock.o: stdio/mingw_lock.c - @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarm64_libmsvcrt_os_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stdio/libarm64_libmsvcrt_os_a-mingw_lock.o -MD -MP -MF stdio/$(DEPDIR)/libarm64_libmsvcrt_os_a-mingw_lock.Tpo -c -o stdio/libarm64_libmsvcrt_os_a-mingw_lock.o `test -f 'stdio/mingw_lock.c' || echo '$(srcdir)/'`stdio/mingw_lock.c - @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) stdio/$(DEPDIR)/libarm64_libmsvcrt_os_a-mingw_lock.Tpo stdio/$(DEPDIR)/libarm64_libmsvcrt_os_a-mingw_lock.Po -diff --git a/mingw-w64-crt/lib32/msvcr100.def.in b/mingw-w64-crt/lib32/msvcr100.def.in -index 53ccd37b..1c6ae3dc 100644 ---- a/mingw-w64-crt/lib32/msvcr100.def.in -+++ b/mingw-w64-crt/lib32/msvcr100.def.in -@@ -880,7 +880,7 @@ _freefls@4 - _fscanf_l - _fscanf_s_l - _fseek_nolock --_fseeki64 DATA -+_fseeki64 - _fseeki64_nolock - _fsopen - _fstat32 -@@ -890,7 +890,7 @@ _fstat32i64 - _fstat64 - _fstat64i32 - _ftell_nolock --_ftelli64 DATA -+_ftelli64 - _ftelli64_nolock - _ftime32 - _ftime32_s -diff --git a/mingw-w64-crt/lib32/msvcr90.def.in b/mingw-w64-crt/lib32/msvcr90.def.in -index 69765e53..fd4ef944 100644 ---- a/mingw-w64-crt/lib32/msvcr90.def.in -+++ b/mingw-w64-crt/lib32/msvcr90.def.in -@@ -507,7 +507,7 @@ _freefls@4 - _fscanf_l - _fscanf_s_l - _fseek_nolock --_fseeki64 DATA -+_fseeki64 - _fseeki64_nolock - _fsopen - _fstat32 -@@ -517,7 +517,7 @@ _fstat32i64 - _fstat64 - _fstat64i32 - _ftell_nolock --_ftelli64 DATA -+_ftelli64 - _ftelli64_nolock - _ftime32 - _ftime32_s -diff --git a/mingw-w64-crt/lib64/msvcr100.def.in b/mingw-w64-crt/lib64/msvcr100.def.in -index b1e3e073..68c09d6c 100644 ---- a/mingw-w64-crt/lib64/msvcr100.def.in -+++ b/mingw-w64-crt/lib64/msvcr100.def.in -@@ -837,7 +837,7 @@ _freefls - _fscanf_l - _fscanf_s_l - _fseek_nolock --_fseeki64 DATA -+_fseeki64 - _fseeki64_nolock - _fsopen - _fstat32 -@@ -847,7 +847,7 @@ _fstat32i64 - _fstat64 - _fstat64i32 - _ftell_nolock --_ftelli64 DATA -+_ftelli64 - _ftelli64_nolock - _ftime32 - _ftime32_s -diff --git a/mingw-w64-crt/lib64/msvcr90.def.in b/mingw-w64-crt/lib64/msvcr90.def.in -index 72f30700..49b57010 100644 ---- a/mingw-w64-crt/lib64/msvcr90.def.in -+++ b/mingw-w64-crt/lib64/msvcr90.def.in -@@ -454,7 +454,7 @@ _freefls - _fscanf_l - _fscanf_s_l - _fseek_nolock --_fseeki64 DATA -+_fseeki64 - _fseeki64_nolock - _fsopen - _fstat32 -@@ -464,7 +464,7 @@ _fstat32i64 - _fstat64 - _fstat64i32 - _ftell_nolock --_ftelli64 DATA -+_ftelli64 - _ftelli64_nolock - _ftime32 - _ftime32_s -diff --git a/mingw-w64-crt/stdio/fseeki64.c b/mingw-w64-crt/stdio/fseeki64.c -new file mode 100644 -index 00000000..fdb8f1c1 ---- /dev/null -+++ b/mingw-w64-crt/stdio/fseeki64.c -@@ -0,0 +1,177 @@ -+/** -+ * This file has no copyright assigned and is placed in the Public Domain. -+ * This file is part of the mingw-w64 runtime package. -+ * No warranty is given; refer to the file DISCLAIMER.PD within this package. -+ */ -+#include -+#include -+#include -+#include -+ -+#define _IOYOURBUF 0x0100 -+#define _IOSETVBUF 0x0400 -+#define _IOFEOF 0x0800 -+#define _IOFLRTN 0x1000 -+#define _IOCTRLZ 0x2000 -+#define _IOCOMMIT 0x4000 -+ -+/* General use macros */ -+ -+#define inuse(s) ((s)->_flag & (_IOREAD|_IOWRT|_IORW)) -+#define mbuf(s) ((s)->_flag & _IOMYBUF) -+#define nbuf(s) ((s)->_flag & _IONBF) -+#define ybuf(s) ((s)->_flag & _IOYOURBUF) -+#define bigbuf(s) ((s)->_flag & (_IOMYBUF|_IOYOURBUF)) -+#define anybuf(s) ((s)->_flag & (_IOMYBUF|_IONBF|_IOYOURBUF)) -+ -+#define _INTERNAL_BUFSIZ 4096 -+#define _SMALL_BUFSIZ 512 -+ -+#define FOPEN 0x01 /* file handle open */ -+#define FEOFLAG 0x02 /* end of file has been encountered */ -+#define FCRLF 0x04 /* CR-LF across read buffer (in text mode) */ -+#define FPIPE 0x08 /* file handle refers to a pipe */ -+#define FNOINHERIT 0x10 /* file handle opened _O_NOINHERIT */ -+#define FAPPEND 0x20 /* file handle opened O_APPEND */ -+#define FDEV 0x40 /* file handle refers to device */ -+#define FTEXT 0x80 /* file handle is in text mode */ -+ -+_CRTIMP __int64 __cdecl _lseeki64(int fh,__int64 pos,int mthd); -+__int64 __cdecl _ftelli64(FILE *str); -+ -+#if !defined(__arm__) && !defined(__aarch64__) /* we have F_ARM_ANY(_fseeki64) in msvcrt.def.in */ -+int __cdecl _flush (FILE *str); -+ -+int __cdecl _flush (FILE *str) -+{ -+ FILE *stream; -+ int rc = 0; /* assume good return */ -+ __int64 nchar; -+ -+ stream = str; -+ if ((stream->_flag & (_IOREAD | _IOWRT)) == _IOWRT && bigbuf(stream) -+ && (nchar = (__int64) (stream->_ptr - stream->_base)) > 0ll) -+ { -+ if ( _write(_fileno(stream), stream->_base, nchar) == nchar) { -+ if (_IORW & stream->_flag) -+ stream->_flag &= ~_IOWRT; -+ } else { -+ stream->_flag |= _IOERR; -+ rc = EOF; -+ } -+ } -+ stream->_ptr = stream->_base; -+ stream->_cnt = 0ll; -+ return rc; -+} -+ -+int __cdecl _fseeki64(FILE *str,__int64 offset,int whence) -+{ -+ FILE *stream; -+ /* Init stream pointer */ -+ stream = str; -+ errno=0; -+ if(!stream || ((whence != SEEK_SET) && (whence != SEEK_CUR) && (whence != SEEK_END))) -+ { -+ errno=EINVAL; -+ return -1; -+ } -+ /* Clear EOF flag */ -+ stream->_flag &= ~_IOEOF; -+ -+ if (whence == SEEK_CUR) { -+ offset += _ftelli64(stream); -+ whence = SEEK_SET; -+ } -+ /* Flush buffer as necessary */ -+ _flush(stream); -+ -+ /* If file opened for read/write, clear flags since we don't know -+ what the user is going to do next. If the file was opened for -+ read access only, decrease _bufsiz so that the next _filbuf -+ won't cost quite so much */ -+ -+ if (stream->_flag & _IORW) -+ stream->_flag &= ~(_IOWRT|_IOREAD); -+ else if ( (stream->_flag & _IOREAD) && (stream->_flag & _IOMYBUF) && -+ !(stream->_flag & _IOSETVBUF) ) -+ stream->_bufsiz = _SMALL_BUFSIZ; -+ -+ /* Seek to the desired locale and return. */ -+ -+ return (_lseeki64(_fileno(stream), offset, whence) == -1ll ? -1 : 0); -+} -+ -+int __cdecl (*__MINGW_IMP_SYMBOL(_fseeki64))(FILE *, __int64, int) = _fseeki64; -+#endif /* !defined(__arm__) && !defined(__aarch64__) */ -+ -+__int64 __cdecl _ftelli64(FILE *str) -+{ -+ FILE *stream; -+ size_t offset; -+ __int64 filepos; -+ register char *p; -+ char *max; -+ int fd; -+ size_t rdcnt = 0; -+ -+ errno=0; -+ stream = str; -+ fd = _fileno(stream); -+ if (stream->_cnt < 0ll) stream->_cnt = 0ll; -+ if ((filepos = _lseeki64(fd, 0ll, SEEK_CUR)) < 0L) -+ return -1ll; -+ -+ if (!bigbuf(stream)) /* _IONBF or no buffering designated */ -+ return (filepos - (__int64) stream->_cnt); -+ -+ offset = (size_t)(stream->_ptr - stream->_base); -+ -+ if (stream->_flag & (_IOWRT|_IOREAD)) -+ { -+ if (_osfile(fd) & FTEXT) -+ for (p = stream->_base; p < stream->_ptr; p++) -+ if (*p == '\n') /* adjust for '\r' */ -+ offset++; -+ } -+ else if (!(stream->_flag & _IORW)) { -+ errno=EINVAL; -+ return -1ll; -+ } -+ if (filepos == 0ll) -+ return ((__int64)offset); -+ -+ if (stream->_flag & _IOREAD) /* go to preceding sector */ -+ { -+ if (stream->_cnt == 0ll) /* filepos holds correct location */ -+ offset = 0ll; -+ else -+ { -+ rdcnt = ((size_t) stream->_cnt) + ((size_t) (size_t)(stream->_ptr - stream->_base)); -+ if (_osfile(fd) & FTEXT) { -+ if (_lseeki64(fd, 0ll, SEEK_END) == filepos) { -+ max = stream->_base + rdcnt; -+ for (p = stream->_base; p < max; p++) -+ if (*p == '\n') /* adjust for '\r' */ -+ rdcnt++; -+ if (stream->_flag & _IOCTRLZ) -+ ++rdcnt; -+ } else { -+ _lseeki64(fd, filepos, SEEK_SET); -+ if ( (rdcnt <= _SMALL_BUFSIZ) && (stream->_flag & _IOMYBUF) && -+ !(stream->_flag & _IOSETVBUF)) -+ rdcnt = _SMALL_BUFSIZ; -+ else -+ rdcnt = stream->_bufsiz; -+ if (_osfile(fd) & FCRLF) -+ ++rdcnt; -+ } -+ } /* end if FTEXT */ -+ } -+ filepos -= (__int64)rdcnt; -+ } /* end else stream->_cnt != 0 */ -+ return (filepos + (__int64)offset); -+} -+ -+__int64 __cdecl (*__MINGW_IMP_SYMBOL(_ftelli64))(FILE *) = _ftelli64; -+ -diff --git a/mingw-w64-crt/stdio/fseeko64.c b/mingw-w64-crt/stdio/fseeko64.c -index 5905aa22..99a54f77 100644 ---- a/mingw-w64-crt/stdio/fseeko64.c -+++ b/mingw-w64-crt/stdio/fseeko64.c -@@ -76,33 +76,7 @@ static struct oserr_map local_errtab[] = { - { ERROR_NOT_ENOUGH_QUOTA, ENOMEM }, { 0, -1 } - }; - --_CRTIMP __int64 __cdecl _lseeki64(int fh,__int64 pos,int mthd); --__int64 __cdecl _ftelli64(FILE *str); - void mingw_dosmaperr (unsigned long oserrno); --int __cdecl _flush (FILE *str); -- --int __cdecl _flush (FILE *str) --{ -- FILE *stream; -- int rc = 0; /* assume good return */ -- __int64 nchar; -- -- stream = str; -- if ((stream->_flag & (_IOREAD | _IOWRT)) == _IOWRT && bigbuf(stream) -- && (nchar = (__int64) (stream->_ptr - stream->_base)) > 0ll) -- { -- if ( _write(_fileno(stream), stream->_base, nchar) == nchar) { -- if (_IORW & stream->_flag) -- stream->_flag &= ~_IOWRT; -- } else { -- stream->_flag |= _IOERR; -- rc = EOF; -- } -- } -- stream->_ptr = stream->_base; -- stream->_cnt = 0ll; -- return rc; --} - - int fseeko64 (FILE* stream, _off64_t offset, int whence) - { -@@ -130,111 +104,6 @@ int fseeko64 (FILE* stream, _off64_t offset, int whence) - return fsetpos (stream, &pos); - } - --int __cdecl _fseeki64(FILE *str,__int64 offset,int whence) --{ -- FILE *stream; -- /* Init stream pointer */ -- stream = str; -- errno=0; -- if(!stream || ((whence != SEEK_SET) && (whence != SEEK_CUR) && (whence != SEEK_END))) -- { -- errno=EINVAL; -- return -1; -- } -- /* Clear EOF flag */ -- stream->_flag &= ~_IOEOF; -- -- if (whence == SEEK_CUR) { -- offset += _ftelli64(stream); -- whence = SEEK_SET; -- } -- /* Flush buffer as necessary */ -- _flush(stream); -- -- /* If file opened for read/write, clear flags since we don't know -- what the user is going to do next. If the file was opened for -- read access only, decrease _bufsiz so that the next _filbuf -- won't cost quite so much */ -- -- if (stream->_flag & _IORW) -- stream->_flag &= ~(_IOWRT|_IOREAD); -- else if ( (stream->_flag & _IOREAD) && (stream->_flag & _IOMYBUF) && -- !(stream->_flag & _IOSETVBUF) ) -- stream->_bufsiz = _SMALL_BUFSIZ; -- -- /* Seek to the desired locale and return. */ -- -- return (_lseeki64(_fileno(stream), offset, whence) == -1ll ? -1 : 0); --} -- --__int64 __cdecl _ftelli64(FILE *str) --{ -- FILE *stream; -- size_t offset; -- __int64 filepos; -- register char *p; -- char *max; -- int fd; -- size_t rdcnt = 0; -- -- errno=0; -- stream = str; -- fd = _fileno(stream); -- if (stream->_cnt < 0ll) stream->_cnt = 0ll; -- if ((filepos = _lseeki64(fd, 0ll, SEEK_CUR)) < 0L) -- return -1ll; -- -- if (!bigbuf(stream)) /* _IONBF or no buffering designated */ -- return (filepos - (__int64) stream->_cnt); -- -- offset = (size_t)(stream->_ptr - stream->_base); -- -- if (stream->_flag & (_IOWRT|_IOREAD)) -- { -- if (_osfile(fd) & FTEXT) -- for (p = stream->_base; p < stream->_ptr; p++) -- if (*p == '\n') /* adjust for '\r' */ -- offset++; -- } -- else if (!(stream->_flag & _IORW)) { -- errno=EINVAL; -- return -1ll; -- } -- if (filepos == 0ll) -- return ((__int64)offset); -- -- if (stream->_flag & _IOREAD) /* go to preceding sector */ -- { -- if (stream->_cnt == 0ll) /* filepos holds correct location */ -- offset = 0ll; -- else -- { -- rdcnt = ((size_t) stream->_cnt) + ((size_t) (size_t)(stream->_ptr - stream->_base)); -- if (_osfile(fd) & FTEXT) { -- if (_lseeki64(fd, 0ll, SEEK_END) == filepos) { -- max = stream->_base + rdcnt; -- for (p = stream->_base; p < max; p++) -- if (*p == '\n') /* adjust for '\r' */ -- rdcnt++; -- if (stream->_flag & _IOCTRLZ) -- ++rdcnt; -- } else { -- _lseeki64(fd, filepos, SEEK_SET); -- if ( (rdcnt <= _SMALL_BUFSIZ) && (stream->_flag & _IOMYBUF) && -- !(stream->_flag & _IOSETVBUF)) -- rdcnt = _SMALL_BUFSIZ; -- else -- rdcnt = stream->_bufsiz; -- if (_osfile(fd) & FCRLF) -- ++rdcnt; -- } -- } /* end if FTEXT */ -- } -- filepos -= (__int64)rdcnt; -- } /* end else stream->_cnt != 0 */ -- return (filepos + (__int64)offset); --} -- - void mingw_dosmaperr (unsigned long oserrno) - { - size_t i; -diff --git a/mingw-w64-headers/crt/stdio.h b/mingw-w64-headers/crt/stdio.h -index d981f701..0ee6789d 100644 ---- a/mingw-w64-headers/crt/stdio.h -+++ b/mingw-w64-headers/crt/stdio.h -@@ -611,10 +611,9 @@ int vsnprintf (char *__stream, size_t __n, const char *__format, __builtin_va_li - - /* Shouldn't be any fseeko32 in glibc, 32bit to 64bit casting should be fine */ - /* int fseeko32(FILE* stream, _off_t offset, int whence);*/ /* fseeko32 redirects to fseeko64 */ --#if __MSVCRT_VERSION__ >= 0x1400 -- // Mark these as _CRTIMP to avoid trying to link in the mingwex versions. - _CRTIMP int __cdecl _fseeki64(FILE *_File,__int64 _Offset,int _Origin); - _CRTIMP __int64 __cdecl _ftelli64(FILE *_File); -+#if __MSVCRT_VERSION__ >= 0x1400 - __mingw_static_ovr int fseeko(FILE *_File, _off_t _Offset, int _Origin) { - return fseek(_File, _Offset, _Origin); - } -@@ -628,8 +627,6 @@ int vsnprintf (char *__stream, size_t __n, const char *__format, __builtin_va_li - return _ftelli64(_File); - } - #else -- __MINGW_EXTENSION int __cdecl _fseeki64(FILE *_File,__int64 _Offset,int _Origin); -- __MINGW_EXTENSION __int64 __cdecl _ftelli64(FILE *_File); - int fseeko64(FILE* stream, _off64_t offset, int whence); - int fseeko(FILE* stream, _off_t offset, int whence); - /* Returns truncated 64bit off_t */ --- -2.14.1 - diff --git a/recipes-toolchain/mpc.recipe b/recipes-toolchain/mpc.recipe index f47b2e033..d911af0e6 100644 --- a/recipes-toolchain/mpc.recipe +++ b/recipes-toolchain/mpc.recipe @@ -2,16 +2,12 @@ class Recipe(recipe.Recipe): name = 'mpc' - version = '1.1.0' + version = '1.3.1' url = 'https://ftp.gnu.org/gnu/mpc/mpc-%(version)s.tar.gz' - tarball_checksum = '6985c538143c1208dcb1ac42cedad6ff52e267b47e5f970183a3e75125b43c2e' + tarball_checksum = 'ab642492f5cf882b74aa0cb730cd410a81edcdbec895183ce930e706c1c759b8' stype = SourceType.TARBALL licenses = [License.LGPLv2_1Plus] configure_options = "--disable-shared --enable-static" deps = ['mpfr'] - async def configure(self): - shell.new_call(['chmod', '+w', 'config.guess'], self.build_dir) - shell.new_call(['chmod', '+w', 'config.sub'], self.build_dir) - shell.new_call(['chmod', '+w', 'ltmain.sh'], self.build_dir) - await super(Recipe, self).configure() + override_libtool = False diff --git a/recipes-toolchain/mpfr.recipe b/recipes-toolchain/mpfr.recipe index 5104b5081..a5bbddb82 100644 --- a/recipes-toolchain/mpfr.recipe +++ b/recipes-toolchain/mpfr.recipe @@ -2,10 +2,12 @@ class Recipe(recipe.Recipe): name = 'mpfr' - version = '4.0.1' + version = '4.2.1' stype = SourceType.TARBALL url = 'https://ftpmirror.gnu.org/gnu/mpfr/mpfr-%(version)s.tar.bz2' - tarball_checksum = 'a4d97610ba8579d380b384b225187c250ef88cfe1d5e7226b89519374209b86b' + tarball_checksum = 'b9df93635b20e4089c29623b19420c4ac848a1b29df1cfd59f26cab0d2666aa0' licenses = [License.LGPLv3Plus] configure_options = "--disable-shared --enable-static" deps = ['gmp'] + + override_libtool = False diff --git a/recipes-toolchain/toolchain.recipe b/recipes-toolchain/toolchain.recipe index 138c03d24..7dbf54e64 100644 --- a/recipes-toolchain/toolchain.recipe +++ b/recipes-toolchain/toolchain.recipe @@ -1,6 +1,8 @@ class Recipe(recipe.Recipe): name = 'toolchain' - version = '8.2.0' + version = '14.2.0' stype = SourceType.CUSTOM btype = BuildType.CUSTOM - deps = ['gcc', 'gendef'] + deps = ['gcc', 'gendef', 'winstorecompat'] + can_msvc = False + diff --git a/recipes-toolchain/windows-default-manifest.recipe b/recipes-toolchain/windows-default-manifest.recipe new file mode 100644 index 000000000..683a567b9 --- /dev/null +++ b/recipes-toolchain/windows-default-manifest.recipe @@ -0,0 +1,61 @@ +# -*- Mode: Python -*- vi:si:et:sw=4:sts=4:ts=4:syntax=python +from pathlib import Path +from cerbero.build.build import modify_environment + +class Recipe(recipe.Recipe): + name = 'windows-default-manifest' + version = '6.4' + stype = SourceType.GIT + remotes = {'origin': 'https://sourceware.org/git/cygwin-apps/%(name)s.git'} + commit = 'release-6_4' + licenses = [{License.BSD_like: ['COPYING']}] + deps = ['gcc-bootstrap'] + override_libtool = False + + def prepare(self): + if self.config.target_arch == Architecture.X86: + raise InvalidRecipeError(self) + # Since we are cross-compiling we have to reset all the env + # variables set by cerbero (eg: we don't want -m64 overriding + # a i386 build or gcc being used instead of x86_64-mingw32-w64-gcc) + for v in ['CC', 'LD', 'CPP', 'AS', 'RC', 'CXX', 'CFLAGS', 'LDFLAGS', + 'CXXFLAGS', 'CCASFLAGS', 'CPPFLAGS', 'RCFLAGS']: + self.set_env(v) + self.host = 'x86_64-w64-mingw32' + self.sysroot = f'{self.config.prefix}/{self.host}/sysroot' + self.make_install += [f'DESTDIR={self.sysroot}'] + self.configure_tpl = "%%(config-sh)s --prefix /usr/%(host)s "\ + "--libdir /usr/%(host)s %%(options)s" % {'host': self.host} + self.build_dir_32 = os.path.join(self.make_dir, 'cerbero-build-dir-32') + self.build_dir_64 = os.path.join(self.make_dir, 'cerbero-build-dir-64') + + @modify_environment + async def configure(self): + # Since the toolchain is built with multilib support + # this recipe builds winpthreads for both x86_64 and x86 + Path(self.build_dir_32).mkdir(exist_ok=True) + flags = "WINDRES=x86_64-w64-mingw32-windres " + target = 'i386-w64-mingw32' + libdir = "/usr/%s/lib32" % self.host + + self.configure_options += ' --build=%s' % self.host + # i686 is always a cross build + shell.new_call('%s ../configure --bindir=%s --libdir=%s --prefix=/usr/%s --host=%s %s' %\ + (flags, libdir, libdir, target, target, self.configure_options), + self.build_dir_32, logfile=self.logfile, env=self.env) + + Path(self.build_dir_64).mkdir(exist_ok=True) + flags = "WINDRES=x86_64-w64-mingw32-windres " + target = 'x86_64-w64-mingw32' + libdir = "/usr/%s/lib" % self.host + shell.new_call('%s ../configure --bindir=%s --libdir=%s --prefix=/usr/%s --host=%s %s' %\ + (flags, libdir, libdir, target, target, self.configure_options), + self.build_dir_64, logfile=self.logfile, env=self.env) + + async def compile(self): + shell.new_call(self.make, self.build_dir_32, logfile=self.logfile, env=self.env) + shell.new_call(self.make, self.build_dir_64, logfile=self.logfile, env=self.env) + + async def install(self): + shell.new_call(self.make_install, self.build_dir_32, logfile=self.logfile, env=self.env) + shell.new_call(self.make_install, self.build_dir_64, logfile=self.logfile, env=self.env) diff --git a/recipes-toolchain/winpthreads.recipe b/recipes-toolchain/winpthreads.recipe index 5ea587779..2e8ed2230 100644 --- a/recipes-toolchain/winpthreads.recipe +++ b/recipes-toolchain/winpthreads.recipe @@ -1,17 +1,17 @@ +from pathlib import Path import shutil from cerbero.build.build import modify_environment - class Recipe(recipe.Recipe): name = 'winpthreads' - version = 'v6.0.0' - licenses = [License.LGPLv2_1Plus] + version = 'v12.0.0' + licenses = [{License.BSD_like: ['COPYING']}] configure_options = '--enable-shared --enable-static' add_host_build_target = False autoreconf = True - allow_parallel_build = False + requires_non_src_build = True stype = SourceType.CUSTOM - deps = ['mingw-w64-headers'] + deps = ['mingw-w64-crt'] files_all = [ 'bin/libwinpthread-1.dll', 'lib/libpthread.a', @@ -25,76 +25,77 @@ class Recipe(recipe.Recipe): 'include/pthread_unistd.h', 'include/sched.h', 'include/semaphore.h', - ] + ] + + patches = [ + f'{name}/0001-Define-__-de-register_frame_info-in-fake-libgcc_s.patch', + ] + override_libtool = False def prepare(self): if self.config.target_arch == Architecture.X86: raise InvalidRecipeError(self) + if self.config.target_platform == Platform.LINUX: + self.deps.append('gcc-bootstrap') # Since we are cross-compiling we have to reset all the env # variables set by cerbero (eg: we don't want -m64 overriding # a i386 build or gcc being used instead of x86_64-mingw32-w64-gcc) - for v in ['CC', 'LD', 'CPP', 'AS', 'RC', 'CXX','CFLAGS', 'LDFLAGS', - 'CXXFLAGS', 'CCASFLAGS']: + for v in ['CC', 'LD', 'CPP', 'AS', 'RC', 'CXX', 'CFLAGS', 'LDFLAGS', + 'CXXFLAGS', 'CCASFLAGS', 'CPPFLAGS']: self.set_env(v) self.host = 'x86_64-w64-mingw32' - self.sysroot = os.path.join(self.config.prefix, self.host, 'sysroot') - self.configure_options += ' --with-sysroot=%s ' % self.sysroot - self.make_install = ['make', 'install', 'DESTDIR=' + self.sysroot] - self.build_dir = os.path.join(self.config.sources, - 'mingw-w64-%s' % self.version) - self.make_dir = os.path.join(self.config.sources, - 'mingw-w64-%s/mingw-w64-libraries/winpthreads' % self.version) + self.sysroot = f'{self.config.prefix}/{self.host}/sysroot' + self.configure_options += f' --with-sysroot={self.sysroot}' + self.make_install += [f'DESTDIR={self.sysroot}'] + self.config_src_dir = os.path.join(self.config.sources, f'mingw-w64-sources-{self.version}', 'mingw-w64-libraries', 'winpthreads') + self.build_dir = self.config_src_dir + self.make_dir = self.build_dir self.configure_tpl = "%%(config-sh)s --prefix /usr/%(host)s "\ "--libdir /usr/%(host)s %%(options)s" % {'host': self.host} - self.build_dir_32 = os.path.join(self.make_dir, 'winpthread_build_32') - self.build_dir_64 = os.path.join(self.make_dir, 'winpthread_build_64') + self.build_dir_32 = os.path.join(self.make_dir, 'cerbero-build-dir-32') + self.build_dir_64 = os.path.join(self.make_dir, 'cerbero-build-dir-64') @modify_environment - def configure(self): + async def configure(self): # Since the toolchain is built with multilib support # this recipe builds winpthreads for both x86_64 and x86 - try: - os.mkdir(self.build_dir_32) - except: - pass - flags = "CC=x86_64-w64-mingw32-gcc RC=x86_64-w64-mingw32-windres " \ + Path(self.build_dir_32).mkdir(exist_ok=True) + flags = "CC=x86_64-w64-mingw32-gcc CPP=x86_64-w64-mingw32-cpp RC=x86_64-w64-mingw32-windres " \ "LD=x86_64-w64-mingw32-ld LDFLAGS=' -m32' CFLAGS=' -m32' CXXFLAGS=' -m32' " \ "RCFLAGS='-F pe-i386' DLLTOOLFLAGS='-m i386'" host = 'i386-w64-mingw32' libdir = "/usr/%s/lib32" % self.host + # i686 is always a cross build shell.new_call('%s ../configure --bindir=%s --libdir=%s --prefix=/usr/%s --host=%s %s' %\ (flags, libdir, libdir, host, host, self.configure_options), - self.build_dir_32) + self.build_dir_32, logfile=self.logfile, env=self.env) - try: - os.mkdir(self.build_dir_64) - except: - pass - flags = "CC=x86_64-w64-mingw32-gcc RC=x86_64-w64-mingw32-windres " \ + Path(self.build_dir_64).mkdir(exist_ok=True) + flags = "CC=x86_64-w64-mingw32-gcc CPP=x86_64-w64-mingw32-cpp RC=x86_64-w64-mingw32-windres " \ "LD=x86_64-w64-mingw32-ld LDFLAGS=' -m64' CFLAGS=' -m64' CXXFLAGS=' -m64' " host = 'x86_64-w64-mingw32' libdir = "/usr/%s/lib" % self.host shell.new_call('%s ../configure --bindir=%s --libdir=%s --prefix=/usr/%s --host=%s %s' %\ (flags, libdir, libdir, host, host, self.configure_options), - self.build_dir_64) + self.build_dir_64, logfile=self.logfile, env=self.env) - def compile(self): - shell.new_call(self.make, self.build_dir_32) - shell.new_call(self.make, self.build_dir_64) + async def compile(self): + shell.new_call(self.make, self.build_dir_32, logfile=self.logfile, env=self.env) + shell.new_call(self.make, self.build_dir_64, logfile=self.logfile, env=self.env) - @modify_environment - def install(self): + async def install(self): src_winpthread_dll = "%s/usr/%s/bin/libwinpthread-1.dll" % \ (self.sysroot, self.host) libdir = "%s/usr/%s/lib32/" % (self.sysroot, self.host) dest_winpthread_dll = os.path.join(libdir, "libwinpthread-1.dll") - shell.new_call(self.make_install, self.build_dir_32) - if os.path.exists(dest_winpthread_dll): - os.remove(dest_winpthread_dll) + shell.new_call(self.make_install, self.build_dir_32, logfile=self.logfile, env=self.env) + Path(dest_winpthread_dll).unlink(missing_ok=True) shutil.move(src_winpthread_dll, dest_winpthread_dll) - shell.new_call(self.make_install, self.build_dir_64) + shell.new_call(self.make_install, self.build_dir_64, logfile=self.logfile, env=self.env) libdir = "%s/usr/%s/lib/" % (self.sysroot, self.host) dest_winpthread_dll = os.path.join(libdir, "libwinpthread-1.dll") - if os.path.exists(dest_winpthread_dll): - os.remove(dest_winpthread_dll) + Path(dest_winpthread_dll).unlink(missing_ok=True) shutil.move(src_winpthread_dll, libdir) + # and to /bin because dlltool depends on it + bindir = os.path.join(self.config.prefix, 'bin') + shutil.copy(libdir / "libwinpthread-1.dll", bindir) diff --git a/recipes-toolchain/winpthreads/0001-Define-__-de-register_frame_info-in-fake-libgcc_s.patch b/recipes-toolchain/winpthreads/0001-Define-__-de-register_frame_info-in-fake-libgcc_s.patch new file mode 100644 index 000000000..e6290f915 --- /dev/null +++ b/recipes-toolchain/winpthreads/0001-Define-__-de-register_frame_info-in-fake-libgcc_s.patch @@ -0,0 +1,46 @@ +From c402bcc0139033a365f30e00caecff9f8be40974 Mon Sep 17 00:00:00 2001 +From: Ray Donnelly +Date: Fri, 7 Nov 2014 22:43:58 +0000 +Subject: [PATCH] Define __{de,}register_frame_info in fake libgcc_s + +--- + mingw-w64-libraries/winpthreads/Makefile.am | 2 +- + mingw-w64-libraries/winpthreads/src/libgcc/dll_frame_info.c | 12 ++++++++++++ + 2 files changed, 13 insertions(+), 1 deletion(-) + create mode 100644 mingw-w64-libraries/winpthreads/src/libgcc/dll_frame_info.c + +diff --git a/mingw-w64-libraries/winpthreads/Makefile.am b/mingw-w64-libraries/winpthreads/Makefile.am +index 231c313..6d3b857 100644 +--- a/mingw-w64-libraries/winpthreads/Makefile.am ++++ b/mingw-w64-libraries/winpthreads/Makefile.am +@@ -25,7 +25,7 @@ libwinpthread_la_SOURCES = \ + # Break circular dep on bootstrap + noinst_LIBRARIES = fakelib/libgcc.a fakelib/libgcc_eh.a fakelib/libgcc_s.a + fakelib_libgcc_a_SOURCES = src/libgcc/dll_dependency.S src/libgcc/dll_math.c +-fakelib_libgcc_s_a_SOURCES = ++fakelib_libgcc_s_a_SOURCES = src/libgcc/dll_frame_info.c + fakelib_libgcc_eh_a_SOURCES = + endif + +diff --git a/mingw-w64-libraries/winpthreads/src/libgcc/dll_frame_info.c b/mingw-w64-libraries/winpthreads/src/libgcc/dll_frame_info.c +new file mode 100644 +index 0000000..115ac12 +--- /dev/null ++++ b/mingw-w64-libraries/winpthreads/src/libgcc/dll_frame_info.c +@@ -0,0 +1,13 @@ ++/* Because of: ++ https://github.com/Alexpux/MINGW-packages/blob/master/mingw-w64-gcc/955-4.9.2-apply-hack-so-gcc_s-isnt-stripped.patch ++ .. we need to define these functions. ++*/ ++ ++void __register_frame_info (__attribute__((unused)) const void *vp, __attribute__((unused)) void *op) ++{ ++} ++ ++void *__deregister_frame_info (__attribute__((unused)) const void *vp) ++{ ++ return (void *)0; ++} +-- +2.1.3 + diff --git a/recipes-toolchain/winstorecompat.recipe b/recipes-toolchain/winstorecompat.recipe new file mode 100644 index 000000000..393db1f11 --- /dev/null +++ b/recipes-toolchain/winstorecompat.recipe @@ -0,0 +1,63 @@ +from pathlib import Path +from cerbero.build.build import modify_environment + +class Recipe(recipe.Recipe): + name = 'winstorecompat' + version = 'v12.0.0' + licenses = [{License.MIT: ['COPYING']}] + requires_non_src_build = True + stype = SourceType.CUSTOM + deps = ['mingw-w64-crt', 'gcc'] + override_libtool = False + + def prepare(self): + if self.config.target_arch == Architecture.X86: + raise InvalidRecipeError(self) + # Since we are cross-compiling we have to reset all the env + # variables set by cerbero (eg: we don't want -m64 overriding + # a i386 build or gcc being used instead of x86_64-mingw32-w64-gcc) + for v in ['CC', 'LD', 'CPP', 'AS', 'RC', 'CXX', 'CFLAGS', 'LDFLAGS', + 'CXXFLAGS', 'CCASFLAGS', 'CPPFLAGS']: + self.set_env(v) + self.host = 'x86_64-w64-mingw32' + self.sysroot = f'{self.config.prefix}/{self.host}/sysroot' + self.make_install += [f'DESTDIR={self.sysroot}'] + self.config_src_dir = os.path.join(self.config.sources, f'mingw-w64-sources-{self.version}', 'mingw-w64-libraries', 'winstorecompat') + self.build_dir = self.config_src_dir + self.make_dir = self.build_dir + self.configure_tpl = "%%(config-sh)s --prefix /usr/%(host)s "\ + "--libdir /usr/%(host)s %%(options)s" % {'host': self.host} + self.build_dir_32 = os.path.join(self.make_dir, 'cerbero-build-dir-32') + self.build_dir_64 = os.path.join(self.make_dir, 'cerbero-build-dir-64') + + @modify_environment + async def configure(self): + # Since the toolchain is built with multilib support + # this recipe builds winpthreads for both x86_64 and x86 + Path(self.build_dir_32).mkdir(exist_ok=True) + flags = "CC=x86_64-w64-mingw32-gcc CPP=x86_64-w64-mingw32-cpp RC=x86_64-w64-mingw32-windres " \ + "LD=x86_64-w64-mingw32-ld LDFLAGS=' -m32' CFLAGS=' -m32' CXXFLAGS=' -m32' " \ + "RCFLAGS='-F pe-i386' DLLTOOLFLAGS='-m i386'" + host = 'i386-w64-mingw32' + libdir = "/usr/%s/lib32" % self.host + # i686 is always a cross build + shell.new_call('%s ../configure --bindir=%s --libdir=%s --prefix=/usr/%s --host=%s %s' %\ + (flags, libdir, libdir, host, host, self.configure_options), + self.build_dir_32, logfile=self.logfile, env=self.env) + + Path(self.build_dir_64).mkdir(exist_ok=True) + flags = "CC=x86_64-w64-mingw32-gcc CPP=x86_64-w64-mingw32-cpp RC=x86_64-w64-mingw32-windres " \ + "LD=x86_64-w64-mingw32-ld LDFLAGS=' -m64' CFLAGS=' -m64' CXXFLAGS=' -m64' " + host = 'x86_64-w64-mingw32' + libdir = "/usr/%s/lib" % self.host + shell.new_call('%s ../configure --bindir=%s --libdir=%s --prefix=/usr/%s --host=%s %s' %\ + (flags, libdir, libdir, host, host, self.configure_options), + self.build_dir_64, logfile=self.logfile, env=self.env) + + async def compile(self): + shell.new_call(self.make, self.build_dir_32, logfile=self.logfile, env=self.env) + shell.new_call(self.make, self.build_dir_64, logfile=self.logfile, env=self.env) + + async def install(self): + shell.new_call(self.make_install, self.build_dir_32, logfile=self.logfile, env=self.env) + shell.new_call(self.make_install, self.build_dir_64, logfile=self.logfile, env=self.env) diff --git a/recipes/build-tools/cargo-c.recipe b/recipes/build-tools/cargo-c.recipe index 13df28b4d..f73125006 100644 --- a/recipes/build-tools/cargo-c.recipe +++ b/recipes/build-tools/cargo-c.recipe @@ -2,11 +2,11 @@ class Recipe(recipe.Recipe): name = 'cargo-c' - version = '0.9.30' + version = '0.10.11' stype = SourceType.TARBALL btype = BuildType.CARGO - url = 'https://github.com/lu-zero/cargo-c/archive/refs/tags/v0.9.30.tar.gz' - tarball_checksum = '174cfc3a69263c3e54b95e00c4bd61b13377f7f72d4bf60aa714fd9e7ed3849c' + url = 'https://github.com/lu-zero/cargo-c/archive/refs/tags/v0.10.11.tar.gz' + tarball_checksum = '8a6d6dc589d6d70bd7eb95971e3c608240e1f9c938dd5b54a049977333b59f05' tarball_dirname = '%(name)s-%(version)s' # Get this from the release page on github cargo_lock = f'{name}/{version}-Cargo.lock' diff --git a/recipes/build-tools/cargo-c/0.9.30-Cargo.lock b/recipes/build-tools/cargo-c/0.10.11-Cargo.lock similarity index 59% rename from recipes/build-tools/cargo-c/0.9.30-Cargo.lock rename to recipes/build-tools/cargo-c/0.10.11-Cargo.lock index 3c031dc54..f1c2b53b1 100644 --- a/recipes/build-tools/cargo-c/0.9.30-Cargo.lock +++ b/recipes/build-tools/cargo-c/0.10.11-Cargo.lock @@ -1,18 +1,18 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", @@ -22,84 +22,108 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "annotate-snippets" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4" +dependencies = [ + "anstyle", + "unicode-width", +] [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "once_cell", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" [[package]] name = "arc-swap" -version = "1.6.0" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "base16ct" @@ -109,9 +133,9 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.21.7" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" @@ -121,15 +145,9 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.2" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "bitmaps" @@ -140,6 +158,20 @@ dependencies = [ "typenum", ] +[[package]] +name = "blake3" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1230237285e3e10cde447185e8975408ae24deaa67205ce684805c25bc0c7937" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "memmap2", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -151,52 +183,51 @@ dependencies = [ [[package]] name = "bstr" -version = "1.9.0" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" +checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" dependencies = [ "memchr", - "regex-automata 0.4.5", + "regex-automata 0.4.9", "serde", ] [[package]] -name = "btoi" -version = "0.4.3" +name = "bumpalo" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd6407f73a9b8b6162d8a2ef999fe6afd7cc15902ebf42c5cd296addf17e0ad" -dependencies = [ - "num-traits", -] +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] -name = "bumpalo" -version = "3.14.0" +name = "byteorder" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" [[package]] name = "bytesize" -version = "1.3.0" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" +checksum = "2d2c12f985c78475a6b8d629afd0c360260ef34cfef52efccdcfd31972f81c2e" [[package]] name = "cargo" -version = "0.77.0" +version = "0.86.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a399e5bde59d144aa2c7ba643765e2f8c6c3c601daa2da03202caf66f2552b3" +checksum = "62fdf5dbde4bf8d8149a4d32568d28d92af9dc4a4975727d89bd8dfb69fb810e" dependencies = [ + "annotate-snippets", "anstream", "anstyle", "anyhow", "base64", + "blake3", "bytesize", "cargo-credential", "cargo-credential-libsecret", @@ -204,7 +235,9 @@ dependencies = [ "cargo-credential-wincred", "cargo-platform", "cargo-util", + "cargo-util-schemas", "clap", + "clap_complete", "color-print", "crates-io", "curl", @@ -214,7 +247,6 @@ dependencies = [ "git2", "git2-curl", "gix", - "gix-features 0.35.0", "glob", "hex", "hmac", @@ -223,8 +255,8 @@ dependencies = [ "humantime", "ignore", "im-rc", - "indexmap 2.2.2", - "itertools", + "indexmap", + "itertools 0.13.0", "jobserver", "lazycell", "libc", @@ -235,39 +267,41 @@ dependencies = [ "os_info", "pasetors", "pathdiff", - "pulldown-cmark", "rand", "regex", "rusqlite", + "rustc-hash", + "rustc-stable-hash", "rustfix", + "same-file", "semver", "serde", "serde-untagged", - "serde-value", "serde_ignored", "serde_json", "sha1", "shell-escape", "supports-hyperlinks", - "syn 2.0.48", + "supports-unicode", "tar", "tempfile", + "thiserror 1.0.69", "time", - "toml 0.8.10", - "toml_edit 0.21.1", + "toml", + "toml_edit", "tracing", + "tracing-chrome", "tracing-subscriber", "unicase", "unicode-width", - "unicode-xid", "url", "walkdir", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "cargo-c" -version = "0.9.30+cargo-0.77.0" +version = "0.10.11+cargo-0.86.0" dependencies = [ "anyhow", "cargo", @@ -276,37 +310,38 @@ dependencies = [ "cc", "clap", "glob", - "itertools", + "implib", + "itertools 0.14.0", "log", + "object", "regex", "semver", "serde", "serde_derive", "serde_json", - "toml 0.8.10", - "windows-sys 0.52.0", + "toml", ] [[package]] name = "cargo-credential" -version = "0.4.2" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec27ad011c37339b865c765fa28096cd63d5b25fab680c04d9e410cb586c327d" +checksum = "ac1ef5080adde1db190e901884d2c400990856c2a23201c5a181b910a6dbdf2a" dependencies = [ "anyhow", "libc", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "time", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "cargo-credential-libsecret" -version = "0.4.2" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b0ff7a44dd0af0fcd8d09bb1a6d7f7652847cba10aad017a6ea0a25ba7f00f" +checksum = "f2d33572942f4b5f59376b7041198c56b5585404c59172c62fff2372dedba102" dependencies = [ "anyhow", "cargo-credential", @@ -315,9 +350,9 @@ dependencies = [ [[package]] name = "cargo-credential-macos-keychain" -version = "0.4.2" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b7cf89a47dc2c20ae3a7c94335e151be32c20f85cc2790defdb1f5dac818de5" +checksum = "41e699cfa3f0a45e8973839768622302a03ab7148c126e96215c2e3e1fc82375" dependencies = [ "cargo-credential", "security-framework", @@ -325,28 +360,28 @@ dependencies = [ [[package]] name = "cargo-credential-wincred" -version = "0.4.2" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "341df45dc893bdffa36e2f7cbe3da90b38c5c74e7f4c0088ac801fd055b6df5b" +checksum = "62219d774bd2d26e803d75d7dfd234022173af157eb9d6f887016839db4d1f19" dependencies = [ "cargo-credential", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "cargo-platform" -version = "0.1.7" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" +checksum = "84982c6c0ae343635a3a4ee6dedef965513735c8b183caa7289fa6e27399ebd4" dependencies = [ "serde", ] [[package]] name = "cargo-util" -version = "0.2.9" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74862c3c6e53a1c1f8f0178f9d38ab41e49746cd3a7cafc239b3d0248fd4e342" +checksum = "932c5376dc904ef005f0d229a5edc1116f40a78a18d30cdc992ec5acbeffd4d9" dependencies = [ "anyhow", "core-foundation", @@ -362,35 +397,52 @@ dependencies = [ "tempfile", "tracing", "walkdir", - "windows-sys 0.52.0", + "windows-sys 0.59.0", +] + +[[package]] +name = "cargo-util-schemas" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f905f68f8cb8a8182592d9858a5895360f0a5b08b6901fdb10498fb91829804" +dependencies = [ + "semver", + "serde", + "serde-untagged", + "serde-value", + "thiserror 1.0.69", + "toml", + "unicode-xid", + "url", ] [[package]] name = "cbindgen" -version = "0.26.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da6bc11b07529f16944307272d5bd9b22530bc7d05751717c9d416586cedab49" +checksum = "eadd868a2ce9ca38de7eeafdcec9c7065ef89b42b32f0839278d55f35c54d1ff" dependencies = [ - "heck", - "indexmap 1.9.3", + "heck 0.4.1", + "indexmap", "log", "proc-macro2", "quote", "serde", "serde_json", - "syn 1.0.109", + "syn", "tempfile", - "toml 0.5.11", + "toml", ] [[package]] name = "cc" -version = "1.0.83" +version = "1.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "c736e259eea577f443d5c86c304f9f4ae0295c43f3ba05c21f1d66b5f06001af" dependencies = [ "jobserver", "libc", + "shlex", ] [[package]] @@ -401,9 +453,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.0" +version = "4.5.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" +checksum = "92b7b18d71fad5313a1e320fa9897994228ce274b60faa4d694fe0ea89cd9e6d" dependencies = [ "clap_builder", "clap_derive", @@ -411,9 +463,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.0" +version = "4.5.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" +checksum = "a35db2071778a7344791a4fb4f95308b5673d219dee3ae348b86642574ecc90c" dependencies = [ "anstream", "anstyle", @@ -422,56 +474,68 @@ dependencies = [ "terminal_size", ] +[[package]] +name = "clap_complete" +version = "4.5.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e3040c8291884ddf39445dc033c70abc2bc44a42f0a3a00571a0f483a83f0cd" +dependencies = [ + "clap", + "clap_lex", + "is_executable", + "shlex", +] + [[package]] name = "clap_derive" -version = "4.5.0" +version = "4.5.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "clru" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8191fa7302e03607ff0e237d4246cc043ff5b3cb9409d995172ba3bea16b807" +checksum = "cbd0f76e066e64fdc5631e3bb46381254deab9ef1158292f27c8c57e3bf3fe59" [[package]] name = "color-print" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a858372ff14bab9b1b30ea504f2a4bc534582aee3e42ba2d41d2a7baba63d5d" +checksum = "3aa954171903797d5623e047d9ab69d91b493657917bdfb8c2c80ecaf9cdb6f4" dependencies = [ "color-print-proc-macro", ] [[package]] name = "color-print-proc-macro" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e37866456a721d0a404439a1adae37a31be4e0055590d053dfe6981e05003f" +checksum = "692186b5ebe54007e45a59aea47ece9eb4108e141326c304cdc91699a7118a22" dependencies = [ "nom", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "const-oid" @@ -479,11 +543,17 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "core-foundation" -version = "0.9.4" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" dependencies = [ "core-foundation-sys", "libc", @@ -491,56 +561,56 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] [[package]] name = "crates-io" -version = "0.39.2" +version = "0.40.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6622f902c3c338eced1f000091f034846ae36aadaf35d0acd1ab0469a2d8ef1f" +checksum = "3278cae111be507cd074ac10cac0ca4638c90911f978a849c1b96086381d347c" dependencies = [ "curl", "percent-encoding", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "url", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.11" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -557,9 +627,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crypto-bigint" @@ -585,15 +655,15 @@ dependencies = [ [[package]] name = "ct-codecs" -version = "1.1.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3b7eb4404b8195a9abb6356f4ac07d8ba267045c8d6d220ac4dc992e6cc75df" +checksum = "b916ba8ce9e4182696896f015e8a5ae6081b305f74690baa8465e35f5a142ea4" [[package]] name = "curl" -version = "0.4.45" +version = "0.4.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8e5123ab8c31200ce725939049ecd4a090b242608f24048131dedf9dd195aed" +checksum = "d9fb4d13a1be2b58f14d60adba57c9834b78c62fd86c3e76a148f732686e9265" dependencies = [ "curl-sys", "libc", @@ -606,9 +676,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.72+curl-8.6.0" +version = "0.4.80+curl-8.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29cbdc8314c447d11e8fd156dcdd031d9e02a7a976163e396b548c03153bc9ea" +checksum = "55f7df2eac63200c3ab25bde3b2268ef2ee56af3d238e76d61f01c3c49bff734" dependencies = [ "cc", "libc", @@ -620,11 +690,22 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "dbus" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bb21987b9fb1613058ba3843121dd18b163b254d8a6e797e144cbac14d96d1b" +dependencies = [ + "libc", + "libdbus-sys", + "winapi", +] + [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "pem-rfc7468", @@ -653,11 +734,22 @@ dependencies = [ "subtle", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dunce" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "ecdsa" @@ -679,14 +771,14 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9b3460f44bea8cd47f45a0c70892f1eff856d97cd55358b2f73f663789f6190" dependencies = [ - "getrandom", + "getrandom 0.2.15", ] [[package]] name = "either" -version = "1.10.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -711,36 +803,37 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "erased-serde" -version = "0.4.2" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55d05712b2d8d88102bc9868020c9e5c7a1f5527c452b9b97450a1d006140ba7" +checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" dependencies = [ "serde", + "typeid", ] [[package]] name = "errno" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -766,9 +859,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "ff" @@ -782,33 +875,45 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.6" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "filetime" -version = "0.2.23" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", - "redox_syscall", - "windows-sys 0.52.0", + "libredox", + "windows-sys 0.59.0", ] [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "libz-sys", "miniz_oxide", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + [[package]] name = "foreign-types" version = "0.3.2" @@ -846,24 +951,38 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.13.3+wasi-0.2.2", "wasm-bindgen", + "windows-targets 0.52.6", ] [[package]] name = "git2" -version = "0.18.2" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b3ba52851e73b46a4c3df1d89343741112003f0f6f13beb0dfac9e457c3fdcd" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" dependencies = [ - "bitflags 2.4.2", + "bitflags", "libc", "libgit2-sys", "log", @@ -874,9 +993,9 @@ dependencies = [ [[package]] name = "git2-curl" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78e26b61608c573ffd26fc79061a823aa5147449a1afe1f61679a21e2031f7c3" +checksum = "68ff14527a1c242320039b138376f8e0786697a1b7b172bc44f6efda3ab9079f" dependencies = [ "curl", "git2", @@ -886,9 +1005,9 @@ dependencies = [ [[package]] name = "gix" -version = "0.56.0" +version = "0.69.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0dcdc9c60d66535897fa40a7ea2a635e72f99456b1d9ae86b7e170e80618cb" +checksum = "8d0eebdaecdcf405d5433a36f85e4f058cf4de48ee2604388be0dbccbaad353e" dependencies = [ "gix-actor", "gix-attributes", @@ -898,8 +1017,9 @@ dependencies = [ "gix-credentials", "gix-date", "gix-diff", + "gix-dir", "gix-discover", - "gix-features 0.36.1", + "gix-features", "gix-filter", "gix-fs", "gix-glob", @@ -908,7 +1028,6 @@ dependencies = [ "gix-ignore", "gix-index", "gix-lock", - "gix-macros", "gix-negotiate", "gix-object", "gix-odb", @@ -922,6 +1041,7 @@ dependencies = [ "gix-revision", "gix-revwalk", "gix-sec", + "gix-shallow", "gix-submodule", "gix-tempfile", "gix-trace", @@ -932,32 +1052,30 @@ dependencies = [ "gix-validate", "gix-worktree", "once_cell", - "parking_lot", "prodash", "smallvec", - "thiserror", - "unicode-normalization", + "thiserror 2.0.11", ] [[package]] name = "gix-actor" -version = "0.28.1" +version = "0.33.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eadca029ef716b4378f7afb19f7ee101fde9e58ba1f1445971315ac866db417" +checksum = "20018a1a6332e065f1fcc8305c1c932c6b8c9985edea2284b3c79dc6fa3ee4b2" dependencies = [ "bstr", - "btoi", "gix-date", + "gix-utils", "itoa", - "thiserror", - "winnow", + "thiserror 2.0.11", + "winnow 0.6.26", ] [[package]] name = "gix-attributes" -version = "0.20.1" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f395469d38c76ec47cd1a6c5a53fbc3f13f737b96eaf7535f4e6b367e643381" +checksum = "ddf9bf852194c0edfe699a2d36422d2c1f28f73b7c6d446c3f0ccd3ba232cadc" dependencies = [ "bstr", "gix-glob", @@ -966,33 +1084,33 @@ dependencies = [ "gix-trace", "kstring", "smallvec", - "thiserror", + "thiserror 2.0.11", "unicode-bom", ] [[package]] name = "gix-bitmap" -version = "0.2.10" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b6cd0f246180034ddafac9b00a112f19178135b21eb031b3f79355891f7325" +checksum = "b1db9765c69502650da68f0804e3dc2b5f8ccc6a2d104ca6c85bc40700d37540" dependencies = [ - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-chunk" -version = "0.4.7" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "003ec6deacf68076a0c157271a127e0bb2c031c1a41f7168cbe5d248d9b85c78" +checksum = "0b1f1d8764958699dc764e3f727cef280ff4d1bd92c107bbf8acd85b30c1bd6f" dependencies = [ - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-command" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82b5e9494e61983e61049bbd15fe0fa6b70672dd236362bdb5b2b50fc428f10" +checksum = "cb410b84d6575db45e62025a9118bdbf4d4b099ce7575a76161e898d9ca98df1" dependencies = [ "bstr", "gix-path", @@ -1002,27 +1120,27 @@ dependencies = [ [[package]] name = "gix-commitgraph" -version = "0.22.1" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a7007ba021f059803afaf6f8a48872422abc20550ac12ede6ddea2936cec36" +checksum = "a8da6591a7868fb2b6dabddea6b09988b0b05e0213f938dbaa11a03dd7a48d85" dependencies = [ "bstr", "gix-chunk", - "gix-features 0.36.1", + "gix-features", "gix-hash", "memmap2", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-config" -version = "0.32.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0341471d55d8676e98b88e121d7065dfa4c9c5acea4b6d6ecdd2846e85cce0c3" +checksum = "6649b406ca1f99cb148959cf00468b231f07950f8ec438cc0903cda563606f19" dependencies = [ "bstr", "gix-config-value", - "gix-features 0.36.1", + "gix-features", "gix-glob", "gix-path", "gix-ref", @@ -1030,29 +1148,29 @@ dependencies = [ "memchr", "once_cell", "smallvec", - "thiserror", + "thiserror 2.0.11", "unicode-bom", - "winnow", + "winnow 0.6.26", ] [[package]] name = "gix-config-value" -version = "0.14.4" +version = "0.14.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e7bfb37a46ed0b8468db37a6d8a0a61d56bdbe4603ae492cb322e5f3958" +checksum = "11365144ef93082f3403471dbaa94cfe4b5e72743bdb9560719a251d439f4cee" dependencies = [ - "bitflags 2.4.2", + "bitflags", "bstr", "gix-path", "libc", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-credentials" -version = "0.22.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "513dac42450b27946bd0a0535a3a5a88e473d6522e5e3439a129cab779c88f3d" +checksum = "82a50c56b785c29a151ab4ccf74a83fe4e21d2feda0d30549504b4baed353e0a" dependencies = [ "bstr", "gix-command", @@ -1062,85 +1180,96 @@ dependencies = [ "gix-sec", "gix-trace", "gix-url", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-date" -version = "0.8.3" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb7f3dfb72bebe3449b5e642be64e3c6ccbe9821c8b8f19f487cf5bfbbf4067e" +checksum = "c57c477b645ee248b173bb1176b52dd528872f12c50375801a58aaf5ae91113f" dependencies = [ "bstr", "itoa", - "thiserror", - "time", + "jiff", + "thiserror 2.0.11", ] [[package]] name = "gix-diff" -version = "0.38.0" +version = "0.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8119a985887cfe68f4bdf92e51bd64bc758a73882d82fcfc03ebcb164441c85d" +checksum = "a8e92566eccbca205a0a0f96ffb0327c061e85bc5c95abbcddfe177498aa04f6" dependencies = [ "bstr", "gix-hash", "gix-object", - "thiserror", + "thiserror 2.0.11", ] [[package]] -name = "gix-discover" -version = "0.27.0" +name = "gix-dir" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fad89416ebe0b3b7df78464124e2a02417b6cd3743d48ad93df86f4d2929c07" +checksum = "fba2ffbcf4bd34438e8a8367ccbc94870549903d1f193a14f47eb6b0967e1293" dependencies = [ "bstr", - "dunce", - "gix-hash", + "gix-discover", + "gix-fs", + "gix-ignore", + "gix-index", + "gix-object", "gix-path", - "gix-ref", - "gix-sec", - "thiserror", + "gix-pathspec", + "gix-trace", + "gix-utils", + "gix-worktree", + "thiserror 2.0.11", ] [[package]] -name = "gix-features" -version = "0.35.0" +name = "gix-discover" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b9ff423ae4983f762659040d13dd7a5defbd54b6a04ac3cc7347741cec828cd" +checksum = "83bf6dfa4e266a4a9becb4d18fc801f92c3f7cc6c433dd86fdadbcf315ffb6ef" dependencies = [ - "crossbeam-channel", + "bstr", + "dunce", + "gix-fs", "gix-hash", - "gix-trace", - "libc", - "parking_lot", + "gix-path", + "gix-ref", + "gix-sec", + "thiserror 2.0.11", ] [[package]] name = "gix-features" -version = "0.36.1" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d46a4a5c6bb5bebec9c0d18b65ada20e6517dbd7cf855b87dd4bbdce3a771b2" +checksum = "7d85d673f2e022a340dba4713bed77ef2cf4cd737d2f3e0f159d45e0935fd81f" dependencies = [ "bytes", "crc32fast", + "crossbeam-channel", "flate2", "gix-hash", "gix-trace", + "gix-utils", "libc", "once_cell", + "parking_lot", "prodash", "sha1_smol", - "thiserror", + "thiserror 2.0.11", "walkdir", ] [[package]] name = "gix-filter" -version = "0.7.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d6a5c9d8e55c364e7c226919c19c9a28be1392d6208b5008059fa94ff7e2bf0" +checksum = "3d0ecdee5667f840ba20c7fe56d63f8e1dc1e6b3bfd296151fe5ef07c874790a" dependencies = [ "bstr", "encoding_rs", @@ -1154,173 +1283,172 @@ dependencies = [ "gix-trace", "gix-utils", "smallvec", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-fs" -version = "0.8.1" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20e86eb040f5776a5ade092282e51cdcad398adb77d948b88d17583c2ae4e107" +checksum = "3b3d4fac505a621f97e5ce2c69fdc425742af00c0920363ca4074f0eb48b1db9" dependencies = [ - "gix-features 0.36.1", + "fastrand", + "gix-features", + "gix-utils", ] [[package]] name = "gix-glob" -version = "0.14.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db19298c5eeea2961e5b3bf190767a2d1f09b8802aeb5f258e42276350aff19" +checksum = "aaf69a6bec0a3581567484bf99a4003afcaf6c469fd4214352517ea355cf3435" dependencies = [ - "bitflags 2.4.2", + "bitflags", "bstr", - "gix-features 0.36.1", + "gix-features", "gix-path", ] [[package]] name = "gix-hash" -version = "0.13.3" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f8cf8c2266f63e582b7eb206799b63aa5fa68ee510ad349f637dfe2d0653de0" +checksum = "0b5eccc17194ed0e67d49285e4853307e4147e95407f91c1c3e4a13ba9f4e4ce" dependencies = [ "faster-hex", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-hashtable" -version = "0.4.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb61880816d7ec4f0b20606b498147d480860ddd9133ba542628df2f548d3ca" +checksum = "0ef65b256631078ef733bc5530c4e6b1c2e7d5c2830b75d4e9034ab3997d18fe" dependencies = [ "gix-hash", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "parking_lot", ] [[package]] name = "gix-ignore" -version = "0.9.1" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a215cc8cf21645bca131fcf6329d3ebd46299c47dbbe27df71bb1ca9e328b879" +checksum = "b6b1fb24d2a4af0aa7438e2771d60c14a80cf2c9bd55c29cf1712b841f05bb8a" dependencies = [ "bstr", "gix-glob", "gix-path", + "gix-trace", "unicode-bom", ] [[package]] name = "gix-index" -version = "0.27.1" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f308f5cd2992e96a274b0d1931e9a0e44fdcba87695ead3f6df30d8a697e9c" +checksum = "270645fd20556b64c8ffa1540d921b281e6994413a0ca068596f97e9367a257a" dependencies = [ - "bitflags 2.4.2", + "bitflags", "bstr", - "btoi", "filetime", + "fnv", "gix-bitmap", - "gix-features 0.36.1", + "gix-features", "gix-fs", "gix-hash", "gix-lock", "gix-object", "gix-traverse", + "gix-utils", + "gix-validate", + "hashbrown 0.14.5", "itoa", "libc", "memmap2", "rustix", "smallvec", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-lock" -version = "11.0.1" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e5c65e6a29830a435664891ced3f3c1af010f14900226019590ee0971a22f37" +checksum = "1cd3ab68a452db63d9f3ebdacb10f30dba1fa0d31ac64f4203d395ed1102d940" dependencies = [ "gix-tempfile", "gix-utils", - "thiserror", -] - -[[package]] -name = "gix-macros" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75e7ab728059f595f6ddc1ad8771b8d6a231971ae493d9d5948ecad366ee8bb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", + "thiserror 2.0.11", ] [[package]] name = "gix-negotiate" -version = "0.10.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "979f6accd9c051b3dd018b50adf29c0a2459edddf6105cc70b767976cd6f8014" +checksum = "d27f830a16405386e9c83b9d5be8261fe32bbd6b3caf15bd1b284c6b2b7ef1a8" dependencies = [ - "bitflags 2.4.2", + "bitflags", "gix-commitgraph", "gix-date", "gix-hash", "gix-object", "gix-revwalk", "smallvec", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-object" -version = "0.39.0" +version = "0.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "febf79c5825720c1c63fe974c7bbe695d0cb54aabad73f45671c60ce0e501e33" +checksum = "e42d58010183ef033f31088479b4eb92b44fe341b35b62d39eb8b185573d77ea" dependencies = [ "bstr", - "btoi", "gix-actor", "gix-date", - "gix-features 0.36.1", + "gix-features", "gix-hash", + "gix-hashtable", + "gix-path", + "gix-utils", "gix-validate", "itoa", "smallvec", - "thiserror", - "winnow", + "thiserror 2.0.11", + "winnow 0.6.26", ] [[package]] name = "gix-odb" -version = "0.55.0" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fae5f971540c99c6ecc8d4368ecc9d18a9dc8b9391025c68c4399747dc93bac" +checksum = "cb780eceb3372ee204469478de02eaa34f6ba98247df0186337e0333de97d0ae" dependencies = [ "arc-swap", "gix-date", - "gix-features 0.36.1", + "gix-features", + "gix-fs", "gix-hash", + "gix-hashtable", "gix-object", "gix-pack", "gix-path", "gix-quote", "parking_lot", "tempfile", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-pack" -version = "0.45.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4569491c92446fddf373456ff360aff9a9effd627b40a70f2d7914dcd75a3205" +checksum = "4158928929be29cae7ab97afc8e820a932071a7f39d8ba388eed2380c12c566c" dependencies = [ "clru", "gix-chunk", - "gix-features 0.36.1", + "gix-features", "gix-hash", "gix-hashtable", "gix-object", @@ -1329,159 +1457,166 @@ dependencies = [ "memmap2", "parking_lot", "smallvec", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-packetline" -version = "0.17.3" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ff45eef7747bde4986429a3e813478d50c2688b8f239e57bd3aa81065b285f" +checksum = "c7e5ae6bc3ac160a6bf44a55f5537813ca3ddb08549c0fd3e7ef699c73c439cd" dependencies = [ "bstr", "faster-hex", "gix-trace", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-packetline-blocking" -version = "0.17.3" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8ef6dd3ea50e26f3bf572e90c034d033c804d340cd1eb386392f184a9ba2f7" +checksum = "c1cbf8767c6abd5a6779f586702b5bcd8702380f4208219449cf1c9d0cd1e17c" dependencies = [ "bstr", "faster-hex", "gix-trace", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-path" -version = "0.10.5" +version = "0.10.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97e9ad649bf5e109562d6acba657ca428661ec08e77eaf3a755d8fa55485be9c" +checksum = "c40f12bb65a8299be0cfb90fe718e3be236b7a94b434877012980863a883a99f" dependencies = [ "bstr", "gix-trace", "home", "once_cell", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-pathspec" -version = "0.4.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dbbb92f75a38ef043c8bb830b339b38d0698d7f3746968b5fcbade7a880494d" +checksum = "4c472dfbe4a4e96fcf7efddcd4771c9037bb4fdea2faaabf2f4888210c75b81e" dependencies = [ - "bitflags 2.4.2", + "bitflags", "bstr", "gix-attributes", "gix-config-value", "gix-glob", "gix-path", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-prompt" -version = "0.8.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02bd89d058258e53e0fd6c57f13ee16c5673a83066a68e11f88626fc8cfda5f6" +checksum = "79f2185958e1512b989a007509df8d61dca014aa759a22bee80cfa6c594c3b6d" dependencies = [ "gix-command", "gix-config-value", "parking_lot", "rustix", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-protocol" -version = "0.42.0" +version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95736ef407db0bd15a5bdea791fbfcf523b9f13b96c852c240cd86a9ee0ef817" +checksum = "c84642e8b6fed7035ce9cc449593019c55b0ec1af7a5dce1ab8a0636eaaeb067" dependencies = [ "bstr", - "btoi", "gix-credentials", "gix-date", - "gix-features 0.36.1", + "gix-features", "gix-hash", + "gix-lock", + "gix-negotiate", + "gix-object", + "gix-ref", + "gix-refspec", + "gix-revwalk", + "gix-shallow", + "gix-trace", "gix-transport", + "gix-utils", "maybe-async", - "thiserror", - "winnow", + "thiserror 2.0.11", + "winnow 0.6.26", ] [[package]] name = "gix-quote" -version = "0.4.10" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7dc10303d73a960d10fb82f81188b036ac3e6b11b5795b20b1a60b51d1321f" +checksum = "e49357fccdb0c85c0d3a3292a9f6db32d9b3535959b5471bb9624908f4a066c6" dependencies = [ "bstr", - "btoi", - "thiserror", + "gix-utils", + "thiserror 2.0.11", ] [[package]] name = "gix-ref" -version = "0.39.1" +version = "0.49.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2069adc212cf7f3317ef55f6444abd06c50f28479dbbac5a86acf3b05cbbfe" +checksum = "a91b61776c839d0f1b7114901179afb0947aa7f4d30793ca1c56d335dfef485f" dependencies = [ "gix-actor", - "gix-date", - "gix-features 0.36.1", + "gix-features", "gix-fs", "gix-hash", "gix-lock", "gix-object", "gix-path", "gix-tempfile", + "gix-utils", "gix-validate", "memmap2", - "thiserror", - "winnow", + "thiserror 2.0.11", + "winnow 0.6.26", ] [[package]] name = "gix-refspec" -version = "0.20.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d9d3b82e1ee78fc0dc1c37ea5ea76c2dbc73f407db155f0dfcea285e583bee" +checksum = "00c056bb747868c7eb0aeb352c9f9181ab8ca3d0a2550f16470803500c6c413d" dependencies = [ "bstr", "gix-hash", "gix-revision", "gix-validate", "smallvec", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-revision" -version = "0.24.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe5dd51710ce5434bc315ea30394fab483c5377276494edd79222b321a5a9544" +checksum = "61e1ddc474405a68d2ce8485705dd72fe6ce959f2f5fe718601ead5da2c8f9e7" dependencies = [ "bstr", + "gix-commitgraph", "gix-date", "gix-hash", - "gix-hashtable", "gix-object", "gix-revwalk", - "gix-trace", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-revwalk" -version = "0.10.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d4ed2493ca94a475fdf147138e1ef8bab3b6ebb56abf3d9bda1c05372ec1dd" +checksum = "510026fc32f456f8f067d8f37c34088b97a36b2229d88a6a5023ef179fcb109d" dependencies = [ "gix-commitgraph", "gix-date", @@ -1489,41 +1624,53 @@ dependencies = [ "gix-hashtable", "gix-object", "smallvec", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-sec" -version = "0.10.4" +version = "0.10.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8d9bf462feaf05f2121cba7399dbc6c34d88a9cad58fc1e95027791d6a3c6d2" +checksum = "d84dae13271f4313f8d60a166bf27e54c968c7c33e2ffd31c48cafe5da649875" dependencies = [ - "bitflags 2.4.2", + "bitflags", "gix-path", "libc", "windows-sys 0.52.0", ] [[package]] -name = "gix-submodule" -version = "0.6.0" +name = "gix-shallow" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02a3d7f60a95bdcaeb8981663c99d1c9f4de42aab1169524c949e948989809f9" +checksum = "88d2673242e87492cb6ff671f0c01f689061ca306c4020f137197f3abc84ce01" dependencies = [ "bstr", - "gix-config", + "gix-hash", + "gix-lock", + "thiserror 2.0.11", +] + +[[package]] +name = "gix-submodule" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2455f8c0fcb6ebe2a6e83c8f522d30615d763eb2ef7a23c7d929f9476e89f5c" +dependencies = [ + "bstr", + "gix-config", "gix-path", "gix-pathspec", "gix-refspec", "gix-url", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-tempfile" -version = "11.0.1" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388dd29114a86ec69b28d1e26d6d63a662300ecf61ab3f4cc578f7d7dc9e7e23" +checksum = "2feb86ef094cc77a4a9a5afbfe5de626897351bbbd0de3cb9314baf3049adb82" dependencies = [ "gix-fs", "libc", @@ -1534,35 +1681,36 @@ dependencies = [ [[package]] name = "gix-trace" -version = "0.1.7" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b202d766a7fefc596e2cc6a89cda8ad8ad733aed82da635ac120691112a9b1" +checksum = "7c396a2036920c69695f760a65e7f2677267ccf483f25046977d87e4cb2665f7" [[package]] name = "gix-transport" -version = "0.39.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f731cfefc4d62468c6dd2053f5c6707828256a6d2f5488c1811e3f42c178b144" +checksum = "dd04d91e507a8713cfa2318d5a85d75b36e53a40379cc7eb7634ce400ecacbaf" dependencies = [ "base64", "bstr", "curl", "gix-command", "gix-credentials", - "gix-features 0.36.1", + "gix-features", "gix-packetline", "gix-quote", "gix-sec", "gix-url", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-traverse" -version = "0.35.0" +version = "0.43.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2112088122a0206592c84fbd42020db63b2ccaed66a0293779f2e5fbf80474" +checksum = "6ed47d648619e23e93f971d2bba0d10c1100e54ef95d2981d609907a8cabac89" dependencies = [ + "bitflags", "gix-commitgraph", "gix-date", "gix-hash", @@ -1570,52 +1718,53 @@ dependencies = [ "gix-object", "gix-revwalk", "smallvec", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-url" -version = "0.25.2" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c427a1a11ccfa53a4a2da47d9442c2241deee63a154bc15cc14b8312fbc4005" +checksum = "d096fb733ba6bd3f5403dba8bd72bdd8809fe2b347b57844040b8f49c93492d9" dependencies = [ "bstr", - "gix-features 0.36.1", + "gix-features", "gix-path", - "home", - "thiserror", + "percent-encoding", + "thiserror 2.0.11", "url", ] [[package]] name = "gix-utils" -version = "0.1.9" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e839f3d0798b296411263da6bee780a176ef8008a5dfc31287f7eda9266ab8" +checksum = "ff08f24e03ac8916c478c8419d7d3c33393da9bb41fa4c24455d5406aeefd35f" dependencies = [ + "bstr", "fastrand", "unicode-normalization", ] [[package]] name = "gix-validate" -version = "0.8.3" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac7cc36f496bd5d96cdca0f9289bb684480725d40db60f48194aa7723b883854" +checksum = "9eaa01c3337d885617c0a42e92823922a2aea71f4caeace6fe87002bdcadbd90" dependencies = [ "bstr", - "thiserror", + "thiserror 2.0.11", ] [[package]] name = "gix-worktree" -version = "0.28.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f1d0ae01dee14abe8c8117d78d7518f9a507de2dc4522546fbf4c444e9860b4" +checksum = "756dbbe15188fa22540d5eab941f8f9cf511a5364d5aec34c88083c09f4bea13" dependencies = [ "bstr", "gix-attributes", - "gix-features 0.36.1", + "gix-features", "gix-fs", "gix-glob", "gix-hash", @@ -1623,25 +1772,26 @@ dependencies = [ "gix-index", "gix-object", "gix-path", + "gix-validate", ] [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "globset" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.5", - "regex-syntax 0.8.2", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", ] [[package]] @@ -1657,27 +1807,30 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ - "ahash", - "allocator-api2", + "foldhash", ] [[package]] name = "hashlink" -version = "0.8.4" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -1687,10 +1840,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] -name = "hermit-abi" -version = "0.3.5" +name = "heck" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hex" @@ -1718,18 +1871,18 @@ dependencies = [ [[package]] name = "home" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "http-auth" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643c9bbf6a4ea8a656d6b4cd53d34f79e3f841ad5203c1a55fb7d761923bc255" +checksum = "150fa4a9462ef926824cf4519c84ed652ca8f4fbae34cb8af045b5cbcaf98822" dependencies = [ "memchr", ] @@ -1740,27 +1893,156 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] name = "ignore" -version = "0.4.22" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" dependencies = [ "crossbeam-deque", "globset", "log", "memchr", - "regex-automata 0.4.5", + "regex-automata 0.4.9", "same-file", "walkdir", "winapi-util", @@ -1781,83 +2063,126 @@ dependencies = [ ] [[package]] -name = "indexmap" -version = "1.9.3" +name = "implib" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "598bf7096215f835b0f70c94d7b033da3cbf66181b619f25e54d65adaf825e62" dependencies = [ - "autocfg", - "hashbrown 0.12.3", + "memoffset", + "object", ] [[package]] name = "indexmap" -version = "2.2.2" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.15.2", ] [[package]] -name = "is-terminal" -version = "0.4.12" +name = "is_executable" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +checksum = "d4a1b5bad6f9072935961dfbf1cced2f3d129963d091b6f69f007fe04e758ae2" dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.52.0", + "winapi", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", ] [[package]] name = "itertools" -version = "0.12.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "jiff" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c04ef77ae73f3cf50510712722f0c4e8b46f5aaa1bf5ffad2ae213e6495e78e5" +dependencies = [ + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", + "windows-sys 0.59.0", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2cec2f5d266af45a071ece48b1fb89f3b00b2421ac3a5fe10285a6caaa60d3" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a63c62e404e7b92979d2792352d885a7f8f83fd1d0d31eea582d77b2ceca697e" +dependencies = [ + "jiff-tzdb", +] [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.68" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] [[package]] name = "kstring" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747" +checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1" dependencies = [ "static_assertions", ] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "lazycell" @@ -1867,15 +2192,25 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "libdbus-sys" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72" +dependencies = [ + "cc", + "pkg-config", +] [[package]] name = "libgit2-sys" -version = "0.16.2+1.7.2" +version = "0.17.0+1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" dependencies = [ "cc", "libc", @@ -1887,29 +2222,40 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.1" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-sys 0.48.0", + "windows-targets 0.52.6", ] [[package]] name = "libnghttp2-sys" -version = "0.1.9+1.58.0" +version = "0.1.11+1.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b57e858af2798e167e709b9d969325b6d8e9d50232fcbc494d7d54f976854a64" +checksum = "1b6c24e48a7167cffa7119da39d577fa482e66c688a4aac016bee862e1a713c4" dependencies = [ "cc", "libc", ] +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags", + "libc", + "redox_syscall", +] + [[package]] name = "libsqlite3-sys" -version = "0.27.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ "cc", "pkg-config", @@ -1918,9 +2264,9 @@ dependencies = [ [[package]] name = "libssh2-sys" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" +checksum = "220e4f05ad4a218192533b300327f5150e809b54c4ec83b5a1d91833601811b9" dependencies = [ "cc", "libc", @@ -1932,9 +2278,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.15" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" +checksum = "df9b68e50e6e0b26f672573834882eb57759f6db9b3be2ea3c35c91188bb4eaa" dependencies = [ "cc", "libc", @@ -1944,15 +2290,21 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "litemap" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1960,9 +2312,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" [[package]] name = "matchers" @@ -1975,30 +2327,39 @@ dependencies = [ [[package]] name = "maybe-async" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc95a651c82daf7004c824405aa1019723644950d488571bd718e3ed84646ed" +checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" dependencies = [ "libc", ] +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2007,11 +2368,11 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" dependencies = [ - "adler", + "adler2", ] [[package]] @@ -2035,11 +2396,11 @@ dependencies = [ [[package]] name = "normpath" -version = "1.1.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec60c60a693226186f5d6edf073232bfb6464ed97eb22cf3b01c1e8198fd97f5" +checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -2060,46 +2421,50 @@ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] -name = "num_threads" -version = "0.1.6" +name = "object" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ - "libc", + "crc32fast", + "hashbrown 0.15.2", + "indexmap", + "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "opener" -version = "0.6.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c62dcb6174f9cb326eac248f07e955d5d559c272730b6c03e396b443b562788" +checksum = "d0812e5e4df08da354c851a3376fead46db31c2214f849d3de356d774d057681" dependencies = [ "bstr", + "dbus", "normpath", - "winapi", + "windows-sys 0.59.0", ] [[package]] name = "openssl" -version = "0.10.63" +version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ - "bitflags 2.4.2", + "bitflags", "cfg-if", "foreign-types", "libc", @@ -2116,29 +2481,29 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] name = "openssl-probe" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-src" -version = "300.2.2+3.2.1" +version = "300.4.2+3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bbfad0063610ac26ee79f7484739e2b07555a75c42453b89263830b5c8103bc" +checksum = "168ce4e058f975fe43e89d9ccf78ca668601887ae736090aacc23ae353c298e2" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.99" +version = "0.9.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" +checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" dependencies = [ "cc", "libc", @@ -2158,9 +2523,9 @@ dependencies = [ [[package]] name = "orion" -version = "0.17.6" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abdb10181903c8c4b016ba45d6d6d5af1a1e2a461aa4763a83b87f5df4695e5" +checksum = "dd806049e71da4c4a7880466b37afdc5a4c5b35a398b0d4fd9ff5d278d3b4db9" dependencies = [ "fiat-crypto", "subtle", @@ -2169,13 +2534,12 @@ dependencies = [ [[package]] name = "os_info" -version = "3.7.0" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e" +checksum = "2a604e53c24761286860eba4e2c8b23a0161526476b1de520139d69cdb85a6b5" dependencies = [ "log", - "serde", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -2186,9 +2550,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "p384" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" dependencies = [ "ecdsa", "elliptic-curve", @@ -2198,9 +2562,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -2208,26 +2572,26 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] name = "pasetors" -version = "0.6.8" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b36d47c66f2230dd1b7143d9afb2b4891879020210eddf2ccb624e529b96dba" +checksum = "c54944fa25a6e7c9c5b3315f118d360cc00d555cf53bb2b2fdf32dd31c71b729" dependencies = [ "ct-codecs", "ed25519-compact", - "getrandom", + "getrandom 0.3.1", "orion", "p384", "rand_core", @@ -2242,9 +2606,9 @@ dependencies = [ [[package]] name = "pathdiff" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "pem-rfc7468" @@ -2263,9 +2627,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pkcs8" @@ -2279,9 +2643,24 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "portable-atomic" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] [[package]] name = "powerfmt" @@ -2291,9 +2670,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "primeorder" @@ -2306,38 +2688,28 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] [[package]] name = "prodash" -version = "26.2.2" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794b5bf8e2d19b53dcdcec3e4bba628e20f5b6062503ba89281fa7037dd7bbcf" +checksum = "a266d8d6020c61a437be704c5e618037588e1985c7dbb7bf8d265db84cffe325" dependencies = [ + "log", "parking_lot", ] -[[package]] -name = "pulldown-cmark" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" -dependencies = [ - "bitflags 2.4.2", - "memchr", - "unicase", -] - [[package]] name = "quote" -version = "1.0.35" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -2369,7 +2741,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", ] [[package]] @@ -2383,23 +2755,23 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f" dependencies = [ - "bitflags 1.3.2", + "bitflags", ] [[package]] name = "regex" -version = "1.10.3" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.5", - "regex-syntax 0.8.2", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", ] [[package]] @@ -2413,13 +2785,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.5", ] [[package]] @@ -2430,9 +2802,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rfc6979" @@ -2446,11 +2818,11 @@ dependencies = [ [[package]] name = "rusqlite" -version = "0.30.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a78046161564f5e7cd9008aff3b2990b3850dc8e0349119b98e8f251e099f24d" +checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" dependencies = [ - "bitflags 2.4.2", + "bitflags", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -2458,36 +2830,48 @@ dependencies = [ "smallvec", ] +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc-stable-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2febf9acc5ee5e99d1ad0afcdbccc02d87aa3f857a1f01f825b80eacf8edfcd1" + [[package]] name = "rustfix" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ec10cbeb92a2e494ef354d66126882da8c0a244ad769e2a7193efc5de625175" +checksum = "7f66156d7471ff4f12253cd7fd76dfe637a595a9418168154e8570f3947fe9a8" dependencies = [ "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tracing", ] [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.4.2", + "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" [[package]] name = "same-file" @@ -2500,11 +2884,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2529,11 +2913,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ - "bitflags 1.3.2", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -2542,9 +2926,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -2552,30 +2936,31 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.196" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" dependencies = [ "serde_derive", ] [[package]] name = "serde-untagged" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a160535368dfc353348e7eaa299156bd508c60c45a9249725f5f6d370d82a66" +checksum = "2676ba99bd82f75cae5cbd2c8eda6fa0b8760f18978ea840e980dd5567b5c5b6" dependencies = [ "erased-serde", "serde", + "typeid", ] [[package]] @@ -2590,13 +2975,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] @@ -2610,20 +2995,21 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.113" +version = "1.0.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -2641,9 +3027,9 @@ dependencies = [ [[package]] name = "sha1_smol" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" [[package]] name = "sha2" @@ -2677,6 +3063,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signature" version = "2.2.0" @@ -2699,18 +3091,18 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2723,6 +3115,12 @@ dependencies = [ "der", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -2731,30 +3129,33 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "supports-hyperlinks" -version = "2.1.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84231692eb0d4d41e4cdd0cabfdd2e6cd9e255e65f80c9aa7c98dd502b4233d" -dependencies = [ - "is-terminal", -] +checksum = "804f44ed3c63152de6a9f90acbea1a110441de43006ea51bcce8f436196a288b" + +[[package]] +name = "supports-unicode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", @@ -2762,21 +3163,21 @@ dependencies = [ ] [[package]] -name = "syn" -version = "2.0.48" +name = "synstructure" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "unicode-ident", + "syn", ] [[package]] name = "tar" -version = "0.4.40" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" dependencies = [ "filetime", "libc", @@ -2784,51 +3185,73 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.0" +version = "3.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" +checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" dependencies = [ "cfg-if", "fastrand", + "getrandom 0.3.1", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "terminal_size" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9" dependencies = [ "rustix", - "windows-sys 0.48.0", + "windows-sys 0.59.0", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", ] [[package]] name = "thiserror" -version = "1.0.56" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.11", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -2836,15 +3259,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.34" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", - "libc", "num-conv", - "num_threads", "powerfmt", "serde", "time-core", @@ -2859,19 +3280,29 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" dependencies = [ "tinyvec_macros", ] @@ -2884,65 +3315,43 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "toml" -version = "0.8.10" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" +checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.4", + "toml_edit", ] [[package]] name = "toml_datetime" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.21.1" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ - "indexmap 2.2.2", "serde", - "serde_spanned", - "toml_datetime", - "winnow", ] [[package]] name = "toml_edit" -version = "0.22.4" +version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9ffdf896f8daaabf9b66ba8e77ea1ed5ed0f72821b398aba62352e95062951" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ - "indexmap 2.2.2", + "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.7.3", ] [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -2951,20 +3360,31 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", +] + +[[package]] +name = "tracing-chrome" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf0a738ed5d6450a9fb96e86a23ad808de2b727fd1394585da5cdd6788ffe724" +dependencies = [ + "serde_json", + "tracing-core", + "tracing-subscriber", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -2983,9 +3403,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -3000,25 +3420,22 @@ dependencies = [ ] [[package]] -name = "typenum" -version = "1.17.0" +name = "typeid" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" [[package]] -name = "unicase" -version = "2.7.0" +name = "typenum" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] -name = "unicode-bidi" -version = "0.3.15" +name = "unicase" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-bom" @@ -3028,53 +3445,65 @@ checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "url" -version = "2.5.0" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "valuable" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "vcpkg" @@ -3084,15 +3513,15 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -3104,36 +3533,45 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.13.3+wasi-0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" -version = "0.2.91" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.91" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.91" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3141,22 +3579,25 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.91" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.91" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "winapi" @@ -3176,11 +3617,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -3204,7 +3645,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -3224,17 +3674,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -3245,9 +3696,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -3257,9 +3708,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -3269,9 +3720,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -3281,9 +3738,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -3293,9 +3750,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -3305,9 +3762,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -3317,41 +3774,139 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.39" +version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5389a154b01683d28c77f8f68f49dea75f0a4da32557a58f68ee51ebba472d29" +checksum = "1e90edd2ac1aa278a5c4599b1d89cf03074b610800f866d4026dc199d7929a28" dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags", +] + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", + "synstructure", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/recipes/build-tools/gettext-m4.recipe b/recipes/build-tools/gettext-m4.recipe index 5c86e6d16..7a3159a2e 100644 --- a/recipes/build-tools/gettext-m4.recipe +++ b/recipes/build-tools/gettext-m4.recipe @@ -13,38 +13,31 @@ class Recipe(recipe.Recipe): btype = BuildType.CUSTOM files_devel = [ - 'share/aclocal/codeset.m4', - 'share/aclocal/fcntl-o.m4', - 'share/aclocal/gettext.m4', - 'share/aclocal/glibc2.m4', - 'share/aclocal/glibc21.m4', - 'share/aclocal/iconv.m4', - 'share/aclocal/intdiv0.m4', - 'share/aclocal/intl.m4', - 'share/aclocal/intldir.m4', - 'share/aclocal/intlmacosx.m4', - 'share/aclocal/intmax.m4', - 'share/aclocal/inttypes-pri.m4', - 'share/aclocal/inttypes_h.m4', - 'share/aclocal/lcmessage.m4', - 'share/aclocal/lib-ld.m4', - 'share/aclocal/lib-link.m4', - 'share/aclocal/lib-prefix.m4', - 'share/aclocal/lock.m4', - 'share/aclocal/longlong.m4', - 'share/aclocal/nls.m4', - 'share/aclocal/po.m4', - 'share/aclocal/printf-posix.m4', - 'share/aclocal/progtest.m4', - 'share/aclocal/size_max.m4', - 'share/aclocal/stdint_h.m4', - 'share/aclocal/threadlib.m4', - 'share/aclocal/uintmax_t.m4', - 'share/aclocal/visibility.m4', - 'share/aclocal/wchar_t.m4', - 'share/aclocal/wint_t.m4', - 'share/aclocal/xsize.m4', - ] + 'share/aclocal/fcntl-o.m4', + 'share/aclocal/flexmember.m4', + 'share/aclocal/gettext.m4', + 'share/aclocal/glibc21.m4', + 'share/aclocal/glibc2.m4', + 'share/aclocal/iconv.m4', + 'share/aclocal/intdiv0.m4', + 'share/aclocal/intl.m4', + 'share/aclocal/intlmacosx.m4', + 'share/aclocal/intmax.m4', + 'share/aclocal/inttypes_h.m4', + 'share/aclocal/inttypes-pri.m4', + 'share/aclocal/lib-ld.m4', + 'share/aclocal/lib-link.m4', + 'share/aclocal/lib-prefix.m4', + 'share/aclocal/nls.m4', + 'share/aclocal/po.m4', + 'share/aclocal/printf-posix.m4', + 'share/aclocal/progtest.m4', + 'share/aclocal/size_max.m4', + 'share/aclocal/stdint_h.m4', + 'share/aclocal/uintmax_t.m4', + 'share/aclocal/visibility.m4', + 'share/aclocal/xsize.m4', + ] def post_install(self): m4dir = os.path.join(self.build_dir, 'gettext-runtime', 'm4') diff --git a/recipes/build-tools/glib-tools.recipe b/recipes/build-tools/glib-tools.recipe index 84cea0d44..352557d65 100644 --- a/recipes/build-tools/glib-tools.recipe +++ b/recipes/build-tools/glib-tools.recipe @@ -2,16 +2,38 @@ class Recipe(recipe.Recipe): name = 'glib-tools' - version = '2.62.5' + version = '2.80.5' stype = SourceType.TARBALL url = 'gnome://glib/%(maj_ver)s/glib-%(version)s.tar.xz' tarball_dirname = 'glib-%(version)s' - tarball_checksum = 'b8d1cdafa46658b63d7512efbe2cd21bd36cd7be83140e44930c47b79f82452e' + tarball_checksum = '9f23a9de803c695bbfde7e37d6626b18b9a83869689dd79019bf3ae66c3e6771' licenses = [License.LGPLv2Plus] btype = BuildType.MESON - meson_options = {'internal_pcre': 'true', 'libmount': 'false', - 'dtrace': 'false', 'iconv': 'auto', 'selinux' : 'disabled'} - deps = ['libffi', 'zlib', 'pkg-config'] + meson_options = {'libmount': 'disabled', 'dtrace': 'false', 'selinux' : 'disabled', 'introspection': 'disabled', 'tests': 'false'} + deps = ['libffi', 'zlib', 'pkg-config', 'pcre2'] + + # Without these, the relocator won't take effect on macOS + files_bins = [ + 'gtester', + 'gobject-query', + 'gio', + 'gresource', + 'gio-querymodules', + 'glib-compile-schemas', + 'glib-compile-resources', + 'gsettings', + 'gdbus', + 'glib-mkenums', + ] + + files_devel = [ + 'bin/gtester-report', + 'bin/glib-genmarshal', + 'bin/glib-mkenums', + 'bin/glib-genmarshal', + 'bin/gdbus-codegen', + 'bin/glib-gettextize', + ] # Without these, the relocator won't take effect on macOS files_bins = [ @@ -37,6 +59,14 @@ class Recipe(recipe.Recipe): ] def prepare(self): + if self.config.platform == Platform.WINDOWS: + # glib-2.80.5/COPYING: Can't create 'glib-2.80.5/COPYING': No such file or directory + self.force_tarfile = True + + # Glib doesn't support static libraries on Windows yet + if self.config.target_platform == Platform.WINDOWS: + self.library_type = LibraryType.SHARED + # On Linux we must use the system gettext if self.config.platform != Platform.LINUX: self.deps.append('proxy-libintl') diff --git a/recipes/build-tools/libtool.recipe b/recipes/build-tools/libtool.recipe index fa7951046..1416ee9b6 100644 --- a/recipes/build-tools/libtool.recipe +++ b/recipes/build-tools/libtool.recipe @@ -17,7 +17,6 @@ class Recipe(recipe.Recipe): files_libs = ['libltdl'] files_share = ['share/libtool'] files_aclocal = [ - 'share/aclocal/argz.m4', 'share/aclocal/libtool.m4', 'share/aclocal/ltdl.m4', 'share/aclocal/ltoptions.m4', diff --git a/recipes/build-tools/m4.recipe b/recipes/build-tools/m4.recipe index 0f9e6fd88..ba2a82e04 100644 --- a/recipes/build-tools/m4.recipe +++ b/recipes/build-tools/m4.recipe @@ -4,12 +4,13 @@ import shutil class Recipe(recipe.Recipe): name = 'm4' - version = '1.4.19' + version = '1.4.20' licenses = [License.GPLv2Plus] stype = SourceType.TARBALL url = 'gnu://' - tarball_checksum = '63aede5c6d33b6d9b13511cd0be2cac046f2e70fd0a07aa9573a04a82783af96' + tarball_checksum = 'e236ea3a1ccf5f6c270b1c4bb60726f371fa49459a8eaaebc90b216b328daf2b' files_bins = ['m4'] + patches = ['m4/0001-build-disable-documentation-build.patch'] def prepare(self): self.configure_options += " --disable-gcc-warnings" diff --git a/recipes/build-tools/m4/0001-build-disable-documentation-build.patch b/recipes/build-tools/m4/0001-build-disable-documentation-build.patch new file mode 100644 index 000000000..0a085fd64 --- /dev/null +++ b/recipes/build-tools/m4/0001-build-disable-documentation-build.patch @@ -0,0 +1,28 @@ +From 9ed10387772ff8b93451f0d8372e64d5ab3f026c Mon Sep 17 00:00:00 2001 +From: Andoni Morales Alastruey +Date: Sat, 17 May 2025 11:31:51 +0200 +Subject: [PATCH] build: disable documentation build + +m4 does not support --disable-maintainer-mode and an +update of the .texi files is triggered requiring makeinfo +which might not be installed on the build host. +--- + Makefile.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.in b/Makefile.in +index bd6f0d8..71e03a6 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -2460,7 +2460,7 @@ target_alias = @target_alias@ + top_build_prefix = @top_build_prefix@ + top_builddir = @top_builddir@ + top_srcdir = @top_srcdir@ +-SUBDIRS = . examples lib src doc checks po tests ++SUBDIRS = . examples lib src checks po tests + EXTRA_DIST = bootstrap c-boxes.el cfg.mk maint.mk \ + .prev-version .version m4/gnulib-cache.m4 ChangeLog-2014 + +-- +2.39.2 + diff --git a/recipes/build-tools/meson.recipe b/recipes/build-tools/meson.recipe index bc50b622f..6e94bb8b3 100644 --- a/recipes/build-tools/meson.recipe +++ b/recipes/build-tools/meson.recipe @@ -2,11 +2,11 @@ import glob import shutil -from pathlib import PurePath +from pathlib import PurePath, Path class Recipe(recipe.Recipe): name = 'meson' - version = '1.3.1' + version = '1.6.1' licenses = [License.Apachev2] btype = BuildType.CUSTOM @@ -18,15 +18,14 @@ class Recipe(recipe.Recipe): else: stype = SourceType.TARBALL url = 'https://github.com/mesonbuild/meson/releases/download/%(version)s/meson-%(version)s.tar.gz' - tarball_checksum = '6020568bdede1643d4fb41e28215be38eff5d52da28ac7d125457c59e0032ad7' + tarball_checksum = '1eca49eb6c26d58bbee67fd3337d8ef557c0804e30a6d16bfdf269db997464de' + patches = [ + f'{name}/0001-Python-Work-around-missing-rpath-in-Xcode-python3-em.patch' + ] files_bin = ['bin/meson'] files_python = [] - patches = [ - f'{name}/0001-nasm-Add-mms-bitfields-to-the-list-of-ignored-flags.patch' - ] - async def install(self): # setup.py barfs if using posix paths on Windows if self.config.platform == Platform.WINDOWS: @@ -42,9 +41,9 @@ class Recipe(recipe.Recipe): scriptsdir = os.path.join(prefix, 'Scripts') bindir = os.path.join(prefix, 'bin') os.makedirs(bindir, exist_ok=True) - for f in glob.glob('*', root_dir=scriptsdir): - tof = os.path.join(bindir, f) + for f in Path(scriptsdir).glob('*'): + tof = os.path.join(bindir, f.name) if os.path.isfile(tof): os.remove(tof) - shutil.move(os.path.join(scriptsdir, f), tof) + shutil.move(f, tof) os.rmdir(scriptsdir) diff --git a/recipes/build-tools/meson/0001-Python-Work-around-missing-rpath-in-Xcode-python3-em.patch b/recipes/build-tools/meson/0001-Python-Work-around-missing-rpath-in-Xcode-python3-em.patch new file mode 100644 index 000000000..4a0ae832b --- /dev/null +++ b/recipes/build-tools/meson/0001-Python-Work-around-missing-rpath-in-Xcode-python3-em.patch @@ -0,0 +1,191 @@ +From ac57571fc369305b79c03274f83fb31186cc0b89 Mon Sep 17 00:00:00 2001 +From: "L. E. Segovia" +Date: Tue, 21 Jan 2025 23:14:23 +0000 +Subject: [PATCH 1/3] Python: Work around missing rpath in Xcode python3-embed + +This enables generating Python bindings and linking against +`python3-embed` without resorting to later `install_name_tool` changes, +as the pkg-config module provided by Xcode doesn't say that +Python3.framework requires a rpath entry: + + $ otool -L /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Python3 + /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Python3: + @rpath/Python3.framework/Versions/3.9/Python3 (compatibility version 3.9.0, current version 3.9.0) + /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1933.0.0) + /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1319.0.0) + +(cherry picked from commit c616f1ed50ffcd8f513d888c2dace105476a9168) +--- + mesonbuild/dependencies/python.py | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/mesonbuild/dependencies/python.py b/mesonbuild/dependencies/python.py +index 326e605d8..dbf65f656 100644 +--- a/mesonbuild/dependencies/python.py ++++ b/mesonbuild/dependencies/python.py +@@ -327,6 +327,12 @@ class PythonPkgConfigDependency(PkgConfigDependency, _PythonDependencyBase): + if not self.link_libpython and mesonlib.version_compare(self.version, '< 3.8'): + self.link_args = [] + ++ # But not Apple, because it's a framework ++ if self.env.machines.host.is_darwin() and 'PYTHONFRAMEWORKPREFIX' in self.variables: ++ framework_prefix = self.variables['PYTHONFRAMEWORKPREFIX'] ++ # Add rpath, will be de-duplicated if necessary ++ if framework_prefix.startswith('/Applications/Xcode.app/'): ++ self.link_args += ['-rpath,' + framework_prefix] + + class PythonFrameworkDependency(ExtraFrameworkDependency, _PythonDependencyBase): + +-- +2.47.0.windows.2 + + +From d8a6cd8111b2c618d3237c187848e26639781364 Mon Sep 17 00:00:00 2001 +From: "L. E. Segovia" +Date: Fri, 31 Jan 2025 00:06:48 +0000 +Subject: [PATCH 2/3] Python: fix typo in the inserted workaround for missing + RPATH + +See #14169 + +(cherry picked from commit f75e45887c86c8c73a38f387bd93467dda36df3c) +--- + mesonbuild/dependencies/python.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mesonbuild/dependencies/python.py b/mesonbuild/dependencies/python.py +index dbf65f656..e53a3ea0d 100644 +--- a/mesonbuild/dependencies/python.py ++++ b/mesonbuild/dependencies/python.py +@@ -332,7 +332,7 @@ class PythonPkgConfigDependency(PkgConfigDependency, _PythonDependencyBase): + framework_prefix = self.variables['PYTHONFRAMEWORKPREFIX'] + # Add rpath, will be de-duplicated if necessary + if framework_prefix.startswith('/Applications/Xcode.app/'): +- self.link_args += ['-rpath,' + framework_prefix] ++ self.link_args += ['-Wl,-rpath,' + framework_prefix] + + class PythonFrameworkDependency(ExtraFrameworkDependency, _PythonDependencyBase): + +-- +2.47.0.windows.2 + + +From 690b167d41f22387a1cd8a79cfe0359cb462e787 Mon Sep 17 00:00:00 2001 +From: "L. E. Segovia" +Date: Mon, 10 Feb 2025 15:47:39 -0300 +Subject: [PATCH 3/3] modules/gnome, modules/Python: Allow injecting RPATH + flags through LDFLAGS if needed + +Fixes communicating the RPATH to g-i-scanner in macOS. + +See #14169 + +(cherry picked from commit d6d8b18f70a0021484932bd8481b764e52a48a89) +--- + mesonbuild/dependencies/python.py | 1 + + mesonbuild/modules/gnome.py | 34 +++++++++++++++++++++---------- + 2 files changed, 24 insertions(+), 11 deletions(-) + +diff --git a/mesonbuild/dependencies/python.py b/mesonbuild/dependencies/python.py +index e53a3ea0d..f102aad19 100644 +--- a/mesonbuild/dependencies/python.py ++++ b/mesonbuild/dependencies/python.py +@@ -333,6 +333,7 @@ class PythonPkgConfigDependency(PkgConfigDependency, _PythonDependencyBase): + # Add rpath, will be de-duplicated if necessary + if framework_prefix.startswith('/Applications/Xcode.app/'): + self.link_args += ['-Wl,-rpath,' + framework_prefix] ++ self.raw_link_args += ['-Wl,-rpath,' + framework_prefix] + + class PythonFrameworkDependency(ExtraFrameworkDependency, _PythonDependencyBase): + +diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py +index e0c1214d0..cb9a826db 100644 +--- a/mesonbuild/modules/gnome.py ++++ b/mesonbuild/modules/gnome.py +@@ -702,14 +702,14 @@ class GnomeModule(ExtensionModule): + lib_dir = os.path.dirname(flag) + external_ldflags.update([f'-L{lib_dir}']) + if include_rpath: +- external_ldflags.update([f'-Wl,-rpath {lib_dir}']) ++ external_ldflags.update([f'-Wl,-rpath,{lib_dir}']) + libname = os.path.basename(flag) + if libname.startswith("lib"): + libname = libname[3:] + libname = libname.split(".so")[0] + flag = f"-l{libname}" + # FIXME: Hack to avoid passing some compiler options in +- if flag.startswith("-W"): ++ if flag.startswith("-W") and not flag.startswith('-Wl,-rpath'): + continue + # If it's a framework arg, slurp the framework name too + # to preserve the order of arguments +@@ -962,6 +962,7 @@ class GnomeModule(ExtensionModule): + scan_command: T.Sequence[T.Union['FileOrString', Executable, ExternalProgram, OverrideProgram]], + generated_files: T.Sequence[T.Union[str, mesonlib.File, CustomTarget, CustomTargetIndex, GeneratedList]], + depends: T.Sequence[T.Union['FileOrString', build.BuildTarget, 'build.GeneratedTypes', build.StructuredSources]], ++ env_flags: T.Sequence[str], + kwargs: T.Dict[str, T.Any]) -> GirTarget: + install = kwargs['install_gir'] + if install is None: +@@ -982,6 +983,7 @@ class GnomeModule(ExtensionModule): + # g-ir-scanner uses Python's distutils to find the compiler, which uses 'CC' + cc_exelist = state.environment.coredata.compilers.host['c'].get_exelist() + run_env.set('CC', [quote_arg(x) for x in cc_exelist], ' ') ++ run_env.set('CFLAGS', [quote_arg(x) for x in env_flags], ' ') + run_env.merge(kwargs['env']) + + return GirTarget( +@@ -1088,11 +1090,12 @@ class GnomeModule(ExtensionModule): + yield f + + @staticmethod +- def _get_scanner_ldflags(ldflags: T.Iterable[str]) -> T.Iterable[str]: ++ def _get_scanner_ldflags(ldflags: T.Iterable[str]) -> tuple[list[str], list[str]]: + 'g-ir-scanner only accepts -L/-l; must ignore -F and other linker flags' +- for f in ldflags: +- if f.startswith(('-L', '-l', '--extra-library')): +- yield f ++ return ( ++ [f for f in ldflags if f.startswith(('-L', '-l', '--extra-library'))], ++ [f for f in ldflags if f.startswith(('-Wl,-rpath'))], ++ ) + + @typed_pos_args('gnome.generate_gir', varargs=(Executable, build.SharedLibrary, build.StaticLibrary), min_varargs=1) + @typed_kwargs( +@@ -1161,11 +1164,20 @@ class GnomeModule(ExtensionModule): + scan_cflags += list(self._get_scanner_cflags(dep_cflags)) + scan_cflags += list(self._get_scanner_cflags(self._get_external_args_for_langs(state, [lc[0] for lc in langs_compilers]))) + scan_internal_ldflags = [] +- scan_internal_ldflags += list(self._get_scanner_ldflags(internal_ldflags)) +- scan_internal_ldflags += list(self._get_scanner_ldflags(dep_internal_ldflags)) + scan_external_ldflags = [] +- scan_external_ldflags += list(self._get_scanner_ldflags(external_ldflags)) +- scan_external_ldflags += list(self._get_scanner_ldflags(dep_external_ldflags)) ++ scan_env_ldflags = [] ++ for cli_flags, env_flags in [ ++ self._get_scanner_ldflags(internal_ldflags), ++ self._get_scanner_ldflags(dep_internal_ldflags), ++ ]: ++ scan_internal_ldflags += cli_flags ++ scan_env_ldflags = env_flags ++ for cli_flags, env_flags in [ ++ self._get_scanner_ldflags(external_ldflags), ++ self._get_scanner_ldflags(dep_external_ldflags) ++ ]: ++ scan_external_ldflags += cli_flags ++ scan_env_ldflags = env_flags + girtargets_inc_dirs = self._get_gir_targets_inc_dirs(girtargets) + inc_dirs = kwargs['include_directories'] + +@@ -1216,7 +1228,7 @@ class GnomeModule(ExtensionModule): + generated_files = [f for f in libsources if isinstance(f, (GeneratedList, CustomTarget, CustomTargetIndex))] + + scan_target = self._make_gir_target( +- state, girfile, scan_command, generated_files, depends, ++ state, girfile, scan_command, generated_files, depends, scan_env_ldflags, + # We have to cast here because mypy can't figure this out + T.cast('T.Dict[str, T.Any]', kwargs)) + +-- +2.47.0.windows.2 + diff --git a/recipes/build-tools/meson/0001-nasm-Add-mms-bitfields-to-the-list-of-ignored-flags.patch b/recipes/build-tools/meson/0001-nasm-Add-mms-bitfields-to-the-list-of-ignored-flags.patch deleted file mode 100644 index a91b534ff..000000000 --- a/recipes/build-tools/meson/0001-nasm-Add-mms-bitfields-to-the-list-of-ignored-flags.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 677feadf9f6d6d544be27c807d92538297044920 Mon Sep 17 00:00:00 2001 -From: "L. E. Segovia" -Date: Tue, 9 Jul 2024 19:02:09 -0300 -Subject: [PATCH] nasm: Add -mms-bitfields to the list of ignored flags - -Fixes building Nasm objects with Meson's native language support, when -depending against a library that exports that flag, like Glib. - -(cherry picked from commit 8b73edd80a3c8ccb8fb6e1f8c8b48fd21175187b) ---- - mesonbuild/compilers/asm.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/mesonbuild/compilers/asm.py b/mesonbuild/compilers/asm.py -index d04fbd293..c5e552165 100644 ---- a/mesonbuild/compilers/asm.py -+++ b/mesonbuild/compilers/asm.py -@@ -73,7 +73,7 @@ class NasmCompiler(Compiler): - def unix_args_to_native(self, args: T.List[str]) -> T.List[str]: - outargs: T.List[str] = [] - for arg in args: -- if arg == '-pthread': -+ if arg in {'-mms-bitfields', '-pthread'}: - continue - outargs.append(arg) - return outargs --- -2.44.0.windows.1 - diff --git a/recipes/build-tools/moltenvk-tools.recipe b/recipes/build-tools/moltenvk-tools.recipe index a4850ff3c..18abd27d6 100644 --- a/recipes/build-tools/moltenvk-tools.recipe +++ b/recipes/build-tools/moltenvk-tools.recipe @@ -5,14 +5,14 @@ from cerbero.utils import messages as m class Recipe(recipe.Recipe): name = 'moltenvk-tools' - version = '1.2.182.0' + version = '1.3.283.0' licenses = [License.Apachev2] stype = SourceType.TARBALL tarball_dirname = "vulkansdk-macos-%(version)s" # Mirrored because lunarg.com has an extremely small download limit #url = 'https://sdk.lunarg.com/sdk/download/%(version)s/mac/' + tarball_dirname + '.dmg' url = 'https://gstreamer.freedesktop.org/data/src/mirror/' + tarball_dirname + '.dmg' - tarball_checksum = '9e89291283e41d62673bf48007dac764e99a504d145ee4d70d2d32e328f7ee40' + tarball_checksum = '60ca47ad5a84a890087e7b372b5b2352bbced07966767dd30159efd49d0f7118' btype = BuildType.CUSTOM # The binaries from the SDK are already signed and do not require relocation skip_steps = [BuildSteps.RELOCATE_OSX_LIBRARIES, BuildSteps.CODE_SIGN] @@ -35,20 +35,13 @@ class Recipe(recipe.Recipe): if self.config.target_platform not in (Platform.IOS, Platform.DARWIN): raise InvalidRecipeError(self, "Invalid platform") - async def extract(self): - if self.config.arch == Architecture.ARM64: - m.message("Installing rosetta needed for some package installation scripts") - await shell.async_call(['/usr/sbin/softwareupdate', '--install-rosetta', '--agree-to-license'], logfile=self.logfile) - - await super().extract() - async def install(self): srcdir = self.config.moltenvk_prefix prefix = self.config.prefix if os.path.exists(srcdir): shutil.rmtree(srcdir) - # https://vulkan.lunarg.com/doc/sdk/1.2.182.0/mac/getting_started.html + # https://vulkan.lunarg.com/doc/sdk/1.3.283.0/mac/getting_started.html vulkan_installer = os.path.join(self.build_dir, 'InstallVulkan.app/Contents/MacOS/InstallVulkan') await shell.async_call([vulkan_installer, '--root', self.config.moltenvk_prefix, @@ -64,5 +57,5 @@ class Recipe(recipe.Recipe): patch = os.path.join(self.config.recipes_dir, 'build-tools', self.name, 'ifdef-new-metal-types.patch') - moltenvk_dir = os.path.join(self.config.moltenvk_prefix, 'MoltenVK') + moltenvk_dir = os.path.join(self.config.moltenvk_prefix, 'macOS') shell.apply_patch(patch, moltenvk_dir, logfile=self.logfile) diff --git a/recipes/build-tools/moltenvk-tools/ifdef-new-metal-types.patch b/recipes/build-tools/moltenvk-tools/ifdef-new-metal-types.patch index 3f5f5816e..bb30e3818 100644 --- a/recipes/build-tools/moltenvk-tools/ifdef-new-metal-types.patch +++ b/recipes/build-tools/moltenvk-tools/ifdef-new-metal-types.patch @@ -11,9 +11,9 @@ /** Returns all four Metal texture swizzles from the Vulkan component mapping. */ -MTLTextureSwizzleChannels mvkMTLTextureSwizzleChannelsFromVkComponentMapping(VkComponentMapping vkMapping); +MTLTextureSwizzleChannels mvkMTLTextureSwizzleChannelsFromVkComponentMapping(VkComponentMapping vkMapping) API_AVAILABLE(macos(10.15), ios(13.0)); - - - #pragma mark Mipmaps + + /** Maps a clear color according to the specified VkComponentSwizzle. */ + float mvkVkClearColorFloatValueFromVkComponentSwizzle(float *colors, uint32_t index, VkComponentSwizzle vkSwizzle); @@ -362,8 +360,8 @@ /** Returns the Metal MTLStoreAction corresponding to the specified Vulkan VkAttachmentStoreOp. */ MTLStoreAction mvkMTLStoreActionFromVkAttachmentStoreOp(VkAttachmentStoreOp vkStoreOp, bool hasResolveAttachment); diff --git a/recipes/build-tools/nasm.recipe b/recipes/build-tools/nasm.recipe index ff78c4032..525627d1e 100644 --- a/recipes/build-tools/nasm.recipe +++ b/recipes/build-tools/nasm.recipe @@ -3,10 +3,10 @@ class Recipe(recipe.Recipe): name = 'nasm' - version = '2.14.02' + version = '2.16.03' licenses = [{License.BSD_like: ['LICENSE']}] stype = SourceType.TARBALL - url = 'https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.xz' - tarball_checksum = 'e24ade3e928f7253aa8c14aa44726d1edf3f98643f87c9d72ec1df44b26be8f5' + url = 'https://www.nasm.us/pub/nasm/releasebuilds/%(version)s/nasm-%(version)s.tar.xz' + tarball_checksum = '1412a1c760bbd05db026b6c0d1657affd6631cd0a63cddb6f73cc6d4aa616148' files_bins = ['nasm'] diff --git a/recipes/build-tools/ninja.recipe b/recipes/build-tools/ninja.recipe index 51a4e28ee..9564c28a6 100644 --- a/recipes/build-tools/ninja.recipe +++ b/recipes/build-tools/ninja.recipe @@ -2,12 +2,12 @@ class Recipe(recipe.Recipe): name = 'ninja' - version = '1.11.1' + version = '1.12.1' licenses = [License.Apachev2] btype = BuildType.CUSTOM stype = SourceType.TARBALL url = 'https://github.com/ninja-build/ninja/archive/v%(version)s.tar.gz' - tarball_checksum = '31747ae633213f1eda3842686f83c2aa1412e0f5691d1c14dbbcc67fe7400cea' + tarball_checksum = '821bdff48a3f683bc4bb3b6f0b5fe7b2d647cf65d52aeb63328c91a6c6df285a' patches = ['ninja/0001-configure.py-Look-for-cl.exe-before-assuming-MSVC.patch'] files_bin = ['bin/ninja'] diff --git a/recipes/build-tools/ninja/0001-configure.py-Look-for-cl.exe-before-assuming-MSVC.patch b/recipes/build-tools/ninja/0001-configure.py-Look-for-cl.exe-before-assuming-MSVC.patch index de14ca888..8e8a46156 100644 --- a/recipes/build-tools/ninja/0001-configure.py-Look-for-cl.exe-before-assuming-MSVC.patch +++ b/recipes/build-tools/ninja/0001-configure.py-Look-for-cl.exe-before-assuming-MSVC.patch @@ -1,4 +1,4 @@ -From b6784276d7ccea28ab1a5d5936f98b8342e8eb57 Mon Sep 17 00:00:00 2001 +From 97d00158834d0489a0be9ef289623c77b5cae9a3 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Wed, 16 May 2018 13:32:14 +0530 Subject: [PATCH] configure.py: Look for cl.exe before assuming MSVC @@ -10,18 +10,18 @@ incorrectly. 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/configure.py b/configure.py -index a443748..a627f46 100644 +index 6ee64a8..26d0bba 100755 --- a/configure.py +++ b/configure.py -@@ -27,6 +27,7 @@ import pipes - import string +@@ -24,6 +24,7 @@ import os + import shlex import subprocess import sys +import shutil sourcedir = os.path.dirname(os.path.realpath(__file__)) sys.path.insert(0, os.path.join(sourcedir, 'misc')) -@@ -53,7 +54,10 @@ class Platform(object): +@@ -50,7 +51,10 @@ class Platform(object): elif self._platform.startswith('mingw'): self._platform = 'mingw' elif self._platform.startswith('win'): @@ -34,5 +34,5 @@ index a443748..a627f46 100644 self._platform = 'bitrig' elif self._platform.startswith('netbsd'): -- -2.12.2.windows.2 +2.43.0 diff --git a/recipes/build-tools/wine-mono.recipe b/recipes/build-tools/wine-mono.recipe index 3638b492e..32f031fc6 100644 --- a/recipes/build-tools/wine-mono.recipe +++ b/recipes/build-tools/wine-mono.recipe @@ -22,4 +22,4 @@ class Recipe(recipe.Recipe): self.env['WINEPREFIX'] = os.path.join(self.config.prefix, 'var', 'tmp', 'wine') self.env['WINEDEBUG'] = 'fixme-all' await shell.async_call(['wine', 'msiexec', '/i', os.path.join(self.download_dir, self.tarball_name)], - cmd_dir=wine_path, env=self.env) + cmd_dir=wine_path, env=self.env, logfile=self.logfile) diff --git a/recipes/build-tools/winetricks.recipe b/recipes/build-tools/winetricks.recipe index 23f1b832d..3e068392e 100644 --- a/recipes/build-tools/winetricks.recipe +++ b/recipes/build-tools/winetricks.recipe @@ -6,10 +6,10 @@ from cerbero.utils import shell class Recipe(recipe.Recipe): name = 'winetricks' - version = '20210825' + version = '20240105' stype = SourceType.TARBALL url = 'https://github.com/Winetricks/winetricks/archive/refs/tags/%(version)s.tar.gz' - tarball_checksum = 'bac77918ef4d58c6465a1043fd996d09c3ee2c5a07f56ed089c4c65a71881277' + tarball_checksum = 'e92929045cf9ffb1e8d16ef8fd971ea1cf63a28a73916b1951e9553c94482f61' btype = BuildType.CUSTOM async def install(self): diff --git a/recipes/build-tools/wix.recipe b/recipes/build-tools/wix.recipe index a28c7bb63..f4c8a5471 100644 --- a/recipes/build-tools/wix.recipe +++ b/recipes/build-tools/wix.recipe @@ -1,32 +1,28 @@ # -*- Mode: Python -*- vi:si:et:sw=4:sts=4:ts=4:syntax=python import os -import shutil from cerbero.utils import shell class Recipe(recipe.Recipe): name = 'wix' - version = '3.11.1' + version = '5.0.1' stype = SourceType.TARBALL - url = 'https://github.com/wixtoolset/wix3/releases/download/wix3111rtm/wix311-binaries.zip' - tarball_checksum = '37f0a533b0978a454efb5dc3bd3598becf9660aaf4287e55bf68ca6b527d051d' + url = 'https://github.com/wixtoolset/wix/releases/download/v%(version)s/wix-cli-x64.msi' + tarball_checksum = 'c07686d17feed239b9dfa2fc2c14967e0fa03d693b87a4da49548a17b74229a9' deps = ['winetricks', 'wine-mono'] btype = BuildType.CUSTOM async def extract(self): - if os.path.exists(self.build_dir): - shutil.rmtree(self.build_dir) - os.makedirs(self.build_dir) - await shell.unpack(os.path.join(self.download_dir, self.tarball_name), self.build_dir) + pass async def install(self): - shell.copy_dir(self.build_dir, os.path.join(self.config.prefix, 'lib', 'wix', 'bin')) - # wineconsole fails trying to get env var in a VT with DISPLAY. - # This is working on docker buildbot and on a real terminal. - winetricks_tool = os.path.join(self.config.prefix, 'bin', 'winetricks') - if not 'DISPLAY' in self.env: - self.env['WINE'] = "wineconsole" - if self.config.target_platform == Platform.WINDOWS and \ - self.config.platform == Platform.LINUX: - await shell.async_call([winetricks_tool, '-q', 'dotnet40'], env=self.env) - + if self.config.platform == Platform.LINUX: + wine_path = os.path.join(self.config.prefix, 'share', 'wine') + if not os.path.exists(wine_path): + os.makedirs(wine_path) + # Override the environment with the Wine prefix + env = self.config.get_wine_runtime_env(self.config.prefix, self.env) + winetricks_tool = os.path.join(self.config.prefix, 'bin', 'winetricks') + await shell.async_call(['xvfb-run', winetricks_tool, '-q', 'dotnet6'], env=env, logfile=self.logfile) + await shell.async_call(['wine', 'msiexec', '/i', os.path.join(self.download_dir, self.tarball_name)], + cmd_dir=wine_path, env=env, logfile=self.logfile) diff --git a/recipes/cairo.recipe b/recipes/cairo.recipe index 874bdba05..8a93d6125 100644 --- a/recipes/cairo.recipe +++ b/recipes/cairo.recipe @@ -1,13 +1,12 @@ # -*- Mode: Python -*- vi:si:et:sw=4:sts=4:ts=4:syntax=python from cerbero.tools.libtool import LibtoolLibrary -from cerbero.tools.libtool import get_libtool_versions class Recipe(recipe.Recipe): name = 'cairo' - version = '1.18.0' + version = '1.18.4' stype = SourceType.TARBALL url = 'https://cairographics.org/releases/cairo-%(version)s.tar.xz' - tarball_checksum = '243a0736b978a33dee29f9cca7521733b78a65b5418206fef7bd1c3d4cf10b64' + tarball_checksum = '445ed8208a6e4823de1226a74ca319d3600e83f6369f99b14265006599c32ccb' # Either LGPL-2.1+ or MPL-1.1 licenses = [License.LGPLv2_1Plus, {License.MPLv1_1: ['COPYING-MPL-1.1']}] deps = ['glib', 'libpng', 'zlib', 'pixman', 'fontconfig', 'freetype'] @@ -18,14 +17,7 @@ class Recipe(recipe.Recipe): 'tests': 'disabled', 'xcb': 'disabled', 'xlib': 'disabled'} - patches = [ - 'cairo/0001-cairo-ps-surface-fix-Walloc-size.patch', - 'cairo/0001-Copy-font-options-during-creation-of-a-fallback-font.patch', - 'cairo/0001-Fix-alloca-undefined-with-MSVC.patch', - 'cairo/0001-Fix-surface-type-mismatch-error-in-pdf-interchange.patch', - 'cairo/0001-quartz-Fix-Cairo-1.18.0-doesn-t-draw-italic-or-bold-.patch', - 'cairo/0001-util-remove-malloc-stats.patch', - ] + patches = [] files_libs = ['libcairo', 'libcairo-gobject', 'libcairo-script-interpreter'] files_devel = [ @@ -79,4 +71,8 @@ class Recipe(recipe.Recipe): self.config.libdir, self.config.target_platform, deps=['cairo', 'gobject-2.0', 'pixman-1', 'freetype', 'fontconfig', 'png16', 'z']) libtool_la.save() + libtool_la = LibtoolLibrary('libcairo-script-interpreter', None, None, None, + self.config.libdir, self.config.target_platform, + deps=['cairo', 'gobject-2.0', 'pixman-1', 'freetype', 'fontconfig', 'png16', 'z']) + libtool_la.save() super().post_install() diff --git a/recipes/cairo/0001-Copy-font-options-during-creation-of-a-fallback-font.patch b/recipes/cairo/0001-Copy-font-options-during-creation-of-a-fallback-font.patch deleted file mode 100644 index c5b7dde3b..000000000 --- a/recipes/cairo/0001-Copy-font-options-during-creation-of-a-fallback-font.patch +++ /dev/null @@ -1,682 +0,0 @@ -From 3bcad03f6bc33c436122f4acaefc9e58caa37116 Mon Sep 17 00:00:00 2001 -From: Behdad Esfahbod -Date: Sun, 14 Jan 2024 09:17:40 -0700 -Subject: [PATCH] Copy font-options during creation of a fallback font - -Specially important for font variations, which before did not -work in PDF, etc, output. - -Script surface is not updated. It seems out of date with all -recent additions to cairo_font_options_t, so it loses the -variations :(. - -Fixes https://gitlab.freedesktop.org/cairo/cairo/-/issues/819 ---- - .gitlab-ci.yml | 1 + - src/cairo-scaled-font-subsets.c | 1 + - src/cairo-type1-fallback.c | 1 + - test/ft-variable-font.c | 127 ++++++++++++++++++ - test/meson.build | 1 + - .../ft-variable-font.image16.ref.png | Bin 0 -> 3871 bytes - test/reference/ft-variable-font.pdf.ref.png | Bin 0 -> 4379 bytes - test/reference/ft-variable-font.ps.ref.png | Bin 0 -> 2564 bytes - test/reference/ft-variable-font.ref.png | Bin 0 -> 4413 bytes - .../ft-variable-font.script.xfail.png | Bin 0 -> 4316 bytes - test/reference/ft-variable-font.svg.ref.png | Bin 0 -> 4359 bytes - 11 files changed, 131 insertions(+) - create mode 100644 test/ft-variable-font.c - create mode 100644 test/reference/ft-variable-font.image16.ref.png - create mode 100644 test/reference/ft-variable-font.pdf.ref.png - create mode 100644 test/reference/ft-variable-font.ps.ref.png - create mode 100644 test/reference/ft-variable-font.ref.png - create mode 100644 test/reference/ft-variable-font.script.xfail.png - create mode 100644 test/reference/ft-variable-font.svg.ref.png - -diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml -index 9384e0abd..0b54eefd3 100644 ---- a/.gitlab-ci.yml -+++ b/.gitlab-ci.yml -@@ -91,6 +91,7 @@ fedora image: - dejavu-sans-mono-fonts - dejavu-serif-fonts - google-noto-emoji-color-fonts -+ google-noto-sans-vf-fonts - fonttools - util-linux - -diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c -index 8a25a4612..a240bebbe 100644 ---- a/src/cairo-scaled-font-subsets.c -+++ b/src/cairo-scaled-font-subsets.c -@@ -922,6 +922,7 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets, - font_face = cairo_scaled_font_get_font_face (scaled_font); - cairo_matrix_init_identity (&identity); - _cairo_font_options_init_default (&font_options); -+ cairo_scaled_font_get_font_options (scaled_font, &font_options); - cairo_font_options_set_hint_style (&font_options, CAIRO_HINT_STYLE_NONE); - cairo_font_options_set_hint_metrics (&font_options, CAIRO_HINT_METRICS_OFF); - unscaled_font = cairo_scaled_font_create (font_face, -diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c -index 3a44c4666..c81e85143 100644 ---- a/src/cairo-type1-fallback.c -+++ b/src/cairo-type1-fallback.c -@@ -107,6 +107,7 @@ cairo_type1_font_create (cairo_scaled_font_subset_t *scaled_font_subset, - cairo_matrix_init_identity (&ctm); - - _cairo_font_options_init_default (&font_options); -+ cairo_scaled_font_get_font_options (scaled_font_subset->scaled_font, &font_options); - cairo_font_options_set_hint_style (&font_options, CAIRO_HINT_STYLE_NONE); - cairo_font_options_set_hint_metrics (&font_options, CAIRO_HINT_METRICS_OFF); - -diff --git a/test/ft-variable-font.c b/test/ft-variable-font.c -new file mode 100644 -index 000000000..2adba66dd ---- /dev/null -+++ b/test/ft-variable-font.c -@@ -0,0 +1,127 @@ -+/* -+ * Copyright © 2021 Adrian Johnson -+ * -+ * Permission is hereby granted, free of charge, to any person -+ * obtaining a copy of this software and associated documentation -+ * files (the "Software"), to deal in the Software without -+ * restriction, including without limitation the rights to use, copy, -+ * modify, merge, publish, distribute, sublicense, and/or sell copies -+ * of the Software, and to permit persons to whom the Software is -+ * furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -+ * SOFTWARE. -+ * -+ * Author: Adrian Johnson -+ */ -+ -+#include "cairo-test.h" -+#include -+ -+#define SIZE 200 -+#define HEIGHT SIZE -+#define WIDTH (SIZE * 1.5) -+#define FONT "Noto Sans" -+ -+static cairo_test_status_t -+set_variable_font (cairo_t *cr) -+{ -+ cairo_font_options_t *font_options; -+ cairo_font_face_t *font_face; -+ FcPattern *pattern; -+ FcPattern *resolved; -+ FcChar8 *font_name; -+ FcBool variable; -+ FcResult result; -+ -+ pattern = FcPatternCreate (); -+ if (pattern == NULL) -+ return CAIRO_TEST_NO_MEMORY; -+ -+ FcPatternAddString (pattern, FC_FAMILY, (FcChar8 *) FONT); -+ FcPatternAddBool (pattern, FC_VARIABLE, TRUE); -+ FcConfigSubstitute (NULL, pattern, FcMatchPattern); -+ -+ font_options = cairo_font_options_create (); -+ cairo_get_font_options (cr, font_options); -+ cairo_ft_font_options_substitute (font_options, pattern); -+ -+ FcDefaultSubstitute (pattern); -+ resolved = FcFontMatch (NULL, pattern, &result); -+ if (resolved == NULL) { -+ FcPatternDestroy (pattern); -+ return CAIRO_TEST_NO_MEMORY; -+ } -+ -+ if (FcPatternGetString (resolved, FC_FAMILY, 0, &font_name) == FcResultMatch) { -+ if (strcmp((char*)font_name, FONT) != 0) { -+ const cairo_test_context_t *ctx = cairo_test_get_context (cr); -+ cairo_test_log (ctx, "Could not find %s font\n", FONT); -+ return CAIRO_TEST_UNTESTED; -+ } -+ } else { -+ return CAIRO_TEST_FAILURE; -+ } -+ if (FcPatternGetBool (resolved, FC_VARIABLE, 0, &variable) == FcResultMatch) { -+ if (!variable) { -+ const cairo_test_context_t *ctx = cairo_test_get_context (cr); -+ cairo_test_log (ctx, "Could not find %s font\n", FONT); -+ return CAIRO_TEST_UNTESTED; -+ } -+ } else { -+ return CAIRO_TEST_FAILURE; -+ } -+ -+ font_face = cairo_ft_font_face_create_for_pattern (resolved); -+ cairo_set_font_face (cr, font_face); -+ -+ cairo_font_options_destroy (font_options); -+ cairo_font_face_destroy (font_face); -+ FcPatternDestroy (pattern); -+ FcPatternDestroy (resolved); -+ -+ return CAIRO_TEST_SUCCESS; -+} -+ -+static cairo_test_status_t -+draw (cairo_t *cr, int width, int height) -+{ -+ cairo_test_status_t result; -+ cairo_font_options_t *font_options; -+ -+ cairo_set_source_rgb (cr, 1, 1, 1); -+ cairo_paint (cr); -+ cairo_set_source_rgb (cr, 0, 0, 0); -+ -+ result = set_variable_font (cr); -+ if (result != CAIRO_TEST_SUCCESS) -+ return result; -+ -+ font_options = cairo_font_options_create (); -+ cairo_font_options_set_variations (font_options, "wght=700"); -+ cairo_set_font_options (cr, font_options); -+ cairo_font_options_destroy (font_options); -+ -+ cairo_set_font_size (cr, SIZE/2); -+ cairo_move_to (cr, SIZE/8, 0.7 * SIZE); -+ -+ cairo_show_text(cr, "Test"); -+ -+ return CAIRO_TEST_SUCCESS; -+} -+ -+CAIRO_TEST (ft_variable_font, -+ "Test variable font", -+ "ft, font", /* keywords */ -+ NULL, /* requirements */ -+ WIDTH, HEIGHT, -+ NULL, draw) -diff --git a/test/meson.build b/test/meson.build -index 53a8eb675..d7834438f 100644 ---- a/test/meson.build -+++ b/test/meson.build -@@ -429,6 +429,7 @@ test_ft_font_sources = [ - 'ft-text-vertical-layout-type1.c', - 'ft-text-vertical-layout-type3.c', - 'ft-text-antialias-none.c', -+ 'ft-variable-font.c', - ] - - test_ft_svg_font_sources = [ -diff --git a/test/reference/ft-variable-font.image16.ref.png b/test/reference/ft-variable-font.image16.ref.png -new file mode 100644 -index 0000000000000000000000000000000000000000..94d4d63c428ff4ea20ed0f415fd79004a01b9904 -GIT binary patch -literal 3871 -zcmds4`#%%hA6Jp(I&z!acqGa#g~)x6gycb*xsSpq -zxl==PdkV`n(Oky%-Sf-$k9c0^yv{kVbKd8CUa!yjd_M2b=aG{GR9HY(fQN@i*w*H< -zGY`)ZP44;w;3#*TrojH4j$ea8FY|EzZ7(PlnLIoq9Vf1@?mJq2Q7X{!hCv3``$B7Q`ouqKy)-(;*s5iZKx)F(Z=B8utsP -zA@K;CbRpqC=dK!vo`Dxr&z?dF3r|`c)v&P;6hqDPw)5vt*lLDGkw+aH+KYNU2tCQ| -zGn2Wq{qhqN6Mj4vOZahN9!4ZUnMaohye9(zSO_WeDm?%m1zG`)JX9v~bORwg*Z%9r -zIiEJ&uOjRW*?A(rnoNry0dX2U4GLThVRt1(<*`h@=c-XDR5j~mIL{3$yu|3ogDeaw1MBGBs;8yCymnnasZHoH>iY~DOu3k5TtKvGWCo~q0r -zE(bzTiFBQ2*|-srBp^gX^DfC|n#fE9LblvIei?6DS3v;9KSn==cAb0WJ<`raw@|}J -zq^qfWXOhW9v{h5xDD5ny!!0vI6VQ_b{cGQRc#EynN?%C`B=!#o;WVc5wv<;1q}iF1 -zrqhaS{yP-p*KpqIzuJ;p-(MP5NL=h}LixPP3H>WHZ`st%&F!!flhuE%4h6qz2{chm -zV@SoBnt5g|Aaj3a8rZw|xVyP&$y$>FrHUj6GD6{3N3^02+hG#cX -zHuh{Qi4uoJ#`K;^s!|Hz7>y~bYW7LQRkJ_%li~vi@>}4o#yOXZg|d|ku8YB^@fRzm -zmr%+9k9949-&Nkmx+-pq9)H6BT_r*#Y*-PU-my8;sHUwtO1ll^J=%M$IFp46VqW^WMcUf&tM+;|B}6(U7p5+^ -z430ha?$fGlJTnk2qI@H(LD;_;VYc-#H#j!84H>@d^?Flkabt1eqU`deh?{l8ADvRK -zH`T0E|4>~g0k1{Yi{O0LjHjeI?rk6)q`E{8ThHKdBvM5u1L+{zrvGB*I(rwI7=#Ia -zUA+&Beg0Gg2AkE=r+`=@5Dyr$V)X^#DZ#I+u$%U1e(sIu`7o1F@cuGAKOYXT{Z*tm -zqz}F;fB&sM2`1Tx4Z#KrFntUOC1NXpqfcLDy+a3^70$0tk)tbaRk{ll0P24!81tVE -zMwZjzqqAFC7!zrEf#cBl`}m_~wT=?jrGbpJ-w5q&FNd<)ioI~AP#3^4(S_!WQ*`&w -zl}v%1MD!E-&4hm>}m7iLWe0@TG)|VEz{HQN%?VM)^ -z_V)YH3h6?j@Po9KXF~@Aox*O@A5k#lY`&!UgCdJPPovwaAbElH1J;f32>K|2kqX94 -zM5i1c*&*sY^nG*gjQRcyqjQ08aIkxiP_$$&jNbf8opMpxcX_^5CKK>YP3vj^0HdrY -z){@>_Y(5&`+igH|E7${Aowp|fF`w8u3$@0Z%;;*&%jW2tbyt#p@=0bjBUiG9oPFyN -zXSU3DjcRFfrgERbKdL4_!^gXE=ZM&^2h`ha{-L{6 -zu=o=k-H@ -zgL-5FB!lNy7}x4_0vcvtJH2vIVj@P=zwG|l9^W2yV`-oUGC-WOirg+QaK!;yKyN;# -z2?2lt;Nl--s@^mc`t_@|zM^+z4to#oe><{Z5U!8V&&|*6A9y^jVO{=5`bV2y#cUX0 -z`p+I27sB;kif+mf+UEo)U`u-G`P9hO*4i-UpCRT&RDo$JD*%Y(ac}fIE?eRgG%#eR -z(EzqcH(!daWd(BqMs`{W!1FyGb*@W!RtW*x%8}>w2=5`qqM~DZOKc-GTj!K)%_vRc -z)4C{%ctmo+lb1DR@*UY1gaTsFF+ZPMK7L^!2l*fqa3wSxPq{J+9$5P25Y|R -z+PvZ9bm)7p@3*zxscEyr3XTkwj5wC0%xd>=6!71lzFT#iEUSVYu#WMl{VP-xH^U_s -z3YEx<&@=&wI6mOA1RK}3>6Tb`OP4r&lkwzyPfp}S=PwhV#y1_Xd_Vz!zB}J@Y|Zj} -zmyL?G!E#G-CSDw@(XLZq=cA6&!3#~tV1K@hFc-}-WXTa`1#h**hLBu-WrUmfu1{1mkBh{@6x&MC1RmT9uqLBU4&>-u&=RMtJ -zyad{QnbjQnO^ccj_EZjw%%-PB`N9x(lX0h1a8{F%7Rk;!m7S4w#mSlGTu^&pamVj>W}vpz-nqAV -zKGV175Op4iff{WD5@1g()EW0;-A?7;Z`^vN5O;r0N?ckTzCya#7@W(Z(HBKf3E{#q -z$gSvBiqE<>+&_qPL*@bdG7Y?vS6;b-*3Q1(V@UKoKlbUzc0``;;@al%nG@RzYb%6O -z-%FadrlW)6pfNo%D=z|Si?sDx<`sy4*I`r==_GDFGKJKa%xd~;f)2NmuqItw&mXCk -z1$Jg9o`zH|j4!%R<_U0Paabm`HnBIcY$Iy||CRFxAYKX3PwmeLyWnA!R7` -z<|cEud~h;UV29Z1(bgaLbZ*8!ubj)PE~V)pqpF?$36~sxNRwclw<}yCNxEVqu5=^K -z%d`r6@ZHd?rv=zK{W1JQZa%1@;mb5X*M@Jt|0VK}>yr)}>E!H4VCU52$y~?T7s9jX4PC$v5T1(S}?`BZACLaAq^*Xz+2w?e^1FnP|#+CgSILj{^z6; -z05TV?#I)8VT%5HD_=VqE>M#MzpD@_1uw0e0I$7*`$xS=^`TmP2+)78|m03A*jGF`< -zf>k#p_}?|BhL7D(O-;SRUh*ReY1J-%#<{WVF9?--oW;16HRa5S=cGI;VThTw(_&{7 -zYa^YOjp?-6Ssie?0=UL$qq4cRxh;?DmWjQ5hmVkY4YDMC=*G2prH7chPt&U0#H1l) -zj$y&^KGag|(u0*pKs_m>yw>b7J$oHS{+a}@C00Kb{Wri}w5KlYNRoj3s$z8%s#VSO#M^gbclH -z*)pjywkRh1jIqx5=$G&R@VV!@Uh|r3t~2L8=XF2t=i^L*nTakN^F?L`1_m~LJ#BLa -zhGSR3eJ>LuxDs)OM{lQG40W{`=tr+NxcBJ{43IDS+M1RjxqpZc%`B|>POoveov|}J -z_K&3*#IG=txX@@>;0jnExC%4*ijaA=+@jS2{leeuaGW+vP -zR#Kjj!pth^_3OTyqVcoaqVosO?j=G@UZGUw_TfSUfkTnE4@GmsSDHjBtoj(9rLa9Y -z&VUnuGTmksK5;1y!U)k~I`%>s!SD$JWpH5NM?V2r8|q*_gtG6LGh^ -z39@`Bhuw^4km&6G0u2oXh1wSD*9Ij>B=Y87H9v0aDSOs85}Y2n^5f=`^i@tM(}LgH -zv}Ur77BMy!%GAM6T_u?kqkn?i`N{`P=H}*5V(i~f<`x#Eb{H=v;Vdgd!@ilW_|g`P -zSEpmql`B_d$sg$ltMHx_fw`*=jeavlcaW^g$h^F~W4g~fO!8HCraO*<$#T|&lU}@# -zCEqqRH9d3@5)z6rJ+XioDpKq0xhq?^x4pXDc$@tX#sz;rIXStzyIV|5j6$I>$3hFu -zuvly(h~}f%-Q7Jaa4V?yrEui#R^bw+sj2Dh+qYP(rF5ngy=2%+^n8N0h<{*Ux}NCN -z)Ko`D2e@|T?|v!NYE&g$Mtp%78ynl$*hrY<_J01{6u$j9b=z(7`}g>`IFp>~`jW48 -zbaZl@)7*@W2NF0W2J_Xz4|XXvHS&X^dZMqUr>9@Oe0jH6=gyrwJ2V>asFsPzV2Xf> -zGSa&IzB8tShg0$!5v@S5!6ew}^s?i$tmVZD%VsdgtS=mx$vXpft -zB0e6~%oYd9NpX+EV6oRlMLz{;m?l*ZY0!UUoec~Oq%=3XCLJE^DJd$d5xZhev(L`W -z4Fqewc^wPkP-y1l=a68{LNlXm`R;uwK?`&9sNLTZgR@8;nfzN%{(E~6v;h*$*$l#+h7w}M -z3^UA#bn39Kkbhg#0c|ez-Q#z~Z{EB)!y%rvnS?tn?r}>6ei&hEo71LioFzN+r-3AR -zGvIAQLxZ+R)6-Q4P$GLleIzyD&=4En!ph3Z -z%*-&@EsMWlW0PG_K$`o0I8tJGEy9=L$pfVcJ*wM{VORgM{PNso9dA+_Zd9`D+20s0 -z)|GkCh{0fF<>cffB;o@FZn*;TldRaAxwG#q%D201DbMcyH2ujugTc4u(HmVN8B)T -zyd2tjzLH~Qvd*w-b*jd_Pf$IAFoyv{R@>?7bPSUF+KAfp@6q==x_lZ@tvbas`)9|# -zeq8~5X}&j2fV9mm${1ef&OfTozoLu*VDy~XZdZe -za!-tp|K{}}wMFhng8BNMt?Jm=e9KXU<--p{@q{|q1S{_`;dw+twnR-$je()zP2_P# -z#w~;B(fO>YDC|v97S~wkcOZg#BFVjAhyH&fEGux|pmqB}?<0ehyJD -zvO@1Pyr6DvT_@`ogOdDN-rwIp=FjmaGn0p|4<2G|O$}|iqaV_#D{bFAMj-Uss6HGK -z?Yfb)vAH?d%2(Ic*4EnE+G0&%c80;wmXgFq|G80)ET=PI#9)EOkYm3__XhUEhbw~y -z0xYNU!&h$NOv;A6UcGt+g+eg`xRX#Oq0fDNb22wPiaIAIGHcCsnT{VnzS9$GB%The -zLqb&4Z75$&^0fh}t3w<7C~fi11y}r!kArma;63V}6$j8EK|fL|fBwC}x2LCPZ+ExS -zwvKsQ$cC{z%Q;EzwZT0bo6k1n>1m96A9u_UWx^5eZzajeEKr62^oe&=$KIZ}Fn|K8 -zyC@(aAS9&WKdW7CP#g`B$KMC_o3ZE6mXVP`S)M>)3xW+w%zMzz&d$ZUse^-qHx@WA -zCNIo?PM0vv=f4%?1%-B&+tji)R`VtyQj3%1g11-fm$;k1%n_4-A@DphESa611)X0r -z=9JHm#x!_`1QVmMTT(Ura3{VwR(ebM>Fna-Hb{^q1YcHG28=*hD^65Gq5+F#QkMVq -z>?kD*3yvo&_R~8ERabmcgw=h}^YpP%R8fFDq- -zm6Vj6<6nPvtMwR2Oh~BiCz*XcA?(&~PCBy#RQ+>tQCCNYSv|nk*4EAKZ3B0hRcCR^)#&9-!Cy?m5!zL{&a0$$ -z5_9FM0=}rIXk%kze}A9G-a$e{YcUBWq@*msFHu3qFv(SR9*OD~mzDKf9L(FNG_MAb -z^{Q}~6;k_o);%*HI+xLyKp(YK3EaRPO7r*tJxR!)cj%d8Qc- -zu*ZUeg8P(sb|DizJueuHW1bA?=E(V83Tvq!Y>f&cfwRU$N53`yU25?@$@fiDQ#QOu -z0>IMXf52-uw_oPwMl22r9EQQ7A?h>p^Vo=;0Nh!9ef>0p61-})eetlHrzfxj(CeQU -zL~JA&iO;EGDk}bf?h52a-QIS@g*|a_$nW4wd_2{fP4AcnvIJ@V(SL6#>FVMF^b?d> -zS6}bY76BME8$R#J@O#edFlN8h2ym!$CLacd)E2R+^)UAFxkgXmWbOty0ycAbWo7Ci -z_Sdgpg6yjs)fXc7sChShY#%);0|~5(iizE+lA#i+U2`ulQ@m4yrKP2pzgDz_QOcl& -zA*v?s?mwFX7blhCV2(eR$>e_eNn7=Dfdh6WrG|h1w)F~U_N5A{O&*>g9Xo!C -zRY+Y`b+mR1$vxE`ho1iIX%X*%1ZUf -z-JthXod8)nIy6hn6%`dPP^Fyy`}d#y%@0+r8;NMN6kROYBrGDjVf-TrVNY8?`EKPD -zhFV>D{U1;U9+7F;dod~B|D4=fX<1F-m4jAk -zabL4_EAl8m10~b}q7YIEPNH{W$2Zs3WSvaRC0_$p9^*W?&w;?$`L^vW$h7Z^(5#|| -zL{wB-04ae*FNeR;6P*Msm>*Ec2mN4ZX=$mcsVPIZUm=qt_G#;Yb}t0efJbFW+e>;I -zTAdOmYnqvvMMWI~2=Mj^pEIgyZ-<+hm;?o3%g-lf1 -zD=ZwtsR9N(@{Nb1?*ye{iNhGf`uchy_`d($yLUrE8rQW1)WU-BNf)B8d&IurVF_|N -zBjpihX=VoD;aMb;uafD}si{M|lw~v;y`$0;xfg71KJrF02Jr_WC!VHv{`~pLOb#X( -zzy?74I`tCVNYBCCe?oi_5UAD_&O|^0Sy{Z1zJ{y49UabOLN)4!PjeXMk)0jNIS*S` -z=kDnVr+)J+)=3Ts3cB8S0iT6JeFxSLtY(qQk|17WUP@gd@^NvAaU&^@hWh$oOJk+r -zD200_LT%4YsURzt+(h~0E -vtn?06FF1Rn9j*YB`{ -z_)AfjLwbq17IxjI2uGd7uZue+X}`?{oI+tg+zmE3|I{M#FTr%z;$$%_qc1}Jr5a~7 -z_QDasx4mm^BHguWxc}%|0fGPT!0+PSm=159@nbZy!ZlfS$e8ALMS)Whl)!|sWRO3^t~!ypQB#wn?%8x{5BsQMIEyVDS*=hr&_izwv)%Uht+Iz -zOh5Bvh=U4x|-7iP1+HtV>a<6Dv$e!ULN@sjYWl(f5@cD4Sv{o*qIbs -zjTI0F5v@{M*sW;4qR^32}xs^1zPf6mij#Wa%mdwYS}{)P`|)O_30 -zvRtL76)j=U9d1RM<8twEOJIcexy0TyFb0j*WzsmAzf;mdGb22~($dn8E>@n)cJhU0 -zDcIcvj0f`b!Vx*z$(UR`mHn*yrJVW^|K2ai(Q0_ -z`nHDRoAq3NxmKt~$d%aS$`tc`Qpi#xYu_Q$5C~+?`kau;QD?5+!(u6ps?9nE49#t# -zv)w|x+1{r6IGJ(VWT1&%v1d=58uU{{D9A*Bsh-)vnBSPKBb}eWGJghgQu=F+bjGMN -z$Daie7tUO~^m;--9a7%V3syzmn&|wE!Q1(RN%5+p83qwG97!q -z?+3eTcJ>hG>1YTqMgi}cuPl=~zmDQOQOq350No6!Up1euEc(pZ8fbd05|!SFE>u}V -znd&)7{+t7{^B7B*cX}d>j~@F$j|XJs&rFuAiiDzt1R6-vQfj@8G;i2Ypp|P)cv6wL -zHG1_)FuFHa@Cnv4UPal4tEi|LjFtvmutF_$lIksg=_xbBOk>duz@FQBTE$m4wi9IVR -zJYLUU{jDe)XF@c$@PCKU3wV)E3;M<^zC&|*uUbngz -zqN1p*rpxycIDH_vwtGx1JK(X2)V?z5==&5onks4nBxd*h?^?t|*?TA~e -zCV1<$&mKm|Xd`_t$Xo4%()11a0Kt_{MHWjdqif2UTb5rvBp+;0UYa=QWKXT$i!Ui8 -zqo9ngMNy@2ZC*A=EHU6x)$YULafQb;efoy!a7;bfrQbeY8nT(qz72xm*W^^PJ{#88 -zETc@}K5lzkE^d!3gd#-2eo|i0v@-geigqYkn4Q552rd|&5T;_B`nFZRsJFOmd&Hc7 -zK~AXjP$b)4b@5h7Xl+gO>QV8s`$GG)an}sg?Q_1NOry)obcC+Gu8rG0`E*epU*^i; -zF!sK#SOSO3wW61$G-skZPTS^8$l3)jpZ7DF!mag(9H|Q_AclV=$A7<5(93Nm3ZSJ# -ztDXMG1wxYJU#besb@_we)5*nPXmsU7Xs(a@@4nV^D83IIyuOyV^LToX|Nx -z6kDU=23JmUxzo%fWUaZHy@g+0oZt}~-lOx)F;gv_66<4DKfV5}HS)};3u$~xFaI+z=vuHR$kwbLH#B>V4m!S+Bf_Wj5;L7XKZ@+KZI5rul -zddED=w45&Z0dK>w1D@^cMw0O*BTp{jVq&jR09E`e!D!7F)tcXkYhqQIqJ9}G1_r?r -zQ>r*)YiBq2yx23>HEoZMJH6t56oa(uX3v{s>nHd$q!{&n&jkBPK-$j?Gzl=nlrIxp -z-h4i136`+@5k!L^p?_zN8yA{IZZcRDz0C>`&5uA5tw5^1C-%*!U+y<_^xKwxZ3)EQ -zXFh1{_VLRPI{#ukNDPH!O%GIGr?UQWmRXcj?YI(6E{UUwFsLbo^ua)Qo?a!kL@lfG -z;c)fYZEnf)S7>lwjNvs22$;0e)}&K4yLh5+eekrdrn|c^uR6LUdh{I`O*+0STpwa< -zxV5A(1b>U6Pqr^~6vM014^YsdFIaNe-P4~6DtD7d7c*JI-iCAl#Z=sk^|J* - -literal 0 -HcmV?d00001 - -diff --git a/test/reference/ft-variable-font.ref.png b/test/reference/ft-variable-font.ref.png -new file mode 100644 -index 0000000000000000000000000000000000000000..49050251ac810e1fc2d478129b3b9b6a588dd9a2 -GIT binary patch -literal 4413 -zcmds*hg*}$+J|A06{$f$Iv8mygeXMm5Jf|N8jdPW!$Z73J6KEg>(NiVCv(K5do3=!6eX7#m@pzKFY^@LxQ -z?hYgL!qq6qZ;*R*)Gwh}s#b_9l^q?FN(u{k%Jsi~dAN67hwv$V2ukmmN| -zpt>A#jW8IDzP`Te -zu)QKg_2b|3^Yg8(t+^^a-@c{Y{4?VAS~(@!7vTKM*wo0~f$ -z9^I36JLJHP&C$!(_trbkl=WV`qP)C3_|2`o7oO8i&vO0t4-OVR*5~Hzchzilot>Q( -z@Cmi_=}|2PA7Om4JdqrTo*a`R1_p*3HVu~M=H^ybR>sCT15Q6doA}j4E#$?7UMZ9QS2MhR{J!qyma(UT_lan*K(bL0YOGNw4&o4e5mlvF?#(L6a6Zz!7fBpJ( -zp5A7gM2e4%J>Ba=l7b0urEl@{$WDb4Gdwy!%KI#u&5nPFfb1%So$Md&%=M5E-rn9Z -zv9U%4s73Lu6=ELn+}2PL?u)ovKDsYc8wV%&tzFR<2?`1dJ3XjUbVtva-@sb`yzgv}p`?ys^cRkdTlprr!{9=x*fjvmq?xd-j7j@aI*v -zklEFI*2u`n^V37h%nL!77oJdGuOu!muAuXjk)N77!nus&AR_1&RTh3*{`LpeX(o@vq6(t;^ydwcJ;MzguPxacg`1#C^` -z=jV&*XQmJeHF{E{J`5lTU}t?<$i~9LZwd~T(sX|&gKcXh3OvE9CthR`h>MF0J=rgK -zYpt%XE}h!#Qq#P#v4K3_Cu$%Ii;FAum`X0I{`ma<{d+KPN21`PC+#4TQc}3?S}peC -zUB{;MiE3(UX3Nd`ye}X!syT*)!^x0gaW4!y=lZM -ze!4$}7Q0jJSN586VV0k_Hz(?pBxT)yI<468>>eHpD*6}SM!P9~v|BXBobB8X4zBID -zo|&0p6VnS_!Uxp)u3Wnk3pVRMSs!$;J_gDb0kAV@9z%M -zqXAQ4BOq3Dd0ydgON)z+U{z>zW4P%0;-buxv0F5A_tn%ih5t4s8^Cd#SFU)Qa0v)Z -z5<&uc+l4gZrrk!RA5P_mc3yEG_L!_U@2`<{9fp;dxcZvm^>Bav)r4FJ*}%l|*}j9B -zJkZ?Ia@_c=u&@vq78w7Q<+RIKkJnwwy^2qtbW+~?HObFlgvG@6WXaRdS-`_v_X4p5 -z!g(T+%*D^&Bkyftkv0=c2Ff(Y7b7L=R8mn_clzqO5i_5h=f+r7StGgjexg8J`HvrF -zWY#->V7EoSSY~Er^^KZcOUlm8rB~3^dhlRntV%*(J6^+Qx`~>G$;H+6c&VhQXwKs- -zA~CVg)Fv$F;U5WtNC7@Rw`RJgOVChfVy^C4Jd$#@r@`sTJ-xZ# -z1_=oX;UpjB4!O{hep|akm!%kbbQ3eTz3rJS#-kD{ht{S!ZRc%xwxfX8s|h{cZE9*7 -z97Mg7Kz;oVXzmxxW#YIDdA}Mecm2j{nMhx*d;$8nIP%3`Qdc-Q{0`R5wUr#ia9tOfc!ZZl#pxm;((M7$=(%jem2&$ILnEU) -zzct6nBtfOXn~vRF5?g3u?p18uB}l(dNuq5r{NCH8lt<2&AH^ -zscCY@br`HQJ)nmfn72GrIb@e|>$R2x10ix_X$hB+QH&C2V`I}*VOpHRP{~2DaZ-+G -zbO$A+SS#n`a0(-7k*FRN5+Wuda-BT}D0oQ7SLD-(h~KnPLvNtizDvQKj(U0t3*zO> -zpu#fo%48@7eedhjf7l^mT56V`EyDl}b?;7*I*Sij|1qEdA7%mdYOuiQ?%lg*R!5xv -zbJXg3bTdAztgL4@TH)8PJKrwLChhK8)VT9wLdaoKfz|5a?{doc+?YW|0E^I#+4^+; -zEmD0<_3Bb{bMukuk8KYGP|kLn=L53eEA8lJv;mx)#dFX{>WCsv-y0FE`}PiwL0L`> -zVC7yKo{p0$H|riXd`S1`t8;ZHq#2j1o8I2Yz-A9aAP_1lla^vHjE#-2U%yUGO&!a5 -zLuSkjjyqf-iosxRK>K>8bWtA$EE~h|6;c$_`Gtixn|s#QlhJHqN8>f3;NhjErF)A# -zY=aIhQA~5~@pTwVLuc};Z>`Y%1f49EiH;628JRbfg=`XubU%SF^_KJBYS*HH`1SPM -zmXCi_?KXoX&P{C^ENA*AB_%EO;t^xTpFanJnMzi-UmxT=WEyQQ8bFB;@p{xl_Z9cI -zw~uCHZvY%P5-ZHl*VNa~lCp1KV^Et4JGA;R!5gMqrYU@~-NI7yWZZwQor$dFzxngJ -zlkARi$bn~qrHP5?e!AOKLzs?EcW1H~Z-Zy)r%%7IAYIl20Lj75PSEh~{tEGo5--E- -zdY{rlB>DiYH_FrF7%VC*6bJ4itq$FbV&uN# -z!omWeIS~;N07tiHF1ny}b#*mi8WzS2Pbw%Wk(88F -z2Al~vmX`m50$}i|u9Znb9S+Ay>7wPbw#9Qu66eSl$O11$y6Hp5Dq>#gs+5X{5M`9Y@9`pn` -z-yeSlk$Dd+0)YE$WOn=|sF#61KK>a|tER4gsa9i528xYmU}l~KdyI``@Pk&r_gU(7 -z9WG`a>lzy3C>xWZhq@VRYHGT>mtMMobP40*=Leh?K&<}DqSDEr%$m?`ZRi>S;gJqK -z+6D^1$aCvuEkx^D(jO8Mv6QNqvH;2g&StEtMWjg-iq+5*zWl|K3`Ww{N?0UgQR3%o -zWsN%FOydX;fIn;fBm@eb=vAFEfS|;1NW{d%sGKYd#p=yZPv3O@o()jtgQT*O66`$P -z-`Cf&KG5s#-LFrnY0{8sI-=Uz+OEC5JSE&DmuEP)KilFA0G4Kj9i)!l$T&GYEi)@u -z?bpJ6`t%7PkV*fCrx{90N>|{PfqRR(6_^kJ^^T*WO2Wcw{Q(Yh5LKi6p;a5qx!>ww -zLC@&sSX-OJV7`HbN%22@eI9yJOMO`s^68eCPKs@FL|v4E|2kk0d{WXolcFAy`fYJp -zSy^dm!{r%*rZ7DViw$tCVL_!+&@kF`YB%6%p5O8A0`#RA0HpLwY6#G>>g~4 -zgX|C4Up6o{9s;4Ty1Kd_3@CB~kH=eCT7s?C`mKp3X$J2v?<}T!04VDJHgdD5s3=ho -z84f}WD2X_G%)A=xQQBH0HGL-wUKj3Hari56>H8;q&-*;@d++l;@45G$b3UJQ&ileZPm7(Emz9BmfnEEKh7kk9 -zA#pHnVL1%$12uOK9!$1(wKN#$2iNz_)Pp(QiZOkP+i@4y_krqFNQD9=g%;mB% -zOf5px7;IT!43bz#Ft-}Z&Ev46LgA3Z5OtPA&tX`GZ~ynN{XMD_eU{!=^1r-$C82E` -zJtM}jubx4j{x+v~?qsPfrHMpB^;bj@S%c~IB*Xu;m1L@d*Gv#y6KQx=XhoQHYEmyn -z&SR0LJR|1E6Q|BCD2Q_8AjJq?y?mM4Uxu0fMak4krf$s^*F7dL)E9sLy!sUoOyU -z3ig8#`0l2E(%ah$o*f;ix!ddi$m4zt&g?hB%W5S;w`=eZcpc=q@-kIWDto8u&PP|fsv8%9SccC?q5%=&wstd)Y|T3~1sGc&H98-f8#AxkIDpF6ib8gM){Dp3|CV3r3qgnbqt -zAK&!tTZ_FERBt8MFf*E8aeaz%o>Jh7LJfXFSvx!D@&p}@loW~A$hJ4YUmR3*?Y!v0vCXOG41FYlm6w;dva+(>i_^aF -zI*L!$^*XO~L4JOIlFCz}IecwwXvhGG99XSnK5@3>&#n7G?6BKfTi-~ejznp#Z~mSb -z1*EO5t+~0mu`#YSmGjJ*@bK`7iHVnRxW1vGA&o|RJ1dwL0YUeb*fct&KW&yCdmxo% -z#B=71i2LTpf>Nr$)ugS~z4mlnH%gR2sym_5C~o%e0*@RuKE5iUe!H+$It{}CS)+1TCSFkj*gMhsSc*-=x9kv$+ou= -z$v52kf)5=bmd{{_p`oFp03QmNJ9tx1uM88h(UFl;Q0OzRx9{Hh>}`9cv1jWhehS!H -zSz2;WJCvNAoejR&-Q8_VxH>sDR#s8r-Tz>3d(Cp^wx;GZQrUNFWjre@%kPP#tH?do -zz2myOsb$P7A&CtQYFb)aY0?$;t*2_j&M4=ZS`ppJeA(F!3?d -zR}R=T_+U_IRnteMu6n4dhaZ=;`SW~|_eCjkP5s7`XlM0YigR-$Pa`}yEUXd4LDc+e -zeaI1S@07tBQY262hV4y#r6;pd+>#j;72TVH8;R@d>rhd>AIY+)o%MNM|Hk8@5RwZu -z+ikFRAcc&3{kl@biB{up_Q8OA?gNpCSe(U)+>^?=CKLft`OxLcA*k}Bi}+;GD$m4K -zk1ik}pp-6Jw>7~Rrd(EDKK*o{wYBx{r+OwKtiHXYBdspT8b$p>@N7?qwR8K^_cjO% -zS#m-90UdW42dbAE*!-+X->=m0t8E_b=pP~p28n-%0moVSj-Rf%$Is87a0NLsI504P -zT$}|5kdc#Rc*LXD!fgiv5HLhCE&FR2bH_VL^}-`-mV6s|0IbW4e4LygH`cPVMU=M6 -z%+y(U?8Iedzhq{rqo~QK+E&l_4s#{yS5`K*t&LPE2Uasiy;!B|6ksl?lv -zlzw~nSnA*)y(RAaE3T^(gLBKB>B|1=8k(ATWL0;@#!%Q6SaMBHquJcSAUiC9sr?r5O6h{!~7-M*A-x3h&s -zf2kcQTR&X|B#Eax>%C-sc9su6Hv}!9XV0c2BqY3kEoI*V$@CVNkU-W2))W^nPP8XW -z`q;5S8fd&~&F@lE2a;qSes625+Z0c3Rw -zziVo3bpe#|1vRLrtu5(&p9aA6=FOY9^I8jk2)Ku2h&k_VEuM~Niix^6oPP>gnP& -zz?~q?9Bd{&{`AR{F!vLFo}R0rjBIE$S{x~$!~wHc(mxrnG!!Cp`DChzSX5->4>Gyd -zcXcBBUb4^rfKnHYCcw{+G&Hn%wlXA%josSbM#~HkJV{CM=H#W}MqnGU%a=z-N7+?~ -zWu>JaUHS0tOUJnZR7QDTRsx8l1QnmARaNa&xb*{@n&A;m^q;>#R1c}=b^SYFFNvgu -zGInyBEPvQjXc?2mE}$eQBeMpeyGyn8?cQPVfMFw-YkAhYTHo5(*yv=Tf0x);@?GR) -z9i~pzpJjpBMb>Q36jCtoEbIi -zZo>A`(Y9kyk?K{lq9tAyMJscZ+&goCY%~Fw;j3S=f}&!~S$W%Wzrsrj3P}apo1<9Y -zB6StNzb#Wq+dKzIotv9Gcm6y90fj<$mZDUZ^go_8@1z(i(@%7`l{dq9;lgToPg(v-yl2wG_txjx;PXCz32(;0E| -zrDi^qdpY2|AVB?Zxy!jWpW)~(YuTXW*&2=z{Ck6uiHS8xbZpBuF)fYOpEHEuRofKY -z*;t$;({63V)~iyV8Xj& -z%RfDT{v2R(*6ll)9R2)xi5fd^l!&z&#H219ED_Z!7c1~k}^5UBH -zB(Fe5kvb?M)ILfDkE{QNP3s%dZD*e{v>t^EpC|6owPLGu^c7#bUU6Bjo;J$=a*zIRBi -zMeAH#p>^H*Z^mQmt5svsy(RD&hT7!Hq*jlJeMq07w74BcPp4>gDAHT;y7g$fW%4?^l$QlarSx5D310e%ssIOh=C%Wn_#JR1N&~QTtqNf>iT= -zn-{PTP_Dw^Sw?xFLh5w&($b1BEr`E!K`K#K1P8tcbh^E>6CW^q)$Pt983*&@-5bmFvN8Fdj6< -lAw2)v0RDe9%cb-q*%;rr8w>sq!0!qMZB0FmBDDvh{{h6p9)kb? - -literal 0 -HcmV?d00001 - -diff --git a/test/reference/ft-variable-font.svg.ref.png b/test/reference/ft-variable-font.svg.ref.png -new file mode 100644 -index 0000000000000000000000000000000000000000..eeb99d7c9704d19750bb8f315a76135de3554833 -GIT binary patch -literal 4359 -zcmds5`9GB3`&QoX8WoMDEWQM@A) -zL$VW+b+WHxnP$GnPv8IHbLRET%xj+WJm-F{`@XO1Iul`_r@?xP?-Uag6RVcyT|*|O -zV^_iVPRMcaK0(wz`Z!^$t#Ox$arDY27A7z;L7TPisv7&HuS^6P7!NW|u2&b8d~QNM -z?|gZCvu5AG>5XXO)Q_8e@vZlzv@ynz0rAH?JU*BjB#&V6je*Vx9)SWU2{F!%OP0c7 -zKKHJ2K|IxOsYAJap-|{?=>PobgZq;+b#CLrYeq;mHa2#4 -z_JIdXih0m~RDZ+IopM%qn?xWS?ko)#moWK33UmJ-CyJN@lf3c6hyF7i(LHDZS@(45 -z$f`>agc<2)qnCdA?Y?R4Q?K5am65;gjIgE0gh;a=?Qii>mq*nsU+E^$ -zIogYj3a=_WnP~EPRF+ijX>4rl?OpS4?)K7fZ%FQETNT>+%RZ;P^0opk!M0z&th?B} -zy}V{TmMIkHjXT!5x4Bn1^fXlO1rX7N{b1dtO4|a$nG}`NxPEM}a -z_;TX?x#{VgKBrJtnCQy)sUWJrwX?n~h#GvW^~fh2155?*fVKMUvH6C)TwGjyeDXmD -z+Y4E^$sWC3&bSXBK3E0si^$4S0g`ibbLo+7;HLL-d2iT$$B{#xIVXK{3vNrx8~FW9S^78DE( -z4Shppk}wAcOBG_esRM=jf{|AOtp|!wS-}UCwNH%6p&`)^QIChq$yq9&4*&I@AGX3J -z&P?QnKsV(B_tv!~iNb@pi;4GZZQEamhMp+?_SoHhvf017h$Ior7wynrpj+=g@#kYy -zQc{wHd0o+HQb)7qNW&xG&-SH#7`U%z&7bE_Q-2P-`uDxLO_gtWa8(bf@7 -z2o$N60tue}FU;JnVUiiKd`Dfqz4T#qYHDh!;_6uKV=pf+IoQJ7oPbKO#ZbW5!#dX# -z>98dwXxr{Ts(x!kDyRs}(3psbX^U0Yxr`p>W^RUy!Ft1%=F*p&HS(km!k!_v|c -zi3}-HbLdX4a_%qq{Q0v6ZgKf&DEcms6crVOqOg1QA=`<(`(BI*DTh(cMie&~7biDC$YwEaeP_ -zJO%`5VlouPD+RaogbN6e{r7U4o11T6F&5`KzddCqgg+}SD~k;X*c`6(rWn$D%+1ZM -zaDRPzGQou~7>vAKXY=0)x_tG=k5~O<%hAMxQOB$aLdE;a%I_g?C{iyu*EsSkLHdDqewViom>aCfD -z#m`Y~zUX@c*??X^0HC!2>ygRi_c8xABJk9Ru~>0&@y_2b#w<~{X4+nz&LGaNt$DPv -znt*zYJTJi~@9ku3dx62l)yay$MBPw@()SkxdpbZ>(h|M5_F{>C8@7&;m$*(va>qY- -z@F2gS;9!4W0^Pg^IH<0aGY)FfeZ9lX-d==3%|FI`BCnv}k)jC-#qOvrHO0bf*VorK -zG5Vvrs%m50D>J{3Yq~@__!M#XHGEtum}LDxHV<{C7gW<#~|VhT|)vCE-1Gb1TUbY)mBf%G;t^+TT%P~M?5K@ksW2*OVPDTLQf -zFnG_#*SBugJP7?MSV=}^7soiX^7n77QBqSln&SuNc+Gdqfn%1GAhIT>qJpFCZTJ;M -zmL5GbXC^HyY47k*P&v@7WDo$VHSVRWOCBgTiWN{0b*o=zLUty1?tHIv1zf7Gu72s# -zrSkG}4&U*S5gs@kZDJy7lXW!5?CdFoT`7)1XJKIpASz2p=(f2Dxlgqy;pl-SE1qK| -zzigH4q9RfUA*`&m%gUlvO#HGaWis@$po~%D6BK9X;o*TIaIpUwu9yn>_w{PMlZL|b)u=ZxtW%r -zuUvKeH4Ter7CV}f4tismG^*$6xsiCq6jP>QvbwqolXbr;DH$6RQ)gXF2JJ7R@qoyS -z^b=et=cI-=u};Y}5(pksEq_O<>_9r-vt5;tNG#4np9T$9JB*(3NRN+4Scwd6Z+1xv -zsst+v2|Z`Tjn{j0nd-0Mp_AO_&v#5UWM^lm$!?CaNlHqhuu4P2!(Mf>xcOos2+^PO -zGUz+@i}%70?r3UiF5XZO)y-5KZEt^7?FpJ+&RkwzeskCWg=(E@2vda!rYd1&a5F}Q -zdVr?2&}u;RdZnMge}4f*IOZLJLw_TYBC7L?p!0Kc8?vi5(6+GOzkkDVLIhqAk`=+X -z%sBGXl`B_F%PlA~Gh1`-tb9k!3j3XJrCu^Bz&JWSW7re`??c-ny1TolOYEyy^4bA> -zW&^L=^}d8E&#tbv0Hs8Q35$r3Q>4NekAKYQi1ueHVJCwRSAe#OiHU7_NFX3>z`;!h -zQ73ZL!hn(6{``XZe4*#p7y%l!FP2v-6htTjJ$LTh^z<~)nfbKZnws?6o*@fs0}1$L -z)U8+q?s9?=M(8;4QMOlw(gIt@_=99EL)n#JDy)ZH|GBGiE^eAAyn^$hAg*W -zc7M;zP*=tsTZyx*tgO_!vu|@RR{_73l9o2^9+7fCAM}uwkx@eXFf$wM7w`14{0IR=5-eHyft!`+oGhQ+|- -z8DLDTt*zbNuhq4>IrgN>af<12`Dp6sMCr6|3qx$ait42&XJq_c^cu%DBGf`%e>R|& -zQAPzi{;Q1(vqgnsst^TfuX&v^lktna+U4l% -z`dP{nf877e)W|pdOWW!_uX5|~6*oFOHuhaz9{dDi8F}Zx!NjsE7FYc#a1H%m}=tQOTgQv$JDwX3$KuEJmP{L~`EWoCBPtC_?%xER}EA -z2ux~Q8-#=JXYZChvo7N>PzGsa}&GoB~`Nb?+ih1T@I# -zNBc|)X`575%JA3NJx$d*fTgd%s2aQHEngG9UT`& -zs~sIN7>mZI`3mjnN?70jLRoEWZ1k0O-nO@2?>KQ5&d<)CGw7l#nqcfPFvACf_4oIy -zA(3B#-y8zzdsMUdRS@UuXcO@ky;Cd3~ -zCSSBm?W1Dj4}&fzPlnO|9ugWG{r&w}VKU2}OFIEX -z`sQ30gML`iYVG9aR#s8r;qESzq65ryW&P1G1&#)do&;80Sy@$8wY9Z%Vsw7sI8b!Z -zzzY7G7!X6g_PY-yB``j|)U>pW^mMQ}65!_trFNV#wYM=tBofOWW=bFJsIT8({@>n4 -b@8axYR+o%d>#l=;Hkh>3_3oA -Date: Sat, 30 Sep 2023 13:30:51 -0400 -Subject: [PATCH] Fix alloca undefined with MSVC - -Conditionally includes malloc.h when compiling with -MSVC so that alloca is defined. ---- - src/cairo-colr-glyph-render.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/cairo-colr-glyph-render.c b/src/cairo-colr-glyph-render.c -index 28254fd51..a9ad84bbf 100644 ---- a/src/cairo-colr-glyph-render.c -+++ b/src/cairo-colr-glyph-render.c -@@ -43,6 +43,10 @@ - #include - #include - -+#ifdef _MSC_VER -+#include -+#endif -+ - #if HAVE_FT_COLR_V1 - - #include --- -2.43.0 - diff --git a/recipes/cairo/0001-Fix-compilation-with-Android-s-bionic-libc.patch b/recipes/cairo/0001-Fix-compilation-with-Android-s-bionic-libc.patch deleted file mode 100644 index 18e3ac8f8..000000000 --- a/recipes/cairo/0001-Fix-compilation-with-Android-s-bionic-libc.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 169c625ba54c2e7509a19fe19202e0e82746686c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= -Date: Tue, 15 Oct 2013 13:05:27 +0200 -Subject: [PATCH 1/2] Fix compilation with Android's bionic libc - -It does not properly implement localeconv() and -the decimal point in struct lconv. - -https://bugs.freedesktop.org/show_bug.cgi?id=70492 ---- - util/cairo-trace/trace.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c -index d5d7668..23db778 100644 ---- a/util/cairo-trace/trace.c -+++ b/util/cairo-trace/trace.c -@@ -527,7 +527,9 @@ _fini_trace (void) - static void - _trace_dtostr (char *buffer, size_t size, double d) - { -+#ifndef __BIONIC__ - struct lconv *locale_data; -+#endif - const char *decimal_point; - int decimal_point_len; - char *p; -@@ -538,9 +540,14 @@ _trace_dtostr (char *buffer, size_t size, double d) - if (d == 0.0) - d = 0.0; - -+#ifndef __BIONIC__ - locale_data = localeconv (); - decimal_point = locale_data->decimal_point; - decimal_point_len = strlen (decimal_point); -+#else -+ decimal_point = "."; -+ decimal_point_len = 1; -+#endif - - /* Using "%f" to print numbers less than 0.1 will result in - * reduced precision due to the default 6 digits after the --- -2.1.0 - diff --git a/recipes/cairo/0001-Fix-surface-type-mismatch-error-in-pdf-interchange.patch b/recipes/cairo/0001-Fix-surface-type-mismatch-error-in-pdf-interchange.patch deleted file mode 100644 index a3ab72b1b..000000000 --- a/recipes/cairo/0001-Fix-surface-type-mismatch-error-in-pdf-interchange.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0fce59ff8d250a59ccc86894b8f1459070bf6ddb Mon Sep 17 00:00:00 2001 -From: Adrian Johnson -Date: Mon, 2 Oct 2023 15:29:25 +1030 -Subject: [PATCH] Fix surface type mismatch error in pdf-interchange - ---- - src/cairo-pdf-interchange.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/src/cairo-pdf-interchange.c b/src/cairo-pdf-interchange.c -index 2f97b081c..9d7aa42fd 100644 ---- a/src/cairo-pdf-interchange.c -+++ b/src/cairo-pdf-interchange.c -@@ -52,6 +52,7 @@ - #include "cairo-array-private.h" - #include "cairo-error-private.h" - #include "cairo-output-stream-private.h" -+#include "cairo-recording-surface-inline.h" - #include "cairo-recording-surface-private.h" - #include "cairo-surface-snapshot-inline.h" - -@@ -2071,7 +2072,9 @@ _cairo_pdf_interchange_struct_tree_requires_recording_surface ( - if (_cairo_surface_is_snapshot (recording_surface)) - free_me = recording_surface = _cairo_surface_snapshot_get_target (recording_surface); - -- if (_cairo_recording_surface_has_tags (recording_surface)) { -+ if (_cairo_surface_is_recording (recording_surface) && -+ _cairo_recording_surface_has_tags (recording_surface)) -+ { - /* Check if tags are to be ignored in this source */ - switch (source_type) { - case CAIRO_ANALYSIS_SOURCE_PAINT: --- -2.43.0 - diff --git a/recipes/cairo/0001-cairo-ps-surface-fix-Walloc-size.patch b/recipes/cairo/0001-cairo-ps-surface-fix-Walloc-size.patch deleted file mode 100644 index ecb4b1c8a..000000000 --- a/recipes/cairo/0001-cairo-ps-surface-fix-Walloc-size.patch +++ /dev/null @@ -1,43 +0,0 @@ -From c84a13c576e25ee22b5441ac41338323822ba361 Mon Sep 17 00:00:00 2001 -From: Sam James -Date: Sun, 5 Nov 2023 22:09:21 +0000 -Subject: [PATCH] cairo-ps-surface: fix -Walloc-size -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -GCC 14 introduces a new -Walloc-size included in -Wextra which gives: -``` -src/cairo-ps-surface.c:3524:18: warning: allocation of insufficient size ‘1’ for type ‘cairo_ps_form_t’ {aka ‘struct _cairo_ps_form’} with size ‘88’ [-Walloc-size] -``` - -The calloc prototype is: -``` -void *calloc(size_t nmemb, size_t size); -``` - -So, just swap the number of members and size arguments to match the prototype, as -we're initialising 1 struct of size `sizeof(cairo_ps_form_t)`. GCC then sees we're not -doing anything wrong. - -Signed-off-by: Sam James ---- - src/cairo-ps-surface.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c -index 381b4cf75..ad52918c2 100644 ---- a/src/cairo-ps-surface.c -+++ b/src/cairo-ps-surface.c -@@ -3521,7 +3521,7 @@ _cairo_ps_surface_use_form (cairo_ps_surface_t *surface, - unique_id_length = source_key.unique_id_length; - memcpy (unique_id, source_key.unique_id, unique_id_length); - -- source_entry = calloc (sizeof (cairo_ps_form_t), 1); -+ source_entry = calloc (1, sizeof (cairo_ps_form_t)); - if (source_entry == NULL) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail; --- -2.43.0 - diff --git a/recipes/cairo/0001-quartz-Fix-Cairo-1.18.0-doesn-t-draw-italic-or-bold-.patch b/recipes/cairo/0001-quartz-Fix-Cairo-1.18.0-doesn-t-draw-italic-or-bold-.patch deleted file mode 100644 index c796c808e..000000000 --- a/recipes/cairo/0001-quartz-Fix-Cairo-1.18.0-doesn-t-draw-italic-or-bold-.patch +++ /dev/null @@ -1,44 +0,0 @@ -From bd6aa966df0a593b44830582b2e2b1f160768295 Mon Sep 17 00:00:00 2001 -From: Diego Pino Garcia -Date: Mon, 15 Jan 2024 14:30:51 +0100 -Subject: [PATCH] [quartz] Fix: Cairo 1.18.0 doesn't draw italic or bold text - on Mac - -Commit cf351a8a attempted to convert the font generation in -'_cairo_quartz_font_create_for_toy' to use CTFontCreateWithName and that uses -only Postscript Names, meaning with the hyphens. - -Commit c6dc5df6 converted back to CGFont. CGFontCreateWithFontName is supposed -to work with Postscript Names, but it seems sometimes it does not. - -In case a CGFont cannot be created using Postscript Names, attempt unhyphenated -version of font family name. ---- - src/cairo-quartz-font.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c -index 621d3540c..b7efc54de 100644 ---- a/src/cairo-quartz-font.c -+++ b/src/cairo-quartz-font.c -@@ -165,6 +165,17 @@ _cairo_quartz_font_face_create_for_toy (cairo_toy_font_face_t *toy_face, - cgFont = CGFontCreateWithFontName (FontName); - CFRelease (FontName); - -+ if (!cgFont) { -+ /* Attempt to create font by replacing hyphens for spaces in font name. */ -+ for (size_t i = 0; i < strlen (full_name); i++) { -+ if (full_name[i] == '-') -+ full_name[i] = ' '; -+ } -+ FontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII); -+ cgFont = CGFontCreateWithFontName (FontName); -+ CFRelease (FontName); -+ } -+ - if (cgFont) - break; - } --- -2.43.0 - diff --git a/recipes/cairo/0001-util-remove-malloc-stats.patch b/recipes/cairo/0001-util-remove-malloc-stats.patch deleted file mode 100644 index 1614b4c22..000000000 --- a/recipes/cairo/0001-util-remove-malloc-stats.patch +++ /dev/null @@ -1,440 +0,0 @@ -From e0d4c1c9a959b686c62ed11ce5ff7a14996b5261 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= -Date: Thu, 28 Sep 2023 11:21:53 +0200 -Subject: [PATCH] util: remove malloc-stats - -Not really cairo-related and has now been moved into a -separate repository at https://github.com/behdad/malloc-stats - -Fixes #640 ---- - util/README | 16 -- - util/malloc-stats.c | 376 -------------------------------------------- - util/meson.build | 4 - - 3 files changed, 396 deletions(-) - delete mode 100644 util/malloc-stats.c - -diff --git a/util/README b/util/README -index b75ae4336..90e1f7fab 100644 ---- a/util/README -+++ b/util/README -@@ -3,22 +3,6 @@ Cairo Utilities - - There are a varieties of utilities we use with cairo. - -- --malloc-stats -------------- -- --This is a small shared library designed to be preloaded by the --linker and its purpose is to make the malloc_stats() function --of glibc produce more useful information. -- --Build by: -- -- make malloc-stats.so -- --and use by: -- -- LD_PRELOAD=$(blddir)/util/libmalloc-stats.so app-to-run -- - cairo-trace - ----------- - -diff --git a/util/malloc-stats.c b/util/malloc-stats.c -deleted file mode 100644 -index a086b0543..000000000 ---- a/util/malloc-stats.c -+++ /dev/null -@@ -1,376 +0,0 @@ --/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ --/* -- * Copyright © 2007 Red Hat, Inc. -- * -- * Permission to use, copy, modify, distribute, and sell this software -- * and its documentation for any purpose is hereby granted without -- * fee, provided that the above copyright notice appear in all copies -- * and that both that copyright notice and this permission notice -- * appear in supporting documentation, and that the name of -- * Red Hat, Inc. not be used in advertising or publicity pertaining to -- * distribution of the software without specific, written prior -- * permission. Red Hat, Inc. makes no representations about the -- * suitability of this software for any purpose. It is provided "as -- * is" without express or implied warranty. -- * -- * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -- * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, -- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION -- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -- * -- * Author: Behdad Esfahbod -- */ -- --/* A simple malloc wrapper that prints out statistics on termination */ -- --#ifndef _GNU_SOURCE --#define _GNU_SOURCE --#endif -- --#include --#include --#include -- --/* caller-logging */ -- --#include -- --struct alloc_stat_t { -- unsigned int num; -- unsigned long long size; --}; -- --struct alloc_stats_t { -- struct alloc_stat_t malloc, realloc, total; --}; -- --struct func_stat_t { -- struct func_stat_t *next; -- -- const void *addr; -- const char *name; -- -- struct alloc_stats_t stat; --}; -- --static struct alloc_stats_t total_allocations; --static struct func_stat_t *func_stats[31627]; --static int func_stats_num; -- --#ifndef ARRAY_LENGTH --#define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0]))) --#endif --static void --alloc_stats_add (struct alloc_stats_t *stats, int is_realloc, size_t size) --{ -- struct alloc_stat_t *stat = is_realloc ? &stats->realloc : &stats->malloc; -- -- stats->total.num++; -- stats->total.size += size; -- -- stat->num++; -- stat->size += size; --} -- --#include -- --static void * --_perm_alloc (size_t size) --{ -- static uint8_t *ptr; -- static size_t rem; -- -- void *ret; -- --#define SUPERBLOCK_SIZE (1<<23) --#define align(x, y) (((x) + ((y)-1)) & ~((y)-1)) -- -- size = align (size, 2 * sizeof (void *)); -- if (size > rem || rem == 0) { -- ptr = malloc (SUPERBLOCK_SIZE); -- if (ptr == NULL) -- exit (1); -- rem = SUPERBLOCK_SIZE; -- } -- --#undef SUPERBLOCK_SIZE --#undef align -- -- ret = ptr; -- rem -= size; -- ptr += size; -- -- return ret; --} -- --static void --resolve_addrs (struct func_stat_t *func_stats, int num) --{ -- int i; -- void **addrs; -- char **strings; -- -- addrs = malloc (num * sizeof (void *)); -- for (i = 0; i < num; i++) -- addrs[i] = (void *) func_stats[i].addr; -- -- strings = backtrace_symbols (addrs, num); -- -- for (i = 0; i < num; i++) { -- char *p; -- char *name; -- int len; -- -- p = strchr (strings[i], '\t'); -- if (p) -- p++; -- else -- p = strings[i]; -- -- len = strlen (p) + 1; -- name = _perm_alloc (len); -- memcpy (name, p, len); -- func_stats[i].name = name; -- } -- -- free (strings); -- free (addrs); --} -- --static void --func_stats_add (const void *caller, int is_realloc, size_t size) --{ -- int i; -- struct func_stat_t *elt; -- -- alloc_stats_add (&total_allocations, is_realloc, size); -- -- i = ((uintptr_t) caller ^ 1215497) % ARRAY_LENGTH (func_stats); -- for (elt = func_stats[i]; elt != NULL; elt = elt->next) { -- if (elt->addr == caller) -- break; -- } -- -- if (elt == NULL) { -- func_stats_num++; -- -- elt = _perm_alloc (sizeof (struct func_stat_t)); -- elt->next = func_stats[i]; -- func_stats[i] = elt; -- elt->addr = caller; -- elt->name = NULL; -- memset (&elt->stat, 0, sizeof (struct alloc_stats_t)); -- } -- -- alloc_stats_add (&elt->stat, is_realloc, size); --} -- --/* wrapper stuff */ -- --#include -- --static void *(*old_malloc)(size_t); --static void *(*old_calloc)(size_t, size_t); --static void *(*old_realloc)(void *, size_t); --static int enable_hook = 0; -- --static void init(void); -- --void * --malloc(size_t size) --{ -- if (!old_malloc) -- init (); -- -- if (enable_hook) { -- enable_hook = 0; -- void *caller = __builtin_return_address(0); -- func_stats_add (caller, 0, size); -- enable_hook = 1; -- } -- -- return old_malloc (size); --} -- --void * --calloc(size_t nmemb, size_t size) --{ -- if (!old_calloc) -- init (); -- -- if (enable_hook) { -- enable_hook = 0; -- void *caller = __builtin_return_address(0); -- func_stats_add (caller, 0, nmemb * size); -- enable_hook = 1; -- } -- -- return old_calloc (nmemb, size); --} -- --void * --realloc(void *ptr, size_t size) --{ -- if (!old_malloc) -- init (); -- -- if (enable_hook) { -- enable_hook = 0; -- void *caller = __builtin_return_address(0); -- func_stats_add (caller, 1, size); -- enable_hook = 1; -- } -- -- return old_realloc (ptr, size); --} -- --static void --init(void) --{ -- old_malloc = dlsym(RTLD_NEXT, "malloc"); -- if (!old_malloc) { -- fprintf(stderr, "%s\n", dlerror()); -- exit(1); -- } -- old_calloc = dlsym(RTLD_NEXT, "calloc"); -- if (!old_calloc) { -- fprintf(stderr, "%s\n", dlerror()); -- exit(1); -- } -- old_realloc = dlsym(RTLD_NEXT, "realloc"); -- if (!old_realloc) { -- fprintf(stderr, "%s\n", dlerror()); -- exit(1); -- } -- enable_hook = 1; --} -- --/* reporting */ -- --#include -- --static void --add_alloc_stats (struct alloc_stats_t *a, struct alloc_stats_t *b) --{ -- a->total.num += b->total.num; -- a->total.size += b->total.size; -- a->malloc.num += b->malloc.num; -- a->malloc.size += b->malloc.size; -- a->realloc.num += b->realloc.num; -- a->realloc.size += b->realloc.size; --} -- --static void --dump_alloc_stats (struct alloc_stats_t *stats, const char *name) --{ -- printf ("%8u %'11llu %8u %'11llu %8u %'11llu %s\n", -- stats->total.num, stats->total.size, -- stats->malloc.num, stats->malloc.size, -- stats->realloc.num, stats->realloc.size, -- name); --} -- --static int --compare_func_stats_name (const void *pa, const void *pb) --{ -- const struct func_stat_t *a = pa, *b = pb; -- int i; -- -- i = strcmp (a->name, b->name); -- if (i) -- return i; -- -- return ((char *) a->addr - (char *) b->addr); --} -- --static int --compare_func_stats (const void *pa, const void *pb) --{ -- const struct func_stat_t *a = pa, *b = pb; -- -- if (a->stat.total.num != b->stat.total.num) -- return (a->stat.total.num - b->stat.total.num); -- -- if (a->stat.total.size != b->stat.total.size) -- return (a->stat.total.size - b->stat.total.size); -- -- return compare_func_stats_name (pa, pb); --} -- --static int --merge_similar_entries (struct func_stat_t *func_stats, int num) --{ -- int i, j; -- -- j = 0; -- for (i = 1; i < num; i++) { -- if (i != j && 0 == strcmp (func_stats[i].name, func_stats[j].name)) { -- add_alloc_stats (&func_stats[j].stat, &func_stats[i].stat); -- } else { -- j++; -- if (i != j) -- func_stats[j] = func_stats[i]; -- } -- } -- j++; -- -- return j; --} -- --__attribute__ ((destructor)) --static void --malloc_stats (void) --{ -- unsigned int i, j; -- struct func_stat_t *sorted_func_stats; -- -- enable_hook = 0; -- -- if (! func_stats_num) -- return; -- -- sorted_func_stats = malloc (sizeof (struct func_stat_t) * (func_stats_num + 1)); -- if (sorted_func_stats == NULL) -- return; -- -- j = 0; -- for (i = 0; i < ARRAY_LENGTH (func_stats); i++) { -- struct func_stat_t *elt; -- for (elt = func_stats[i]; elt != NULL; elt = elt->next) -- sorted_func_stats[j++] = *elt; -- } -- -- resolve_addrs (sorted_func_stats, j); -- -- /* merge entries with same name */ -- qsort (sorted_func_stats, j, -- sizeof (struct func_stat_t), compare_func_stats_name); -- j = merge_similar_entries (sorted_func_stats, j); -- -- qsort (sorted_func_stats, j, -- sizeof (struct func_stat_t), compare_func_stats); -- -- /* add total */ -- sorted_func_stats[j].next = NULL; -- sorted_func_stats[j].addr = (void *) -1; -- sorted_func_stats[j].name = "(total)"; -- sorted_func_stats[j].stat = total_allocations; -- j++; -- -- setlocale (LC_ALL, ""); -- -- printf (" TOTAL MALLOC REALLOC\n"); -- printf (" num size num size num size\n"); -- -- for (i = 0; i < j; i++) { -- dump_alloc_stats (&sorted_func_stats[i].stat, -- sorted_func_stats[i].name); -- } -- -- /* XXX free other stuff? */ -- -- free (sorted_func_stats); --} -diff --git a/util/meson.build b/util/meson.build -index d64dbad0b..1e186bf66 100644 ---- a/util/meson.build -+++ b/util/meson.build -@@ -41,7 +41,3 @@ foreach util : cairo_utils - dependencies: deps + util_deps + [libcairo_dep, libcairoscript_dep], - ) - endforeach -- --if conf.get('CAIRO_HAS_DLSYM', 0) == 1 and cc.has_header('execinfo.h') -- libmallocstats = library('malloc-stats', 'malloc-stats.c', dependencies : dl_dep) --endif --- -2.43.0 - diff --git a/recipes/cdparanoia.recipe b/recipes/cdparanoia.recipe index 8ed2230d6..5b7b8dad4 100644 --- a/recipes/cdparanoia.recipe +++ b/recipes/cdparanoia.recipe @@ -1,6 +1,7 @@ # -*- Mode: Python -*- vi:si:et:sw=4:sts=4:ts=4:syntax=python import os +import shutil from fnmatch import fnmatch @@ -28,6 +29,12 @@ class Recipe(recipe.Recipe): # No rule check make_check = None + async def configure(self): + autotools_dir = os.path.join(self.config._relative_path('data'), 'autotools') + shutil.copy(os.path.join(autotools_dir, 'config.guess'), os.path.join(self.config_src_dir, 'configure.guess')) + shutil.copy(os.path.join(autotools_dir, 'config.sub'), os.path.join(self.config_src_dir, 'configure.sub')) + await super().configure() + def post_install(self): if self.config.target_platform == Platform.LINUX: # Fix the libs permissions to 0755 to make the rpm packaging happy. diff --git a/recipes/custom.py b/recipes/custom.py index fc062d768..59d89b6ef 100644 --- a/recipes/custom.py +++ b/recipes/custom.py @@ -21,7 +21,7 @@ def running_on_cerbero_ci(): class GStreamer(recipe.Recipe): licenses = [License.LGPLv2Plus] - version = '1.24.8' + version = '1.26.3' tagged_for_release = True # Decide what stype to use diff --git a/recipes/dav1d.recipe b/recipes/dav1d.recipe index c8209d219..925d33587 100644 --- a/recipes/dav1d.recipe +++ b/recipes/dav1d.recipe @@ -5,10 +5,10 @@ import shutil class Recipe(recipe.Recipe): name = 'dav1d' - version = '1.1.0' + version = '1.4.1' stype = SourceType.TARBALL url = 'https://download.videolan.org/pub/videolan/%(name)s/%(version)s/%(name)s-%(version)s.tar.xz' - tarball_checksum = 'fb57aae7875f28c30fb3dbae4a3683d27e2f91dde09ce5c60c22cef9bc58dfd1' + tarball_checksum = '8d407dd5fe7986413c937b14e67f36aebd06e1fa5cfec679d10e548476f2d5f8' licenses = [{License.BSD_like: ['COPYING']}] btype = BuildType.MESON diff --git a/recipes/directx-headers.recipe b/recipes/directx-headers.recipe index aae23f289..a703d4eb5 100644 --- a/recipes/directx-headers.recipe +++ b/recipes/directx-headers.recipe @@ -1,4 +1,6 @@ # -*- Mode: Python -*- vi:si:et:sw=4:sts=4:ts=4:syntax=python +from pathlib import Path +import shutil class Recipe(recipe.Recipe): version = '1.611.0' @@ -6,7 +8,22 @@ class Recipe(recipe.Recipe): licenses = [{License.MIT: ['LICENSE']}] stype = SourceType.TARBALL btype = BuildType.MESON + library_type = LibraryType.STATIC url = 'https://github.com/microsoft/DirectX-Headers/archive/refs/tags/v%(version)s.tar.gz' tarball_checksum = 'edb8b52b1379f841df5d0d5e11dde08e0c3912508179fb3711f163382e88865c' + tarball_dirname = 'DirectX-Headers-%(version)s' files_devel = [] + files_libs = ['libd3dx12-format-properties', 'libDirectX-Guids'] + + def post_install(self): + # g-ir-scanner expects import libraries to end in .lib when + # building a gir for "internal" (same project) libraries + if self.using_msvc() and self.config.variants.gi: + prefix = Path(self.config.libdir) + for f in ['libd3dx12-format-properties.a', 'libDirectX-Guids.a']: + src = prefix / f + dst = src.with_stem(src.stem.replace('lib', '')).with_suffix('.lib') + dst.unlink(missing_ok=True) + shutil.copyfile(src, dst) + super().post_install() diff --git a/recipes/expat.recipe b/recipes/expat.recipe index 79392664a..f97239a21 100644 --- a/recipes/expat.recipe +++ b/recipes/expat.recipe @@ -4,12 +4,12 @@ from cerbero.tools.libtool import LibtoolLibrary class Recipe(recipe.Recipe): name = 'expat' - version = '2.6.2' + version = '2.6.4' licenses = [{License.BSD_like: ['COPYING']}] stype = SourceType.TARBALL btype = BuildType.CMAKE - url = 'https://github.com/libexpat/libexpat/releases/download/R_2_6_2/%(name)s-%(version)s.tar.xz' - tarball_checksum = 'ee14b4c5d8908b1bec37ad937607eab183d4d9806a08adee472c3c3121d27364' + url = 'https://github.com/libexpat/libexpat/releases/download/R_2_6_4/%(name)s-%(version)s.tar.xz' + tarball_checksum = 'a695629dae047055b37d50a0ff4776d1d45d0a4c842cf4ccee158441f55ff7ee' cmake_generator = 'ninja' can_msvc = True configure_options = '-DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_DOCS=OFF -DEXPAT_BUILD_FUZZERS=OFF -DEXPAT_BUILD_PKGCONFIG=ON' @@ -19,7 +19,7 @@ class Recipe(recipe.Recipe): def prepare(self): # We only want static libs on iOS and Android - if self.config.target_platform in (Platform.IOS): + if self.config.target_platform in (Platform.IOS, Platform.ANDROID): self.configure_options += ' -DBUILD_SHARED_LIBS=OFF ' self.library_type = LibraryType.STATIC else: diff --git a/recipes/ffmpeg.recipe b/recipes/ffmpeg.recipe index 4366a800b..5bf9cc9f7 100644 --- a/recipes/ffmpeg.recipe +++ b/recipes/ffmpeg.recipe @@ -3,13 +3,16 @@ from cerbero.tools.libtool import LibtoolLibrary class Recipe(recipe.Recipe): name = 'ffmpeg' - version = '6.0' + version = '7.1' licenses = [License.LGPLv2_1Plus] stype = SourceType.TARBALL url = 'https://ffmpeg.org/releases/%(name)s-%(version)s.tar.xz' - tarball_checksum = '57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082' + tarball_checksum = '40973d44970dbc83ef302b0609f2e74982be2d85916dd2ee7472d30678a7abe6' patches = [ + # https://gitlab.freedesktop.org/gstreamer/meson-ports/ffmpeg/-/tree/a66a916f069fe490a3fe418ec54f9cd05dd608be name + '/0001-Add-Meson-build.patch', + # https://gitlab.freedesktop.org/gstreamer/meson-ports/ffmpeg/-/merge_requests/151 + name + '/fix-textrels.patch', ] btype = BuildType.MESON @@ -42,7 +45,6 @@ class Recipe(recipe.Recipe): 'cuvid': 'disabled', 'libmfx': 'disabled', 'libnpp': 'disabled', - 'libnpp': 'disabled', 'iconv': 'disabled', 'jni': 'disabled', 'v4l2_m2m': 'disabled', @@ -57,19 +59,16 @@ class Recipe(recipe.Recipe): deps = ['bzip2', 'zlib'] - files_libs = ['libavcodec', 'libavformat', 'libavutil', 'libswresample', 'libavfilter', 'libpostproc', 'libswscale'] + files_libs = ['libavcodec', 'libavformat', 'libavutil', 'libswresample', 'libavfilter', 'libswscale'] files_devel = [] def prepare(self): # Arch-specific flags - if self.config.target_arch == Architecture.X86: - if self.config.target_platform == Platform.IOS: - # Simulator doesn't like shared libs - self.library_type = LibraryType.STATIC - elif self.config.target_platform == Platform.ANDROID: - # ld.lld: error: relocation R_386_32 cannot be used against local symbol; recompile with -fPIC - # See https://github.com/FFmpeg/FFmpeg/blob/n6.0/libavutil/x86/x86inc.asm#L104-L108 - self.meson_options['asm'] = 'disabled' + if self.config.target_arch == Architecture.X86 and self.config.target_platform == Platform.IOS: + # Simulator doesn't like shared libs + self.library_type = LibraryType.STATIC + if self.config.target_arch == Architecture.X86 and self.config.target_platform == Platform.ANDROID: + self.meson_options['asm'] = 'disabled' # Populate self.files_devel files_devel_tpl = ['%(libdir)s/{}.la', '%(libdir)s/pkgconfig/{}.pc', 'include/{}'] @@ -95,9 +94,6 @@ class Recipe(recipe.Recipe): LibtoolLibrary('avutil', None, None, None, self.config.libdir, self.config.target_platform, static_only=self.library_type == LibraryType.STATIC).save() - LibtoolLibrary('postproc', None, None, None, - self.config.libdir, self.config.target_platform, - static_only=self.library_type == LibraryType.STATIC).save() LibtoolLibrary('swresample', None, None, None, self.config.libdir, self.config.target_platform, deps=['avutil'], diff --git a/recipes/ffmpeg/0001-Add-Meson-build.patch b/recipes/ffmpeg/0001-Add-Meson-build.patch index 626428167..dd6ad09b0 100644 --- a/recipes/ffmpeg/0001-Add-Meson-build.patch +++ b/recipes/ffmpeg/0001-Add-Meson-build.patch @@ -5,88 +5,150 @@ Date: Thu, 7 Sep 2023 22:05:23 +0000 Subject: [PATCH] Add Meson build --- - README.meson | 87 + - capture_build_options.py | 29 + - ci/vs-arm64-cross-file.txt | 14 + - compat/windows/makedef.py | 118 + - depgraph.py | 1274 ++++++++ - depresolver.py | 198 ++ - ffbuild/bin2c.py | 39 + - fftools/meson.build | 72 + - find_things.py | 97 + - find_things_extern.py | 125 + - libavcodec/aarch64/meson.build | 74 + - libavcodec/arm/meson.build | 118 + - libavcodec/libavcodec.v.in | 6 + - libavcodec/meson.build | 1231 ++++++++ - libavcodec/neon/meson.build | 33 + - libavcodec/x86/meson.build | 207 ++ - libavdevice/libavdevice.v.in | 7 + - libavdevice/meson.build | 115 + - libavfilter/aarch64/meson.build | 34 + - libavfilter/dnn/meson.build | 35 + - libavfilter/libavfilter.v.in | 7 + - libavfilter/meson.build | 689 +++++ - libavfilter/x86/meson.build | 128 + - libavformat/libavformat.v.in | 6 + - libavformat/meson.build | 707 +++++ - libavutil/aarch64/meson.build | 43 + - libavutil/arm/meson.build | 47 + - libavutil/libavutil.v.in | 6 + - libavutil/meson.build | 350 +++ - libavutil/version.py | 99 + - libavutil/x86/meson.build | 53 + - libpostproc/libpostproc.v.in | 7 + - libpostproc/meson.build | 69 + - libswresample/aarch64/meson.build | 43 + - libswresample/arm/meson.build | 43 + - libswresample/libswresample.v.in | 7 + - libswresample/meson.build | 89 + - libswresample/x86/meson.build | 45 + - libswscale/aarch64/meson.build | 45 + - libswscale/arm/meson.build | 45 + - libswscale/libswscale.v.in | 7 + - libswscale/meson.build | 98 + - libswscale/x86/meson.build | 53 + - meson.build | 3584 +++++++++++++++++++++++ - meson_options.txt | 2397 +++++++++++++++ - parse_sources.py | 422 +++ - print_things.py | 62 + - rc_workaround.py | 32 + - recursive_selects.py | 65 + - subprojects/win-nasm/download-binary.py | 76 + - subprojects/win-nasm/meson.build | 41 + - subprojects/win-nasm/patch_nasm.py | 15 + - 52 files changed, 13293 insertions(+) + .gitattributes | 1 + + .gitignore | 46 + + .gitlab-ci.yml | 317 +++ + README.meson | 87 + + VERSION | 1 - + capture_build_options.py | 30 + + ci/vs-arm64-cross-file.txt | 14 + + compat/windows/makedef.py | 184 ++ + depgraph.py | 1375 +++++++++++++ + depresolver.py | 198 ++ + doc/.gitignore | 9 + + doc/doxy/.gitignore | 1 + + doc/examples/.gitignore | 25 + + ffbuild/.gitignore | 7 + + ffbuild/bin2c.py | 39 + + fftools/meson.build | 77 + + find_things.py | 101 + + find_things_extern.py | 126 ++ + libavcodec/.gitignore | 6 + + libavcodec/aac/meson.build | 35 + + libavcodec/aarch64/meson.build | 96 + + libavcodec/aarch64/vvc/meson.build | 34 + + libavcodec/arm/meson.build | 112 ++ + libavcodec/bsf/meson.build | 78 + + libavcodec/hevc/meson.build | 37 + + libavcodec/libavcodec.v.in | 6 + + libavcodec/meson.build | 1261 ++++++++++++ + libavcodec/neon/meson.build | 34 + + libavcodec/opus/meson.build | 36 + + libavcodec/tests/.gitignore | 21 + + libavcodec/vvc/meson.build | 34 + + libavcodec/x86/meson.build | 219 ++ + libavcodec/x86/vvc/meson.build | 46 + + libavdevice/.gitignore | 2 + + libavdevice/libavdevice.v.in | 7 + + libavdevice/meson.build | 116 ++ + libavdevice/tests/.gitignore | 1 + + libavfilter/.gitignore | 1 + + libavfilter/aarch64/meson.build | 37 + + libavfilter/dnn/meson.build | 40 + + libavfilter/libavfilter.v.in | 7 + + libavfilter/meson.build | 704 +++++++ + libavfilter/opencl/.gitignore | 1 + + libavfilter/tests/.gitignore | 12 + + libavfilter/textutils.c | 2 +- + libavfilter/vulkan/.gitignore | 1 + + libavfilter/x86/meson.build | 136 ++ + libavformat/.gitignore | 3 + + libavformat/Makefile | 2 +- + libavformat/bitstream.c | 1 + + libavformat/libavformat.v.in | 6 + + libavformat/meson.build | 733 +++++++ + libavformat/tests/.gitignore | 9 + + libavutil/.gitignore | 2 + + libavutil/aarch64/meson.build | 44 + + libavutil/arm/meson.build | 48 + + libavutil/file.c | 2 +- + libavutil/libavutil.v.in | 6 + + libavutil/meson.build | 358 ++++ + libavutil/tests/.gitignore | 54 + + libavutil/version.py | 99 + + libavutil/x86/meson.build | 54 + + libpostproc/libpostproc.v.in | 7 + + libpostproc/meson.build | 69 + + libswresample/aarch64/meson.build | 44 + + libswresample/arm/meson.build | 44 + + libswresample/libswresample.v.in | 7 + + libswresample/meson.build | 89 + + libswresample/tests/.gitignore | 1 + + libswresample/x86/meson.build | 46 + + libswscale/aarch64/meson.build | 49 + + libswscale/arm/meson.build | 46 + + libswscale/libswscale.v.in | 7 + + libswscale/meson.build | 98 + + libswscale/tests/.gitignore | 4 + + libswscale/x86/meson.build | 55 + + meson.build | 3907 ++++++++++++++++++++++++++++++++++++ + meson_options.txt | 2487 +++++++++++++++++++++++ + parse_sources.py | 449 +++++ + print_things.py | 62 + + recursive_selects.py | 65 + + subprojects/nasm.wrap | 7 + + tests/.gitignore | 11 + + tests/api/.gitignore | 1 + + tests/checkasm/.gitignore | 1 + + tools/.gitignore | 22 + + 86 files changed, 14755 insertions(+), 4 deletions(-) + create mode 100644 .gitattributes + create mode 100644 .gitignore + create mode 100644 .gitlab-ci.yml create mode 100644 README.meson + delete mode 100644 VERSION create mode 100644 capture_build_options.py create mode 100644 ci/vs-arm64-cross-file.txt create mode 100644 compat/windows/makedef.py create mode 100644 depgraph.py create mode 100644 depresolver.py + create mode 100644 doc/.gitignore + create mode 100644 doc/doxy/.gitignore + create mode 100644 doc/examples/.gitignore + create mode 100644 ffbuild/.gitignore create mode 100644 ffbuild/bin2c.py create mode 100644 fftools/meson.build create mode 100755 find_things.py create mode 100755 find_things_extern.py + create mode 100644 libavcodec/.gitignore + create mode 100644 libavcodec/aac/meson.build create mode 100644 libavcodec/aarch64/meson.build + create mode 100644 libavcodec/aarch64/vvc/meson.build create mode 100644 libavcodec/arm/meson.build + create mode 100644 libavcodec/bsf/meson.build + create mode 100644 libavcodec/hevc/meson.build create mode 100644 libavcodec/libavcodec.v.in create mode 100644 libavcodec/meson.build create mode 100644 libavcodec/neon/meson.build + create mode 100644 libavcodec/opus/meson.build + create mode 100644 libavcodec/tests/.gitignore + create mode 100644 libavcodec/vvc/meson.build create mode 100644 libavcodec/x86/meson.build + create mode 100644 libavcodec/x86/vvc/meson.build + create mode 100644 libavdevice/.gitignore create mode 100644 libavdevice/libavdevice.v.in create mode 100644 libavdevice/meson.build + create mode 100644 libavdevice/tests/.gitignore + create mode 100644 libavfilter/.gitignore create mode 100644 libavfilter/aarch64/meson.build create mode 100644 libavfilter/dnn/meson.build create mode 100644 libavfilter/libavfilter.v.in create mode 100644 libavfilter/meson.build + create mode 100644 libavfilter/opencl/.gitignore + create mode 100644 libavfilter/tests/.gitignore + create mode 100644 libavfilter/vulkan/.gitignore create mode 100644 libavfilter/x86/meson.build + create mode 100644 libavformat/.gitignore + create mode 100644 libavformat/bitstream.c create mode 100644 libavformat/libavformat.v.in create mode 100644 libavformat/meson.build + create mode 100644 libavformat/tests/.gitignore + create mode 100644 libavutil/.gitignore create mode 100644 libavutil/aarch64/meson.build create mode 100644 libavutil/arm/meson.build create mode 100644 libavutil/libavutil.v.in create mode 100644 libavutil/meson.build + create mode 100644 libavutil/tests/.gitignore create mode 100644 libavutil/version.py create mode 100644 libavutil/x86/meson.build create mode 100644 libpostproc/libpostproc.v.in @@ -95,25 +157,410 @@ Subject: [PATCH] Add Meson build create mode 100644 libswresample/arm/meson.build create mode 100644 libswresample/libswresample.v.in create mode 100644 libswresample/meson.build + create mode 100644 libswresample/tests/.gitignore create mode 100644 libswresample/x86/meson.build create mode 100644 libswscale/aarch64/meson.build create mode 100644 libswscale/arm/meson.build create mode 100644 libswscale/libswscale.v.in create mode 100644 libswscale/meson.build + create mode 100644 libswscale/tests/.gitignore create mode 100644 libswscale/x86/meson.build create mode 100644 meson.build create mode 100644 meson_options.txt create mode 100644 parse_sources.py create mode 100755 print_things.py - create mode 100755 rc_workaround.py create mode 100644 recursive_selects.py - create mode 100755 subprojects/win-nasm/download-binary.py - create mode 100644 subprojects/win-nasm/meson.build - create mode 100755 subprojects/win-nasm/patch_nasm.py + create mode 100644 subprojects/nasm.wrap + create mode 100644 tests/.gitignore + create mode 100644 tests/api/.gitignore + create mode 100644 tests/checkasm/.gitignore + create mode 100644 tools/.gitignore +diff --git a/.gitattributes b/.gitattributes +new file mode 100644 +index 00000000..a900528e +--- /dev/null ++++ b/.gitattributes +@@ -0,0 +1 @@ ++*.pnm -diff -text +diff --git a/.gitignore b/.gitignore +new file mode 100644 +index 00000000..82947905 +--- /dev/null ++++ b/.gitignore +@@ -0,0 +1,46 @@ ++*.a ++*.o ++*.o.* ++*.d ++*.def ++*.dll ++*.dylib ++*.exe ++*.exp ++*.gcda ++*.gcno ++*.h.c ++*.ilk ++*.lib ++*.pc ++*.pdb ++*.so ++*.so.* ++*.swp ++*.ver ++*.version ++*.metal.air ++*.metallib ++*.metallib.c ++*.ptx ++*.ptx.c ++*.ptx.gz ++*_g ++\#* ++.\#* ++/.cache ++/__pycache__ ++/.config ++/.version ++/ffmpeg ++/ffplay ++/ffprobe ++/config.asm ++/config.h ++/config_components.h ++/coverage.info ++/lcov/ ++/src ++/mapfile ++/tools/python/__pycache__/ ++/.meson-subproject-wrap-hash.txt +diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml +new file mode 100644 +index 00000000..719d2aff +--- /dev/null ++++ b/.gitlab-ci.yml +@@ -0,0 +1,317 @@ ++include: ++ - project: 'freedesktop/ci-templates' ++ ref: 'master' ++ file: '/templates/debian.yml' ++ ++default: ++ interruptible: true ++ ++# Is it worth making an image with ffmpeg git repo and packages installed? ++stages: ++ - 'image-build' ++ - 'build' ++ ++.container.debian@common: ++ variables: ++ FDO_DISTRIBUTION_VERSION: "bookworm-slim" ++ FDO_UPSTREAM_REPO: "gstreamer/meson-ports/ffmpeg" ++ FDO_DISTRIBUTION_PACKAGES: >- ++ meson ++ python3-setuptools ++ ninja-build ++ build-essential ++ git ++ ++.container.debian@common.minimum: ++ extends: '.container.debian@common' ++ variables: ++ FDO_DISTRIBUTION_TAG: "2022-10-19.3-meson-4.4-minimum" ++ ++.container.debian@common.full: ++ extends: '.container.debian@common' ++ variables: ++ FDO_DISTRIBUTION_TAG: "2023-04-27.1-meson-4.4-full" ++ FDO_DISTRIBUTION_EXEC: >- ++ echo "deb-src http://deb.debian.org/debian bookworm main" >> /etc/apt/sources.list && ++ apt-get update && ++ apt-get build-dep --yes ffmpeg && ++ apt-get install --yes liblzo2-dev ++ ++debian-container-build@x86_64@minimum: ++ extends: ++ - '.fdo.container-build@debian@x86_64' ++ - '.container.debian@common.minimum' ++ stage: 'image-build' ++ ++debian-container-build@x86_64@full: ++ extends: ++ - '.fdo.container-build@debian@x86_64' ++ - '.container.debian@common.full' ++ stage: 'image-build' ++ ++.build: ++ stage: 'build' ++ script: ++ - meson ${MESON_OPTIONS} build/ ++ - stat build/build.ninja ++ - ninja -C build/ ++ - ninja -C build/ test ++ - ninja -C build/ install ++ artifacts: ++ when: on_failure ++ paths: ++ - build/meson-logs/ ++ - build/*.build ++ ++.build nodeps: ++ extends: ++ - '.build' ++ - '.container.debian@common.minimum' ++ - '.fdo.distribution-image@debian' ++ variables: ++ MESON_OPTIONS: '--auto-features=disabled' ++ ++.build withdeps: ++ extends: ++ - '.build' ++ - '.container.debian@common.full' ++ - '.fdo.distribution-image@debian' ++ ++.build withdepsnoyasm: ++ extends: '.build withdeps' ++ before_script: ++ - apt-get remove --yes nasm ++ - apt-get update ++ - apt-get install --yes yasm ++ ++no external deps: ++ extends: '.build nodeps' ++ ++with deps: ++ extends: '.build withdeps' ++ ++with deps yasm: ++ extends: '.build withdepsnoyasm' ++ ++.build@i386.common: ++ image: 'i386/debian:bookworm' ++ tags: ['gstreamer'] ++ variables: ++ DEPENDENCIES: >- ++ meson ++ python3-setuptools ++ ninja-build ++ build-essential ++ git ++ ++no external@i386: ++ extends: ++ - '.build nodeps' ++ - '.build@i386.common' ++ before_script: ++ - apt-get update ++ - apt-get install --yes ${DEPENDENCIES} ++ ++with deps@i386: ++ extends: ++ - '.build withdeps' ++ - '.build@i386.common' ++ before_script: ++ - echo "deb-src http://deb.debian.org/debian bookworm main" >> /etc/apt/sources.list ++ - apt-get update ++ - apt-get build-dep --yes ffmpeg ++ - apt-get install --yes ${DEPENDENCIES} ++ ++.build windows: ++ image: 'registry.freedesktop.org/gstreamer/gstreamer/amd64/windows:2022-09-23.0-main' ++ stage: 'build' ++ tags: ++ - 'docker' ++ - 'windows' ++ - '2022' ++ variables: ++ # Make sure any failure in PowerShell scripts is fatal ++ ErrorActionPreference: 'Stop' ++ WarningPreference: 'Stop' ++ # Uncomment the following key if need to pass custom args, as well with the ++ # $env:MESON_ARGS line in the `script:` blocks ++ # MESON_ARGS: >- ++ # -Dfoo=enabled ++ # -Dbar=disabled ++ before_script: ++ # Block Meson on 1.4.1 -- https://github.com/mesonbuild/meson/issues/13403 ++ - pip3 install -U meson==1.4.1 ++ script: ++ # For some reason, options are separated by newline instead of space, so we ++ # have to replace them first. ++ # - $env:MESON_ARGS = $env:MESON_ARGS.replace("`n"," ") ++ # Gitlab executes PowerShell in docker, but VsDevCmd.bat is a batch script. ++ # Environment variables substitutions is done by PowerShell before calling ++ # cmd.exe, that's why we use $env:FOO instead of %FOO% ++ - cmd.exe /C "C:\BuildTools\Common7\Tools\VsDevCmd.bat -host_arch=amd64 -arch=$env:ARCH && ++ meson build $env:MESON_ARGS && ++ ninja -C build && ++ ninja -C build test" ++ ++vs2019: ++ extends: '.build windows' ++ variables: ++ ARCH: 'amd64' ++ ++vs2019 no-optimization debug: ++ extends: '.build windows' ++ variables: ++ ARCH: 'amd64' ++ MESON_ARGS: '--optimization=0 --debug' ++ ++# VS 2019 with a number of features disabled, as they might be by consumers that only need a subset of ffmpeg's features. ++# Also verifies that the ffmpeg build is useable even with "debug build" settings ++vs2019 no-optimization debug feature-customization: ++ extends: '.build windows' ++ variables: ++ ARCH: 'amd64' ++ MESON_ARGS: '--optimization=0 --debug -D encoders=disabled -D muxers=disabled -D programs=enabled -D tests=disabled -D avdevice=disabled' ++ ++vs2019 x86: ++ extends: '.build windows' ++ stage: 'build' ++ variables: ++ ARCH: 'x86' ++ artifacts: ++ paths: ++ - build1/meson-logs/ ++ - build2/meson-logs/ ++ script: ++ # MSVC hangs while linking with -Dasm=enabled (default), so only run setup with -Dasm=enabled ++ - cmd.exe /C "C:\BuildTools\Common7\Tools\VsDevCmd.bat -host_arch=amd64 -arch=$env:ARCH && ++ meson build1 $env:MESON_ARGS" ++ - cmd.exe /C "C:\BuildTools\Common7\Tools\VsDevCmd.bat -host_arch=amd64 -arch=$env:ARCH && ++ meson build2 $env:MESON_ARGS -Dasm=disabled && ninja -C build2 && ninja -C build2 test" ++ ++vs2019 arm64 cross: ++ extends: '.build windows' ++ stage: 'build' ++ variables: ++ ARCH: 'arm64' ++ MESON_ARGS: '--cross-file ci/vs-arm64-cross-file.txt' ++ ++.build darwin: ++ stage: 'build' ++ image: "registry.freedesktop.org/gstreamer/gstreamer/macos-arm64/15-sequoia:2024-10-28.0" ++ tags: ++ - gst-mac-arm ++ artifacts: ++ name: "${CI_JOB_NAME}_${CI_COMMIT_SHA}" ++ expire_in: '5 days' ++ when: 'always' ++ paths: ++ - "build/meson-logs/*txt" ++ before_script: ++ - pip3 install --upgrade pip ++ - pip3 install -U meson ninja ++ script: ++ - meson setup build ++ - meson compile -C build ++ - meson test -C build ++ ++macOS arm64: ++ extends: '.build darwin' ++ stage: 'build' ++ ++iOS arm64 cross: ++ extends: '.build darwin' ++ stage: 'build' ++ script: ++ - | ++ cat > ios-cross-file.txt < android-cross-file.txt < | patch -p1 ++git diff n5.1.3 HEAD | patch -p1 +``` + -+Once done, hit `git commit` and make sure the message is a merge commit and that ++Once done, hit `git commit` and make sure the message is a merge commit and that +it looks like: + +``` @@ -181,7 +628,7 @@ index 0000000000..d06c0c4dfe + +## Updating the Meson port + -+Once done, you need to apply the following generation scripts, usually with `py ++Once done, you need to apply the following generation scripts, usually with `py +-3`. Then replace the current generated files with them, but make sure to bring +back in the manual changes (that's the tedious part). + @@ -189,7 +636,7 @@ index 0000000000..d06c0c4dfe + written parts as specified by the `#### --- [END] GENERATED --- ####` + specifiers + -+- `find_things_extern.py` and `find_things.py` update the meson_options.txt file ++- `find_things_extern.py` and `find_things.py` update the meson_options.txt file + trying to keep manually written parts as specified by the + `#### --- [END] GENERATED [EXTERN|FILTER] OPTIONS --- ####` specifiers, + respectively @@ -204,12 +651,19 @@ index 0000000000..d06c0c4dfe +for the Meson port. Some documentation of that is at the top of `depgraph.py`. + +Good luck! +diff --git a/VERSION b/VERSION +deleted file mode 100644 +index 0f0fefae..00000000 +--- a/VERSION ++++ /dev/null +@@ -1 +0,0 @@ +-7.1 diff --git a/capture_build_options.py b/capture_build_options.py new file mode 100644 -index 0000000000..6e6a84ab86 +index 00000000..72093e53 --- /dev/null +++ b/capture_build_options.py -@@ -0,0 +1,29 @@ +@@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +# Copyright (c) 2022 L. E. Segovia +# @@ -239,9 +693,10 @@ index 0000000000..6e6a84ab86 + + if options is not None: + print(options.group(1)) ++ diff --git a/ci/vs-arm64-cross-file.txt b/ci/vs-arm64-cross-file.txt new file mode 100644 -index 0000000000..acfc9b5ade +index 00000000..acfc9b5a --- /dev/null +++ b/ci/vs-arm64-cross-file.txt @@ -0,0 +1,14 @@ @@ -261,10 +716,10 @@ index 0000000000..acfc9b5ade +pkgconfig = 'false' diff --git a/compat/windows/makedef.py b/compat/windows/makedef.py new file mode 100644 -index 0000000000..9b331e5a66 +index 00000000..b42958ce --- /dev/null +++ b/compat/windows/makedef.py -@@ -0,0 +1,118 @@ +@@ -0,0 +1,184 @@ +#!/usr/bin/env python3 +# Copyright (c) 2022 L. E. Segovia +# @@ -284,26 +739,55 @@ index 0000000000..9b331e5a66 +# License along with this library; if not, see . + +import argparse -+import pathlib ++import errno +import os ++import pathlib +import re +import subprocess -+import tempfile ++ ++ ++def output(platform, symbols): ++ if platform == 'win': ++ print("EXPORTS") ++ print(*[f' {symbol}' for symbol in sorted(set(symbols))], sep='\n') ++ elif platform == 'darwin': ++ print(*[f'{prefix}{symbol}' for symbol in sorted(set(symbols))], sep='\n') ++ else: ++ print('{') ++ print(' global:') ++ print( ++ *[f' {prefix}{symbol};' for symbol in sorted(set(symbols))], sep='\n') ++ print(' local:') ++ print(' *;') ++ print('};') ++ + +if __name__ == '__main__': + arg_parser = argparse.ArgumentParser( -+ description='Craft the Windows exports file') ++ description='Craft the symbols exports file') + -+ arg_parser.add_argument('vscript', metavar='VERSION_SCRIPT', -+ type=argparse.FileType('r'), help='Version script') + arg_parser.add_argument('--prefix', metavar='PREFIX', + help='Prefix for extern symbols') -+ arg_parser.add_argument('--nm', metavar='NM_PATH', type=pathlib.Path, -+ help='If specified, runs this instead of dumpbin (MinGW)') -+ arg_parser.add_argument('--dumpbin', metavar='DUMPBIN_PATH', type=pathlib.Path, -+ help='If specified, runs this instead of nm (MSVC)') ++ g = arg_parser.add_argument_group('Library parsing tool') ++ group = g.add_mutually_exclusive_group(required=True) ++ group.add_argument('--nm', metavar='NM_PATH', type=pathlib.Path, ++ help='If specified, runs this instead of dumpbin (MinGW)') ++ group.add_argument('--dumpbin', metavar='DUMPBIN_PATH', type=pathlib.Path, ++ help='If specified, runs this instead of nm (MSVC)') ++ group.add_argument( ++ '--list', action='store_true', help='If specified, consider FILE as an exported symbols list instead of a library') ++ g = arg_parser.add_argument_group('Symbol naming') ++ group = g.add_mutually_exclusive_group(required=True) ++ group.add_argument('--regex', metavar='REGEX', type=str, ++ nargs='+', ++ help='Regular expression for exported symbols') ++ group.add_argument('--vscript', metavar='VERSION_SCRIPT', ++ type=argparse.FileType('r'), help='Version script') ++ arg_parser.add_argument('--os', type=str, choices=('win', 'linux', 'darwin'), ++ default='linux', required=True, ++ help='Target operating system for the exports file (win = MSVC module definition file, linux = version script, darwin = exported symbols list)') + arg_parser.add_argument('libname', metavar='FILE', type=pathlib.Path, -+ help='Library to parse') ++ help='Source file to parse') + + args = arg_parser.parse_args() + @@ -317,34 +801,72 @@ index 0000000000..9b331e5a66 + started = 0 + regex = [] + -+ for line in args.vscript: -+ # We only care about global symbols -+ if re.match(r'^\s+global:', line): -+ started = 1 -+ line = re.sub(r'^\s+global: *', '', line) -+ else: -+ if re.match('^\s+local:', line): -+ started = 0 ++ if args.vscript: ++ for line in args.vscript: ++ # We only care about global symbols ++ if re.match(r'^\s+global:', line): ++ started = 1 ++ line = re.sub(r'^\s+global: *', '', line) ++ else: ++ if re.match(r'^\s+local:', line): ++ started = 0 + -+ if started == 0: -+ continue ++ if started == 0: ++ continue + -+ line = line.replace(';', '') ++ line = line.replace(';', '') + -+ for exp in line.split(): -+ # Remove leading and trailing whitespace -+ regex.append(exp.strip()) ++ for exp in line.split(): ++ # Remove leading and trailing whitespace ++ regex.append(exp.strip()) ++ else: ++ regex.extend(args.regex) + -+ if args.nm is not None: ++ if args.list: ++ dump = libname.open('r', encoding='utf-8').readlines() ++ # Strip whitespaces ++ dump = [x.strip() for x in dump] ++ # Exclude blank lines ++ dump = [x for x in dump if len(x) > 0] ++ elif args.nm is not None: + # Use eval, since NM="nm -g" + # Add -j to ensure only symbol names are output (otherwise in macOS + # a race condition can occur in the redirection) -+ s = subprocess.run([args.nm, '--defined-only', -+ '-g', '-j', libname], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, check=False) ++ # And use `--no-llvm-bc` in case it's /usr/bin/nm on macOS ++ s = subprocess.run( ++ [args.nm, '-U', '-g', '-j', '--no-llvm-bc', libname], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.STDOUT, ++ universal_newlines=True, ++ check=False, ++ ) ++ if s.returncode != 0: ++ # If it fails, retry without skipping LLVM bitcode (macOS flag) ++ s = subprocess.run( ++ [args.nm, '-U', '-g', '-j', libname], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.STDOUT, ++ universal_newlines=True, ++ check=False, ++ ) + if s.returncode != 0: + # -j was added only in Binutils 2.37 -+ s = subprocess.run([args.nm, '--defined-only', -+ '-g', libname], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, universal_newlines=True, check=True) ++ s = subprocess.run( ++ [args.nm, '-U', '-g', libname], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.DEVNULL, ++ universal_newlines=True, ++ check=False, ++ ) ++ if s.returncode != 0: ++ # -U was added only in Binutils 2.39 ++ s = subprocess.run( ++ [args.nm, '--defined-only', '-g', libname], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.DEVNULL, ++ universal_newlines=True, ++ check=True, ++ ) + dump = s.stdout.splitlines() + # Exclude lines with ':' (object name) + dump = [x for x in dump if ":" not in x] @@ -366,29 +888,28 @@ index 0000000000..9b331e5a66 + end = i + dump = dump[start:end] + # Substitute prefix out -+ dump = [re.sub(f'\s+{prefix}', ' ', x) for x in dump] ++ dump = [re.sub(fr'\s+{prefix}', ' ', x) for x in dump] + # Substitute big chonky spaces out -+ dump = [re.sub(f'\s+', ' ', x) for x in dump] ++ dump = [re.sub(r'\s+', ' ', x) for x in dump] + # Exclude blank lines + dump = [x for x in dump if len(x) > 0] + # Take only the *second* field (split by spaces) + # Python's split excludes whitespace at the beginning + dump = [x.split()[1] for x in dump] + -+ list = [] ++ symbols = [] + for exp in regex: + for i in dump: -+ if re.match(f'^{exp}', i): -+ list.append(f' {i}') ++ if re.match(exp, i): ++ symbols.append(i) + -+ print("EXPORTS") -+ print("\n".join(sorted(set(list)))) ++ output(args.os, symbols) diff --git a/depgraph.py b/depgraph.py new file mode 100644 -index 0000000000..d6f65769c7 +index 00000000..02d300ec --- /dev/null +++ b/depgraph.py -@@ -0,0 +1,1274 @@ +@@ -0,0 +1,1375 @@ +''' +This describes a dependency graph as a set of named nodes, the following +was automatically generated by parsing the configure script, @@ -414,6 +935,8 @@ index 0000000000..d6f65769c7 + 'sinewin']}, + 'aac_fixed_decoder': {'select': ['adts_header', 'mpeg4audio']}, + 'aac_latm_decoder': {'select': ['aac_decoder', 'aac_latm_parser']}, ++ 'aac_mediacodec_decoder': {'deps': ['mediacodec'], ++ 'select': ['aac_adtstoasc_bsf', 'aac_parser']}, + 'aac_mf_encoder': {'deps': ['mediafoundation']}, + 'aac_parser': {'select': ['adts_header', 'mpeg4audio']}, + 'ac3_at_decoder': {'deps': ['audiotoolbox'], 'select': ['ac3_parser']}, @@ -448,7 +971,9 @@ index 0000000000..d6f65769c7 + 'amovie_filter': {'deps': ['avcodec', 'avformat']}, + 'amr_nb_at_decoder': {'deps': ['audiotoolbox']}, + 'amrnb_decoder': {'select': ['lsp']}, ++ 'amrnb_mediacodec_decoder': {'deps': ['mediacodec'], 'select': ['amr_parser']}, + 'amrwb_decoder': {'select': ['lsp']}, ++ 'amrwb_mediacodec_decoder': {'deps': ['mediacodec'], 'select': ['amr_parser']}, + 'amv_decoder': {'select': ['sp5x_decoder', 'exif']}, + 'amv_encoder': {'select': ['jpegtables', 'mpegvideoenc']}, + 'amv_muxer': {'select': ['riffenc']}, @@ -456,6 +981,7 @@ index 0000000000..d6f65769c7 + 'camera2ndk', + 'mediandk', + 'pthreads']}, ++ 'android_content_protocol': {'deps': ['jni'], 'select': ['file_protocol']}, + 'ape_decoder': {'select': ['bswapdsp', 'llauddsp']}, + 'apng_decoder': {'select': ['inflate_wrapper']}, + 'apng_encoder': {'select': ['deflate_wrapper', 'llvidencdsp']}, @@ -483,24 +1009,29 @@ index 0000000000..d6f65769c7 + 'fdctdsp', + 'pixblockdsp']}, + 'async_protocol': {'deps': ['threads']}, -+ 'atomics_gcc': {'if': ['sync_val_compare_and_swap']}, -+ 'atomics_suncc': {'if': ['atomic_cas_ptr', 'machine_rw_barrier']}, + 'atomics_win32': {'if': ['memorybarrier']}, ++ 'atomics_native': {'if_any': ['atomics_win32']}, # MANUAL + 'atrac1_decoder': {'select': ['sinewin']}, -+ 'audiotoolbox_outdev': {'deps': ['audiotoolbox', 'pthreads', 'coreaudio']}, # MANUAL https://ffmpeg.org/pipermail/ffmpeg-devel/2023-July/312785.html ++ 'atrac3p_decoder': {'select': ['sinewin']}, ++ 'atrac3pal_decoder': {'select': ['sinewin']}, ++ 'audiotoolbox_outdev': {'deps': ['audiotoolbox', 'pthreads']}, + 'av1_amf_encoder': {'deps': ['amf']}, + 'av1_cuvid_decoder': {'deps': ['cuvid', 'cuvidav1picparams']}, + 'av1_d3d11va2_hwaccel': {'deps': ['d3d11va', 'dxva_picparams_av1'], + 'select': ['av1_decoder']}, + 'av1_d3d11va_hwaccel': {'deps': ['d3d11va', 'dxva_picparams_av1'], + 'select': ['av1_decoder']}, -+ 'av1_decoder': {'select': ['av1_frame_split_bsf', 'cbs_av1']}, ++ 'av1_d3d12va_hwaccel': {'deps': ['d3d12va', 'dxva_picparams_av1'], ++ 'select': ['av1_decoder']}, ++ 'av1_decoder': {'select': ['atsc_a53', 'cbs_av1', 'dovi_rpudec']}, + 'av1_demuxer': {'select': ['av1_frame_merge_bsf', 'av1_parser']}, + 'av1_dxva2_hwaccel': {'deps': ['dxva2', 'dxva_picparams_av1'], + 'select': ['av1_decoder']}, + 'av1_frame_merge_bsf': {'select': ['cbs_av1']}, + 'av1_frame_split_bsf': {'select': ['cbs_av1']}, + 'av1_mediacodec_decoder': {'deps': ['mediacodec']}, ++ 'av1_mediacodec_encoder': {'deps': ['mediacodec'], ++ 'select': ['extract_extradata_bsf']}, + 'av1_metadata_bsf': {'select': ['cbs_av1']}, + 'av1_nvdec_hwaccel': {'deps': ['nvdec', 'cuvidav1picparams'], + 'select': ['av1_decoder']}, @@ -509,12 +1040,16 @@ index 0000000000..d6f65769c7 + 'av1_parser': {'select': ['cbs_av1']}, + 'av1_qsv_decoder': {'select': ['qsvdec']}, + 'av1_qsv_encoder': {'deps': ['libvpl'], 'select': ['qsvenc']}, ++ 'av1_vaapi_encoder': {'deps': ['vaencpictureparameterbufferav1'], ++ 'select': ['cbs_av1', 'vaapi_encode']}, + 'av1_vaapi_hwaccel': {'deps': ['vaapi', + 'vadecpictureparameterbufferav1_bit_depth_idx'], + 'select': ['av1_decoder']}, + 'av1_vdpau_hwaccel': {'deps': ['vdpau', 'vdppictureinfoav1'], + 'select': ['av1_decoder']}, -+ 'avcodec': {'deps': ['avutil'], 'suggest': ['libm', 'stdatomic']}, ++ 'av1_vulkan_hwaccel': {'deps': ['vulkan'], 'select': ['av1_decoder']}, ++ 'avcodec': {'deps': ['avutil'], ++ 'suggest': ['libm', 'stdatomic', 'liblcevc_dec']}, + 'avdevice': {'deps': ['avformat', 'avcodec', 'avutil'], + 'suggest': ['libm', 'stdatomic']}, + 'avfilter': {'deps': ['avutil'], 'suggest': ['libm', 'stdatomic']}, @@ -537,10 +1072,12 @@ index 0000000000..d6f65769c7 + 'avisynth_demuxer': {'deps': ['avisynth'], 'select': ['riffdec']}, + 'avutil': {'suggest': ['clock_gettime', + 'ffnvcodec', ++ 'gcrypt', + 'libm', + 'libdrm', + 'libmfx', + 'opencl', ++ 'openssl', + 'user32', + 'vaapi', + 'vulkan', @@ -570,6 +1107,9 @@ index 0000000000..d6f65769c7 + 'boxblur_filter': {'deps': ['gpl']}, + 'boxblur_opencl_filter': {'deps': ['opencl', 'gpl']}, + 'bs2b_filter': {'deps': ['libbs2b']}, ++ 'bwdif_cuda_filter': {'deps': ['ffnvcodec'], ++ 'deps_any': ['cuda_nvcc', 'cuda_llvm']}, ++ 'bwdif_vulkan_filter': {'deps': ['vulkan', 'spirv_compiler']}, + 'caca_outdev': {'deps': ['libcaca']}, + 'caf_demuxer': {'select': ['iso_media']}, + 'caf_muxer': {'select': ['iso_media']}, @@ -582,8 +1122,10 @@ index 0000000000..d6f65769c7 + 'cbs_av1': {'select': ['cbs']}, + 'cbs_h264': {'select': ['cbs']}, + 'cbs_h265': {'select': ['cbs']}, ++ 'cbs_h266': {'select': ['cbs']}, + 'cbs_jpeg': {'select': ['cbs']}, + 'cbs_mpeg2': {'select': ['cbs']}, ++ 'cbs_vp8': {'select': ['cbs']}, + 'cbs_vp9': {'select': ['cbs']}, + 'chromaber_vulkan_filter': {'deps': ['vulkan', 'spirv_compiler']}, + 'chromakey_cuda_filter': {'deps': ['ffnvcodec'], @@ -591,6 +1133,7 @@ index 0000000000..d6f65769c7 + 'chromaprint_muxer': {'deps': ['chromaprint']}, + 'clearvideo_decoder': {'select': ['idctdsp']}, + 'cllc_decoder': {'select': ['bswapdsp']}, ++ 'color_vulkan_filter': {'deps': ['vulkan', 'spirv_compiler']}, + 'colorkey_opencl_filter': {'deps': ['opencl']}, + 'colormatrix_filter': {'deps': ['gpl']}, + 'colorspace_cuda_filter': {'deps': ['ffnvcodec'], @@ -601,18 +1144,20 @@ index 0000000000..d6f65769c7 + 'coreimage_filter': {'deps': ['coreimage', 'appkit']}, + 'coreimagesrc_filter': {'deps': ['coreimage', 'appkit']}, + 'cover_rect_filter': {'deps': ['avcodec', 'avformat', 'gpl']}, -+ 'cpunop': {'deps': ['i686']}, + 'cri_decoder': {'select': ['mjpeg_decoder']}, + 'cropdetect_filter': {'deps': ['gpl']}, -+ 'crystalhd': {'deps': ['libcrystalhd_libcrystalhd_if_h']}, + 'cscd_decoder': {'suggest': ['zlib']}, + 'cuda': {'deps': ['ffnvcodec']}, + 'cuvid': {'deps': ['ffnvcodec']}, + 'd3d11va': {'deps': ['dxva_h', 'id3d11videodecoder', 'id3d11videocontext']}, ++ 'd3d12va': {'deps': ['dxva_h', 'id3d12device', 'id3d12videodecoder']}, ++ 'd3d12va_encode': {'deps': ['d3d12va', ++ 'id3d12videoencoder', ++ 'd3d12_encoder_feature']}, + 'dash_demuxer': {'deps': ['libxml2']}, + 'dash_muxer': {'select': ['mp4_muxer']}, ++ 'daud_muxer': {'select': ['pcm_rechunk_bsf']}, + 'dcbzl': {'deps': ['ppc']}, -+ 'dct': {'select': ['rdft']}, + 'ddagrab_filter': {'deps': ['d3d11va', + 'idxgioutput1', + 'dxgi_outdupl_frame_info']}, @@ -643,12 +1188,13 @@ index 0000000000..d6f65769c7 + 'dirac_decoder': {'select': ['dirac_parse', + 'dwt', + 'golomb', -+ 'videodsp', -+ 'mpegvideoenc']}, ++ 'mpegvideoenc', ++ 'qpeldsp', ++ 'videodsp']}, + 'dirac_demuxer': {'select': ['dirac_parser']}, + 'dirac_parse': {'select': ['golomb']}, + 'dnn': {'deps': ['avformat', 'swscale'], -+ 'suggest': ['libtensorflow', 'libopenvino']}, ++ 'deps_any': ['libtensorflow', 'libopenvino', 'libtorch']}, + 'dnn_classify_filter': {'select': ['dnn']}, + 'dnn_detect_filter': {'select': ['dnn']}, + 'dnn_processing_filter': {'select': ['dnn']}, @@ -660,8 +1206,15 @@ index 0000000000..d6f65769c7 + 'pixblockdsp', + 'videodsp']}, + 'doc': {'deps_any': ['manpages', 'htmlpages', 'podpages', 'txtpages']}, -+ 'dovi_rpu': {'select': ['golomb']}, -+ 'drawtext_filter': {'deps': ['libfreetype'], ++ 'dotprod': {'deps': ['aarch64', 'neon']}, ++ 'dovi_rpu_bsf': {'select': ['cbs_h265', ++ 'cbs_av1', ++ 'dovi_rpudec', ++ 'dovi_rpuenc']}, ++ 'dovi_rpudec': {'select': ['golomb']}, ++ 'dovi_rpuenc': {'select': ['golomb']}, ++ 'drawbox_vaapi_filter': {'deps': ['vaapi_1']}, ++ 'drawtext_filter': {'deps': ['libfreetype', 'libharfbuzz'], + 'suggest': ['libfontconfig', 'libfribidi']}, + 'dshow_indev': {'deps': ['ibasefilter']}, + 'dts2pts_bsf': {'select': ['cbs_h264', 'h264parse']}, @@ -669,6 +1222,8 @@ index 0000000000..d6f65769c7 + 'dtshd_demuxer': {'select': ['dca_parser']}, + 'dv_demuxer': {'select': ['dvprofile']}, + 'dv_muxer': {'select': ['dvprofile']}, ++ 'dvdvideo_demuxer': {'deps': ['libdvdnav', 'libdvdread'], ++ 'select': ['mpegps_demuxer']}, + 'dvvideo_decoder': {'select': ['dvprofile', 'idctdsp']}, + 'dvvideo_encoder': {'select': ['dvprofile', + 'fdctdsp', @@ -677,6 +1232,7 @@ index 0000000000..d6f65769c7 + 'dxa_decoder': {'deps': ['zlib']}, + 'dxa_demuxer': {'select': ['riffdec']}, + 'dxv_decoder': {'select': ['lzf', 'texturedsp']}, ++ 'dxv_encoder': {'select': ['texturedspenc']}, + 'dxva2': {'deps': ['dxva2api_h', + 'dxva2_configpicturedecode', + 'ole32', @@ -695,6 +1251,10 @@ index 0000000000..d6f65769c7 + 'eq_filter': {'deps': ['gpl']}, + 'erosion_opencl_filter': {'deps': ['opencl']}, + 'error_resilience': {'select': ['me_cmp']}, ++ 'evc_demuxer': {'select': ['evc_frame_merge_bsf', 'evc_parser']}, ++ 'evc_frame_merge_bsf': {'select': ['evcparse']}, ++ 'evc_parser': {'select': ['evcparse']}, ++ 'evcparse': {'select': ['golomb']}, + 'exr_decoder': {'deps': ['zlib']}, + 'exr_encoder': {'deps': ['zlib']}, + 'extract_mvs_example': {'deps': ['avcodec', 'avformat', 'avutil']}, @@ -702,7 +1262,6 @@ index 0000000000..d6f65769c7 + 'faandct': {'deps': ['faan'], 'select': ['fdctdsp']}, + 'faanidct': {'deps': ['faan'], 'select': ['idctdsp']}, + 'fast_64bit': {'if_any': ['aarch64', -+ 'alpha', + 'ia64', + 'mips64', + 'parisc64', @@ -710,21 +1269,36 @@ index 0000000000..d6f65769c7 + 'riscv64', + 'sparc64', + 'x86_64']}, -+ 'fast_clz': {'if_any': ['aarch64', 'alpha', 'avr32', 'mips', 'ppc', 'x86']}, ++ 'fast_clz': {'if_any': ['aarch64', 'mips', 'ppc', 'x86']}, + 'fast_unaligned': {'if_any': ['aarch64', 'ppc', 'x86']}, + 'fbdev_indev': {'deps': ['linux_fb_h']}, + 'fbdev_outdev': {'deps': ['linux_fb_h']}, + 'ffmpeg': {'deps': ['avcodec', 'avfilter', 'avformat', 'threads'], ++ 'select': ['aformat_filter', ++ 'anull_filter', ++ 'atrim_filter', ++ 'crop_filter', ++ 'format_filter', ++ 'hflip_filter', ++ 'null_filter', ++ 'rotate_filter', ++ 'transpose_filter', ++ 'trim_filter', ++ 'vflip_filter'], # MANUAL + 'suggest': ['ole32', 'psapi', 'shell32']}, + 'ffnvcodec': {'deps_any': ['libdl', 'loadlibrary']}, -+ 'ffplay': {'deps': ['avcodec', 'avformat', 'swscale', 'swresample', 'sdl2'], -+ 'select': ['rdft', -+ 'crop_filter', ++ 'ffplay': {'deps': ['avcodec', ++ 'avformat', ++ 'avfilter', ++ 'swscale', ++ 'swresample', ++ 'sdl2'], ++ 'select': ['crop_filter', + 'transpose_filter', + 'hflip_filter', + 'vflip_filter', + 'rotate_filter'], -+ 'suggest': ['shell32']}, ++ 'suggest': ['shell32', 'libplacebo', 'vulkan']}, + 'ffprobe': {'deps': ['avcodec', 'avformat'], 'suggest': ['shell32']}, + 'ffrtmpcrypt_protocol': {'conflict': ['librtmp_protocol'], + 'deps_any': ['gcrypt', 'gmp', 'openssl', 'mbedtls'], @@ -750,7 +1324,7 @@ index 0000000000..d6f65769c7 + 'flite_filter': {'deps': ['libflite', 'threads']}, + 'flv_decoder': {'select': ['h263_decoder']}, + 'flv_encoder': {'select': ['h263_encoder']}, -+ 'flv_muxer': {'select': ['aac_adtstoasc_bsf']}, ++ 'flv_muxer': {'select': ['aac_adtstoasc_bsf', 'iso_writer']}, + 'fma3': {'deps': ['avx']}, + 'fma4': {'deps': ['avx']}, + 'fourxm_decoder': {'select': ['blockdsp', 'bswapdsp']}, @@ -762,7 +1336,10 @@ index 0000000000..d6f65769c7 + 'frei0r_filter': {'deps': ['frei0r']}, + 'frei0r_src_filter': {'deps': ['frei0r']}, + 'fspp_filter': {'deps': ['gpl']}, ++ 'fsync_filter': {'deps': ['avformat']}, + 'ftp_protocol': {'select': ['tcp_protocol']}, ++ 'ftr_decoder': {'select': ['adts_header']}, ++ 'ftr_parser': {'select': ['adts_header', 'mpeg4audio']}, + 'g2m_decoder': {'deps': ['zlib'], + 'select': ['blockdsp', 'idctdsp', 'jpegtables']}, + 'g729_decoder': {'select': ['audiodsp']}, @@ -788,12 +1365,10 @@ index 0000000000..d6f65769c7 + 'h263p_decoder': {'select': ['h263_decoder']}, + 'h263p_encoder': {'select': ['h263_encoder']}, + 'h264_amf_encoder': {'deps': ['amf']}, -+ 'h264_crystalhd_decoder': {'select': ['crystalhd', -+ 'h264_mp4toannexb_bsf', -+ 'h264_parser']}, + 'h264_cuvid_decoder': {'deps': ['cuvid'], 'select': ['h264_mp4toannexb_bsf']}, + 'h264_d3d11va2_hwaccel': {'deps': ['d3d11va'], 'select': ['h264_decoder']}, + 'h264_d3d11va_hwaccel': {'deps': ['d3d11va'], 'select': ['h264_decoder']}, ++ 'h264_d3d12va_hwaccel': {'deps': ['d3d12va'], 'select': ['h264_decoder']}, + 'h264_decoder': {'select': ['cabac', + 'golomb', + 'h264chroma', @@ -808,7 +1383,8 @@ index 0000000000..d6f65769c7 + 'h264_mediacodec_decoder': {'deps': ['mediacodec'], + 'select': ['h264_mp4toannexb_bsf', 'h264_parser']}, + 'h264_mediacodec_encoder': {'deps': ['mediacodec'], -+ 'select': ['h264_metadata']}, ++ 'select': ['extract_extradata_bsf', ++ 'h264_metadata']}, + 'h264_metadata_bsf': {'deps': ['const_nan'], 'select': ['cbs_h264']}, + 'h264_mf_encoder': {'deps': ['mediafoundation']}, + 'h264_mmal_decoder': {'deps': ['mmal']}, @@ -831,7 +1407,10 @@ index 0000000000..d6f65769c7 + 'select': ['atsc_a53', 'videotoolbox_encoder']}, + 'h264_videotoolbox_hwaccel': {'deps': ['videotoolbox'], + 'select': ['h264_decoder']}, ++ 'h264_vulkan_encoder': {'select': ['cbs_h264', 'vulkan_encode']}, ++ 'h264_vulkan_hwaccel': {'deps': ['vulkan'], 'select': ['h264_decoder']}, + 'h264dsp': {'select': ['startcode']}, ++ 'h264parse': {'select': ['golomb']}, + 'hap_decoder': {'select': ['snappy', 'texturedsp']}, + 'hap_encoder': {'deps': ['libsnappy'], 'select': ['texturedspenc']}, + 'hds_muxer': {'select': ['flv_muxer']}, @@ -841,9 +1420,12 @@ index 0000000000..d6f65769c7 + 'select': ['hevc_decoder']}, + 'hevc_d3d11va_hwaccel': {'deps': ['d3d11va', 'dxva_picparams_hevc'], + 'select': ['hevc_decoder']}, ++ 'hevc_d3d12va_encoder': {'select': ['cbs_h265', 'd3d12va_encode']}, ++ 'hevc_d3d12va_hwaccel': {'deps': ['d3d12va', 'dxva_picparams_hevc'], ++ 'select': ['hevc_decoder']}, + 'hevc_decoder': {'select': ['bswapdsp', + 'cabac', -+ 'dovi_rpu', ++ 'dovi_rpudec', + 'golomb', + 'hevcparse', + 'hevc_sei', @@ -853,7 +1435,8 @@ index 0000000000..d6f65769c7 + 'hevc_mediacodec_decoder': {'deps': ['mediacodec'], + 'select': ['hevc_mp4toannexb_bsf', 'hevc_parser']}, + 'hevc_mediacodec_encoder': {'deps': ['mediacodec'], -+ 'select': ['hevc_metadata']}, ++ 'select': ['extract_extradata_bsf', ++ 'hevc_metadata']}, + 'hevc_metadata_bsf': {'select': ['cbs_h265']}, + 'hevc_mf_encoder': {'deps': ['mediafoundation']}, + 'hevc_nvdec_hwaccel': {'deps': ['nvdec'], 'select': ['hevc_decoder']}, @@ -876,15 +1459,19 @@ index 0000000000..d6f65769c7 + 'select': ['atsc_a53', 'videotoolbox_encoder']}, + 'hevc_videotoolbox_hwaccel': {'deps': ['videotoolbox'], + 'select': ['hevc_decoder']}, ++ 'hevc_vulkan_encoder': {'select': ['atsc_a53', 'cbs_h265', 'vulkan_encode']}, ++ 'hevc_vulkan_hwaccel': {'deps': ['vulkan'], 'select': ['hevc_decoder']}, + 'hevcparse': {'select': ['golomb']}, + 'hflip_vulkan_filter': {'deps': ['vulkan', 'spirv_compiler']}, + 'histeq_filter': {'deps': ['gpl']}, -+ 'hls_demuxer': {'select': ['adts_header', ++ 'hls_demuxer': {'select': ['aac_demuxer', ++ 'ac3_demuxer', ++ 'adts_header', + 'ac3_parser', ++ 'eac3_demuxer', + 'mov_demuxer', + 'mpegts_demuxer']}, -+ 'hls_muxer': {'select': ['mov_muxer', 'mpegts_muxer'], -+ 'suggest': ['gcrypt', 'openssl']}, ++ 'hls_muxer': {'select': ['mov_muxer', 'mpegts_muxer']}, + 'hqdn3d_filter': {'deps': ['gpl']}, + 'hstack_qsv_filter': {'deps': ['libmfx'], 'select': ['qsvvpp']}, + 'hstack_vaapi_filter': {'deps': ['vaapi_1']}, @@ -901,10 +1488,16 @@ index 0000000000..d6f65769c7 + 'hwupload_cuda_filter': {'deps': ['ffnvcodec']}, + 'hymt_decoder': {'select': ['huffyuv_decoder']}, + 'i686': {'deps': ['x86']}, ++ 'i8mm': {'deps': ['aarch64', 'neon']}, + 'iac_decoder': {'select': ['imc_decoder']}, ++ 'iamf_demuxer': {'select': ['iamfdec']}, ++ 'iamf_muxer': {'select': ['iamfenc']}, ++ 'iamfdec': {'deps': ['iamf'], 'select': ['iso_media', 'mpeg4audio']}, ++ 'iamfenc': {'deps': ['iamf']}, + 'iccdetect_filter': {'deps': ['lcms2']}, + 'iccgen_filter': {'deps': ['lcms2']}, + 'icecast_protocol': {'select': ['http_protocol']}, ++ 'identity_filter': {'select': ['scene_sad']}, + 'iec61883_indev': {'deps': ['libiec61883'], 'select': ['dv_demuxer']}, + 'ilbc_at_decoder': {'deps': ['audiotoolbox']}, + 'ilbc_at_encoder': {'deps': ['audiotoolbox'], 'select': ['audio_frame_queue']}, @@ -922,6 +1515,7 @@ index 0000000000..d6f65769c7 + 'interplay_video_decoder': {'select': ['hpeldsp']}, + 'intrax8': {'select': ['blockdsp', 'wmv2dsp']}, + 'intrinsics_neon': {'deps': ['neon']}, ++ 'intrinsics_sse2': {'deps': ['sse2']}, + 'ipfs_gateway_protocol': {'select': ['https_protocol']}, + 'ipns_gateway_protocol': {'select': ['https_protocol']}, + 'ipod_muxer': {'select': ['mov_muxer']}, @@ -940,18 +1534,22 @@ index 0000000000..d6f65769c7 + 'lasx': {'deps': ['lsx']}, + 'latm_muxer': {'select': ['aac_adtstoasc_bsf', 'mpeg4audio']}, + 'lavfi_indev': {'deps': ['avfilter']}, ++ 'lcevc_filter': {'deps': ['liblcevc_dec']}, + 'ldbrx': {'deps': ['ppc']}, ++ 'lead_decoder': {'select': ['idctdsp', 'jpegtables']}, + 'lensfun_filter': {'deps': ['liblensfun', 'version3']}, + 'libamqp_protocol': {'deps': ['librabbitmq'], 'select': ['network']}, + 'libaom_av1_decoder': {'deps': ['libaom']}, + 'libaom_av1_encoder': {'deps': ['libaom'], -+ 'select': ['extract_extradata_bsf']}, ++ 'select': ['extract_extradata_bsf', 'dovi_rpuenc']}, + 'libaribb24_decoder': {'deps': ['libaribb24']}, ++ 'libaribcaption_decoder': {'deps': ['libaribcaption']}, + 'libcdio_indev': {'deps': ['libcdio']}, + 'libcelt_decoder': {'deps': ['libcelt']}, + 'libcodec2_decoder': {'deps': ['libcodec2']}, + 'libcodec2_encoder': {'deps': ['libcodec2']}, -+ 'libdav1d_decoder': {'deps': ['libdav1d'], 'select': ['atsc_a53']}, ++ 'libdav1d_decoder': {'deps': ['libdav1d'], ++ 'select': ['atsc_a53', 'dovi_rpudec']}, + 'libdavs2_decoder': {'deps': ['libdavs2'], 'select': ['avs2_parser']}, + 'libdc1394_indev': {'deps': ['libdc1394']}, + 'libfdk_aac_decoder': {'deps': ['libfdk_aac']}, @@ -967,6 +1565,8 @@ index 0000000000..d6f65769c7 + 'libjxl_decoder': {'deps': ['libjxl', 'libjxl_threads']}, + 'libjxl_encoder': {'deps': ['libjxl', 'libjxl_threads']}, + 'libkvazaar_encoder': {'deps': ['libkvazaar']}, ++ 'liblc3_decoder': {'deps': ['liblc3']}, ++ 'liblc3_encoder': {'deps': ['liblc3'], 'select': ['audio_frame_queue']}, + 'libmodplug_demuxer': {'deps': ['libmodplug']}, + 'libmp3lame_encoder': {'deps': ['libmp3lame'], + 'select': ['audio_frame_queue', 'mpegaudioheader']}, @@ -977,7 +1577,6 @@ index 0000000000..d6f65769c7 + 'libopenh264_decoder': {'deps': ['libopenh264'], + 'select': ['h264_mp4toannexb_bsf']}, + 'libopenh264_encoder': {'deps': ['libopenh264']}, -+ 'libopenjpeg_decoder': {'deps': ['libopenjpeg']}, + 'libopenjpeg_encoder': {'deps': ['libopenjpeg']}, + 'libopenmpt_demuxer': {'deps': ['libopenmpt']}, + 'libopus_decoder': {'deps': ['libopus']}, @@ -998,11 +1597,12 @@ index 0000000000..d6f65769c7 + 'libspeex_encoder': {'deps': ['libspeex'], 'select': ['audio_frame_queue']}, + 'libsrt_protocol': {'deps': ['libsrt'], 'select': ['network']}, + 'libssh_protocol': {'deps': ['libssh']}, -+ 'libsvtav1_encoder': {'deps': ['libsvtav1']}, ++ 'libsvtav1_encoder': {'deps': ['libsvtav1'], 'select': ['dovi_rpuenc']}, + 'libtheora_encoder': {'deps': ['libtheora']}, + 'libtls': {'conflict': ['openssl', 'gnutls', 'mbedtls']}, + 'libtwolame_encoder': {'deps': ['libtwolame']}, + 'libuavs3d_decoder': {'deps': ['libuavs3d']}, ++ 'libvmaf_cuda_filter': {'deps': ['libvmaf', 'libvmaf_cuda', 'ffnvcodec']}, + 'libvmaf_filter': {'deps': ['libvmaf']}, + 'libvo_amrwbenc_encoder': {'deps': ['libvo_amrwbenc']}, + 'libvorbis_decoder': {'deps': ['libvorbis']}, @@ -1012,14 +1612,18 @@ index 0000000000..d6f65769c7 + 'libvpx_vp8_encoder': {'deps': ['libvpx']}, + 'libvpx_vp9_decoder': {'deps': ['libvpx']}, + 'libvpx_vp9_encoder': {'deps': ['libvpx']}, ++ 'libvvenc_encoder': {'deps': ['libvvenc']}, + 'libwebp_anim_encoder': {'deps': ['libwebp']}, + 'libwebp_encoder': {'deps': ['libwebp']}, + 'libx262_encoder': {'deps': ['libx262']}, -+ 'libx264_encoder': {'deps': ['libx264'], 'select': ['atsc_a53']}, ++ 'libx264_encoder': {'deps': ['libx264'], 'select': ['atsc_a53', 'golomb']}, + 'libx264rgb_encoder': {'deps': ['libx264'], 'select': ['libx264_encoder']}, -+ 'libx265_encoder': {'deps': ['libx265'], 'select': ['atsc_a53']}, ++ 'libx265_encoder': {'deps': ['libx265'], ++ 'select': ['atsc_a53', 'dovi_rpuenc']}, + 'libxavs2_encoder': {'deps': ['libxavs2']}, + 'libxavs_encoder': {'deps': ['libxavs']}, ++ 'libxevd_decoder': {'deps': ['libxevd']}, ++ 'libxeve_encoder': {'deps': ['libxeve']}, + 'libxvid_encoder': {'deps': ['libxvid']}, + 'libzmq_protocol': {'deps': ['libzmq'], 'select': ['network']}, + 'libzvbi_teletext_decoder': {'deps': ['libzvbi']}, @@ -1035,16 +1639,17 @@ index 0000000000..d6f65769c7 + 'manpages': {'deps': ['perl', 'pod2man']}, + 'matroska_audio_muxer': {'select': ['matroska_muxer']}, + 'matroska_demuxer': {'select': ['riffdec'], 'suggest': ['bzlib', 'zlib']}, -+ 'matroska_muxer': {'select': ['mpeg4audio', ++ 'matroska_muxer': {'select': ['iso_writer', ++ 'mpeg4audio', + 'riffenc', + 'aac_adtstoasc_bsf', + 'pgs_frame_merge_bsf', + 'vp9_superframe_bsf']}, + 'mcdeint_filter': {'deps': ['avcodec', 'gpl']}, -+ 'mdct': {'select': ['fft']}, + 'mdec_decoder': {'select': ['blockdsp', 'bswapdsp', 'idctdsp']}, + 'me_cmp': {'select': ['idctdsp']}, + 'media100_decoder': {'select': ['media100_to_mjpegb_bsf', 'mjpegb_decoder']}, ++ 'mediacodec': {'deps': ['android', 'mediandk']}, + 'mediafoundation': {'deps': ['mftransform_h', 'mfcreatealignedmemorybuffer']}, + 'metadata_filter': {'deps': ['avformat']}, + 'metasound_decoder': {'select': ['lsp', 'sinewin']}, @@ -1086,13 +1691,16 @@ index 0000000000..d6f65769c7 + 'mmxext': {'deps': ['mmx']}, + 'mobiclip_decoder': {'select': ['bswapdsp', 'golomb']}, + 'motionpixels_decoder': {'select': ['bswapdsp']}, -+ 'mov_demuxer': {'select': ['iso_media', 'riffdec'], 'suggest': ['zlib']}, ++ 'mov_demuxer': {'select': ['iso_media', 'riffdec'], ++ 'suggest': ['iamfdec', 'zlib']}, + 'mov_muxer': {'select': ['iso_media', ++ 'iso_writer', + 'riffenc', + 'rtpenc_chain', + 'vp9_superframe_bsf', + 'aac_adtstoasc_bsf', -+ 'ac3_parser']}, ++ 'ac3_parser'], ++ 'suggest': ['iamfenc']}, + 'movie_filter': {'deps': ['avcodec', 'avformat']}, + 'mp1_at_decoder': {'deps': ['audiotoolbox'], 'select': ['mpegaudioheader']}, + 'mp1_decoder': {'select': ['mpegaudio']}, @@ -1103,6 +1711,8 @@ index 0000000000..d6f65769c7 + 'mp3_at_decoder': {'deps': ['audiotoolbox'], 'select': ['mpegaudioheader']}, + 'mp3_decoder': {'select': ['mpegaudio']}, + 'mp3_demuxer': {'select': ['mpegaudio_parser']}, ++ 'mp3_mediacodec_decoder': {'deps': ['mediacodec'], ++ 'select': ['mpegaudioheader']}, + 'mp3_mf_encoder': {'deps': ['mediafoundation']}, + 'mp3_muxer': {'select': ['mpegaudioheader']}, + 'mp3adu_decoder': {'select': ['mpegaudio']}, @@ -1122,12 +1732,13 @@ index 0000000000..d6f65769c7 + 'select': ['mpeg1video_decoder']}, + 'mpeg1video_decoder': {'select': ['mpegvideodec']}, + 'mpeg1video_encoder': {'select': ['mpegvideoenc']}, -+ 'mpeg2_crystalhd_decoder': {'select': ['crystalhd']}, + 'mpeg2_cuvid_decoder': {'deps': ['cuvid']}, + 'mpeg2_d3d11va2_hwaccel': {'deps': ['d3d11va'], + 'select': ['mpeg2video_decoder']}, + 'mpeg2_d3d11va_hwaccel': {'deps': ['d3d11va'], + 'select': ['mpeg2video_decoder']}, ++ 'mpeg2_d3d12va_hwaccel': {'deps': ['d3d12va'], ++ 'select': ['mpeg2video_decoder']}, + 'mpeg2_dxva2_hwaccel': {'deps': ['dxva2'], 'select': ['mpeg2video_decoder']}, + 'mpeg2_mediacodec_decoder': {'deps': ['mediacodec']}, + 'mpeg2_metadata_bsf': {'select': ['cbs_mpeg2']}, @@ -1143,11 +1754,12 @@ index 0000000000..d6f65769c7 + 'select': ['mpeg2video_decoder']}, + 'mpeg2video_decoder': {'select': ['mpegvideodec']}, + 'mpeg2video_encoder': {'select': ['mpegvideoenc']}, -+ 'mpeg4_crystalhd_decoder': {'select': ['crystalhd']}, + 'mpeg4_cuvid_decoder': {'deps': ['cuvid']}, -+ 'mpeg4_decoder': {'select': ['h263_decoder', 'mpeg4video_parser']}, ++ 'mpeg4_decoder': {'select': ['h263_decoder']}, + 'mpeg4_encoder': {'select': ['h263_encoder', 'qpeldsp']}, + 'mpeg4_mediacodec_decoder': {'deps': ['mediacodec']}, ++ 'mpeg4_mediacodec_encoder': {'deps': ['mediacodec'], ++ 'select': ['extract_extradata_bsf']}, + 'mpeg4_mmal_decoder': {'deps': ['mmal']}, + 'mpeg4_nvdec_hwaccel': {'deps': ['nvdec'], 'select': ['mpeg4_decoder']}, + 'mpeg4_omx_encoder': {'deps': ['omx']}, @@ -1161,13 +1773,13 @@ index 0000000000..d6f65769c7 + 'mpeg_er': {'select': ['error_resilience']}, + 'mpegaudio': {'select': ['mpegaudiodsp', 'mpegaudioheader']}, + 'mpegaudio_parser': {'select': ['mpegaudioheader']}, -+ 'mpegaudiodsp': {'select': ['dct']}, + 'mpegts_demuxer': {'select': ['iso_media']}, + 'mpegts_muxer': {'select': ['ac3_parser', + 'adts_muxer', + 'latm_muxer', + 'h264_mp4toannexb_bsf', -+ 'hevc_mp4toannexb_bsf']}, ++ 'hevc_mp4toannexb_bsf', ++ 'vvc_mp4toannexb_bsf']}, + 'mpegtsraw_demuxer': {'select': ['mpegts_demuxer']}, + 'mpegvideo': {'select': ['blockdsp', 'hpeldsp', 'idctdsp', 'videodsp']}, + 'mpegvideo_decoder': {'select': ['mpegvideodec']}, @@ -1181,7 +1793,6 @@ index 0000000000..d6f65769c7 + 'msa': {'deps': ['mipsfpu']}, + 'msa1_decoder': {'select': ['mss34dsp']}, + 'mscc_decoder': {'select': ['inflate_wrapper']}, -+ 'msmpeg4_crystalhd_decoder': {'select': ['crystalhd']}, + 'msmpeg4dec': {'select': ['h263_decoder']}, + 'msmpeg4enc': {'select': ['h263_encoder']}, + 'msmpeg4v1_decoder': {'select': ['msmpeg4dec']}, @@ -1196,7 +1807,7 @@ index 0000000000..d6f65769c7 + 'mvha_decoder': {'select': ['inflate_wrapper', 'llviddsp']}, + 'mwsc_decoder': {'select': ['inflate_wrapper']}, + 'mxf_d10_muxer': {'select': ['mxf_muxer']}, -+ 'mxf_muxer': {'select': ['pcm_rechunk_bsf']}, ++ 'mxf_muxer': {'select': ['iso_writer', 'pcm_rechunk_bsf', 'rangecoder']}, + 'mxf_opatom_muxer': {'select': ['mxf_muxer']}, + 'mxpeg_decoder': {'select': ['mjpeg_decoder']}, + 'negate_filter': {'deps': ['lut_filter']}, @@ -1204,6 +1815,7 @@ index 0000000000..d6f65769c7 + 'nellymoser_encoder': {'select': ['audio_frame_queue', 'sinewin']}, + 'neon': {'deps_any': ['aarch64', 'arm']}, + 'nlmeans_opencl_filter': {'deps': ['opencl']}, ++ 'nlmeans_vulkan_filter': {'deps': ['vulkan', 'spirv_compiler']}, + 'nnedi_filter': {'deps': ['gpl']}, + 'notchlc_decoder': {'select': ['lzf']}, + 'nut_muxer': {'select': ['riffenc']}, @@ -1236,6 +1848,7 @@ index 0000000000..d6f65769c7 + 'overlay_vulkan_filter': {'deps': ['vulkan', 'spirv_compiler']}, + 'owdenoise_filter': {'deps': ['gpl']}, + 'pad_opencl_filter': {'deps': ['opencl']}, ++ 'pad_vaapi_filter': {'deps': ['vaapi_1']}, + 'pan_filter': {'deps': ['swresample']}, + 'pcm_alaw_at_decoder': {'deps': ['audiotoolbox']}, + 'pcm_alaw_at_encoder': {'deps': ['audiotoolbox'], @@ -1243,14 +1856,14 @@ index 0000000000..d6f65769c7 + 'pcm_mulaw_at_decoder': {'deps': ['audiotoolbox']}, + 'pcm_mulaw_at_encoder': {'deps': ['audiotoolbox'], + 'select': ['audio_frame_queue']}, ++ 'pdv_decoder': {'select': ['inflate_wrapper']}, + 'perspective_filter': {'deps': ['gpl']}, + 'phase_filter': {'deps': ['gpl']}, + 'pixfmts_super2xsai_test': {'deps': ['super2xsai_filter']}, + 'png_decoder': {'select': ['inflate_wrapper']}, + 'png_encoder': {'select': ['deflate_wrapper', 'llvidencdsp']}, + 'podpages': {'deps': ['perl']}, -+ # See configure line 7531 -- requirement is a sham -+ 'postproc': {'deps': ['avutil'], 'suggest': ['libm', 'stdatomic']}, # MANUAL ++ 'postproc': {'deps': ['avutil', 'gpl'], 'suggest': ['libm', 'stdatomic']}, + 'power8': {'deps': ['vsx']}, + 'pp7_filter': {'deps': ['gpl']}, + 'pp_filter': {'deps': ['gpl', 'postproc']}, @@ -1274,6 +1887,8 @@ index 0000000000..d6f65769c7 + 'qdm2_at_decoder': {'deps': ['audiotoolbox']}, + 'qdm2_decoder': {'select': ['mpegaudiodsp']}, + 'qdmc_at_decoder': {'deps': ['audiotoolbox']}, ++ 'qrencode_filter': {'deps': ['libqrencode']}, ++ 'qrencodesrc_filter': {'deps': ['libqrencode']}, + 'qsv': {'deps': ['libmfx']}, + 'qsv_decode_example': {'deps': ['avcodec', + 'avutil', @@ -1286,12 +1901,12 @@ index 0000000000..d6f65769c7 + 'qsvdec': {'select': ['qsv']}, + 'qsvenc': {'select': ['qsv']}, + 'qsvvpp': {'select': ['qsv']}, ++ 'quirc_filter': {'deps': ['libquirc']}, + 'ra_144_decoder': {'select': ['audiodsp']}, + 'ra_144_encoder': {'select': ['audio_frame_queue', 'lpc', 'audiodsp']}, + 'ralf_decoder': {'select': ['golomb']}, + 'rasc_decoder': {'select': ['inflate_wrapper']}, + 'rawvideo_decoder': {'select': ['bswapdsp']}, -+ 'rdft': {'select': ['fft']}, + 'remap_opencl_filter': {'deps': ['opencl']}, + 'removelogo_filter': {'deps': ['avcodec', 'avformat', 'swscale']}, + 'remux_example': {'deps': ['avcodec', 'avformat', 'avutil']}, @@ -1313,6 +1928,7 @@ index 0000000000..d6f65769c7 + 'suggest': ['zlib']}, + 'rtp_demuxer': {'select': ['sdp_demuxer']}, + 'rtp_mpegts_muxer': {'select': ['mpegts_muxer', 'rtp_muxer']}, ++ 'rtp_muxer': {'select': ['iso_writer']}, + 'rtp_protocol': {'select': ['udp_protocol']}, + 'rtpdec': {'select': ['asf_demuxer', + 'mov_demuxer', @@ -1325,7 +1941,9 @@ index 0000000000..d6f65769c7 + 'http_protocol', + 'rtp_protocol', + 'rtpenc_chain']}, ++ 'rtv1_decoder': {'select': ['texturedsp']}, + 'rubberband_filter': {'deps': ['librubberband']}, ++ 'rv': {'deps': ['riscv']}, + 'rv10_decoder': {'select': ['h263_decoder']}, + 'rv10_encoder': {'select': ['h263_encoder']}, + 'rv20_decoder': {'select': ['h263_decoder']}, @@ -1340,7 +1958,8 @@ index 0000000000..d6f65769c7 + 'h264qpel', + 'mpegvideodec', + 'rv34dsp']}, -+ 'rvv': {'deps': ['riscv']}, ++ 'rv_zvbb': {'deps': ['rvv']}, ++ 'rvv': {'deps': ['rv']}, + 'sab_filter': {'deps': ['gpl', 'swscale']}, + 'sap_demuxer': {'select': ['sdp_demuxer']}, + 'sap_muxer': {'select': ['rtp_muxer', 'rtp_protocol', 'rtpenc_chain']}, @@ -1353,6 +1972,7 @@ index 0000000000..d6f65769c7 + 'scale_qsv_filter': {'deps': ['libmfx'], 'select': ['qsvvpp']}, + 'scale_vaapi_filter': {'deps': ['vaapi']}, + 'scale_video_example': {'deps': ['avutil', 'swscale']}, ++ 'scale_vt_filter': {'deps': ['videotoolbox', 'vtpixeltransfersessioncreate']}, + 'scale_vulkan_filter': {'deps': ['vulkan', 'spirv_compiler']}, + 'scdet_filter': {'select': ['scene_sad']}, + 'schannel': {'conflict': ['openssl', 'gnutls', 'libtls', 'mbedtls']}, @@ -1381,11 +2001,7 @@ index 0000000000..d6f65769c7 + 'smvjpeg_decoder': {'select': ['mjpeg_decoder']}, + 'sndio_indev': {'deps': ['sndio']}, + 'sndio_outdev': {'deps': ['sndio']}, -+ 'snow_decoder': {'select': ['dwt', -+ 'h264qpel', -+ 'hpeldsp', -+ 'rangecoder', -+ 'videodsp']}, ++ 'snow_decoder': {'select': ['dwt', 'h264qpel', 'rangecoder', 'videodsp']}, + 'snow_encoder': {'select': ['dwt', + 'h264qpel', + 'hpeldsp', @@ -1404,11 +2020,7 @@ index 0000000000..d6f65769c7 + 'speedhq_decoder': {'select': ['blockdsp', 'idctdsp']}, + 'speedhq_encoder': {'select': ['mpegvideoenc']}, + 'spp_filter': {'deps': ['gpl', 'avcodec'], -+ 'select': ['fft', -+ 'idctdsp', -+ 'fdctdsp', -+ 'me_cmp', -+ 'pixblockdsp']}, ++ 'select': ['idctdsp', 'fdctdsp', 'me_cmp', 'pixblockdsp']}, + 'spx_muxer': {'select': ['ogg_muxer']}, + 'sr_filter': {'deps': ['avformat', 'swscale'], 'select': ['dnn']}, + 'srgc_decoder': {'select': ['inflate_wrapper']}, @@ -1445,6 +2057,7 @@ index 0000000000..d6f65769c7 + 'tgp_muxer': {'select': ['mov_muxer']}, + 'theora_decoder': {'select': ['vp3_decoder']}, + 'thp_decoder': {'select': ['mjpeg_decoder']}, ++ 'threads': {'if_any': ['pthreads', 'os2threads', 'w32threads']}, # MANUAL + 'thumbnail_cuda_filter': {'deps': ['ffnvcodec'], + 'deps_any': ['cuda_nvcc', 'cuda_llvm']}, + 'tiff_decoder': {'select': ['mjpeg_decoder'], 'suggest': ['zlib', 'lzma']}, @@ -1463,13 +2076,15 @@ index 0000000000..d6f65769c7 + 'tonemap_opencl_filter': {'deps': ['opencl', 'const_nan']}, + 'tonemap_vaapi_filter': {'deps': ['vaapi', + 'vaprocfilterparameterbufferhdrtonemapping']}, -+ 'trace_headers_bsf': {'select': ['cbs']}, ++ 'trace_headers_bsf': {'select': ['cbs', 'cbs_vp8']}, + 'transcode_aac_example': {'deps': ['avcodec', 'avformat', 'swresample']}, + 'transcode_example': {'deps': ['avfilter', 'avcodec', 'avformat', 'avutil']}, + 'transpose_npp_filter': {'deps': ['ffnvcodec', 'libnpp']}, + 'transpose_opencl_filter': {'deps': ['opencl']}, + 'transpose_vaapi_filter': {'deps': ['vaapi', + 'vaprocpipelinecaps_rotation_flags']}, ++ 'transpose_vt_filter': {'deps': ['videotoolbox', ++ 'vtpixelrotationsessioncreate']}, + 'transpose_vulkan_filter': {'deps': ['vulkan', 'spirv_compiler']}, + 'truehd_decoder': {'select': ['mlp_parser']}, + 'truehd_demuxer': {'select': ['mlp_parser']}, @@ -1506,10 +2121,10 @@ index 0000000000..d6f65769c7 + 'vble_decoder': {'select': ['llviddsp']}, + 'vbn_decoder': {'select': ['texturedsp']}, + 'vbn_encoder': {'select': ['texturedspenc']}, -+ 'vc1_crystalhd_decoder': {'select': ['crystalhd']}, + 'vc1_cuvid_decoder': {'deps': ['cuvid']}, + 'vc1_d3d11va2_hwaccel': {'deps': ['d3d11va'], 'select': ['vc1_decoder']}, + 'vc1_d3d11va_hwaccel': {'deps': ['d3d11va'], 'select': ['vc1_decoder']}, ++ 'vc1_d3d12va_hwaccel': {'deps': ['d3d12va'], 'select': ['vc1_decoder']}, + 'vc1_decoder': {'select': ['blockdsp', + 'h264qpel', + 'intrax8', @@ -1527,7 +2142,7 @@ index 0000000000..d6f65769c7 + 'vc1dsp': {'select': ['h264chroma', 'qpeldsp', 'startcode']}, + 'vc1image_decoder': {'select': ['vc1_decoder']}, + 'vflip_vulkan_filter': {'deps': ['vulkan', 'spirv_compiler']}, -+ 'vfp': {'deps_any': ['aarch64', 'arm']}, ++ 'vfp': {'deps': ['arm']}, + 'vfpv3': {'deps': ['vfp']}, + 'vfwcap_indev': {'deps': ['vfw32', 'vfwcap_defines']}, + 'videotoolbox': {'deps': ['corefoundation', 'coremedia', 'corevideo'], @@ -1537,6 +2152,7 @@ index 0000000000..d6f65769c7 + 'videotoolbox_hwaccel': {'deps': ['videotoolbox', 'pthreads']}, + 'vidstabdetect_filter': {'deps': ['libvidstab']}, + 'vidstabtransform_filter': {'deps': ['libvidstab']}, ++ 'vmix_decoder': {'select': ['idctdsp']}, + 'vobsub_demuxer': {'select': ['mpegps_demuxer']}, + 'vorbis_encoder': {'select': ['audio_frame_queue']}, + 'vp3_decoder': {'select': ['hpeldsp', 'vp3dsp', 'videodsp']}, @@ -1558,6 +2174,7 @@ index 0000000000..d6f65769c7 + 'vp8_cuvid_decoder': {'deps': ['cuvid']}, + 'vp8_decoder': {'select': ['h264pred', 'videodsp', 'vp8dsp']}, + 'vp8_mediacodec_decoder': {'deps': ['mediacodec']}, ++ 'vp8_mediacodec_encoder': {'deps': ['mediacodec']}, + 'vp8_nvdec_hwaccel': {'deps': ['nvdec'], 'select': ['vp8_decoder']}, + 'vp8_qsv_decoder': {'select': ['qsvdec']}, + 'vp8_rkmpp_decoder': {'deps': ['rkmpp']}, @@ -1571,12 +2188,15 @@ index 0000000000..d6f65769c7 + 'select': ['vp9_decoder']}, + 'vp9_d3d11va_hwaccel': {'deps': ['d3d11va', 'dxva_picparams_vp9'], + 'select': ['vp9_decoder']}, ++ 'vp9_d3d12va_hwaccel': {'deps': ['d3d12va', 'dxva_picparams_vp9'], ++ 'select': ['vp9_decoder']}, + 'vp9_decoder': {'select': ['videodsp', + 'vp9_parser', + 'vp9_superframe_split_bsf']}, + 'vp9_dxva2_hwaccel': {'deps': ['dxva2', 'dxva_picparams_vp9'], + 'select': ['vp9_decoder']}, + 'vp9_mediacodec_decoder': {'deps': ['mediacodec']}, ++ 'vp9_mediacodec_encoder': {'deps': ['mediacodec']}, + 'vp9_metadata_bsf': {'select': ['cbs_vp9']}, + 'vp9_nvdec_hwaccel': {'deps': ['nvdec'], 'select': ['vp9_decoder']}, + 'vp9_qsv_decoder': {'select': ['qsvdec']}, @@ -1596,7 +2216,12 @@ index 0000000000..d6f65769c7 + 'vstack_qsv_filter': {'deps': ['libmfx'], 'select': ['qsvvpp']}, + 'vstack_vaapi_filter': {'deps': ['vaapi_1']}, + 'vsx': {'deps': ['altivec']}, -+ 'vulkan': {'deps_any': ['libdl', 'loadlibrary']}, ++ 'vulkan': {'deps': ['threads'], 'deps_any': ['libdl', 'loadlibrary']}, ++ 'vulkan_encode': {'deps': ['vulkan']}, ++ 'vvc_decoder': {'select': ['cabac', 'cbs_h266', 'golomb', 'videodsp']}, ++ 'vvc_metadata_bsf': {'select': ['cbs_h266']}, ++ 'vvc_parser': {'select': ['cbs_h266']}, ++ 'vvc_qsv_decoder': {'select': ['vvc_mp4toannexb_bsf', 'qsvdec']}, + 'w32threads': {'deps': ['atomics_native']}, + 'w64_demuxer': {'select': ['wav_demuxer']}, + 'w64_muxer': {'select': ['wav_muxer']}, @@ -1612,7 +2237,7 @@ index 0000000000..d6f65769c7 + 'wmav1_encoder': {'select': ['sinewin', 'wma_freqs']}, + 'wmav2_decoder': {'select': ['sinewin', 'wma_freqs']}, + 'wmav2_encoder': {'select': ['sinewin', 'wma_freqs']}, -+ 'wmavoice_decoder': {'select': ['lsp', 'rdft', 'dct', 'sinewin']}, ++ 'wmavoice_decoder': {'select': ['lsp', 'sinewin']}, + 'wmv1_decoder': {'select': ['msmpeg4dec']}, + 'wmv1_encoder': {'select': ['msmpeg4enc']}, + 'wmv2_decoder': {'select': ['blockdsp', @@ -1623,9 +2248,10 @@ index 0000000000..d6f65769c7 + 'videodsp', + 'wmv2dsp']}, + 'wmv2_encoder': {'select': ['msmpeg4enc', 'wmv2dsp']}, -+ 'wmv3_crystalhd_decoder': {'select': ['crystalhd']}, ++ 'wmv2dsp': {'select': ['qpeldsp']}, + 'wmv3_d3d11va2_hwaccel': {'select': ['vc1_d3d11va2_hwaccel']}, + 'wmv3_d3d11va_hwaccel': {'select': ['vc1_d3d11va_hwaccel']}, ++ 'wmv3_d3d12va_hwaccel': {'select': ['vc1_d3d12va_hwaccel']}, + 'wmv3_decoder': {'select': ['vc1_decoder']}, + 'wmv3_dxva2_hwaccel': {'select': ['vc1_dxva2_hwaccel']}, + 'wmv3_nvdec_hwaccel': {'select': ['vc1_nvdec_hwaccel']}, @@ -1638,6 +2264,7 @@ index 0000000000..d6f65769c7 + 'xcbgrab_indev': {'deps': ['libxcb'], + 'suggest': ['libxcb_shm', 'libxcb_shape', 'libxcb_xfixes']}, + 'xfade_opencl_filter': {'deps': ['opencl']}, ++ 'xfade_vulkan_filter': {'deps': ['vulkan', 'spirv_compiler']}, + 'xma1_decoder': {'select': ['wmapro_decoder']}, + 'xma2_decoder': {'select': ['wmapro_decoder']}, + 'xmv_demuxer': {'select': ['riffdec']}, @@ -1658,14 +2285,9 @@ index 0000000000..d6f65769c7 + 'zmq_filter': {'deps': ['libzmq']}, + 'zoompan_filter': {'deps': ['swscale']}, + 'zscale_filter': {'deps': ['libzimg', 'const_nan']}} -+ -+# Manually added -+ -+GRAPH['threads'] = {'if_any': ['pthreads', 'os2threads', 'w32threads']} -+GRAPH['atomics_native'] = {'if_any': ['atomics_gcc', 'atomics_suncc', 'atomics_win32']} diff --git a/depresolver.py b/depresolver.py new file mode 100644 -index 0000000000..7b4234010e +index 00000000..7b423401 --- /dev/null +++ b/depresolver.py @@ -0,0 +1,198 @@ @@ -1867,9 +2489,75 @@ index 0000000000..7b4234010e + if enabled(conf, comp): + deps.update({comp: None}) + print ('%s=%s' % (comp, ','.join(deps))) +diff --git a/doc/.gitignore b/doc/.gitignore +new file mode 100644 +index 00000000..7628cecb +--- /dev/null ++++ b/doc/.gitignore +@@ -0,0 +1,9 @@ ++/*.1 ++/*.3 ++/*.html ++/*.pod ++/config.texi ++/avoptions_codec.texi ++/avoptions_format.texi ++/fate.txt ++/print_options +diff --git a/doc/doxy/.gitignore b/doc/doxy/.gitignore +new file mode 100644 +index 00000000..ac7af2e8 +--- /dev/null ++++ b/doc/doxy/.gitignore +@@ -0,0 +1 @@ ++/html/ +diff --git a/doc/examples/.gitignore b/doc/examples/.gitignore +new file mode 100644 +index 00000000..d787afdd +--- /dev/null ++++ b/doc/examples/.gitignore +@@ -0,0 +1,25 @@ ++/avio_list_dir ++/avio_reading ++/decode_audio ++/decode_video ++/demuxing_decoding ++/encode_audio ++/encode_video ++/extract_mvs ++/filter_audio ++/filtering_audio ++/filtering_video ++/http_multiclient ++/hw_decode ++/metadata ++/muxing ++/pc-uninstalled ++/qsvdec ++/remuxing ++/resampling_audio ++/scaling_video ++/transcode_aac ++/transcoding ++/vaapi_encode ++/vaapi_transcode ++/qsv_transcode +diff --git a/ffbuild/.gitignore b/ffbuild/.gitignore +new file mode 100644 +index 00000000..adaf399e +--- /dev/null ++++ b/ffbuild/.gitignore +@@ -0,0 +1,7 @@ ++/.config ++/bin2c ++/bin2c.exe ++/config.fate ++/config.log ++/config.mak ++/config.sh diff --git a/ffbuild/bin2c.py b/ffbuild/bin2c.py new file mode 100644 -index 0000000000..de2840090a +index 00000000..de284009 --- /dev/null +++ b/ffbuild/bin2c.py @@ -0,0 +1,39 @@ @@ -1914,10 +2602,10 @@ index 0000000000..de2840090a + shutil.copyfileobj(tmp, output.open('w', encoding='utf-8'), -1) diff --git a/fftools/meson.build b/fftools/meson.build new file mode 100644 -index 0000000000..200baccb5c +index 00000000..2ca4b206 --- /dev/null +++ b/fftools/meson.build -@@ -0,0 +1,72 @@ +@@ -0,0 +1,77 @@ +#### --- GENERATED --- #### + +fftools_sources = files( @@ -1926,7 +2614,8 @@ index 0000000000..200baccb5c +) + +fftools_optional_sources = { -+ # MANUAL 'ffmpeg ' : files('ffmpeg_demux.c','ffmpeg_filter.c','ffmpeg_hw.c','ffmpeg_mux.c','ffmpeg_mux_init.c','ffmpeg_opt.c','objpool.c','sync_queue.c','thread_queue.c'), ++ # MANUAL 'ffmpeg ' : files('ffmpeg_dec.c','ffmpeg_demux.c','ffmpeg_enc.c','ffmpeg_filter.c','ffmpeg_hw.c','ffmpeg_mux.c','ffmpeg_mux_init.c','ffmpeg_opt.c','ffmpeg_sched.c','objpool.c','sync_queue.c','thread_queue.c'), ++ # MANUAL 'ffplay ' : files('ffplay_renderer.c'), +} + +fftools_x86asm_optional_sources = { @@ -1962,12 +2651,15 @@ index 0000000000..200baccb5c +#### --- END GENERATED --- #### + +ffmpeg_sources = files( ++ 'ffmpeg_dec.c', + 'ffmpeg_demux.c', ++ 'ffmpeg_enc.c', + 'ffmpeg_filter.c', + 'ffmpeg_hw.c', + 'ffmpeg_mux.c', + 'ffmpeg_mux_init.c', + 'ffmpeg_opt.c', ++ 'ffmpeg_sched.c', + 'objpool.c', + 'sync_queue.c', + 'thread_queue.c', @@ -1975,7 +2667,8 @@ index 0000000000..200baccb5c +) + +ffplay_sources = files( -+ 'ffplay.c' ++ 'ffplay.c', ++ 'ffplay_renderer.c', +) + +ffprobe_sources = files( @@ -1992,10 +2685,10 @@ index 0000000000..200baccb5c +endif diff --git a/find_things.py b/find_things.py new file mode 100755 -index 0000000000..2782db2ae3 +index 00000000..b94ea942 --- /dev/null +++ b/find_things.py -@@ -0,0 +1,97 @@ +@@ -0,0 +1,101 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2018 Mathieu Duponchelle @@ -2025,12 +2718,16 @@ index 0000000000..2782db2ae3 + for line in infile: + if not full: + matches = re.match( -+ r'^extern\s+(?:const\s+)?AVFilter\s*ff_[^_]*_(.*);', line.strip()) ++ r'^extern\s+(?:const\s+)?AVFilter\s*ff_([^_]+)_(.*);', line.strip()) + else: + matches = re.match(r'extern\s+(?:const\s+)?AVFilter\s*ff_(.*_.*);', line.strip()) -+ if (matches): -+ if not args.full: -+ things.append(('%s_filter' % matches.group(1).strip())) ++ if matches: ++ if not full: ++ if re.match(r'[av](?:src|sink)', matches.group(1)) \ ++ and matches.group(2).endswith('buffer'): ++ things.append(f'{matches.group(1).strip()}_{matches.group(2).strip()}_filter') ++ else: ++ things.append(('%s_filter' % matches.group(2).strip())) + else: + things.append(matches.group(1).strip()) + @@ -2095,10 +2792,10 @@ index 0000000000..2782db2ae3 + print('\n'.join(things)) diff --git a/find_things_extern.py b/find_things_extern.py new file mode 100755 -index 0000000000..cf2d0c47ec +index 00000000..dbfd9446 --- /dev/null +++ b/find_things_extern.py -@@ -0,0 +1,125 @@ +@@ -0,0 +1,126 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2018 Mathieu Duponchelle @@ -2124,17 +2821,18 @@ index 0000000000..cf2d0c47ec + +EXTERN_THINGS = [ + ['FFOutputFormat', 'muxer', 'libavformat/allformats.c', 'muxer_list'], -+ ['AVInputFormat', 'demuxer', 'libavformat/allformats.c', 'demuxer_list'], ++ ['FFInputFormat', 'demuxer', 'libavformat/allformats.c', 'demuxer_list'], + ['FFCodec', 'encoder', 'libavcodec/allcodecs.c', 'encoder_list'], + ['FFCodec', 'decoder', 'libavcodec/allcodecs.c', 'decoder_list'], + ['AVCodecParser', 'parser', 'libavcodec/parsers.c', 'parser_list'], + ['FFBitStreamFilter', 'bsf', 'libavcodec/bitstream_filters.c', 'bsf_list'], -+ ['AVHWAccel', 'hwaccel', 'libavcodec/hwaccels.h', 'hwaccel_list'], ++ ['FFHWAccel', 'hwaccel', 'libavcodec/hwaccels.h', 'hwaccel_list'], + ['URLProtocol', 'protocol', 'libavformat/protocols.c', 'protocol_list'], + ['FFOutputFormat', 'muxer', 'libavdevice/alldevices.c', 'outdev_list', 'outdev'], -+ ['AVInputFormat', 'demuxer', 'libavdevice/alldevices.c', 'indev_list', 'indev'], ++ ['FFInputFormat', 'demuxer', 'libavdevice/alldevices.c', 'indev_list', 'indev'], +] + ++ +def list_components(infile, type, suffix, thing_suffix): + things = [] + @@ -2224,16 +2922,72 @@ index 0000000000..cf2d0c47ec + things += list_components(infile, args.type, args.suffix, args.thing_suffix) + + print('\n'.join(things)) +diff --git a/libavcodec/.gitignore b/libavcodec/.gitignore +new file mode 100644 +index 00000000..28814f72 +--- /dev/null ++++ b/libavcodec/.gitignore +@@ -0,0 +1,6 @@ ++/*_tablegen ++/*_tables.c ++/*_tables.h ++/bsf_list.c ++/codec_list.c ++/parser_list.c +diff --git a/libavcodec/aac/meson.build b/libavcodec/aac/meson.build +new file mode 100644 +index 00000000..cfd3b07f +--- /dev/null ++++ b/libavcodec/aac/meson.build +@@ -0,0 +1,35 @@ ++libavcodec_aac_optional_sources = { ++ 'aac_decoder' : files('aacdec.c','aacdec_tab.c','aacdec_float.c','aacdec_usac.c','aacdec_ac.c','aacdec_lpd.c'), ++ 'aac_fixed_decoder' : files('aacdec.c','aacdec_tab.c','aacdec_fixed.c'), ++} ++ ++libavcodec_aac_x86asm_optional_sources = { ++} ++ ++libavcodec_aac_armv5te_optional_sources = { ++} ++ ++libavcodec_aac_armv6_optional_sources = { ++} ++ ++libavcodec_aac_armv8_optional_sources = { ++} ++ ++libavcodec_aac_neon_optional_sources = { ++} ++ ++libavcodec_aac_vfp_optional_sources = { ++} ++ ++libavcodec_aac_mmx_optional_sources = { ++} ++ ++libavcodec_aac_shlib_optional_sources = { ++} ++ ++libavcodec_aac_slib_optional_sources = { ++} ++ ++libavcodec_aac_optional_tests = { ++} ++ diff --git a/libavcodec/aarch64/meson.build b/libavcodec/aarch64/meson.build new file mode 100644 -index 0000000000..e154503df6 +index 00000000..0d4c59ab --- /dev/null +++ b/libavcodec/aarch64/meson.build -@@ -0,0 +1,74 @@ +@@ -0,0 +1,96 @@ ++#### --- GENERATED --- #### ++ +libavcodec_aarch64_optional_sources = { + 'aac_decoder' : files('aacpsdsp_init_aarch64.c','sbrdsp_init_aarch64.c'), ++ 'ac3dsp' : files('ac3dsp_init_aarch64.c'), + 'dca_decoder' : files('synth_filter_init.c'), -+ 'fft' : files('fft_init_aarch64.c'), ++ 'fdctdsp' : files('fdctdsp_init_aarch64.c'), + 'fmtconvert' : files('fmtconvert_init.c'), + 'h264chroma' : files('h264chroma_init_aarch64.c'), + 'h264dsp' : files('h264dsp_init_aarch64.c'), @@ -2243,6 +2997,7 @@ index 0000000000..e154503df6 + 'idctdsp' : files('idctdsp_init_aarch64.c'), + 'me_cmp' : files('me_cmp_init_aarch64.c'), + 'mpegaudiodsp' : files('mpegaudiodsp_init.c'), ++ 'mpegvideoenc' : files('mpegvideoencdsp_init.c'), + 'neon_clobber_test' : files('neontest.c'), + 'opus_decoder' : files('opusdsp_init.c'), + 'pixblockdsp' : files('pixblockdsp_init_aarch64.c'), @@ -2269,19 +3024,20 @@ index 0000000000..e154503df6 + +libavcodec_aarch64_neon_optional_sources = { + 'aac_decoder' : files('sbrdsp_neon.S','aacpsdsp_neon.S'), ++ 'ac3dsp' : files('ac3dsp_neon.S'), + 'dca_decoder' : files('synth_filter_neon.S'), -+ 'fft' : files('fft_neon.S'), ++ 'fdctdsp' : files('fdctdsp_neon.S'), + 'fmtconvert' : files('fmtconvert_neon.S'), + 'h264chroma' : files('h264cmc_neon.S'), + 'h264dsp' : files('h264dsp_neon.S','h264idct_neon.S'), + 'h264pred' : files('h264pred_neon.S'), + 'h264qpel' : files('h264qpel_neon.S','hpeldsp_neon.S'), -+ 'hevc_decoder' : files('hevcdsp_idct_neon.S','hevcdsp_init_aarch64.c','hevcdsp_qpel_neon.S','hevcdsp_sao_neon.S'), ++ 'hevc_decoder' : files('hevcdsp_deblock_neon.S','hevcdsp_idct_neon.S','hevcdsp_init_aarch64.c'), # MANUAL + 'hpeldsp' : files('hpeldsp_neon.S'), + 'idctdsp' : files('idctdsp_neon.S','simple_idct_neon.S'), -+ 'mdct' : files('mdct_neon.S'), + 'me_cmp' : files('me_cmp_neon.S'), + 'mpegaudiodsp' : files('mpegaudiodsp_neon.S'), ++ 'mpegvideoenc' : files('mpegvideoencdsp_neon.S'), + 'opus_decoder' : files('opusdsp_neon.S'), + 'pixblockdsp' : files('pixblockdsp_neon.S'), + 'vc1dsp' : files('vc1dsp_neon.S'), @@ -2304,19 +3060,75 @@ index 0000000000..e154503df6 + +libavcodec_aarch64_optional_tests = { +} ++ ++#### --- END GENERATED --- #### ++ ++subdir('vvc') ++ ++libavcodec_aarch64_optional_sources += libavcodec_aarch64_vvc_optional_sources ++libavcodec_aarch64_neon_optional_sources += libavcodec_aarch64_vvc_neon_optional_sources ++ ++if conf.get('hevc_decoder') == 1 ++ libavcodec_aarch64_neon_optional_sources += { ++ 'hevc_decoder': libavcodec_aarch64_neon_optional_sources ['hevc_decoder'] + files('h26x/epel_neon.S','h26x/qpel_neon.S','h26x/sao_neon.S') ++ } ++elif conf.get('vvc_decoder') == 1 ++ libavcodec_x86_optional_sources += { ++ 'vvc_decoder': libavcodec_aarch64_neon_optional_sources ['vvc_decoder'] + files('h26x/epel_neon.S','h26x/qpel_neon.S','h26x/sao_neon.S') ++ } ++endif +diff --git a/libavcodec/aarch64/vvc/meson.build b/libavcodec/aarch64/vvc/meson.build +new file mode 100644 +index 00000000..38b65935 +--- /dev/null ++++ b/libavcodec/aarch64/vvc/meson.build +@@ -0,0 +1,34 @@ ++libavcodec_aarch64_vvc_optional_sources = { ++ 'vvc_decoder' : files('dsp_init.c'), ++} ++ ++libavcodec_aarch64_vvc_x86asm_optional_sources = { ++} ++ ++libavcodec_aarch64_vvc_armv5te_optional_sources = { ++} ++ ++libavcodec_aarch64_vvc_armv6_optional_sources = { ++} ++ ++libavcodec_aarch64_vvc_armv8_optional_sources = { ++} ++ ++libavcodec_aarch64_vvc_neon_optional_sources = { ++ 'vvc_decoder' : files('alf.S','inter.S','sad.S'), # MANUAL ++} ++ ++libavcodec_aarch64_vvc_vfp_optional_sources = { ++} ++ ++libavcodec_aarch64_vvc_mmx_optional_sources = { ++} ++ ++libavcodec_aarch64_vvc_shlib_optional_sources = { ++} ++ ++libavcodec_aarch64_vvc_slib_optional_sources = { ++} ++ ++libavcodec_aarch64_vvc_optional_tests = { ++} diff --git a/libavcodec/arm/meson.build b/libavcodec/arm/meson.build new file mode 100644 -index 0000000000..dfb13b22b8 +index 00000000..dfdd3309 --- /dev/null +++ b/libavcodec/arm/meson.build -@@ -0,0 +1,118 @@ +@@ -0,0 +1,112 @@ +libavcodec_arm_optional_sources = { + 'aac_decoder' : files('aacpsdsp_init_arm.c','sbrdsp_init_arm.c'), + 'ac3dsp' : files('ac3dsp_init_arm.c','ac3dsp_arm.S'), + 'audiodsp' : files('audiodsp_init_arm.c'), + 'blockdsp' : files('blockdsp_init_arm.c'), + 'dca_decoder' : files('synth_filter_init_arm.c'), -+ 'fft' : files('fft_init_arm.c'), + 'flac_decoder' : files('flacdsp_init_arm.c','flacdsp_arm.S'), + 'fmtconvert' : files('fmtconvert_init_arm.c'), + 'g722dsp' : files('g722dsp_init_arm.c'), @@ -2335,7 +3147,6 @@ index 0000000000..dfb13b22b8 + 'mpegvideoenc' : files('mpegvideoencdsp_init_arm.c'), + 'neon_clobber_test' : files('neontest.c'), + 'pixblockdsp' : files('pixblockdsp_init_arm.c'), -+ 'rdft' : files('rdft_init_arm.c'), + 'rv34dsp' : files('rv34dsp_init_arm.c'), + 'rv40_decoder' : files('rv40dsp_init_arm.c'), + 'sbc_encoder' : files('sbcdsp_init_arm.c'), @@ -2384,7 +3195,6 @@ index 0000000000..dfb13b22b8 + 'audiodsp' : files('audiodsp_init_neon.c','audiodsp_neon.S','int_neon.S'), + 'blockdsp' : files('blockdsp_init_neon.c','blockdsp_neon.S'), + 'dca_decoder' : files('synth_filter_neon.S'), -+ 'fft' : files('fft_neon.S'), + 'fmtconvert' : files('fmtconvert_neon.S'), + 'g722dsp' : files('g722dsp_neon.S'), + 'h264chroma' : files('h264cmc_neon.S'), @@ -2395,10 +3205,8 @@ index 0000000000..dfb13b22b8 + 'hpeldsp' : files('hpeldsp_init_neon.c','hpeldsp_neon.S'), + 'idctdsp' : files('idctdsp_init_neon.c','idctdsp_neon.S','simple_idct_neon.S'), + 'llauddsp' : files('lossless_audiodsp_neon.S'), -+ 'mdct' : files('mdct_neon.S'), + 'mpegvideo' : files('mpegvideo_neon.S'), + 'pixblockdsp' : files('pixblockdsp_neon.S'), -+ 'rdft' : files('rdft_neon.S'), + 'rv30_decoder' : files('rv34dsp_neon.S'), + 'rv40_decoder' : files('rv34dsp_neon.S','rv40dsp_neon.S'), + 'sbc_encoder' : files('sbcdsp_neon.S'), @@ -2412,9 +3220,7 @@ index 0000000000..dfb13b22b8 + +libavcodec_arm_vfp_optional_sources = { + 'dca_decoder' : files('synth_filter_vfp.S'), -+ 'fft' : files('fft_vfp.S'), + 'fmtconvert' : files('fmtconvert_vfp.S'), -+ 'mdct' : files('mdct_vfp.S'), +} + +libavcodec_arm_mmx_optional_sources = { @@ -2428,9 +3234,137 @@ index 0000000000..dfb13b22b8 + +libavcodec_arm_optional_tests = { +} ++ +diff --git a/libavcodec/bsf/meson.build b/libavcodec/bsf/meson.build +new file mode 100644 +index 00000000..e3158078 +--- /dev/null ++++ b/libavcodec/bsf/meson.build +@@ -0,0 +1,78 @@ ++libavcodec_bsf_optional_sources = { ++ 'aac_adtstoasc_bsf' : files('aac_adtstoasc.c'), ++ 'av1_frame_merge_bsf' : files('av1_frame_merge.c'), ++ 'av1_frame_split_bsf' : files('av1_frame_split.c'), ++ 'av1_metadata_bsf' : files('av1_metadata.c'), ++ 'chomp_bsf' : files('chomp.c'), ++ 'dca_core_bsf' : files('dca_core.c'), ++ 'dovi_rpu_bsf' : files('dovi_rpu.c'), ++ 'dts2pts_bsf' : files('dts2pts.c'), ++ 'dump_extradata_bsf' : files('dump_extradata.c'), ++ 'dv_error_marker_bsf' : files('dv_error_marker.c'), ++ 'eac3_core_bsf' : files('eac3_core.c'), ++ 'evc_frame_merge_bsf' : files('evc_frame_merge.c'), ++ 'extract_extradata_bsf' : files('extract_extradata.c'), ++ 'filter_units_bsf' : files('filter_units.c'), ++ 'h264_metadata_bsf' : files('h264_metadata.c'), ++ 'h264_mp4toannexb_bsf' : files('h264_mp4toannexb.c'), ++ 'h264_redundant_pps_bsf' : files('h264_redundant_pps.c'), ++ 'hapqa_extract_bsf' : files('hapqa_extract.c'), ++ 'hevc_metadata_bsf' : files('h265_metadata.c'), ++ 'hevc_mp4toannexb_bsf' : files('hevc_mp4toannexb.c'), ++ 'imx_dump_header_bsf' : files('imx_dump_header.c'), ++ 'media100_to_mjpegb_bsf' : files('media100_to_mjpegb.c'), ++ 'mjpeg2jpeg_bsf' : files('mjpeg2jpeg.c'), ++ 'mjpega_dump_header_bsf' : files('mjpega_dump_header.c'), ++ 'mov2textsub_bsf' : files('movsub.c'), ++ 'mpeg2_metadata_bsf' : files('mpeg2_metadata.c'), ++ 'mpeg4_unpack_bframes_bsf' : files('mpeg4_unpack_bframes.c'), ++ 'noise_bsf' : files('noise.c'), ++ 'null_bsf' : files('null.c'), ++ 'opus_metadata_bsf' : files('opus_metadata.c'), ++ 'pcm_rechunk_bsf' : files('pcm_rechunk.c'), ++ 'pgs_frame_merge_bsf' : files('pgs_frame_merge.c'), ++ 'prores_metadata_bsf' : files('prores_metadata.c'), ++ 'remove_extradata_bsf' : files('remove_extradata.c'), ++ 'setts_bsf' : files('setts.c'), ++ 'showinfo_bsf' : files('showinfo.c'), ++ 'text2movsub_bsf' : files('movsub.c'), ++ 'trace_headers_bsf' : files('trace_headers.c'), ++ 'truehd_core_bsf' : files('truehd_core.c'), ++ 'vp9_metadata_bsf' : files('vp9_metadata.c'), ++ 'vp9_raw_reorder_bsf' : files('vp9_raw_reorder.c'), ++ 'vp9_superframe_bsf' : files('vp9_superframe.c'), ++ 'vp9_superframe_split_bsf' : files('vp9_superframe_split.c'), ++ 'vvc_metadata_bsf' : files('h266_metadata.c'), ++ 'vvc_mp4toannexb_bsf' : files('vvc_mp4toannexb.c'), ++} ++ ++libavcodec_bsf_x86asm_optional_sources = { ++} ++ ++libavcodec_bsf_armv5te_optional_sources = { ++} ++ ++libavcodec_bsf_armv6_optional_sources = { ++} ++ ++libavcodec_bsf_armv8_optional_sources = { ++} ++ ++libavcodec_bsf_neon_optional_sources = { ++} ++ ++libavcodec_bsf_vfp_optional_sources = { ++} ++ ++libavcodec_bsf_mmx_optional_sources = { ++} ++ ++libavcodec_bsf_shlib_optional_sources = { ++} ++ ++libavcodec_bsf_slib_optional_sources = { ++} ++ ++libavcodec_bsf_optional_tests = { ++} ++ +diff --git a/libavcodec/hevc/meson.build b/libavcodec/hevc/meson.build +new file mode 100644 +index 00000000..bc06c441 +--- /dev/null ++++ b/libavcodec/hevc/meson.build +@@ -0,0 +1,37 @@ ++libavcodec_hevc_optional_sources = { ++ 'hevcparse' : files('data.c','parse.c','ps.c'), ++ 'hevc_decoder' : files('cabac.c','data.c','dsp.c','filter.c','hevcdec.c','mvs.c','pred.c','refs.c'), ++ 'hevc_parser' : files('parser.c'), ++ 'hevc_sei' : files('sei.c'), ++} ++ ++libavcodec_hevc_x86asm_optional_sources = { ++} ++ ++libavcodec_hevc_armv5te_optional_sources = { ++} ++ ++libavcodec_hevc_armv6_optional_sources = { ++} ++ ++libavcodec_hevc_armv8_optional_sources = { ++} ++ ++libavcodec_hevc_neon_optional_sources = { ++} ++ ++libavcodec_hevc_vfp_optional_sources = { ++} ++ ++libavcodec_hevc_mmx_optional_sources = { ++} ++ ++libavcodec_hevc_shlib_optional_sources = { ++} ++ ++libavcodec_hevc_slib_optional_sources = { ++} ++ ++libavcodec_hevc_optional_tests = { ++} ++ diff --git a/libavcodec/libavcodec.v.in b/libavcodec/libavcodec.v.in new file mode 100644 -index 0000000000..1f9aac17ab +index 00000000..1f9aac17 --- /dev/null +++ b/libavcodec/libavcodec.v.in @@ -0,0 +1,6 @@ @@ -2442,10 +3376,10 @@ index 0000000000..1f9aac17ab +}; diff --git a/libavcodec/meson.build b/libavcodec/meson.build new file mode 100644 -index 0000000000..f47061a494 +index 00000000..6dee8799 --- /dev/null +++ b/libavcodec/meson.build -@@ -0,0 +1,1231 @@ +@@ -0,0 +1,1261 @@ +#### --- GENERATED --- #### + +libavcodec_sources = files( @@ -2454,7 +3388,8 @@ index 0000000000..f47061a494 + 'allcodecs.c', + 'avcodec.c', + 'avdct.c', -+ 'avpacket.c', ++ 'avfft.c', ++ 'packet.c', + 'bitstream.c', + 'bitstream_filters.c', + 'bsf.c', @@ -2468,6 +3403,7 @@ index 0000000000..f47061a494 + 'get_buffer.c', + 'imgconvert.c', + 'jni.c', ++ 'lcevcdec.c', + 'mathtables.c', + 'mediacodec.c', + 'mpeg12framerate.c', @@ -2477,6 +3413,8 @@ index 0000000000..f47061a494 + 'profiles.c', + 'qsv_api.c', + 'raw.c', ++ 'refstruct.c', ++ 'threadprogress.c', + 'utils.c', + 'version.c', + 'vlc.c', @@ -2510,19 +3448,18 @@ index 0000000000..f47061a494 + 'version_major.h', + 'videotoolbox.h', + 'vorbis_parser.h', -+ 'xvmc.h', +) + +libavcodec_optional_sources = { + 'a64multi5_encoder' : files('a64multienc.c','elbg.c'), + 'a64multi_encoder' : files('a64multienc.c','elbg.c'), -+ 'aac_adtstoasc_bsf' : files('aac_adtstoasc_bsf.c'), + 'aac_at_decoder' : files('audiotoolboxdec.c'), + 'aac_at_encoder' : files('audiotoolboxenc.c'), -+ 'aac_decoder' : files('aacdec.c','aactab.c','aacsbr.c','aacps_common.c','aacps_float.c','kbdwin.c','sbrdsp.c','aacpsdsp_float.c','cbrt_data.c'), ++ 'aac_decoder' : files('aactab.c','aacsbr.c','aacps_common.c','aacps_float.c','kbdwin.c','sbrdsp.c','aacpsdsp_float.c','cbrt_data.c'), + 'aac_encoder' : files('aacenc.c','aaccoder.c','aacenctab.c','aacpsy.c','aactab.c','aacenc_is.c','aacenc_tns.c','aacenc_ltp.c','aacenc_pred.c','psymodel.c','kbdwin.c','mpeg4audio_sample_rates.c'), -+ 'aac_fixed_decoder' : files('aacdec_fixed.c','aactab.c','aacsbr_fixed.c','aacps_common.c','aacps_fixed.c','kbdwin.c','sbrdsp_fixed.c','aacpsdsp_fixed.c','cbrt_data_fixed.c'), ++ 'aac_fixed_decoder' : files('aactab.c','aacsbr_fixed.c','aacps_common.c','aacps_fixed.c','kbdwin.c','sbrdsp_fixed.c','aacpsdsp_fixed.c','cbrt_data_fixed.c'), + 'aac_latm_parser' : files('latm_parser.c'), ++ 'aac_mediacodec_decoder' : files('mediacodecdec.c'), + 'aac_mf_encoder' : files('mfenc.c','mf_utils.c'), + 'aac_parser' : files('aac_parser.c','aac_ac3_parser.c'), + 'aandcttables' : files('aandcttab.c'), @@ -2617,7 +3554,9 @@ index 0000000000..f47061a494 + 'als_decoder' : files('alsdec.c','bgmc.c','mlz.c'), + 'amf' : files('amfenc.c'), + 'amrnb_decoder' : files('amrnbdec.c','celp_filters.c','celp_math.c','acelp_filters.c','acelp_vectors.c','acelp_pitch_delay.c'), ++ 'amrnb_mediacodec_decoder' : files('mediacodecdec.c'), + 'amrwb_decoder' : files('amrwbdec.c','celp_filters.c','celp_math.c','acelp_filters.c','acelp_vectors.c','acelp_pitch_delay.c'), ++ 'amrwb_mediacodec_decoder' : files('mediacodecdec.c'), + 'amr_nb_at_decoder' : files('audiotoolboxdec.c'), + 'amr_parser' : files('amr_parser.c'), + 'amv_encoder' : files('mjpegenc.c','mjpegenc_common.c'), @@ -2655,18 +3594,19 @@ index 0000000000..f47061a494 + 'av1_amf_encoder' : files('amfenc_av1.c'), + 'av1_cuvid_decoder' : files('cuviddec.c'), + 'av1_d3d11va_hwaccel' : files('dxva2_av1.c'), -+ 'av1_decoder' : files('av1dec.c'), ++ 'av1_d3d12va_hwaccel' : files('dxva2_av1.c','d3d12va_av1.c'), ++ 'av1_decoder' : files('av1dec.c','av1_parse.c'), + 'av1_dxva2_hwaccel' : files('dxva2_av1.c'), -+ 'av1_frame_merge_bsf' : files('av1_frame_merge_bsf.c'), -+ 'av1_frame_split_bsf' : files('av1_frame_split_bsf.c'), + 'av1_mediacodec_decoder' : files('mediacodecdec.c'), -+ 'av1_metadata_bsf' : files('av1_metadata_bsf.c'), ++ 'av1_mediacodec_encoder' : files('mediacodecenc.c'), + 'av1_nvdec_hwaccel' : files('nvdec_av1.c'), + 'av1_nvenc_encoder' : files('nvenc_av1.c','nvenc.c'), -+ 'av1_parser' : files('av1_parser.c'), ++ 'av1_parser' : files('av1_parser.c','av1_parse.c'), + 'av1_qsv_encoder' : files('qsvenc_av1.c'), ++ 'av1_vaapi_encoder' : files('vaapi_encode_av1.c','av1_levels.c'), + 'av1_vaapi_hwaccel' : files('vaapi_av1.c'), + 'av1_vdpau_hwaccel' : files('vdpau_av1.c'), ++ 'av1_vulkan_hwaccel' : files('vulkan_decode.c','vulkan_av1.c'), + 'avrn_decoder' : files('avrndec.c'), + 'avrp_decoder' : files('r210dec.c'), + 'avrp_encoder' : files('r210enc.c'), @@ -2675,8 +3615,6 @@ index 0000000000..f47061a494 + 'avs_decoder' : files('avs.c'), + 'avui_decoder' : files('avuidec.c'), + 'avui_encoder' : files('avuienc.c'), -+ 'ayuv_decoder' : files('v408dec.c'), -+ 'ayuv_encoder' : files('v408enc.c'), + 'bethsoftvid_decoder' : files('bethsoftvideo.c'), + 'bfi_decoder' : files('bfi.c'), + 'binkaudio_dct_decoder' : files('binkaudio.c'), @@ -2698,13 +3636,15 @@ index 0000000000..f47061a494 + 'cabac' : files('cabac.c'), + 'cavsvideo_parser' : files('cavs_parser.c'), + 'cavs_decoder' : files('cavs.c','cavsdec.c','cavsdsp.c','cavsdata.c'), -+ 'cbd2_decoder' : files('dpcm.c'), ++ 'cbd2_dpcm_decoder' : files('dpcm.c'), + 'cbs' : files('cbs.c','cbs_bsf.c'), + 'cbs_av1' : files('cbs_av1.c'), + 'cbs_h264' : files('cbs_h2645.c','cbs_sei.c','h2645_parse.c'), + 'cbs_h265' : files('cbs_h2645.c','cbs_sei.c','h2645_parse.c'), ++ 'cbs_h266' : files('cbs_h2645.c','cbs_sei.c','h2645_parse.c'), + 'cbs_jpeg' : files('cbs_jpeg.c'), + 'cbs_mpeg2' : files('cbs_mpeg2.c'), ++ 'cbs_vp8' : files('cbs_vp8.c','vp8data.c'), + 'cbs_vp9' : files('cbs_vp9.c'), + 'ccaption_decoder' : files('ccaption_dec.c','ass.c'), + 'cdgraphics_decoder' : files('cdgraphics.c'), @@ -2712,7 +3652,6 @@ index 0000000000..f47061a494 + 'cdxl_decoder' : files('cdxl.c'), + 'cfhd_decoder' : files('cfhd.c','cfhddata.c','cfhddsp.c'), + 'cfhd_encoder' : files('cfhdenc.c','cfhddata.c','cfhdencdsp.c'), -+ 'chomp_bsf' : files('chomp_bsf.c'), + 'cinepak_decoder' : files('cinepak.c'), + 'cinepak_encoder' : files('cinepakenc.c','elbg.c'), + 'clearvideo_decoder' : files('clearvideo.c'), @@ -2726,15 +3665,14 @@ index 0000000000..f47061a494 + 'cpia_decoder' : files('cpia.c'), + 'cri_decoder' : files('cri.c'), + 'cri_parser' : files('cri_parser.c'), -+ 'crystalhd' : files('crystalhd.c'), + 'cscd_decoder' : files('cscd.c'), + 'cyuv_decoder' : files('cyuv.c'), + 'd3d11va' : files('dxva2.c'), -+ 'dca_core_bsf' : files('dca_core_bsf.c'), ++ 'd3d12va' : files('dxva2.c','d3d12va_decode.c'), ++ 'd3d12va_encode' : files('d3d12va_encode.c','hw_base_encode.c'), + 'dca_decoder' : files('dcadec.c','dca.c','dcadata.c','dcahuff.c','dca_core.c','dca_exss.c','dca_xll.c','dca_lbr.c','dcadsp.c','dcadct.c','dca_sample_rate_tab.c','synth_filter.c'), + 'dca_encoder' : files('dcaenc.c','dcadata.c','dcahuff.c','dcaadpcm.c'), + 'dca_parser' : files('dca_parser.c','dca_exss.c','dca.c','dca_sample_rate_tab.c'), -+ 'dct' : files('dct.c','dct32_fixed.c','dct32_float.c'), + 'dds_decoder' : files('dds.c'), + 'deflate_wrapper' : files('zlib_wrapper.c'), + 'derf_dpcm_decoder' : files('dpcm.c'), @@ -2748,7 +3686,8 @@ index 0000000000..f47061a494 + 'dnxhd_parser' : files('dnxhd_parser.c','dnxhddata.c'), + 'dolby_e_decoder' : files('dolby_e.c','dolby_e_parse.c','kbdwin.c'), + 'dolby_e_parser' : files('dolby_e_parser.c','dolby_e_parse.c'), -+ 'dovi_rpu' : files('dovi_rpu.c'), ++ 'dovi_rpudec' : files('dovi_rpu.c','dovi_rpudec.c'), ++ 'dovi_rpuenc' : files('dovi_rpu.c','dovi_rpuenc.c'), + 'dpx_decoder' : files('dpx.c'), + 'dpx_encoder' : files('dpxenc.c'), + 'dpx_parser' : files('dpx_parser.c'), @@ -2760,8 +3699,6 @@ index 0000000000..f47061a494 + 'dsicinvideo_decoder' : files('dsicinvideo.c'), + 'dss_sp_decoder' : files('dss_sp.c'), + 'dst_decoder' : files('dstdec.c','dsd.c'), -+ 'dts2pts_bsf' : files('dts2pts_bsf.c'), -+ 'dump_extradata_bsf' : files('dump_extradata_bsf.c'), + 'dvaudio_decoder' : files('dvaudiodec.c'), + 'dvaudio_parser' : files('dvaudio_parser.c'), + 'dvbsub_decoder' : files('dvbsubdec.c'), @@ -2773,13 +3710,12 @@ index 0000000000..f47061a494 + 'dvd_nav_parser' : files('dvd_nav_parser.c'), + 'dvvideo_decoder' : files('dvdec.c','dv.c','dvdata.c'), + 'dvvideo_encoder' : files('dvenc.c','dv.c','dvdata.c'), -+ 'dv_error_marker_bsf' : files('dv_error_marker_bsf.c'), + 'dxa_decoder' : files('dxa.c'), + 'dxtory_decoder' : files('dxtory.c'), + 'dxva2' : files('dxva2.c'), + 'dxv_decoder' : files('dxv.c'), ++ 'dxv_encoder' : files('dxvenc.c'), + 'eac3_at_decoder' : files('audiotoolboxdec.c'), -+ 'eac3_core_bsf' : files('eac3_core_bsf.c'), + 'eac3_decoder' : files('eac3_data.c'), + 'eac3_encoder' : files('eac3enc.c','eac3_data.c'), + 'eacmv_decoder' : files('eacmv.c'), @@ -2794,21 +3730,21 @@ index 0000000000..f47061a494 + 'error_resilience' : files('error_resilience.c'), + 'escape124_decoder' : files('escape124.c'), + 'escape130_decoder' : files('escape130.c'), ++ 'evcparse' : files('evc_parse.c','evc_ps.c'), ++ 'evc_parser' : files('evc_parser.c'), + 'evrc_decoder' : files('evrcdec.c','acelp_vectors.c','lsp.c'), + 'exif' : files('exif.c','tiff_common.c'), + 'exr_decoder' : files('exr.c','exrdsp.c','half2float.c'), + 'exr_encoder' : files('exrenc.c','float2half.c'), -+ 'extract_extradata_bsf' : files('extract_extradata_bsf.c','av1_parse.c','h2645_parse.c'), ++ 'extract_extradata_bsf' : files('av1_parse.c','h2645_parse.c'), + 'faandct' : files('faandct.c'), + 'faanidct' : files('faanidct.c'), + 'fastaudio_decoder' : files('fastaudio.c'), + 'fdctdsp' : files('fdctdsp.c','jfdctfst.c','jfdctint.c'), -+ 'fft' : files('avfft.c','fft_float.c','fft_fixed_32.c','fft_init_table.c'), + 'ffv1_decoder' : files('ffv1dec.c','ffv1.c'), + 'ffv1_encoder' : files('ffv1enc.c','ffv1.c'), + 'ffwavesynth_decoder' : files('ffwavesynth.c'), + 'fic_decoder' : files('fic.c'), -+ 'filter_units_bsf' : files('filter_units_bsf.c'), + 'fits_decoder' : files('fitsdec.c','fits.c'), + 'fits_demuxer' : files('fits.c'), + 'fits_encoder' : files('fitsenc.c'), @@ -2861,20 +3797,20 @@ index 0000000000..f47061a494 + 'h263_videotoolbox_hwaccel' : files('videotoolbox.c'), + 'h264chroma' : files('h264chroma.c'), + 'h264dsp' : files('h264dsp.c','h264idct.c'), -+ 'h264parse' : files('h264_parse.c','h264_ps.c','h2645data.c','h2645_parse.c','h2645_vui.c'), ++ 'h264parse' : files('h264_parse.c','h264_ps.c','h264data.c','h2645data.c','h2645_parse.c','h2645_vui.c'), + 'h264pred' : files('h264pred.c'), + 'h264qpel' : files('h264qpel.c'), + 'h264_amf_encoder' : files('amfenc_h264.c'), + 'h264_cuvid_decoder' : files('cuviddec.c'), + 'h264_d3d11va_hwaccel' : files('dxva2_h264.c'), ++ 'h264_d3d12va_hwaccel' : files('dxva2_h264.c','d3d12va_h264.c'), + 'h264_decoder' : files('h264dec.c','h264_cabac.c','h264_cavlc.c','h264_direct.c','h264_loopfilter.c','h264_mb.c','h264_picture.c','h264_refs.c','h264_slice.c','h264data.c','h274.c'), + 'h264_dxva2_hwaccel' : files('dxva2_h264.c'), + 'h264_mediacodec_decoder' : files('mediacodecdec.c'), + 'h264_mediacodec_encoder' : files('mediacodecenc.c'), -+ 'h264_metadata_bsf' : files('h264_metadata_bsf.c','h264_levels.c','h2645data.c'), ++ 'h264_metadata_bsf' : files('h264_levels.c','h2645data.c'), + 'h264_mf_encoder' : files('mfenc.c','mf_utils.c'), + 'h264_mmal_decoder' : files('mmaldec.c'), -+ 'h264_mp4toannexb_bsf' : files('h264_mp4toannexb_bsf.c'), + 'h264_nvdec_hwaccel' : files('nvdec_h264.c'), + 'h264_nvenc_encoder' : files('nvenc_h264.c','nvenc.c'), + 'h264_omx_encoder' : files('omx.c'), @@ -2882,17 +3818,18 @@ index 0000000000..f47061a494 + 'h264_qsv_decoder' : files('qsvdec.c'), + 'h264_qsv_encoder' : files('qsvenc_h264.c'), + 'h264_qsv_hwaccel' : files('qsvdec.c'), -+ 'h264_redundant_pps_bsf' : files('h264_redundant_pps_bsf.c'), + 'h264_rkmpp_decoder' : files('rkmppdec.c'), + 'h264_sei' : files('h264_sei.c','h2645_sei.c'), + 'h264_v4l2m2m_decoder' : files('v4l2_m2m_dec.c'), + 'h264_v4l2m2m_encoder' : files('v4l2_m2m_enc.c'), -+ 'h264_vaapi_encoder' : files('vaapi_encode_h264.c','h264_levels.c','h2645data.c'), ++ 'h264_vaapi_encoder' : files('vaapi_encode_h264.c','h264_levels.c','h2645data.c','hw_base_encode_h264.c'), + 'h264_vaapi_hwaccel' : files('vaapi_h264.c'), + 'h264_vdpau_hwaccel' : files('vdpau_h264.c'), + 'h264_videotoolbox_encoder' : files('videotoolboxenc.c'), + 'h264_videotoolbox_hwaccel' : files('videotoolbox.c'), -+ 'hapqa_extract_bsf' : files('hapqa_extract_bsf.c','hap.c'), ++ 'h264_vulkan_encoder' : files('vulkan_encode.c','vulkan_encode_h264.c','hw_base_encode.c','hw_base_encode_h264.c','h264_levels.c','h2645data.c'), ++ 'h264_vulkan_hwaccel' : files('vulkan_decode.c','vulkan_h264.c'), ++ 'hapqa_extract_bsf' : files('hap.c'), + 'hap_decoder' : files('hapdec.c','hap.c'), + 'hap_encoder' : files('hapenc.c','hap.c'), + 'hca_decoder' : files('hcadec.c'), @@ -2900,35 +3837,37 @@ index 0000000000..f47061a494 + 'hdr_decoder' : files('hdrdec.c'), + 'hdr_encoder' : files('hdrenc.c'), + 'hdr_parser' : files('hdr_parser.c'), -+ 'hevcparse' : files('hevc_parse.c','hevc_ps.c','hevc_data.c','h2645data.c','h2645_parse.c','h2645_vui.c'), ++ 'hevcparse' : files('h2645data.c','h2645_parse.c','h2645_vui.c'), + 'hevc_amf_encoder' : files('amfenc_hevc.c'), + 'hevc_cuvid_decoder' : files('cuviddec.c'), + 'hevc_d3d11va_hwaccel' : files('dxva2_hevc.c'), -+ 'hevc_decoder' : files('hevcdec.c','hevc_mvs.c','hevc_cabac.c','hevc_refs.c','hevcpred.c','hevcdsp.c','hevc_filter.c','hevc_data.c','h274.c'), ++ 'hevc_d3d12va_encoder' : files('d3d12va_encode_hevc.c','h265_profile_level.c','h2645data.c'), ++ 'hevc_d3d12va_hwaccel' : files('dxva2_hevc.c','d3d12va_hevc.c'), ++ 'hevc_decoder' : files('aom_film_grain.c','h274.c','container_fifo.c'), + 'hevc_dxva2_hwaccel' : files('dxva2_hevc.c'), + 'hevc_mediacodec_decoder' : files('mediacodecdec.c'), + 'hevc_mediacodec_encoder' : files('mediacodecenc.c'), -+ 'hevc_metadata_bsf' : files('h265_metadata_bsf.c','h265_profile_level.c','h2645data.c'), ++ 'hevc_metadata_bsf' : files('h265_profile_level.c','h2645data.c'), + 'hevc_mf_encoder' : files('mfenc.c','mf_utils.c'), -+ 'hevc_mp4toannexb_bsf' : files('hevc_mp4toannexb_bsf.c'), + 'hevc_nvdec_hwaccel' : files('nvdec_hevc.c'), + 'hevc_nvenc_encoder' : files('nvenc_hevc.c','nvenc.c'), -+ 'hevc_parser' : files('hevc_parser.c','hevc_data.c'), + 'hevc_qsv_decoder' : files('qsvdec.c'), -+ 'hevc_qsv_encoder' : files('qsvenc_hevc.c','hevc_ps_enc.c','hevc_data.c'), ++ 'hevc_qsv_encoder' : files('qsvenc_hevc.c','hevc/ps_enc.c'), + 'hevc_qsv_hwaccel' : files('qsvdec.c'), + 'hevc_rkmpp_decoder' : files('rkmppdec.c'), -+ 'hevc_sei' : files('hevc_sei.c','h2645_sei.c','dynamic_hdr10_plus.c','dynamic_hdr_vivid.c'), ++ 'hevc_sei' : files('h2645_sei.c','aom_film_grain.c','dynamic_hdr_vivid.c'), + 'hevc_v4l2m2m_decoder' : files('v4l2_m2m_dec.c'), + 'hevc_v4l2m2m_encoder' : files('v4l2_m2m_enc.c'), -+ 'hevc_vaapi_encoder' : files('vaapi_encode_h265.c','h265_profile_level.c','h2645data.c'), ++ 'hevc_vaapi_encoder' : files('vaapi_encode_h265.c','h265_profile_level.c','h2645data.c','hw_base_encode_h265.c'), + 'hevc_vaapi_hwaccel' : files('vaapi_hevc.c','h265_profile_level.c'), + 'hevc_vdpau_hwaccel' : files('vdpau_hevc.c','h265_profile_level.c'), + 'hevc_videotoolbox_encoder' : files('videotoolboxenc.c'), ++ 'hevc_vulkan_encoder' : files('vulkan_encode.c','vulkan_encode_h265.c','hw_base_encode.c','hw_base_encode_h265.c','h265_profile_level.c','h2645data.c'), ++ 'hevc_vulkan_hwaccel' : files('vulkan_decode.c','vulkan_hevc.c'), + 'hnm4_video_decoder' : files('hnm4video.c'), + 'hpeldsp' : files('hpeldsp.c'), + 'hqx_decoder' : files('hqx.c','hqxvlc.c','hqxdsp.c','canopus.c'), -+ 'hq_hqa_decoder' : files('hq_hqa.c','hq_hqadata.c','hq_hqadsp.c','canopus.c'), ++ 'hq_hqa_decoder' : files('hq_hqa.c','hq_hqadsp.c','canopus.c'), + 'huffman' : files('huffman.c'), + 'huffyuvdsp' : files('huffyuvdsp.c'), + 'huffyuvencdsp' : files('huffyuvencdsp.c'), @@ -2946,7 +3885,6 @@ index 0000000000..f47061a494 + 'imc_decoder' : files('imc.c'), + 'imm4_decoder' : files('imm4.c'), + 'imm5_decoder' : files('imm5.c'), -+ 'imx_dump_header_bsf' : files('imx_dump_header_bsf.c'), + 'indeo2_decoder' : files('indeo2.c'), + 'indeo3_decoder' : files('indeo3.c'), + 'indeo4_decoder' : files('indeo4.c','ivi.c'), @@ -2955,31 +3893,34 @@ index 0000000000..f47061a494 + 'interplay_acm_decoder' : files('interplayacm.c'), + 'interplay_dpcm_decoder' : files('dpcm.c'), + 'interplay_video_decoder' : files('interplayvideo.c'), -+ 'intrax8' : files('intrax8.c','intrax8dsp.c','msmpeg4data.c'), ++ 'intrax8' : files('intrax8.c','intrax8dsp.c','msmpeg4_vc1_data.c'), + 'ipu_decoder' : files('mpeg12dec.c','mpeg12.c','mpeg12data.c'), + 'ipu_parser' : files('ipu_parser.c'), + 'ividsp' : files('ivi_dsp.c'), + 'jacosub_decoder' : files('jacosubdec.c','ass.c'), + 'jni' : files('ffjni.c','jni.c'), -+ 'jpeg2000_decoder' : files('jpeg2000dec.c','jpeg2000.c','jpeg2000dsp.c','jpeg2000dwt.c','mqcdec.c','mqc.c'), ++ 'jpeg2000_decoder' : files('jpeg2000dec.c','jpeg2000.c','jpeg2000dsp.c','jpeg2000dwt.c','mqcdec.c','mqc.c','jpeg2000htdec.c'), + 'jpeg2000_encoder' : files('j2kenc.c','mqcenc.c','mqc.c','jpeg2000.c','jpeg2000dwt.c'), + 'jpeg2000_parser' : files('jpeg2000_parser.c'), + 'jpegls_decoder' : files('jpeglsdec.c','jpegls.c'), + 'jpegls_encoder' : files('jpeglsenc.c','jpegls.c'), + 'jpegtables' : files('jpegtables.c'), ++ 'jpegxl_parser' : files('jpegxl_parser.c','jpegxl_parse.c'), + 'jv_decoder' : files('jvdec.c'), + 'kgv1_decoder' : files('kgv1dec.c'), + 'kmvc_decoder' : files('kmvc.c'), + 'lagarith_decoder' : files('lagarith.c','lagarithrac.c'), + 'lcms2' : files('fflcms2.c'), ++ 'lead_decoder' : files('leaddec.c','jpegquanttables.c'), + 'libaom_av1_decoder' : files('libaomdec.c','libaom.c'), + 'libaom_av1_encoder' : files('libaomenc.c','libaom.c'), + 'libaribb24_decoder' : files('libaribb24.c','ass.c'), ++ 'libaribcaption_decoder' : files('libaribcaption.c','ass.c'), + 'libcelt_decoder' : files('libcelt_dec.c'), + 'libcodec2_decoder' : files('libcodec2.c'), + 'libcodec2_encoder' : files('libcodec2.c'), + 'libc_msvcrt' : files('file_open.c'), -+ 'libdav1d_decoder' : files('libdav1d.c'), ++ 'libdav1d_decoder' : files('libdav1d.c','av1_parse.c'), + 'libdavs2_decoder' : files('libdavs2.c'), + 'libfdk_aac_decoder' : files('libfdk-aacdec.c'), + 'libfdk_aac_encoder' : files('libfdk-aacenc.c'), @@ -2992,13 +3933,14 @@ index 0000000000..f47061a494 + 'libjxl_decoder' : files('libjxldec.c','libjxl.c'), + 'libjxl_encoder' : files('libjxlenc.c','libjxl.c'), + 'libkvazaar_encoder' : files('libkvazaar.c'), ++ 'liblc3_decoder' : files('liblc3dec.c'), ++ 'liblc3_encoder' : files('liblc3enc.c'), + 'libmp3lame_encoder' : files('libmp3lame.c'), + 'libopencore_amrnb_decoder' : files('libopencore-amr.c'), + 'libopencore_amrnb_encoder' : files('libopencore-amr.c'), + 'libopencore_amrwb_decoder' : files('libopencore-amr.c'), + 'libopenh264_decoder' : files('libopenh264dec.c','libopenh264.c'), + 'libopenh264_encoder' : files('libopenh264enc.c','libopenh264.c'), -+ 'libopenjpeg_decoder' : files('libopenjpegdec.c'), + 'libopenjpeg_encoder' : files('libopenjpegenc.c'), + 'libopus_decoder' : files('libopusdec.c','libopus.c','vorbis_data.c'), + 'libopus_encoder' : files('libopusenc.c','libopus.c','vorbis_data.c'), @@ -3016,8 +3958,9 @@ index 0000000000..f47061a494 + 'libvo_amrwbenc_encoder' : files('libvo-amrwbenc.c'), + 'libvpx_vp8_decoder' : files('libvpxdec.c'), + 'libvpx_vp8_encoder' : files('libvpxenc.c'), -+ 'libvpx_vp9_decoder' : files('libvpxdec.c','libvpx.c'), -+ 'libvpx_vp9_encoder' : files('libvpxenc.c','libvpx.c'), ++ 'libvpx_vp9_decoder' : files('libvpxdec.c'), ++ 'libvpx_vp9_encoder' : files('libvpxenc.c'), ++ 'libvvenc_encoder' : files('libvvenc.c'), + 'libwebp_anim_encoder' : files('libwebpenc_common.c','libwebpenc_animencoder.c'), + 'libwebp_encoder' : files('libwebpenc_common.c','libwebpenc.c'), + 'libx262_encoder' : files('libx264.c'), @@ -3025,6 +3968,8 @@ index 0000000000..f47061a494 + 'libx265_encoder' : files('libx265.c'), + 'libxavs2_encoder' : files('libxavs2.c'), + 'libxavs_encoder' : files('libxavs.c'), ++ 'libxevd_decoder' : files('libxevd.c'), ++ 'libxeve_encoder' : files('libxeve.c'), + 'libxvid_encoder' : files('libxvid.c'), + 'libzvbi_teletext_decoder' : files('libzvbi-teletextdec.c','ass.c'), + 'ljpeg_encoder' : files('ljpegenc.c','mjpegenc_common.c'), @@ -3041,10 +3986,8 @@ index 0000000000..f47061a494 + 'mace6_decoder' : files('mace.c'), + 'magicyuv_decoder' : files('magicyuv.c'), + 'magicyuv_encoder' : files('magicyuvenc.c'), -+ 'mdct' : files('mdct_float.c','mdct_fixed_32.c'), + 'mdec_decoder' : files('mdec.c','mpeg12.c','mpeg12data.c'), + 'media100_decoder' : files('mjpegbdec.c'), -+ 'media100_to_mjpegb_bsf' : files('media100_to_mjpegb_bsf.c'), + 'mediacodec' : files('mediacodecdec_common.c','mediacodec_surface.c','mediacodec_wrapper.c','mediacodec_sw_buffer.c'), + 'metasound_decoder' : files('metasound.c','twinvq.c'), + 'me_cmp' : files('me_cmp.c'), @@ -3052,8 +3995,6 @@ index 0000000000..f47061a494 + 'mimic_decoder' : files('mimic.c'), + 'misc4_decoder' : files('misc4.c'), + 'misc4_parser' : files('misc4_parser.c'), -+ 'mjpeg2jpeg_bsf' : files('mjpeg2jpeg_bsf.c'), -+ 'mjpega_dump_header_bsf' : files('mjpega_dump_header_bsf.c'), + 'mjpegb_decoder' : files('mjpegbdec.c'), + 'mjpeg_cuvid_decoder' : files('cuviddec.c'), + 'mjpeg_decoder' : files('mjpegdec.c','mjpegdec_common.c'), @@ -3070,7 +4011,6 @@ index 0000000000..f47061a494 + 'mmvideo_decoder' : files('mmvideo.c'), + 'mobiclip_decoder' : files('mobiclip.c'), + 'motionpixels_decoder' : files('motionpixels.c'), -+ 'mov2textsub_bsf' : files('movsub_bsf.c'), + 'movtext_decoder' : files('movtextdec.c','ass.c'), + 'movtext_encoder' : files('movtextenc.c','ass_split.c'), + 'mp1float_decoder' : files('mpegaudiodec_float.c'), @@ -3088,7 +4028,7 @@ index 0000000000..f47061a494 + 'mp3on4_decoder' : files('mpegaudiodec_fixed.c'), + 'mp3_at_decoder' : files('audiotoolboxdec.c'), + 'mp3_decoder' : files('mpegaudiodec_fixed.c'), -+ 'mp3_header_decompress_bsf' : files('mp3_header_decompress_bsf.c','mpegaudiotabs.c'), ++ 'mp3_mediacodec_decoder' : files('mediacodecdec.c'), + 'mp3_mf_encoder' : files('mfenc.c','mf_utils.c'), + 'mpc7_decoder' : files('mpc7.c','mpc.c'), + 'mpc8_decoder' : files('mpc8.c','mpc.c'), @@ -3103,9 +4043,9 @@ index 0000000000..f47061a494 + 'mpeg2video_encoder' : files('mpeg12enc.c','mpeg12.c'), + 'mpeg2_cuvid_decoder' : files('cuviddec.c'), + 'mpeg2_d3d11va_hwaccel' : files('dxva2_mpeg2.c'), ++ 'mpeg2_d3d12va_hwaccel' : files('dxva2_mpeg2.c','d3d12va_mpeg2.c'), + 'mpeg2_dxva2_hwaccel' : files('dxva2_mpeg2.c'), + 'mpeg2_mediacodec_decoder' : files('mediacodecdec.c'), -+ 'mpeg2_metadata_bsf' : files('mpeg2_metadata_bsf.c'), + 'mpeg2_mmal_decoder' : files('mmaldec.c'), + 'mpeg2_nvdec_hwaccel' : files('nvdec_mpeg12.c'), + 'mpeg2_qsv_decoder' : files('qsvdec.c'), @@ -3122,16 +4062,16 @@ index 0000000000..f47061a494 + 'mpeg4_decoder' : files('mpeg4videodsp.c','xvididct.c'), + 'mpeg4_encoder' : files('mpeg4videoenc.c'), + 'mpeg4_mediacodec_decoder' : files('mediacodecdec.c'), ++ 'mpeg4_mediacodec_encoder' : files('mediacodecenc.c'), + 'mpeg4_nvdec_hwaccel' : files('nvdec_mpeg4.c'), + 'mpeg4_omx_encoder' : files('omx.c'), -+ 'mpeg4_unpack_bframes_bsf' : files('mpeg4_unpack_bframes_bsf.c'), + 'mpeg4_v4l2m2m_decoder' : files('v4l2_m2m_dec.c'), + 'mpeg4_v4l2m2m_encoder' : files('v4l2_m2m_enc.c'), + 'mpeg4_vaapi_hwaccel' : files('vaapi_mpeg4.c'), + 'mpeg4_vdpau_hwaccel' : files('vdpau_mpeg4.c'), + 'mpeg4_videotoolbox_hwaccel' : files('videotoolbox.c'), + 'mpegaudio' : files('mpegaudio.c','mpegaudiodec_common.c','mpegaudiodata.c'), -+ 'mpegaudiodsp' : files('mpegaudiodsp.c','mpegaudiodsp_data.c','mpegaudiodsp_fixed.c','mpegaudiodsp_float.c'), ++ 'mpegaudiodsp' : files('mpegaudiodsp.c','mpegaudiodsp_data.c','mpegaudiodsp_fixed.c','mpegaudiodsp_float.c','dct32_fixed.c','dct32_float.c'), + 'mpegaudioheader' : files('mpegaudiodecheader.c','mpegaudiotabs.c'), + 'mpegaudio_parser' : files('mpegaudio_parser.c'), + 'mpegvideo' : files('mpegvideo.c','rl.c','mpegvideo_motion.c','mpegvideodata.c','mpegpicture.c','to_upper4.c'), @@ -3148,6 +4088,7 @@ index 0000000000..f47061a494 + 'msnsiren_decoder' : files('siren.c'), + 'msp2_decoder' : files('msp2dec.c'), + 'msrle_decoder' : files('msrle.c','msrledec.c'), ++ 'msrle_encoder' : files('msrleenc.c'), + 'mss1_decoder' : files('mss1.c','mss12.c'), + 'mss2_decoder' : files('mss2.c','mss12.c','mss2dsp.c','wmv2data.c'), + 'mss34dsp' : files('mss34dsp.c','jpegquanttables.c'), @@ -3164,16 +4105,13 @@ index 0000000000..f47061a494 + 'mxpeg_decoder' : files('mxpegdec.c'), + 'nellymoser_decoder' : files('nellymoserdec.c','nellymoser.c'), + 'nellymoser_encoder' : files('nellymoserenc.c','nellymoser.c'), -+ 'noise_bsf' : files('noise_bsf.c'), + 'notchlc_decoder' : files('notchlc.c'), -+ 'null_bsf' : files('null_bsf.c'), + 'nuv_decoder' : files('nuv.c','rtjpeg.c','jpegquanttables.c'), + 'nvdec' : files('nvdec.c'), + 'on2avc_decoder' : files('on2avc.c','on2avcdata.c'), -+ 'opus_decoder' : files('opusdec.c','opusdec_celt.c','opus_celt.c','opus_pvq.c','opus_silk.c','opustab.c','vorbis_data.c','opusdsp.c','opus_parse.c','opus_rc.c'), -+ 'opus_encoder' : files('opusenc.c','opusenc_psy.c','opus_celt.c','opus_pvq.c','opus_rc.c','opustab.c'), -+ 'opus_metadata_bsf' : files('opus_metadata_bsf.c'), -+ 'opus_parser' : files('opus_parser.c','opus_parse.c','vorbis_data.c'), ++ 'opus_decoder' : files('vorbis_data.c'), ++ 'opus_parser' : files('vorbis_data.c'), ++ 'osq_decoder' : files('osq.c'), + 'paf_audio_decoder' : files('pafaudio.c'), + 'paf_video_decoder' : files('pafvideo.c'), + 'pam_decoder' : files('pnmdec.c','pnm.c'), @@ -3203,7 +4141,6 @@ index 0000000000..f47061a494 + 'pcm_mulaw_at_encoder' : files('audiotoolboxenc.c'), + 'pcm_mulaw_decoder' : files('pcm.c'), + 'pcm_mulaw_encoder' : files('pcm.c'), -+ 'pcm_rechunk_bsf' : files('pcm_rechunk_bsf.c'), + 'pcm_s16be_decoder' : files('pcm.c'), + 'pcm_s16be_encoder' : files('pcm.c'), + 'pcm_s16be_planar_decoder' : files('pcm.c'), @@ -3253,6 +4190,7 @@ index 0000000000..f47061a494 + 'pcm_vidc_encoder' : files('pcm.c'), + 'pcx_decoder' : files('pcx.c'), + 'pcx_encoder' : files('pcxenc.c'), ++ 'pdv_decoder' : files('pdvdec.c'), + 'pfm_decoder' : files('pnmdec.c','pnm.c'), + 'pfm_encoder' : files('pnmenc.c'), + 'pgmyuv_decoder' : files('pnmdec.c','pnm.c'), @@ -3260,7 +4198,6 @@ index 0000000000..f47061a494 + 'pgm_decoder' : files('pnmdec.c','pnm.c'), + 'pgm_encoder' : files('pnmenc.c'), + 'pgssub_decoder' : files('pgssubdec.c'), -+ 'pgs_frame_merge_bsf' : files('pgs_frame_merge_bsf.c'), + 'pgx_decoder' : files('pgxdec.c'), + 'phm_decoder' : files('pnmdec.c','pnm.c','half2float.c'), + 'phm_encoder' : files('pnmenc.c','float2half.c'), @@ -3276,10 +4213,9 @@ index 0000000000..f47061a494 + 'ppm_decoder' : files('pnmdec.c','pnm.c'), + 'ppm_encoder' : files('pnmenc.c'), + 'prores_aw_encoder' : files('proresenc_anatoliy.c','proresdata.c'), -+ 'prores_decoder' : files('proresdec2.c','proresdsp.c','proresdata.c'), ++ 'prores_decoder' : files('proresdec.c','proresdsp.c','proresdata.c'), + 'prores_encoder' : files('proresenc_anatoliy.c','proresdata.c'), + 'prores_ks_encoder' : files('proresenc_kostya.c','proresdata.c'), -+ 'prores_metadata_bsf' : files('prores_metadata_bsf.c'), + 'prores_videotoolbox_encoder' : files('videotoolboxenc.c'), + 'prosumer_decoder' : files('prosumer.c'), + 'psd_decoder' : files('psd.c'), @@ -3290,6 +4226,7 @@ index 0000000000..f47061a494 + 'qdmc_at_decoder' : files('audiotoolboxdec.c'), + 'qdmc_decoder' : files('qdmc.c'), + 'qdraw_decoder' : files('qdrw.c'), ++ 'qoa_decoder' : files('qoadec.c'), + 'qoi_decoder' : files('qoidec.c'), + 'qoi_encoder' : files('qoienc.c'), + 'qoi_parser' : files('qoi_parser.c'), @@ -3312,9 +4249,8 @@ index 0000000000..f47061a494 + 'ra_144_decoder' : files('ra144dec.c','ra144.c','celp_filters.c'), + 'ra_144_encoder' : files('ra144enc.c','ra144.c','celp_filters.c'), + 'ra_288_decoder' : files('ra288.c','celp_filters.c'), -+ 'rdft' : files('rdft.c'), + 'realtext_decoder' : files('realtextdec.c','ass.c'), -+ 'remove_extradata_bsf' : files('remove_extradata_bsf.c','av1_parse.c'), ++ 'remove_extradata_bsf' : files('av1_parse.c'), + 'rka_decoder' : files('rka.c'), + 'rl2_decoder' : files('rl2.c'), + 'roq_decoder' : files('roqvideodec.c','roqvideo.c'), @@ -3324,15 +4260,15 @@ index 0000000000..f47061a494 + 'rpza_decoder' : files('rpza.c'), + 'rpza_encoder' : files('rpzaenc.c'), + 'rscc_decoder' : files('rscc.c'), ++ 'rtv1_decoder' : files('rtv1.c'), + 'rv10_decoder' : files('rv10.c'), + 'rv10_encoder' : files('rv10enc.c'), + 'rv20_decoder' : files('rv10.c'), + 'rv20_encoder' : files('rv20enc.c'), + 'rv30_decoder' : files('rv30.c','rv34.c','rv30dsp.c'), -+ 'rv30_parser' : files('rv34_parser.c'), + 'rv34dsp' : files('rv34dsp.c'), ++ 'rv34_parser' : files('rv34_parser.c'), + 'rv40_decoder' : files('rv40.c','rv34.c','rv40dsp.c'), -+ 'rv40_parser' : files('rv34_parser.c'), + 's302m_decoder' : files('s302m.c'), + 's302m_encoder' : files('s302menc.c'), + 'sami_decoder' : files('samidec.c','ass.c','htmlsubtitles.c'), @@ -3343,7 +4279,6 @@ index 0000000000..f47061a494 + 'scpr_decoder' : files('scpr.c'), + 'screenpresso_decoder' : files('screenpresso.c'), + 'sdx2_dpcm_decoder' : files('dpcm.c'), -+ 'setts_bsf' : files('setts_bsf.c'), + 'sga_decoder' : files('sga.c'), + 'sgirle_decoder' : files('sgirledec.c'), + 'sgi_decoder' : files('sgidec.c'), @@ -3393,7 +4328,6 @@ index 0000000000..f47061a494 + 'targa_encoder' : files('targaenc.c','rle.c'), + 'targa_y216_decoder' : files('targa_y216dec.c'), + 'tdsc_decoder' : files('tdsc.c'), -+ 'text2movsub_bsf' : files('movsub_bsf.c'), + 'texturedsp' : files('texturedsp.c'), + 'texturedspenc' : files('texturedspenc.c'), + 'text_decoder' : files('textdec.c','ass.c'), @@ -3404,8 +4338,7 @@ index 0000000000..f47061a494 + 'tiff_encoder' : files('tiffenc.c','rle.c','lzwenc.c'), + 'tmv_decoder' : files('tmv.c','cga_data.c'), + 'tpeldsp' : files('tpeldsp.c'), -+ 'trace_headers_bsf' : files('trace_headers_bsf.c'), -+ 'truehd_core_bsf' : files('truehd_core_bsf.c','mlp_parse.c','mlp.c'), ++ 'truehd_core_bsf' : files('mlp_parse.c','mlp.c'), + 'truehd_decoder' : files('mlpdec.c','mlpdsp.c'), + 'truehd_encoder' : files('mlpenc.c','mlp.c'), + 'truemotion1_decoder' : files('truemotion1.c'), @@ -3433,7 +4366,7 @@ index 0000000000..f47061a494 + 'v410_encoder' : files('v410enc.c'), + 'v4l2_m2m' : files('v4l2_m2m.c','v4l2_context.c','v4l2_buffers.c','v4l2_fmt.c'), + 'vaapi' : files('vaapi_decode.c'), -+ 'vaapi_encode' : files('vaapi_encode.c'), ++ 'vaapi_encode' : files('vaapi_encode.c','hw_base_encode.c'), + 'vble_decoder' : files('vble.c'), + 'vbn_decoder' : files('vbndec.c'), + 'vbn_encoder' : files('vbnenc.c'), @@ -3441,6 +4374,7 @@ index 0000000000..f47061a494 + 'vc1dsp' : files('vc1dsp.c'), + 'vc1_cuvid_decoder' : files('cuviddec.c'), + 'vc1_d3d11va_hwaccel' : files('dxva2_vc1.c'), ++ 'vc1_d3d12va_hwaccel' : files('dxva2_vc1.c','d3d12va_vc1.c'), + 'vc1_decoder' : files('vc1dec.c','vc1_block.c','vc1_loopfilter.c','vc1_mc.c','vc1_pred.c','vc1.c','vc1data.c','msmpeg4_vc1_data.c','wmv2data.c'), + 'vc1_dxva2_hwaccel' : files('dxva2_vc1.c'), + 'vc1_mmal_decoder' : files('mmaldec.c'), @@ -3458,6 +4392,7 @@ index 0000000000..f47061a494 + 'videotoolbox' : files('videotoolbox.c'), + 'vmdaudio_decoder' : files('vmdaudio.c'), + 'vmdvideo_decoder' : files('vmdvideo.c'), ++ 'vmix_decoder' : files('vmixdec.c'), + 'vmnc_decoder' : files('vmnc.c'), + 'vnull_decoder' : files('null.c'), + 'vnull_encoder' : files('null.c'), @@ -3469,11 +4404,12 @@ index 0000000000..f47061a494 + 'vp56dsp' : files('vp56dsp.c'), + 'vp5_decoder' : files('vp5.c','vp56.c','vp56data.c','vpx_rac.c'), + 'vp6_decoder' : files('vp6.c','vp56.c','vp56data.c','vp6dsp.c','vpx_rac.c'), -+ 'vp7_decoder' : files('vp8.c','vpx_rac.c'), ++ 'vp7_decoder' : files('vp8.c','vp8data.c','vpx_rac.c'), + 'vp8dsp' : files('vp8dsp.c'), + 'vp8_cuvid_decoder' : files('cuviddec.c'), -+ 'vp8_decoder' : files('vp8.c','vpx_rac.c'), ++ 'vp8_decoder' : files('vp8.c','vp8data.c','vpx_rac.c'), + 'vp8_mediacodec_decoder' : files('mediacodecdec.c'), ++ 'vp8_mediacodec_encoder' : files('mediacodecenc.c'), + 'vp8_nvdec_hwaccel' : files('nvdec_vp8.c'), + 'vp8_parser' : files('vp8_parser.c'), + 'vp8_qsv_decoder' : files('qsvdec.c'), @@ -3485,17 +4421,15 @@ index 0000000000..f47061a494 + 'vp8_vaapi_hwaccel' : files('vaapi_vp8.c'), + 'vp9_cuvid_decoder' : files('cuviddec.c'), + 'vp9_d3d11va_hwaccel' : files('dxva2_vp9.c'), ++ 'vp9_d3d12va_hwaccel' : files('dxva2_vp9.c','d3d12va_vp9.c'), + 'vp9_decoder' : files('vp9.c','vp9data.c','vp9dsp.c','vp9lpf.c','vp9recon.c','vp9block.c','vp9prob.c','vp9mvs.c','vpx_rac.c','vp9dsp_8bpp.c','vp9dsp_10bpp.c','vp9dsp_12bpp.c'), + 'vp9_dxva2_hwaccel' : files('dxva2_vp9.c'), + 'vp9_mediacodec_decoder' : files('mediacodecdec.c'), -+ 'vp9_metadata_bsf' : files('vp9_metadata_bsf.c'), ++ 'vp9_mediacodec_encoder' : files('mediacodecenc.c'), + 'vp9_nvdec_hwaccel' : files('nvdec_vp9.c'), + 'vp9_parser' : files('vp9_parser.c'), + 'vp9_qsv_encoder' : files('qsvenc_vp9.c'), -+ 'vp9_raw_reorder_bsf' : files('vp9_raw_reorder_bsf.c'), + 'vp9_rkmpp_decoder' : files('rkmppdec.c'), -+ 'vp9_superframe_bsf' : files('vp9_superframe_bsf.c'), -+ 'vp9_superframe_split_bsf' : files('vp9_superframe_split_bsf.c'), + 'vp9_v4l2m2m_decoder' : files('v4l2_m2m_dec.c'), + 'vp9_vaapi_encoder' : files('vaapi_encode_vp9.c'), + 'vp9_vaapi_hwaccel' : files('vaapi_vp9.c'), @@ -3504,6 +4438,8 @@ index 0000000000..f47061a494 + 'vplayer_decoder' : files('textdec.c','ass.c'), + 'vqa_decoder' : files('vqavideo.c'), + 'vqc_decoder' : files('vqcdec.c'), ++ 'vulkan' : files('vulkan.c','vulkan_video.c'), ++ 'vvc_parser' : files('vvc_parser.c'), + 'wady_dpcm_decoder' : files('dpcm.c'), + 'wavarc_decoder' : files('wavarc.c'), + 'wavpack_decoder' : files('wavpack.c','wavpackdata.c','dsd.c'), @@ -3593,6 +4529,21 @@ index 0000000000..f47061a494 +} + +libavcodec_slib_optional_sources = { ++ 'avformat' : files('to_upper4.c'), ++ 'flv_muxer' : files('mpeg4audio_sample_rates.c'), ++ 'hls_demuxer' : files('ac3_channel_layout_tab.c'), ++ 'image_jpegxl_pipe_demuxer' : files('jpegxl_parse.c'), ++ 'iso_media' : files('mpegaudiotabs.c'), ++ 'jni' : files('ffjni.c'), ++ 'jpegxl_anim_demuxer' : files('jpegxl_parse.c'), ++ 'matroska_demuxer' : files('mpeg4audio_sample_rates.c'), ++ 'mov_demuxer' : files('ac3_channel_layout_tab.c'), ++ 'mp3_muxer' : files('mpegaudiotabs.c'), ++ 'mxf_muxer' : files('golomb.c'), ++ 'nut_muxer' : files('mpegaudiotabs.c'), ++ 'rtpdec' : files('jpegtables.c'), ++ 'rtp_muxer' : files('golomb.c','jpegtables.c','mpeg4audio_sample_rates.c'), ++ 'spdif_muxer' : files('dca_sample_rate_tab.c'), +} + +libavcodec_tests = [ @@ -3608,16 +4559,12 @@ index 0000000000..f47061a494 +] + +libavcodec_optional_tests = { ++ 'av1_vaapi_encoder' : [ ++ ['av1_levels', files('tests/av1_levels.c')], ++ ], + 'cabac' : [ + ['cabac', files('tests/cabac.c')], + ], -+ 'dct' : [ -+ ['avfft', files('tests/avfft.c')], -+ ], -+ 'fft' : [ -+ ['fft', files('tests/fft.c')], -+ ['fft-fixed32', files('tests/fft-fixed32.c')], -+ ], + 'golomb' : [ + ['golomb', files('tests/golomb.c')], + ], @@ -3652,6 +4599,23 @@ index 0000000000..f47061a494 + +#### --- END GENERATED --- #### + ++subdir('aac') ++subdir('bsf') ++subdir('hevc') ++subdir('opus') ++subdir('vvc') ++ ++libavcodec_optional_includes = {} ++ ++foreach i : [libavcodec_aac_optional_sources, libavcodec_bsf_optional_sources, libavcodec_hevc_optional_sources, libavcodec_opus_optional_sources] ++ foreach k, v: i ++ libavcodec_optional_sources += {k: libavcodec_optional_sources.get(k, []) + v} ++ libavcodec_optional_includes += {k: include_directories('.')} ++ endforeach ++endforeach ++ ++libavcodec_optional_sources += libavcodec_vvc_optional_sources ++ +kwargs = {'prefix': '#include "libavcodec/version.h"'} + get_version_define_kwargs + +libavcodec_majorver = cc.get_define('LIBAVCODEC_VERSION_MAJOR', kwargs: kwargs) @@ -3668,7 +4632,7 @@ index 0000000000..f47061a494 + +install_headers(libavcodec_headers, subdir: 'libavcodec') + -+configure_file( ++libavcodec_ver = configure_file( + input: 'libavcodec.v.in', + output: 'libavcodec.ver', + configuration: ver_conf, @@ -3679,10 +4643,10 @@ index 0000000000..f47061a494 +subdir('x86') diff --git a/libavcodec/neon/meson.build b/libavcodec/neon/meson.build new file mode 100644 -index 0000000000..e5e5dc9a50 +index 00000000..1f751cf9 --- /dev/null +++ b/libavcodec/neon/meson.build -@@ -0,0 +1,33 @@ +@@ -0,0 +1,34 @@ +libavcodec_neon_optional_sources = { + 'mpegvideo' : files('mpegvideo.c'), +} @@ -3716,12 +4680,122 @@ index 0000000000..e5e5dc9a50 + +libavcodec_neon_optional_tests = { +} ++ +diff --git a/libavcodec/opus/meson.build b/libavcodec/opus/meson.build +new file mode 100644 +index 00000000..9837f4d5 +--- /dev/null ++++ b/libavcodec/opus/meson.build +@@ -0,0 +1,36 @@ ++libavcodec_opus_optional_sources = { ++ 'opus_decoder' : files('dec.c','dec_celt.c','celt.c','pvq.c','silk.c','tab.c','dsp.c','parse.c','rc.c'), ++ 'opus_encoder' : files('enc.c','enc_psy.c','celt.c','pvq.c','rc.c','tab.c'), ++ 'opus_parser' : files('parser.c','parse.c'), ++} ++ ++libavcodec_opus_x86asm_optional_sources = { ++} ++ ++libavcodec_opus_armv5te_optional_sources = { ++} ++ ++libavcodec_opus_armv6_optional_sources = { ++} ++ ++libavcodec_opus_armv8_optional_sources = { ++} ++ ++libavcodec_opus_neon_optional_sources = { ++} ++ ++libavcodec_opus_vfp_optional_sources = { ++} ++ ++libavcodec_opus_mmx_optional_sources = { ++} ++ ++libavcodec_opus_shlib_optional_sources = { ++} ++ ++libavcodec_opus_slib_optional_sources = { ++} ++ ++libavcodec_opus_optional_tests = { ++} ++ +diff --git a/libavcodec/tests/.gitignore b/libavcodec/tests/.gitignore +new file mode 100644 +index 00000000..0df4ae10 +--- /dev/null ++++ b/libavcodec/tests/.gitignore +@@ -0,0 +1,21 @@ ++/av1_levels ++/avcodec ++/avpacket ++/bitstream_be ++/bitstream_le ++/cabac ++/celp_math ++/codec_desc ++/dct ++/golomb ++/h264_levels ++/h265_levels ++/htmlsubtitles ++/iirfilter ++/jpeg2000dwt ++/mathops ++/mjpegenc_huffman ++/motion ++/mpeg12framerate ++/rangecoder ++/snowenc +diff --git a/libavcodec/vvc/meson.build b/libavcodec/vvc/meson.build +new file mode 100644 +index 00000000..b93867d1 +--- /dev/null ++++ b/libavcodec/vvc/meson.build +@@ -0,0 +1,34 @@ ++libavcodec_vvc_optional_sources = { ++ 'vvc_decoder' : files('dec.c','dsp.c','cabac.c','ctu.c','data.c','filter.c','inter.c','intra.c','intra_utils.c','itx_1d.c','mvs.c','ps.c','refs.c','thread.c'), ++} ++ ++libavcodec_vvc_x86asm_optional_sources = { ++} ++ ++libavcodec_vvc_armv5te_optional_sources = { ++} ++ ++libavcodec_vvc_armv6_optional_sources = { ++} ++ ++libavcodec_vvc_armv8_optional_sources = { ++} ++ ++libavcodec_vvc_neon_optional_sources = { ++} ++ ++libavcodec_vvc_vfp_optional_sources = { ++} ++ ++libavcodec_vvc_mmx_optional_sources = { ++} ++ ++libavcodec_vvc_shlib_optional_sources = { ++} ++ ++libavcodec_vvc_slib_optional_sources = { ++} ++ ++libavcodec_vvc_optional_tests = { ++} ++ diff --git a/libavcodec/x86/meson.build b/libavcodec/x86/meson.build new file mode 100644 -index 0000000000..4446fef534 +index 00000000..87bf840d --- /dev/null +++ b/libavcodec/x86/meson.build -@@ -0,0 +1,207 @@ +@@ -0,0 +1,219 @@ +#### --- GENERATED --- #### + +libavcodec_x86_sources = files( @@ -3743,12 +4817,10 @@ index 0000000000..4446fef534 + 'cfhd_decoder' : files('cfhddsp_init.c'), + 'cfhd_encoder' : files('cfhdencdsp_init.c'), + 'dca_decoder' : files('dcadsp_init.c','synth_filter_init.c'), -+ 'dct' : files('dct_init.c'), + 'dirac_decoder' : files('diracdsp_init.c','dirac_dwt_init.c'), + 'dnxhd_encoder' : files('dnxhdenc_init.c'), + 'exr_decoder' : files('exrdsp_init.c'), + 'fdctdsp' : files('fdctdsp_init.c'), -+ 'fft' : files('fft_init.c'), + 'flac_decoder' : files('flacdsp_init.c'), + 'flac_encoder' : files('flacencdsp_init.c'), + 'fmtconvert' : files('fmtconvert_init.c'), @@ -3757,7 +4829,7 @@ index 0000000000..4446fef534 + 'h264dsp' : files('h264dsp_init.c'), + 'h264pred' : files('h264_intrapred_init.c'), + 'h264qpel' : files('h264_qpel.c'), -+ 'hevc_decoder' : files('hevcdsp_init.c'), ++ 'hevc_decoder' : files('hevcdsp_init.c'), # MANUAL + 'hpeldsp' : files('hpeldsp_init.c'), + 'huffyuvdsp' : files('huffyuvdsp_init.c'), + 'huffyuvencdsp' : files('huffyuvencdsp_init.c'), @@ -3779,7 +4851,6 @@ index 0000000000..4446fef534 + 'pixblockdsp' : files('pixblockdsp_init.c'), + 'png_decoder' : files('pngdsp_init.c'), + 'prores_decoder' : files('proresdsp_init.c'), -+ 'prores_lgpl_decoder' : files('proresdsp_init.c'), + 'qpeldsp' : files('qpeldsp_init.c'), + 'rv34dsp' : files('rv34dsp_init.c'), + 'rv40_decoder' : files('rv40dsp_init.c'), @@ -3796,7 +4867,6 @@ index 0000000000..4446fef534 + 'videodsp' : files('videodsp_init.c'), + 'vorbis_decoder' : files('vorbisdsp_init.c'), + 'vp3dsp' : files('vp3dsp_init.c'), -+ 'vp3_decoder' : files('hpeldsp_vp3_init.c'), + 'vp6_decoder' : files('vp6dsp_init.c'), + 'vp8dsp' : files('vp8dsp_init.c'), + 'vp9_decoder' : files('vp9dsp_init.c','vp9dsp_init_10bpp.c','vp9dsp_init_12bpp.c','vp9dsp_init_16bpp.c'), @@ -3819,11 +4889,9 @@ index 0000000000..4446fef534 + 'cfhd_decoder' : files('cfhddsp.asm'), + 'cfhd_encoder' : [], # MANUAL + 'dca_decoder' : files('dcadsp.asm','synth_filter.asm'), -+ 'dct' : files('dct32.asm'), + 'dirac_decoder' : files('diracdsp.asm','dirac_dwt.asm'), + 'dnxhd_encoder' : files('dnxhdenc.asm'), + 'exr_decoder' : files('exrdsp.asm'), -+ 'fft' : files('fft.asm'), + 'flac_decoder' : files('flacdsp.asm'), + 'flac_encoder' : files('flac_dsp_gpl.asm'), + 'fmtconvert' : files('fmtconvert.asm'), @@ -3832,7 +4900,7 @@ index 0000000000..4446fef534 + 'h264dsp' : files('h264_deblock.asm','h264_deblock_10bit.asm','h264_idct.asm','h264_idct_10bit.asm','h264_weight.asm','h264_weight_10bit.asm'), + 'h264pred' : files('h264_intrapred.asm','h264_intrapred_10bit.asm'), + 'h264qpel' : files('h264_qpel_8bit.asm','h264_qpel_10bit.asm','fpel.asm','qpel.asm'), -+ 'hevc_decoder' : files('hevc_add_res.asm','hevc_deblock.asm','hevc_idct.asm','hevc_mc.asm','hevc_sao.asm','hevc_sao_10bit.asm'), ++ 'hevc_decoder' : files('hevc_add_res.asm','hevc_deblock.asm','hevc_idct.asm','hevc_mc.asm','hevc_sao.asm','hevc_sao_10bit.asm'), # MANUAL + 'hpeldsp' : files('fpel.asm','hpeldsp.asm'), + 'huffyuvdsp' : files('huffyuvdsp.asm'), + 'huffyuvencdsp' : files('huffyuvencdsp.asm'), @@ -3844,16 +4912,15 @@ index 0000000000..4446fef534 + 'lpc' : files('lpc.asm'), + 'lscr_decoder' : files('pngdsp.asm'), + 'me_cmp' : files('me_cmp.asm'), -+ 'mlp_decoder' : [], # MANUAL ++ 'mlp_decoder' : [], # MANUAL + 'mpeg4_decoder' : files('xvididct.asm'), -+ 'mpegaudiodsp' : files('imdct36.asm'), ++ 'mpegaudiodsp' : files('dct32.asm','imdct36.asm'), + 'mpegvideoenc' : files('mpegvideoencdsp.asm'), + 'opus_decoder' : files('opusdsp.asm'), + 'opus_encoder' : files('celt_pvq_search.asm'), + 'pixblockdsp' : files('pixblockdsp.asm'), + 'png_decoder' : files('pngdsp.asm'), + 'prores_decoder' : [], # MANUAL -+ 'prores_lgpl_decoder' : [], # MANUAL + 'qpeldsp' : files('qpeldsp.asm','fpel.asm','qpel.asm'), + 'rv34dsp' : files('rv34dsp.asm'), + 'rv40_decoder' : files('rv40dsp.asm'), @@ -3870,7 +4937,6 @@ index 0000000000..4446fef534 + 'videodsp' : files('videodsp.asm'), + 'vorbis_decoder' : files('vorbisdsp.asm'), + 'vp3dsp' : files('vp3dsp.asm'), -+ 'vp3_decoder' : files('hpeldsp_vp3.asm'), + 'vp6_decoder' : files('vp6dsp.asm'), + 'vp8dsp' : files('vp8dsp.asm','vp8dsp_loopfilter.asm'), + 'vp9_decoder' : files('vp9intrapred.asm','vp9intrapred_16bpp.asm','vp9itxfm.asm','vp9itxfm_16bpp.asm','vp9lpf.asm','vp9lpf_16bpp.asm','vp9mc.asm','vp9mc_16bpp.asm'), @@ -3910,6 +4976,10 @@ index 0000000000..4446fef534 + +#### --- END GENERATED --- #### + ++subdir('vvc') ++ ++libavcodec_x86_optional_sources += libavcodec_x86_vvc_optional_sources ++ +# This file results in empty codegen and empty PDB generation otherwise. +# https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +# https://developercommunity.visualstudio.com/t/MSVC-Hangs-when-compiling-ffmpeg-When-l/10233953 @@ -3920,18 +4990,94 @@ index 0000000000..4446fef534 +elif conf.get('x86_64', 0) == 1 + # Alternatively, + # panic: ../libavcodec/x86/simple_idct10.asm: assertion cv8_state.source_files != NULL failed at output/codeview.c:512 ++ libavcodec_x86_x86asm_optional_sources += libavcodec_x86_vvc_x86asm_optional_sources + libavcodec_x86_x86asm_optional_sources += { + 'idctdsp': libavcodec_x86_x86asm_optional_sources ['idctdsp'] + files('simple_idct10.asm'), + 'mlp_decoder': libavcodec_x86_x86asm_optional_sources ['mlp_decoder'] + files('mlpdsp.asm'), + 'cfhd_encoder': libavcodec_x86_x86asm_optional_sources ['cfhd_encoder'] + files('cfhdencdsp.asm'), + 'prores_decoder': libavcodec_x86_x86asm_optional_sources ['prores_decoder'] + files('proresdsp.asm'), -+ 'prores_lgpl_decoder': libavcodec_x86_x86asm_optional_sources ['prores_lgpl_decoder'] + files('proresdsp.asm'), + 'truehd_decoder': libavcodec_x86_x86asm_optional_sources ['truehd_decoder'] + files('mlpdsp.asm'), + } ++ ++ if conf.get('hevc_decoder') == 1 ++ libavcodec_x86_optional_sources += { ++ 'hevc_decoder': libavcodec_x86_optional_sources ['hevc_decoder'] + files('h26x/h2656dsp.c') ++ } ++ libavcodec_x86_x86asm_optional_sources += { ++ 'hevc_decoder': libavcodec_x86_x86asm_optional_sources ['hevc_decoder'] + files('h26x/h2656_inter.asm') ++ } ++ elif conf.get('vvc_decoder') == 1 ++ libavcodec_x86_optional_sources += { ++ 'vvc_decoder': libavcodec_x86_optional_sources ['vvc_decoder'] + files('h26x/h2656dsp.c') ++ } ++ libavcodec_x86_x86asm_optional_sources += { ++ 'vvc_decoder': libavcodec_x86_x86asm_optional_sources ['vvc_decoder'] + files('h26x/h2656_inter.asm') ++ } ++ endif ++endif +diff --git a/libavcodec/x86/vvc/meson.build b/libavcodec/x86/vvc/meson.build +new file mode 100644 +index 00000000..751f3f9d +--- /dev/null ++++ b/libavcodec/x86/vvc/meson.build +@@ -0,0 +1,46 @@ ++#### --- GENERATED --- #### ++ ++libavcodec_x86_vvc_optional_sources = { ++ 'vvc_decoder' : files('vvcdsp_init.c'), # MANUAL ++} ++ ++libavcodec_x86_vvc_x86asm_optional_sources = { ++ 'vvc_decoder' : files('vvc_mc.asm') # MANUAL ++} ++ ++libavcodec_x86_vvc_armv5te_optional_sources = { ++} ++ ++libavcodec_x86_vvc_armv6_optional_sources = { ++} ++ ++libavcodec_x86_vvc_armv8_optional_sources = { ++} ++ ++libavcodec_x86_vvc_neon_optional_sources = { ++} ++ ++libavcodec_x86_vvc_vfp_optional_sources = { ++} ++ ++libavcodec_x86_vvc_mmx_optional_sources = { ++} ++ ++libavcodec_x86_vvc_shlib_optional_sources = { ++} ++ ++libavcodec_x86_vvc_slib_optional_sources = { ++} ++ ++libavcodec_x86_vvc_optional_tests = { ++} ++ ++#### --- END GENERATED --- #### ++ ++if conf.get('x86_64', 0) == 1 ++ # Alternatively, ++ # panic: ../libavcodec/x86/simple_idct10.asm: assertion cv8_state.source_files != NULL failed at output/codeview.c:512 ++ libavcodec_x86_vvc_x86asm_optional_sources += { ++ 'vvc_decoder': libavcodec_x86_vvc_x86asm_optional_sources ['vvc_decoder'] + files('vvc_alf.asm', 'vvc_dmvr.asm', 'vvc_of.asm', 'vvc_sad.asm'), ++ } +endif +diff --git a/libavdevice/.gitignore b/libavdevice/.gitignore +new file mode 100644 +index 00000000..08ac3eb8 +--- /dev/null ++++ b/libavdevice/.gitignore +@@ -0,0 +1,2 @@ ++/indev_list.c ++/outdev_list.c diff --git a/libavdevice/libavdevice.v.in b/libavdevice/libavdevice.v.in new file mode 100644 -index 0000000000..f4a6a829ab +index 00000000..f4a6a829 --- /dev/null +++ b/libavdevice/libavdevice.v.in @@ -0,0 +1,7 @@ @@ -3944,10 +5090,10 @@ index 0000000000..f4a6a829ab +}; diff --git a/libavdevice/meson.build b/libavdevice/meson.build new file mode 100644 -index 0000000000..e50ccf331d +index 00000000..85c9ee33 --- /dev/null +++ b/libavdevice/meson.build -@@ -0,0 +1,115 @@ +@@ -0,0 +1,116 @@ +kwargs = {'prefix': '#include "libavdevice/version.h"'} + get_version_define_kwargs + +libavdevice_majorver = cc.get_define('LIBAVDEVICE_VERSION_MAJOR', kwargs: kwargs) @@ -4031,6 +5177,7 @@ index 0000000000..e50ccf331d + +libavdevice_shlib_optional_sources = { + 'decklink_indev' : files('reverse.c'), ++ 'decklink_outdev' : files('ccfifo.c'), +} + +libavdevice_slib_optional_sources = { @@ -4058,18 +5205,33 @@ index 0000000000..e50ccf331d + +install_headers(libavdevice_headers, subdir: 'libavdevice') + -+configure_file( ++libavdevice_ver = configure_file( + input: 'libavdevice.v.in', + output: 'libavdevice.ver', + configuration: ver_conf, +) +diff --git a/libavdevice/tests/.gitignore b/libavdevice/tests/.gitignore +new file mode 100644 +index 00000000..b4a2281a +--- /dev/null ++++ b/libavdevice/tests/.gitignore +@@ -0,0 +1 @@ ++/timefilter +diff --git a/libavfilter/.gitignore b/libavfilter/.gitignore +new file mode 100644 +index 00000000..26bddebc +--- /dev/null ++++ b/libavfilter/.gitignore +@@ -0,0 +1 @@ ++/filter_list.c diff --git a/libavfilter/aarch64/meson.build b/libavfilter/aarch64/meson.build new file mode 100644 -index 0000000000..d222167519 +index 00000000..680060f4 --- /dev/null +++ b/libavfilter/aarch64/meson.build -@@ -0,0 +1,34 @@ +@@ -0,0 +1,37 @@ +libavfilter_aarch64_optional_sources = { ++ 'bwdif_filter' : files('vf_bwdif_init_aarch64.c'), + 'nlmeans_filter' : files('vf_nlmeans_init.c'), +} + @@ -4086,6 +5248,7 @@ index 0000000000..d222167519 +} + +libavfilter_aarch64_neon_optional_sources = { ++ 'bwdif_filter' : files('vf_bwdif_neon.S'), + 'nlmeans_filter' : files('vf_nlmeans_neon.S'), +} + @@ -4103,16 +5266,18 @@ index 0000000000..d222167519 + +libavfilter_aarch64_optional_tests = { +} ++ diff --git a/libavfilter/dnn/meson.build b/libavfilter/dnn/meson.build new file mode 100644 -index 0000000000..2bb85e734d +index 00000000..a5115436 --- /dev/null +++ b/libavfilter/dnn/meson.build -@@ -0,0 +1,35 @@ +@@ -0,0 +1,40 @@ +libavfilter_dnn_optional_sources = { -+ 'dnn' : files('dnn_interface.c','dnn_io_proc.c','queue.c','safe_queue.c','dnn_backend_common.c','dnn_backend_native.c','dnn_backend_native_layers.c','dnn_backend_native_layer_avgpool.c','dnn_backend_native_layer_dense.c','dnn_backend_native_layer_pad.c','dnn_backend_native_layer_conv2d.c','dnn_backend_native_layer_depth2space.c','dnn_backend_native_layer_maximum.c','dnn_backend_native_layer_mathbinary.c','dnn_backend_native_layer_mathunary.c'), ++ 'dnn' : files('dnn_interface.c','dnn_io_proc.c','queue.c','safe_queue.c','dnn_backend_common.c'), + 'libopenvino' : files('dnn_backend_openvino.c'), + 'libtensorflow' : files('dnn_backend_tf.c'), ++ 'libtorch' : files('dnn_backend_torch.cpp'), +} + +libavfilter_dnn_x86asm_optional_sources = { @@ -4144,9 +5309,13 @@ index 0000000000..2bb85e734d + +libavfilter_dnn_optional_tests = { +} ++ ++languages_map += { ++ 'libtorch': ['cpp'], ++} diff --git a/libavfilter/libavfilter.v.in b/libavfilter/libavfilter.v.in new file mode 100644 -index 0000000000..8665ee4bcb +index 00000000..8665ee4b --- /dev/null +++ b/libavfilter/libavfilter.v.in @@ -0,0 +1,7 @@ @@ -4159,10 +5328,10 @@ index 0000000000..8665ee4bcb +}; diff --git a/libavfilter/meson.build b/libavfilter/meson.build new file mode 100644 -index 0000000000..3c87b00368 +index 00000000..d3c25e9f --- /dev/null +++ b/libavfilter/meson.build -@@ -0,0 +1,689 @@ +@@ -0,0 +1,704 @@ +kwargs = {'prefix': '#include "libavfilter/version.h"'} + get_version_define_kwargs + +libavfilter_majorver = cc.get_define('LIBAVFILTER_VERSION_MAJOR', kwargs: kwargs) @@ -4181,8 +5350,8 @@ index 0000000000..3c87b00368 + 'buffersink.c', + 'buffersrc.c', + 'colorspace.c', ++ 'ccfifo.c', + 'drawutils.c', -+ 'fifo.c', + 'formats.c', + 'framepool.c', + 'framequeue.c', @@ -4202,6 +5371,7 @@ index 0000000000..3c87b00368 + +libavfilter_optional_sources = { + 'a3dscope_filter' : files('avf_a3dscope.c'), ++ 'aap_filter' : files('af_aap.c'), + 'abench_filter' : files('f_bench.c'), + 'abitscope_filter' : files('avf_abitscope.c'), + 'acompressor_filter' : files('af_sidechaincompress.c'), @@ -4231,6 +5401,7 @@ index 0000000000..3c87b00368 + 'afdelaysrc_filter' : files('asrc_afdelaysrc.c'), + 'afftdn_filter' : files('af_afftdn.c'), + 'afftfilt_filter' : files('af_afftfilt.c'), ++ 'afireqsrc_filter' : files('asrc_afirsrc.c'), + 'afirsrc_filter' : files('asrc_afirsrc.c'), + 'afir_filter' : files('af_afir.c'), + 'aformat_filter' : files('af_aformat.c'), @@ -4269,11 +5440,13 @@ index 0000000000..3c87b00368 + 'aphasemeter_filter' : files('avf_aphasemeter.c'), + 'aphaser_filter' : files('af_aphaser.c','generate_wave_table.c'), + 'aphaseshift_filter' : files('af_afreqshift.c'), ++ 'apsnr_filter' : files('af_asdr.c'), + 'apsyclip_filter' : files('af_apsyclip.c'), + 'apulsator_filter' : files('af_apulsator.c'), + 'arealtime_filter' : files('f_realtime.c'), + 'aresample_filter' : files('af_aresample.c'), + 'areverse_filter' : files('f_reverse.c'), ++ 'arls_filter' : files('af_arls.c'), + 'arnndn_filter' : files('af_arnndn.c'), + 'asdr_filter' : files('af_asdr.c'), + 'asegment_filter' : files('f_segment.c'), @@ -4285,6 +5458,7 @@ index 0000000000..3c87b00368 + 'asettb_filter' : files('settb.c'), + 'ashowinfo_filter' : files('af_ashowinfo.c'), + 'asidedata_filter' : files('f_sidedata.c'), ++ 'asisdr_filter' : files('af_asdr.c'), + 'asoftclip_filter' : files('af_asoftclip.c'), + 'aspectralstats_filter' : files('af_aspectralstats.c'), + 'asplit_filter' : files('split.c'), @@ -4328,8 +5502,11 @@ index 0000000000..3c87b00368 + 'boxblur_filter' : files('vf_boxblur.c','boxblur.c'), + 'boxblur_opencl_filter' : files('vf_avgblur_opencl.c','opencl.c','opencl/avgblur.cl','boxblur.c'), + 'bs2b_filter' : files('af_bs2b.c'), -+ 'bwdif_filter' : files('vf_bwdif.c','yadif_common.c'), ++ # 'bwdif_cuda_filter' : files('vf_bwdif_cuda.c','yadif_common.c'), ++ 'bwdif_filter' : files('vf_bwdif.c','bwdifdsp.c','yadif_common.c'), ++ 'bwdif_vulkan_filter' : files('vf_bwdif_vulkan.c','yadif_common.c','vulkan.c','vulkan_filter.c'), + 'cas_filter' : files('vf_cas.c'), ++ 'ccrepack_filter' : files('vf_ccrepack.c'), + 'cellauto_filter' : files('vsrc_cellauto.c'), + 'channelmap_filter' : files('af_channelmap.c'), + 'channelsplit_filter' : files('af_channelsplit.c'), @@ -4352,13 +5529,14 @@ index 0000000000..3c87b00368 + 'colorkey_filter' : files('vf_colorkey.c'), + 'colorkey_opencl_filter' : files('vf_colorkey_opencl.c','opencl.c','opencl/colorkey.cl'), + 'colorlevels_filter' : files('vf_colorlevels.c'), -+ 'colormap_filter' : files('vf_colormap.c'), ++ 'colormap_filter' : files('vf_colormap.c','framesync.c'), + 'colormatrix_filter' : files('vf_colormatrix.c'), + # 'colorspace_cuda_filter' : files('vf_colorspace_cuda.c','cuda/load_helper.c'), + 'colorspace_filter' : files('vf_colorspace.c','colorspacedsp.c'), + 'colorspectrum_filter' : files('vsrc_testsrc.c'), + 'colortemperature_filter' : files('vf_colortemperature.c'), + 'color_filter' : files('vsrc_testsrc.c'), ++ 'color_vulkan_filter' : files('vsrc_testsrc_vulkan.c','vulkan.c','vulkan_filter.c'), + 'compand_filter' : files('af_compand.c'), + 'compensationdelay_filter' : files('af_compensationdelay.c'), + 'concat_filter' : files('avf_concat.c'), @@ -4370,7 +5548,7 @@ index 0000000000..3c87b00368 + 'coreimage_filter' : files('vf_coreimage.m'), + 'corr_filter' : files('vf_corr.c','framesync.c'), + 'cover_rect_filter' : files('vf_cover_rect.c','lavfutils.c'), -+ 'cropdetect_filter' : files('vf_cropdetect.c'), ++ 'cropdetect_filter' : files('vf_cropdetect.c','edge_common.c'), + 'crop_filter' : files('vf_crop.c'), + 'crossfeed_filter' : files('af_crossfeed.c'), + 'crystalizer_filter' : files('af_crystalizer.c'), @@ -4409,9 +5587,10 @@ index 0000000000..3c87b00368 + 'dnn_processing_filter' : files('vf_dnn_processing.c'), + 'doubleweave_filter' : files('vf_weave.c'), + 'drawbox_filter' : files('vf_drawbox.c'), ++ 'drawbox_vaapi_filter' : files('vf_drawbox_vaapi.c','vaapi_vpp.c'), + 'drawgraph_filter' : files('f_drawgraph.c'), + 'drawgrid_filter' : files('vf_drawbox.c'), -+ 'drawtext_filter' : files('vf_drawtext.c'), ++ 'drawtext_filter' : files('vf_drawtext.c','textutils.c'), + 'drmeter_filter' : files('af_drmeter.c'), + 'dynaudnorm_filter' : files('af_dynaudnorm.c'), + 'earwax_filter' : files('af_earwax.c'), @@ -4452,6 +5631,7 @@ index 0000000000..3c87b00368 + 'frei0r_filter' : files('vf_frei0r.c'), + 'frei0r_src_filter' : files('vf_frei0r.c'), + 'fspp_filter' : files('vf_fspp.c','qp_table.c'), ++ 'fsync_filter' : files('vf_fsync.c'), + 'gblur_filter' : files('vf_gblur.c'), + 'gblur_vulkan_filter' : files('vf_gblur_vulkan.c','vulkan.c','vulkan_filter.c'), + 'geq_filter' : files('vf_geq.c'), @@ -4460,7 +5640,7 @@ index 0000000000..3c87b00368 + 'graphmonitor_filter' : files('f_graphmonitor.c'), + 'grayworld_filter' : files('vf_grayworld.c'), + 'greyedge_filter' : files('vf_colorconstancy.c'), -+ 'guided_filter' : files('vf_guided.c'), ++ 'guided_filter' : files('vf_guided.c','framesync.c'), + 'haas_filter' : files('af_haas.c'), + 'haldclutsrc_filter' : files('vsrc_testsrc.c'), + 'haldclut_filter' : files('vf_lut3d.c','framesync.c'), @@ -4489,7 +5669,7 @@ index 0000000000..3c87b00368 + 'hysteresis_filter' : files('vf_hysteresis.c','framesync.c'), + 'iccdetect_filter' : files('vf_iccdetect.c','fflcms2.c'), + 'iccgen_filter' : files('vf_iccgen.c','fflcms2.c'), -+ 'identity_filter' : files('vf_identity.c'), ++ 'identity_filter' : files('vf_identity.c','framesync.c'), + 'idet_filter' : files('vf_idet.c'), + 'il_filter' : files('vf_il.c'), + 'inflate_filter' : files('vf_neighbor.c'), @@ -4501,10 +5681,14 @@ index 0000000000..3c87b00368 + 'ladspa_filter' : files('af_ladspa.c'), + 'lagfun_filter' : files('vf_lagfun.c'), + 'latency_filter' : files('f_latency.c'), ++ 'lcevc_filter' : files('vf_lcevc.c'), + 'lenscorrection_filter' : files('vf_lenscorrection.c'), + 'lensfun_filter' : files('vf_lensfun.c'), + 'libc_msvcrt' : files('file_open.c'), ++ 'libglslang' : files('vulkan_glslang.c'), + 'libplacebo_filter' : files('vf_libplacebo.c','vulkan.c','vulkan_filter.c'), ++ 'libshaderc' : files('vulkan_shaderc.c'), ++ 'libvmaf_cuda_filter' : files('vf_libvmaf.c','framesync.c'), + 'libvmaf_filter' : files('vf_libvmaf.c','framesync.c'), + 'life_filter' : files('vsrc_life.c'), + 'limitdiff_filter' : files('vf_limitdiff.c','framesync.c'), @@ -4538,14 +5722,15 @@ index 0000000000..3c87b00368 + 'minterpolate_filter' : files('vf_minterpolate.c','motion_estimation.c'), + 'mix_filter' : files('vf_mix.c','framesync.c'), + 'monochrome_filter' : files('vf_monochrome.c'), -+ 'morpho_filter' : files('vf_morpho.c'), ++ 'morpho_filter' : files('vf_morpho.c','framesync.c'), + 'movie_filter' : files('src_movie.c'), + 'mpdecimate_filter' : files('vf_mpdecimate.c'), + 'mptestsrc_filter' : files('vsrc_mptestsrc.c'), -+ 'multiply_filter' : files('vf_multiply.c'), ++ 'multiply_filter' : files('vf_multiply.c','framesync.c'), + 'negate_filter' : files('vf_negate.c'), + 'nlmeans_filter' : files('vf_nlmeans.c'), + 'nlmeans_opencl_filter' : files('vf_nlmeans_opencl.c','opencl.c','opencl/nlmeans.cl'), ++ 'nlmeans_vulkan_filter' : files('vf_nlmeans_vulkan.c','vulkan.c','vulkan_filter.c'), + 'nnedi_filter' : files('vf_nnedi.c'), + 'noformat_filter' : files('vf_format.c'), + 'noise_filter' : files('vf_noise.c'), @@ -4566,11 +5751,13 @@ index 0000000000..3c87b00368 + 'owdenoise_filter' : files('vf_owdenoise.c'), + 'pad_filter' : files('vf_pad.c'), + 'pad_opencl_filter' : files('vf_pad_opencl.c','opencl.c','opencl/pad.cl'), ++ 'pad_vaapi_filter' : files('vf_pad_vaapi.c','vaapi_vpp.c'), + 'pal100bars_filter' : files('vsrc_testsrc.c'), + 'pal75bars_filter' : files('vsrc_testsrc.c'), + 'palettegen_filter' : files('vf_palettegen.c','palette.c'), + 'paletteuse_filter' : files('vf_paletteuse.c','framesync.c','palette.c'), + 'pan_filter' : files('af_pan.c'), ++ 'perlin_filter' : files('vsrc_perlin.c','perlin.c'), + 'perms_filter' : files('f_perms.c'), + 'perspective_filter' : files('vf_perspective.c'), + 'phase_filter' : files('vf_phase.c'), @@ -4589,7 +5776,10 @@ index 0000000000..3c87b00368 + 'psnr_filter' : files('vf_psnr.c','framesync.c'), + 'pullup_filter' : files('vf_pullup.c'), + 'qp_filter' : files('vf_qp.c'), ++ 'qrencodesrc_filter' : files('qrencode.c','textutils.c'), ++ 'qrencode_filter' : files('qrencode.c','textutils.c'), + 'qsvvpp' : files('qsvvpp.c'), ++ 'quirc_filter' : files('vf_quirc.c'), + 'random_filter' : files('vf_random.c'), + 'readeia608_filter' : files('vf_readeia608.c'), + 'readvitc_filter' : files('vf_readvitc.c'), @@ -4608,13 +5798,14 @@ index 0000000000..3c87b00368 + 'rotate_filter' : files('vf_rotate.c'), + 'rubberband_filter' : files('af_rubberband.c'), + 'sab_filter' : files('vf_sab.c'), -+ 'scale2ref_filter' : files('vf_scale.c','scale_eval.c'), ++ 'scale2ref_filter' : files('vf_scale.c','scale_eval.c','framesync.c'), + 'scale2ref_npp_filter' : files('vf_scale_npp.c','scale_eval.c'), + # 'scale_cuda_filter' : files('vf_scale_cuda.c','scale_eval.c'), -+ 'scale_filter' : files('vf_scale.c','scale_eval.c'), ++ 'scale_filter' : files('vf_scale.c','scale_eval.c','framesync.c'), + 'scale_npp_filter' : files('vf_scale_npp.c','scale_eval.c'), + 'scale_qsv_filter' : files('vf_vpp_qsv.c'), + 'scale_vaapi_filter' : files('vf_scale_vaapi.c','scale_eval.c','vaapi_vpp.c'), ++ 'scale_vt_filter' : files('vf_scale_vt.c','scale_eval.c'), + 'scale_vulkan_filter' : files('vf_scale_vulkan.c','vulkan.c','vulkan_filter.c'), + 'scdet_filter' : files('vf_scdet.c'), + 'scene_sad' : files('scene_sad.c'), @@ -4693,6 +5884,8 @@ index 0000000000..3c87b00368 + # 'thumbnail_cuda_filter' : files('vf_thumbnail_cuda.c','cuda/load_helper.c'), + 'thumbnail_filter' : files('vf_thumbnail.c'), + 'tile_filter' : files('vf_tile.c'), ++ 'tiltandshift_filter' : files('vf_tiltandshift.c'), ++ 'tiltshelf_filter' : files('af_biquads.c'), + 'tinterlace_filter' : files('vf_tinterlace.c'), + 'tlut2_filter' : files('vf_lut2.c','framesync.c'), + 'tmedian_filter' : files('vf_xmedian.c','framesync.c'), @@ -4706,6 +5899,7 @@ index 0000000000..3c87b00368 + 'transpose_npp_filter' : files('vf_transpose_npp.c'), + 'transpose_opencl_filter' : files('vf_transpose_opencl.c','opencl.c','opencl/transpose.cl'), + 'transpose_vaapi_filter' : files('vf_transpose_vaapi.c','vaapi_vpp.c'), ++ 'transpose_vt_filter' : files('vf_transpose_vt.c'), + 'transpose_vulkan_filter' : files('vf_transpose_vulkan.c','vulkan.c','vulkan_filter.c'), + 'treble_filter' : files('af_biquads.c'), + 'tremolo_filter' : files('af_tremolo.c'), @@ -4743,16 +5937,19 @@ index 0000000000..3c87b00368 + 'xcorrelate_filter' : files('vf_convolve.c','framesync.c'), + 'xfade_filter' : files('vf_xfade.c'), + 'xfade_opencl_filter' : files('vf_xfade_opencl.c','opencl.c','opencl/xfade.cl'), ++ 'xfade_vulkan_filter' : files('vf_xfade_vulkan.c','vulkan.c','vulkan_filter.c'), + 'xmedian_filter' : files('vf_xmedian.c','framesync.c'), ++ 'xpsnr_filter' : files('vf_xpsnr.c','framesync.c'), + 'xstack_filter' : files('vf_stack.c','framesync.c'), + 'xstack_qsv_filter' : files('vf_stack_qsv.c','framesync.c'), + 'xstack_vaapi_filter' : files('vf_stack_vaapi.c','framesync.c','vaapi_vpp.c'), + # 'yadif_cuda_filter' : files('vf_yadif_cuda.c','yadif_common.c','cuda/load_helper.c'), + 'yadif_filter' : files('vf_yadif.c','yadif_common.c'), -+ 'yadif_videotoolbox_filter' : files('vf_yadif_videotoolbox.m','metal/utils.m','yadif_common.c'), # MANUAL ++ 'yadif_videotoolbox_filter' : files('vf_yadif_videotoolbox.m','metal/vf_yadif_videotoolbox.metal','metal/utils.m','yadif_common.c'), + 'yaepblur_filter' : files('vf_yaepblur.c'), + 'yuvtestsrc_filter' : files('vsrc_testsrc.c'), + 'zmq_filter' : files('f_zmq.c'), ++ 'zoneplate_filter' : files('vsrc_testsrc.c'), + 'zoompan_filter' : files('vf_zoompan.c'), + 'zscale_filter' : files('vf_zscale.c'), +} @@ -4796,19 +5993,6 @@ index 0000000000..3c87b00368 +] + +libavfilter_optional_tests = { -+ 'dnn' : [ -+ ['dnn-layer-avgpool', files('tests/dnn-layer-avgpool.c')], -+ ['dnn-layer-conv2d', files('tests/dnn-layer-conv2d.c')], -+ ['dnn-layer-dense', files('tests/dnn-layer-dense.c')], -+ ['dnn-layer-depth2space', files('tests/dnn-layer-depth2space.c')], -+ ['dnn-layer-mathbinary', files('tests/dnn-layer-mathbinary.c')], -+ ['dnn-layer-mathunary', files('tests/dnn-layer-mathunary.c')], -+ ['dnn-layer-maximum', files('tests/dnn-layer-maximum.c')], -+ ['dnn-layer-pad', files('tests/dnn-layer-pad.c')], -+ ], -+ 'nlmeans_filter': [ -+ ['integral', files('tests/integral.c')], -+ ] +} + +languages_map += { @@ -4844,7 +6028,7 @@ index 0000000000..3c87b00368 + +install_headers(libavfilter_headers, subdir: 'libavfilter') + -+configure_file( ++libavfilter_ver = configure_file( + input: 'libavfilter.v.in', + output: 'libavfilter.ver', + configuration: ver_conf, @@ -4852,12 +6036,57 @@ index 0000000000..3c87b00368 + +subdir('aarch64') +subdir('x86') +diff --git a/libavfilter/opencl/.gitignore b/libavfilter/opencl/.gitignore +new file mode 100644 +index 00000000..064a8d8e +--- /dev/null ++++ b/libavfilter/opencl/.gitignore +@@ -0,0 +1 @@ ++*.c +diff --git a/libavfilter/tests/.gitignore b/libavfilter/tests/.gitignore +new file mode 100644 +index 00000000..db482cd4 +--- /dev/null ++++ b/libavfilter/tests/.gitignore +@@ -0,0 +1,12 @@ ++/dnn-layer-conv2d ++/dnn-layer-depth2space ++/dnn-layer-maximum ++/dnn-layer-pad ++/dnn-layer-mathbinary ++/dnn-layer-mathunary ++/dnn-layer-avgpool ++/dnn-layer-dense ++/drawutils ++/filtfmts ++/formats ++/integral +diff --git a/libavfilter/textutils.c b/libavfilter/textutils.c +index e6b5239b..a5a9fb76 100644 +--- a/libavfilter/textutils.c ++++ b/libavfilter/textutils.c +@@ -30,7 +30,7 @@ + #include "libavutil/error.h" + #include "libavutil/file.h" + #include "libavutil/mem.h" +-#include "libavutil/time.h" ++#include "libavutil/time_internal.h" + + static int ff_expand_text_function_internal(FFExpandTextContext *expand_text, AVBPrint *bp, + char *name, unsigned argc, char **argv) +diff --git a/libavfilter/vulkan/.gitignore b/libavfilter/vulkan/.gitignore +new file mode 100644 +index 00000000..064a8d8e +--- /dev/null ++++ b/libavfilter/vulkan/.gitignore +@@ -0,0 +1 @@ ++*.c diff --git a/libavfilter/x86/meson.build b/libavfilter/x86/meson.build new file mode 100644 -index 0000000000..3e0bae10c0 +index 00000000..c864898e --- /dev/null +++ b/libavfilter/x86/meson.build -@@ -0,0 +1,128 @@ +@@ -0,0 +1,136 @@ +#### --- GENERATED --- #### + +libavfilter_x86_optional_sources = { @@ -4873,6 +6102,7 @@ index 0000000000..3e0bae10c0 + 'fspp_filter' : files('vf_fspp_init.c'), + 'gblur_filter' : files('vf_gblur_init.c'), + 'gradfun_filter' : files('vf_gradfun_init.c'), ++ 'haldclut_filter' : files('vf_lut3d_init.c'), + 'hflip_filter' : files('vf_hflip_init.c'), + 'hqdn3d_filter' : files('vf_hqdn3d_init.c'), + 'idet_filter' : files('vf_idet_init.c'), @@ -4890,6 +6120,7 @@ index 0000000000..3e0bae10c0 + 'removegrain_filter' : files('vf_removegrain_init.c'), + 'scene_sad' : files('scene_sad_init.c'), + 'showcqt_filter' : files('avf_showcqt_init.c'), ++ 'sobel_filter' : files('vf_convolution_init.c'), + 'spp_filter' : files('vf_spp.c'), + 'ssim_filter' : files('vf_ssim_init.c'), + 'stereo3d_filter' : files('vf_stereo3d_init.c'), @@ -4900,6 +6131,7 @@ index 0000000000..3e0bae10c0 + 'v360_filter' : files('vf_v360_init.c'), + 'volume_filter' : files('af_volume_init.c'), + 'w3fdif_filter' : files('vf_w3fdif_init.c'), ++ 'xpsnr_filter' : files('vf_xpsnr_init.c'), + 'yadif_filter' : files('vf_yadif_init.c'), +} + @@ -4916,6 +6148,7 @@ index 0000000000..3e0bae10c0 + 'fspp_filter' : files('vf_fspp.asm'), + 'gblur_filter' : files('vf_gblur.asm'), + 'gradfun_filter' : files('vf_gradfun.asm'), ++ 'haldclut_filter' : [], # MANUAL + 'hflip_filter' : files('vf_hflip.asm'), + 'hqdn3d_filter' : files('vf_hqdn3d.asm'), + 'idet_filter' : files('vf_idet.asm'), @@ -4932,6 +6165,7 @@ index 0000000000..3e0bae10c0 + 'removegrain_filter' : files('vf_removegrain.asm'), + 'scene_sad' : files('scene_sad.asm'), + 'showcqt_filter' : files('avf_showcqt.asm'), ++ 'sobel_filter' : files('vf_convolution.asm'), + 'ssim_filter' : files('vf_ssim.asm'), + 'stereo3d_filter' : files('vf_stereo3d.asm'), + 'tblend_filter' : files('vf_blend.asm'), @@ -4983,12 +6217,44 @@ index 0000000000..3e0bae10c0 + 'atadenoise_filter': libavfilter_x86_x86asm_optional_sources ['atadenoise_filter'] + files('vf_atadenoise.asm'), + } + libavfilter_x86_x86asm_optional_sources += { ++ 'haldclut_filter': libavfilter_x86_x86asm_optional_sources ['haldclut_filter'] + files('vf_lut3d.asm'), ++ } ++ libavfilter_x86_x86asm_optional_sources += { + 'nlmeans_filter': libavfilter_x86_x86asm_optional_sources ['nlmeans_filter'] + files('vf_nlmeans.asm'), + } +endif +diff --git a/libavformat/.gitignore b/libavformat/.gitignore +new file mode 100644 +index 00000000..fb70c122 +--- /dev/null ++++ b/libavformat/.gitignore +@@ -0,0 +1,3 @@ ++/protocol_list.c ++/muxer_list.c ++/demuxer_list.c +diff --git a/libavformat/Makefile b/libavformat/Makefile +index 7ca68a70..79fac7e8 100644 +--- a/libavformat/Makefile ++++ b/libavformat/Makefile +@@ -726,7 +726,7 @@ OBJS-$(CONFIG_LIBSSH_PROTOCOL) += libssh.o + OBJS-$(CONFIG_LIBZMQ_PROTOCOL) += libzmq.o + + # Objects duplicated from other libraries for shared builds +-SHLIBOBJS += log2_tab.o to_upper4.o ++SHLIBOBJS += log2_tab.o to_upper4.o bitstream.o + SHLIBOBJS-$(CONFIG_ISO_MEDIA) += mpegaudiotabs.o + SHLIBOBJS-$(CONFIG_FLV_MUXER) += mpeg4audio_sample_rates.o + SHLIBOBJS-$(CONFIG_HLS_DEMUXER) += ac3_channel_layout_tab.o +diff --git a/libavformat/bitstream.c b/libavformat/bitstream.c +new file mode 100644 +index 00000000..2afda37c +--- /dev/null ++++ b/libavformat/bitstream.c +@@ -0,0 +1 @@ ++#include "libavcodec/bitstream.c" diff --git a/libavformat/libavformat.v.in b/libavformat/libavformat.v.in new file mode 100644 -index 0000000000..a4557a0c1b +index 00000000..a4557a0c --- /dev/null +++ b/libavformat/libavformat.v.in @@ -0,0 +1,6 @@ @@ -5000,10 +6266,10 @@ index 0000000000..a4557a0c1b +}; diff --git a/libavformat/meson.build b/libavformat/meson.build new file mode 100644 -index 0000000000..0335c5ba09 +index 00000000..5664bdb9 --- /dev/null +++ b/libavformat/meson.build -@@ -0,0 +1,707 @@ +@@ -0,0 +1,733 @@ +kwargs = {'prefix': '#include "libavformat/version.h"'} + get_version_define_kwargs + +libavformat_majorver = cc.get_define('LIBAVFORMAT_VERSION_MAJOR', kwargs: kwargs) @@ -5055,6 +6321,8 @@ index 0000000000..0335c5ba09 + 'aa_demuxer' : files('aadec.c'), + 'ac3_demuxer' : files('ac3dec.c','rawdec.c'), + 'ac3_muxer' : files('rawenc.c'), ++ 'ac4_demuxer' : files('ac4dec.c'), ++ 'ac4_muxer' : files('ac4enc.c'), + 'ace_demuxer' : files('acedec.c'), + 'acm_demuxer' : files('acm.c','rawdec.c'), + 'act_demuxer' : files('act.c'), @@ -5064,7 +6332,8 @@ index 0000000000..0335c5ba09 + 'adts_muxer' : files('adtsenc.c','apetag.c','img2.c','id3v2enc.c'), + 'adx_demuxer' : files('adxdec.c'), + 'adx_muxer' : files('rawenc.c'), -+ 'aea_demuxer' : files('aea.c','pcm.c'), ++ 'aea_demuxer' : files('aeadec.c','pcm.c'), ++ 'aea_muxer' : files('aeaenc.c','rawenc.c'), + 'afc_demuxer' : files('afc.c'), + 'aiff_demuxer' : files('aiffdec.c','aiff.c','pcm.c','mov_chan.c','replaygain.c'), + 'aiff_muxer' : files('aiffenc.c','aiff.c','id3v2enc.c'), @@ -5076,6 +6345,7 @@ index 0000000000..0335c5ba09 + 'amr_demuxer' : files('amr.c','rawdec.c'), + 'amr_muxer' : files('amr.c','rawenc.c'), + 'amv_muxer' : files('amvenc.c'), ++ 'android_content_protocol' : files('file.c'), + 'anm_demuxer' : files('anm.c'), + 'apac_demuxer' : files('apac.c','rawdec.c'), + 'apc_demuxer' : files('apc.c'), @@ -5096,7 +6366,7 @@ index 0000000000..0335c5ba09 + 'argo_cvg_demuxer' : files('argo_cvg.c'), + 'argo_cvg_muxer' : files('argo_cvg.c'), + 'asf_demuxer' : files('asfdec_f.c','asf.c','asfcrypt.c','asf_tags.c','avlanguage.c'), -+ 'asf_muxer' : files('asfenc.c','asf.c','avlanguage.c'), ++ 'asf_muxer' : files('asfenc.c','asf.c','asf_tags.c','avlanguage.c'), + 'asf_o_demuxer' : files('asfdec_o.c','asf.c','asfcrypt.c','asf_tags.c','avlanguage.c'), + 'ass_demuxer' : files('assdec.c','subtitles.c'), + 'ass_muxer' : files('assenc.c'), @@ -5174,6 +6444,7 @@ index 0000000000..0335c5ba09 + 'dts_muxer' : files('rawenc.c'), + 'dvbsub_demuxer' : files('dvbsub.c','rawdec.c'), + 'dvbtxt_demuxer' : files('dvbtxt.c','rawdec.c'), ++ 'dvdvideo_demuxer' : files('dvdvideodec.c','dvdclut.c'), + 'dv_muxer' : files('dvenc.c'), + 'dxa_demuxer' : files('dxa.c'), + 'eac3_demuxer' : files('ac3dec.c','rawdec.c'), @@ -5181,13 +6452,14 @@ index 0000000000..0335c5ba09 + 'ea_cdata_demuxer' : files('eacdata.c'), + 'ea_demuxer' : files('electronicarts.c'), + 'epaf_demuxer' : files('epafdec.c','pcm.c'), ++ 'evc_demuxer' : files('evcdec.c','rawdec.c'), ++ 'evc_muxer' : files('rawenc.c'), + 'fd_protocol' : files('file.c'), + 'ffmetadata_demuxer' : files('ffmetadec.c'), + 'ffmetadata_muxer' : files('ffmetaenc.c'), + 'ffrtmpcrypt_protocol' : files('rtmpcrypt.c','rtmpdigest.c','rtmpdh.c'), + 'ffrtmphttp_protocol' : files('rtmphttp.c'), + 'fifo_muxer' : files('fifo.c'), -+ 'fifo_test_muxer' : files('fifo_test.c'), + 'file_protocol' : files('file.c'), + 'filmstrip_demuxer' : files('filmstripdec.c'), + 'filmstrip_muxer' : files('filmstripenc.c','rawenc.c'), @@ -5197,7 +6469,7 @@ index 0000000000..0335c5ba09 + 'flac_muxer' : files('flacenc.c','flacenc_header.c','vorbiscomment.c'), + 'flic_demuxer' : files('flic.c'), + 'flv_demuxer' : files('flvdec.c'), -+ 'flv_muxer' : files('flvenc.c','avc.c'), ++ 'flv_muxer' : files('flvenc.c'), + 'fourxm_demuxer' : files('4xm.c'), + 'framecrc_muxer' : files('framecrcenc.c','framehash.c'), + 'framehash_muxer' : files('hashenc.c','framehash.c'), @@ -5239,12 +6511,16 @@ index 0000000000..0335c5ba09 + 'hevc_demuxer' : files('hevcdec.c','rawdec.c'), + 'hevc_muxer' : files('rawenc.c'), + 'hls_demuxer' : files('hls.c','hls_sample_encryption.c'), -+ 'hls_muxer' : files('hlsenc.c','hlsplaylist.c','avc.c'), ++ 'hls_muxer' : files('hlsenc.c','hlsplaylist.c'), + 'hls_protocol' : files('hlsproto.c'), + 'hnm_demuxer' : files('hnm.c'), + 'httpproxy_protocol' : files('http.c','httpauth.c','urldecode.c'), + 'https_protocol' : files('http.c','httpauth.c','urldecode.c'), + 'http_protocol' : files('http.c','httpauth.c','urldecode.c'), ++ 'iamfdec' : files('iamf_reader.c','iamf_parse.c','iamf.c'), ++ 'iamfenc' : files('iamf_writer.c','iamf.c'), ++ 'iamf_demuxer' : files('iamfdec.c'), ++ 'iamf_muxer' : files('iamfenc.c'), + 'icecast_protocol' : files('icecast.c'), + 'ico_demuxer' : files('icodec.c'), + 'ico_muxer' : files('icoenc.c'), @@ -5270,7 +6546,7 @@ index 0000000000..0335c5ba09 + 'image_hdr_pipe_demuxer' : files('img2dec.c','img2.c'), + 'image_j2k_pipe_demuxer' : files('img2dec.c','img2.c'), + 'image_jpegls_pipe_demuxer' : files('img2dec.c','img2.c'), -+ 'image_jpegxl_pipe_demuxer' : files('img2dec.c','img2.c','jpegxl_probe.c'), ++ 'image_jpegxl_pipe_demuxer' : files('img2dec.c','img2.c'), + 'image_jpeg_pipe_demuxer' : files('img2dec.c','img2.c'), + 'image_pam_pipe_demuxer' : files('img2dec.c','img2.c'), + 'image_pbm_pipe_demuxer' : files('img2dec.c','img2.c'), @@ -5304,6 +6580,7 @@ index 0000000000..0335c5ba09 + 'ircam_demuxer' : files('ircamdec.c','ircam.c','pcm.c'), + 'ircam_muxer' : files('ircamenc.c','ircam.c','rawenc.c'), + 'iso_media' : files('isom.c'), ++ 'iso_writer' : files('av1.c','avc.c','hevc.c','nal.c','vvc.c','vpcc.c'), + 'iss_demuxer' : files('iss.c'), + 'iv8_demuxer' : files('iv8.c'), + 'ivf_demuxer' : files('ivfdec.c'), @@ -5311,12 +6588,15 @@ index 0000000000..0335c5ba09 + 'ivr_demuxer' : files('rmdec.c','rm.c','rmsipr.c'), + 'jacosub_demuxer' : files('jacosubdec.c','subtitles.c'), + 'jacosub_muxer' : files('jacosubenc.c','rawenc.c'), ++ 'jpegxl_anim_demuxer' : files('jpegxl_anim_dec.c'), + 'jv_demuxer' : files('jvdec.c'), + 'kux_demuxer' : files('flvdec.c'), + 'kvag_demuxer' : files('kvag.c'), + 'kvag_muxer' : files('kvag.c','rawenc.c'), + 'laf_demuxer' : files('lafdec.c'), + 'latm_muxer' : files('latmenc.c','rawenc.c'), ++ 'lc3_demuxer' : files('lc3.c'), ++ 'lc3_muxer' : files('lc3.c'), + 'libamqp_protocol' : files('libamqp.c','urldecode.c'), + 'libc_msvcrt' : files('file_open.c'), + 'libgme_demuxer' : files('libgme.c'), @@ -5329,7 +6609,7 @@ index 0000000000..0335c5ba09 + 'librtmpt_protocol' : files('librtmp.c'), + 'librtmp_protocol' : files('librtmp.c'), + 'libsmbclient_protocol' : files('libsmbclient.c'), -+ 'libsrt_protocol' : files('libsrt.c'), ++ 'libsrt_protocol' : files('libsrt.c','urldecode.c'), + 'libssh_protocol' : files('libssh.c'), + 'libtls' : files('tls_libtls.c'), + 'libzmq_protocol' : files('libzmq.c'), @@ -5344,7 +6624,7 @@ index 0000000000..0335c5ba09 + 'm4v_demuxer' : files('m4vdec.c','rawdec.c'), + 'm4v_muxer' : files('rawenc.c'), + 'matroska_demuxer' : files('matroskadec.c','matroska.c','flac_picture.c','rmsipr.c','oggparsevorbis.c','vorbiscomment.c','qtpalette.c','replaygain.c','dovi_isom.c'), -+ 'matroska_muxer' : files('matroskaenc.c','matroska.c','av1.c','avc.c','hevc.c','flacenc_header.c','avlanguage.c','vorbiscomment.c','wv.c','dovi_isom.c'), ++ 'matroska_muxer' : files('matroskaenc.c','matroska.c','flacenc_header.c','avlanguage.c','vorbiscomment.c','wv.c','dovi_isom.c'), + 'mbedtls' : files('tls_mbedtls.c'), + 'mca_demuxer' : files('mca.c'), + 'mcc_demuxer' : files('mccdec.c','subtitles.c'), @@ -5368,7 +6648,7 @@ index 0000000000..0335c5ba09 + 'mods_demuxer' : files('mods.c'), + 'moflex_demuxer' : files('moflex.c'), + 'mov_demuxer' : files('mov.c','mov_chan.c','mov_esds.c','qtpalette.c','replaygain.c','dovi_isom.c'), -+ 'mov_muxer' : files('movenc.c','av1.c','avc.c','hevc.c','vpcc.c','movenchint.c','mov_chan.c','rtp.c','movenccenc.c','movenc_ttml.c','rawutils.c','dovi_isom.c'), ++ 'mov_muxer' : files('movenc.c','movenchint.c','mov_chan.c','rtp.c','movenccenc.c','movenc_ttml.c','rawutils.c','dovi_isom.c','evc.c'), + 'mp2_muxer' : files('rawenc.c'), + 'mp3_demuxer' : files('mp3dec.c','replaygain.c'), + 'mp3_muxer' : files('mp3enc.c','rawenc.c','id3v2enc.c'), @@ -5398,7 +6678,7 @@ index 0000000000..0335c5ba09 + 'mvi_demuxer' : files('mvi.c'), + 'mv_demuxer' : files('mvdec.c'), + 'mxf_demuxer' : files('mxfdec.c','mxf.c','avlanguage.c'), -+ 'mxf_muxer' : files('mxfenc.c','mxf.c','avc.c'), ++ 'mxf_muxer' : files('mxfenc.c','mxf.c'), + 'mxg_demuxer' : files('mxg.c'), + 'nc_demuxer' : files('ncdec.c'), + 'network' : files('network.c'), @@ -5419,6 +6699,7 @@ index 0000000000..0335c5ba09 + 'oma_muxer' : files('omaenc.c','rawenc.c','oma.c','id3v2enc.c'), + 'openssl' : files('tls_openssl.c'), + 'opus_muxer' : files('oggenc.c','vorbiscomment.c'), ++ 'osq_demuxer' : files('osq.c','rawdec.c'), + 'paf_demuxer' : files('paf.c'), + 'pcm_alaw_demuxer' : files('pcmdec.c','pcm.c'), + 'pcm_alaw_muxer' : files('pcmenc.c','rawenc.c'), @@ -5462,6 +6743,7 @@ index 0000000000..0335c5ba09 + 'pcm_u8_muxer' : files('pcmenc.c','rawenc.c'), + 'pcm_vidc_demuxer' : files('pcmdec.c','pcm.c'), + 'pcm_vidc_muxer' : files('pcmenc.c','rawenc.c'), ++ 'pdv_demuxer' : files('pdvdec.c'), + 'pipe_protocol' : files('file.c'), + 'pjs_demuxer' : files('pjsdec.c','subtitles.c'), + 'pmp_demuxer' : files('pmpdec.c'), @@ -5470,9 +6752,12 @@ index 0000000000..0335c5ba09 + 'pva_demuxer' : files('pva.c'), + 'pvf_demuxer' : files('pvfdec.c','pcm.c'), + 'qcp_demuxer' : files('qcp.c'), ++ 'qoa_demuxer' : files('qoadec.c'), + 'r3d_demuxer' : files('r3d.c'), + 'rawvideo_demuxer' : files('rawvideodec.c'), + 'rawvideo_muxer' : files('rawenc.c'), ++ 'rcwt_demuxer' : files('rcwtdec.c','subtitles.c'), ++ 'rcwt_muxer' : files('rcwtenc.c','subtitles.c'), + 'realtext_demuxer' : files('realtextdec.c','subtitles.c'), + 'redspark_demuxer' : files('redspark.c'), + 'riffdec' : files('riffdec.c'), @@ -5496,7 +6781,7 @@ index 0000000000..0335c5ba09 + 'rtpdec' : files('rdt.c','rtp.c','rtpdec.c','rtpdec_ac3.c','rtpdec_amr.c','rtpdec_asf.c','rtpdec_dv.c','rtpdec_g726.c','rtpdec_h261.c','rtpdec_h263.c','rtpdec_h263_rfc2190.c','rtpdec_h264.c','rtpdec_hevc.c','rtpdec_ilbc.c','rtpdec_jpeg.c','rtpdec_latm.c','rtpdec_mpa_robust.c','rtpdec_mpeg12.c','rtpdec_mpeg4.c','rtpdec_mpegts.c','rtpdec_qcelp.c','rtpdec_qdm2.c','rtpdec_qt.c','rtpdec_rfc4175.c','rtpdec_svq3.c','rtpdec_vc2hq.c','rtpdec_vp8.c','rtpdec_vp9.c','rtpdec_xiph.c'), + 'rtpenc_chain' : files('rtpenc_chain.c','rtp.c'), + 'rtp_mpegts_muxer' : files('rtpenc_mpegts.c'), -+ 'rtp_muxer' : files('rtp.c','rtpenc_aac.c','rtpenc_latm.c','rtpenc_amr.c','rtpenc_h261.c','rtpenc_h263.c','rtpenc_h263_rfc2190.c','rtpenc_h264_hevc.c','rtpenc_jpeg.c','rtpenc_mpv.c','rtpenc.c','rtpenc_rfc4175.c','rtpenc_vc2hq.c','rtpenc_vp8.c','rtpenc_vp9.c','rtpenc_xiph.c','avc.c','hevc.c'), ++ 'rtp_muxer' : files('rtp.c','rtpenc_aac.c','rtpenc_latm.c','rtpenc_amr.c','rtpenc_h261.c','rtpenc_h263.c','rtpenc_h263_rfc2190.c','rtpenc_h264_hevc.c','rtpenc_jpeg.c','rtpenc_mpv.c','rtpenc.c','rtpenc_rfc4175.c','rtpenc_vc2hq.c','rtpenc_vp8.c','rtpenc_vp9.c','rtpenc_xiph.c'), + 'rtp_protocol' : files('rtpproto.c','ip.c'), + 'rtsp_demuxer' : files('rtsp.c','rtspdec.c','httpauth.c','urldecode.c'), + 'rtsp_muxer' : files('rtsp.c','rtspenc.c','httpauth.c','urldecode.c'), @@ -5577,6 +6862,7 @@ index 0000000000..0335c5ba09 + 'udp_protocol' : files('udp.c','ip.c'), + 'uncodedframecrc_muxer' : files('uncodedframecrcenc.c','framehash.c'), + 'unix_protocol' : files('unix.c'), ++ 'usm_demuxer' : files('usmdec.c'), + 'v210x_demuxer' : files('rawvideodec.c'), + 'v210_demuxer' : files('rawvideodec.c'), + 'vag_demuxer' : files('vag.c'), @@ -5594,6 +6880,8 @@ index 0000000000..0335c5ba09 + 'vpk_demuxer' : files('vpk.c'), + 'vplayer_demuxer' : files('vplayerdec.c','subtitles.c'), + 'vqf_demuxer' : files('vqf.c'), ++ 'vvc_demuxer' : files('vvcdec.c','rawdec.c'), ++ 'vvc_muxer' : files('rawenc.c'), + 'w64_demuxer' : files('wavdec.c','w64.c','pcm.c'), + 'w64_muxer' : files('wavenc.c','w64.c'), + 'wady_demuxer' : files('wady.c','pcm.c'), @@ -5651,16 +6939,20 @@ index 0000000000..0335c5ba09 +libavformat_shlib_sources = files( + 'log2_tab.c', + 'to_upper4.c', ++ 'bitstream.c', +) + +libavformat_shlib_optional_sources = { + 'flv_muxer' : files('mpeg4audio_sample_rates.c'), + 'hls_demuxer' : files('ac3_channel_layout_tab.c'), ++ 'image_jpegxl_pipe_demuxer' : files('jpegxl_parse.c'), + 'iso_media' : files('mpegaudiotabs.c'), ++ 'jni' : files('ffjni.c'), ++ 'jpegxl_anim_demuxer' : files('jpegxl_parse.c'), + 'matroska_demuxer' : files('mpeg4audio_sample_rates.c'), + 'mov_demuxer' : files('ac3_channel_layout_tab.c'), + 'mp3_muxer' : files('mpegaudiotabs.c'), -+ 'mxf_muxer' : files('golomb_tab.c'), ++ 'mxf_muxer' : files('golomb_tab.c','rangecoder_dec.c'), + 'nut_muxer' : files('mpegaudiotabs.c'), + 'rtpdec' : files('jpegtables.c'), + 'rtp_muxer' : files('golomb_tab.c','jpegtables.c','mpeg4audio_sample_rates.c'), @@ -5706,17 +6998,40 @@ index 0000000000..0335c5ba09 + +install_headers(libavformat_headers, subdir: 'libavformat') + -+configure_file( ++libavformat_ver = configure_file( + input: 'libavformat.v.in', + output: 'libavformat.ver', + configuration: ver_conf, +) +diff --git a/libavformat/tests/.gitignore b/libavformat/tests/.gitignore +new file mode 100644 +index 00000000..cdd0cce0 +--- /dev/null ++++ b/libavformat/tests/.gitignore +@@ -0,0 +1,9 @@ ++/fifo_muxer ++/imf ++/movenc ++/noproxy ++/rtmpdh ++/seek ++/srtp ++/url ++/seek_utils +diff --git a/libavutil/.gitignore b/libavutil/.gitignore +new file mode 100644 +index 00000000..4dc74667 +--- /dev/null ++++ b/libavutil/.gitignore +@@ -0,0 +1,2 @@ ++/avconfig.h ++/ffversion.h diff --git a/libavutil/aarch64/meson.build b/libavutil/aarch64/meson.build new file mode 100644 -index 0000000000..abf6ac6617 +index 00000000..eaef7861 --- /dev/null +++ b/libavutil/aarch64/meson.build -@@ -0,0 +1,43 @@ +@@ -0,0 +1,44 @@ +libavutil_aarch64_sources = files( + 'cpu.c', + 'float_dsp_init.c', @@ -5760,12 +7075,13 @@ index 0000000000..abf6ac6617 + +libavutil_aarch64_optional_tests = { +} ++ diff --git a/libavutil/arm/meson.build b/libavutil/arm/meson.build new file mode 100644 -index 0000000000..186609dfb9 +index 00000000..d85b76cd --- /dev/null +++ b/libavutil/arm/meson.build -@@ -0,0 +1,47 @@ +@@ -0,0 +1,48 @@ +libavutil_arm_sources = files( + 'cpu.c', + 'float_dsp_init_arm.c', @@ -5813,9 +7129,23 @@ index 0000000000..186609dfb9 + +libavutil_arm_optional_tests = { +} ++ +diff --git a/libavutil/file.c b/libavutil/file.c +index db850728..4ef940a6 100644 +--- a/libavutil/file.c ++++ b/libavutil/file.c +@@ -112,7 +112,7 @@ int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, + return -1; + } + +- ptr = MapViewOfFile(mh, FILE_MAP_READ, 0, 0, *size); ++ ptr = MapViewOfFile(mh, FILE_MAP_COPY, 0, 0, *size); + CloseHandle(mh); + if (!ptr) { + av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in MapViewOfFile()\n"); diff --git a/libavutil/libavutil.v.in b/libavutil/libavutil.v.in new file mode 100644 -index 0000000000..a4037cf0b8 +index 00000000..a4037cf0 --- /dev/null +++ b/libavutil/libavutil.v.in @@ -0,0 +1,6 @@ @@ -5827,10 +7157,10 @@ index 0000000000..a4037cf0b8 +}; diff --git a/libavutil/meson.build b/libavutil/meson.build new file mode 100644 -index 0000000000..7a7595d487 +index 00000000..4deb7f8d --- /dev/null +++ b/libavutil/meson.build -@@ -0,0 +1,350 @@ +@@ -0,0 +1,358 @@ +#### --- GENERATED --- #### + +libavutil_sources = files( @@ -5860,6 +7190,7 @@ index 0000000000..7a7595d487 + 'encryption_info.c', + 'error.c', + 'eval.c', ++ 'executor.c', + 'fifo.c', + 'file.c', + 'file_open.c', @@ -5871,6 +7202,7 @@ index 0000000000..7a7595d487 + 'hdr_dynamic_vivid_metadata.c', + 'hmac.c', + 'hwcontext.c', ++ 'iamf.c', + 'imgutils.c', + 'integer.c', + 'intmath.c', @@ -5902,6 +7234,7 @@ index 0000000000..7a7595d487 + 'threadmessage.c', + 'time.c', + 'timecode.c', ++ 'timestamp.c', + 'tree.c', + 'twofish.c', + 'utils.c', @@ -5915,6 +7248,7 @@ index 0000000000..7a7595d487 + 'uuid.c', + 'version.c', + 'video_enc_params.c', ++ 'video_hint.c', + 'film_grain_params.c', +) + @@ -5949,6 +7283,7 @@ index 0000000000..7a7595d487 + 'encryption_info.h', + 'error.h', + 'eval.h', ++ 'executor.h', + 'fifo.h', + 'file.h', + 'frame.h', @@ -5959,6 +7294,7 @@ index 0000000000..7a7595d487 + 'hwcontext.h', + 'hwcontext_cuda.h', + 'hwcontext_d3d11va.h', ++ 'hwcontext_d3d12va.h', + 'hwcontext_drm.h', + 'hwcontext_dxva2.h', + 'hwcontext_qsv.h', @@ -5968,6 +7304,7 @@ index 0000000000..7a7595d487 + 'hwcontext_videotoolbox.h', + 'hwcontext_vdpau.h', + 'hwcontext_vulkan.h', ++ 'iamf.h', + 'imgutils.h', + 'intfloat.h', + 'intreadwrite.h', @@ -6009,11 +7346,14 @@ index 0000000000..7a7595d487 + 'tea.h', + 'tx.h', + 'film_grain_params.h', ++ 'video_hint.h', +) + +libavutil_optional_sources = { ++ '!vulkan' : files('hwcontext_stub.c'), + 'cuda' : files('hwcontext_cuda.c'), + 'd3d11va' : files('hwcontext_d3d11va.c'), ++ 'd3d12va' : files('hwcontext_d3d12va.c'), + 'dxva2' : files('hwcontext_dxva2.c'), + 'libdrm' : files('hwcontext_drm.c'), + 'macos_kperf' : files('macos_kperf.c'), @@ -6023,7 +7363,7 @@ index 0000000000..7a7595d487 + 'vaapi' : files('hwcontext_vaapi.c'), + 'vdpau' : files('hwcontext_vdpau.c'), + 'videotoolbox' : files('hwcontext_videotoolbox.c'), -+ 'vulkan' : files('hwcontext_vulkan.c','hwcontext_stub.c'), ++ 'vulkan' : files('hwcontext_vulkan.c','vulkan.c'), +} + +libavutil_x86asm_optional_sources = { @@ -6097,6 +7437,7 @@ index 0000000000..7a7595d487 + ['ripemd', files('tests/ripemd.c')], + ['sha', files('tests/sha.c')], + ['sha512', files('tests/sha512.c')], ++ ['side_data_array', files('tests/side_data_array.c')], + ['softfloat', files('tests/softfloat.c')], + ['tree', files('tests/tree.c')], + ['twofish', files('tests/twofish.c')], @@ -6118,9 +7459,6 @@ index 0000000000..7a7595d487 + 'extra_libs': ['threads'], # MANUAL + }], + ], -+ 'pixelutils': [ -+ ['pixelutils', files('tests/pixelutils.c'), {}] # MANUAL -+ ], +} + +#### --- END GENERATED --- #### @@ -6154,7 +7492,7 @@ index 0000000000..7a7595d487 +ver_conf.set('minorver', minorver) +ver_conf.set('microver', microver) + -+configure_file( ++libavutil_ver = configure_file( + input: 'libavutil.v.in', + output: 'libavutil.ver', + configuration: ver_conf, @@ -6181,9 +7519,69 @@ index 0000000000..7a7595d487 +subdir('x86') + +libavutil_sources += compat_objs +diff --git a/libavutil/tests/.gitignore b/libavutil/tests/.gitignore +new file mode 100644 +index 00000000..951cafb2 +--- /dev/null ++++ b/libavutil/tests/.gitignore +@@ -0,0 +1,54 @@ ++/adler32 ++/aes ++/aes_ctr ++/atomic ++/audio_fifo ++/avstring ++/base64 ++/blowfish ++/bprint ++/camellia ++/cast5 ++/channel_layout ++/color_utils ++/cpu ++/cpu_init ++/crc ++/des ++/dict ++/display ++/error ++/encryption_info ++/eval ++/fifo ++/file ++/hash ++/hmac ++/hwdevice ++/imgutils ++/integer ++/lfg ++/lls ++/log ++/lzo ++/md5 ++/murmur3 ++/opt ++/parseutils ++/pca ++/pixdesc ++/pixelutils ++/pixfmt_best ++/random_seed ++/rational ++/ripemd ++/sha ++/sha512 ++/side_data_array ++/softfloat ++/tea ++/tree ++/twofish ++/utf8 ++/uuid ++/xtea diff --git a/libavutil/version.py b/libavutil/version.py new file mode 100644 -index 0000000000..8b133f0860 +index 00000000..8b133f08 --- /dev/null +++ b/libavutil/version.py @@ -0,0 +1,99 @@ @@ -6288,10 +7686,10 @@ index 0000000000..8b133f0860 + f.write('#define FFMPEG_VERSION "%s"\n' % revision) diff --git a/libavutil/x86/meson.build b/libavutil/x86/meson.build new file mode 100644 -index 0000000000..a892ad0548 +index 00000000..a80c3238 --- /dev/null +++ b/libavutil/x86/meson.build -@@ -0,0 +1,53 @@ +@@ -0,0 +1,54 @@ +libavutil_x86_sources = files( + 'cpu.c', + 'fixed_dsp_init.c', @@ -6345,9 +7743,10 @@ index 0000000000..a892ad0548 + +libavutil_x86_optional_tests = { +} ++ diff --git a/libpostproc/libpostproc.v.in b/libpostproc/libpostproc.v.in new file mode 100644 -index 0000000000..c6ef9b3963 +index 00000000..c6ef9b39 --- /dev/null +++ b/libpostproc/libpostproc.v.in @@ -0,0 +1,7 @@ @@ -6360,7 +7759,7 @@ index 0000000000..c6ef9b3963 +}; diff --git a/libpostproc/meson.build b/libpostproc/meson.build new file mode 100644 -index 0000000000..633e9f76df +index 00000000..69319b54 --- /dev/null +++ b/libpostproc/meson.build @@ -0,0 +1,69 @@ @@ -6428,17 +7827,17 @@ index 0000000000..633e9f76df + +install_headers(libpostproc_headers, subdir: 'libpostproc') + -+configure_file( ++libpostproc_ver = configure_file( + input: 'libpostproc.v.in', + output: 'libpostproc.ver', + configuration: ver_conf, +) diff --git a/libswresample/aarch64/meson.build b/libswresample/aarch64/meson.build new file mode 100644 -index 0000000000..da998259e1 +index 00000000..18c269a6 --- /dev/null +++ b/libswresample/aarch64/meson.build -@@ -0,0 +1,43 @@ +@@ -0,0 +1,44 @@ +libswresample_aarch64_sources = files( + 'audio_convert_init.c', + 'resample_init.c', @@ -6482,12 +7881,13 @@ index 0000000000..da998259e1 + +libswresample_aarch64_optional_tests = { +} ++ diff --git a/libswresample/arm/meson.build b/libswresample/arm/meson.build new file mode 100644 -index 0000000000..bc98c24840 +index 00000000..9ec1b57f --- /dev/null +++ b/libswresample/arm/meson.build -@@ -0,0 +1,43 @@ +@@ -0,0 +1,44 @@ +libswresample_arm_sources = files( + 'audio_convert_init.c', + 'resample_init.c', @@ -6531,9 +7931,10 @@ index 0000000000..bc98c24840 + +libswresample_arm_optional_tests = { +} ++ diff --git a/libswresample/libswresample.v.in b/libswresample/libswresample.v.in new file mode 100644 -index 0000000000..575e99e0d6 +index 00000000..575e99e0 --- /dev/null +++ b/libswresample/libswresample.v.in @@ -0,0 +1,7 @@ @@ -6546,7 +7947,7 @@ index 0000000000..575e99e0d6 +}; diff --git a/libswresample/meson.build b/libswresample/meson.build new file mode 100644 -index 0000000000..9415557357 +index 00000000..89977c95 --- /dev/null +++ b/libswresample/meson.build @@ -0,0 +1,89 @@ @@ -6630,7 +8031,7 @@ index 0000000000..9415557357 + +install_headers(libswresample_headers, subdir: 'libswresample') + -+configure_file( ++libswresample_ver = configure_file( + input: 'libswresample.v.in', + output: 'libswresample.ver', + configuration: ver_conf, @@ -6639,12 +8040,19 @@ index 0000000000..9415557357 +subdir('aarch64') +subdir('arm') +subdir('x86') +diff --git a/libswresample/tests/.gitignore b/libswresample/tests/.gitignore +new file mode 100644 +index 00000000..2dc986bd +--- /dev/null ++++ b/libswresample/tests/.gitignore +@@ -0,0 +1 @@ ++/swresample diff --git a/libswresample/x86/meson.build b/libswresample/x86/meson.build new file mode 100644 -index 0000000000..5907491058 +index 00000000..3d84d506 --- /dev/null +++ b/libswresample/x86/meson.build -@@ -0,0 +1,45 @@ +@@ -0,0 +1,46 @@ +libswresample_x86_sources = files( + 'audio_convert_init.c', + 'rematrix_init.c', @@ -6690,12 +8098,13 @@ index 0000000000..5907491058 + +libswresample_x86_optional_tests = { +} ++ diff --git a/libswscale/aarch64/meson.build b/libswscale/aarch64/meson.build new file mode 100644 -index 0000000000..f3444967ff +index 00000000..a331382f --- /dev/null +++ b/libswscale/aarch64/meson.build -@@ -0,0 +1,45 @@ +@@ -0,0 +1,49 @@ +libswscale_aarch64_sources = files( + 'rgb2rgb.c', + 'swscale.c', @@ -6719,8 +8128,11 @@ index 0000000000..f3444967ff + +libswscale_aarch64_neon_sources = files( + 'hscale.S', ++ 'input.S', + 'output.S', ++ 'range_convert_neon.S', + 'rgb2rgb_neon.S', ++ 'swscale_unscaled_neon.S', + 'yuv2rgb_neon.S', +) + @@ -6741,12 +8153,13 @@ index 0000000000..f3444967ff + +libswscale_aarch64_optional_tests = { +} ++ diff --git a/libswscale/arm/meson.build b/libswscale/arm/meson.build new file mode 100644 -index 0000000000..af5e49fb38 +index 00000000..ae1b20f1 --- /dev/null +++ b/libswscale/arm/meson.build -@@ -0,0 +1,45 @@ +@@ -0,0 +1,46 @@ +libswscale_arm_sources = files( + 'swscale.c', + 'swscale_unscaled.c', @@ -6792,9 +8205,10 @@ index 0000000000..af5e49fb38 + +libswscale_arm_optional_tests = { +} ++ diff --git a/libswscale/libswscale.v.in b/libswscale/libswscale.v.in new file mode 100644 -index 0000000000..518b7abd8d +index 00000000..518b7abd --- /dev/null +++ b/libswscale/libswscale.v.in @@ -0,0 +1,7 @@ @@ -6807,7 +8221,7 @@ index 0000000000..518b7abd8d +}; diff --git a/libswscale/meson.build b/libswscale/meson.build new file mode 100644 -index 0000000000..732e695efc +index 00000000..04a09790 --- /dev/null +++ b/libswscale/meson.build @@ -0,0 +1,98 @@ @@ -6900,7 +8314,7 @@ index 0000000000..732e695efc + +install_headers(libswscale_headers, subdir: 'libswscale') + -+configure_file( ++libswscale_ver = configure_file( + input: 'libswscale.v.in', + output: 'libswscale.ver', + configuration: ver_conf, @@ -6909,12 +8323,22 @@ index 0000000000..732e695efc +subdir('aarch64') +subdir('arm') +subdir('x86') +diff --git a/libswscale/tests/.gitignore b/libswscale/tests/.gitignore +new file mode 100644 +index 00000000..c56abf0e +--- /dev/null ++++ b/libswscale/tests/.gitignore +@@ -0,0 +1,4 @@ ++/colorspace ++/floatimg_cmp ++/pixdesc_query ++/swscale diff --git a/libswscale/x86/meson.build b/libswscale/x86/meson.build new file mode 100644 -index 0000000000..553e27c70d +index 00000000..e69dbf39 --- /dev/null +++ b/libswscale/x86/meson.build -@@ -0,0 +1,53 @@ +@@ -0,0 +1,55 @@ +libswscale_x86_sources = files( + 'rgb2rgb.c', + 'swscale.c', @@ -6930,6 +8354,7 @@ index 0000000000..553e27c70d + 'output.asm', + 'scale.asm', + 'scale_avx2.asm', ++ 'range_convert.asm', + 'rgb_2_rgb.asm', + 'yuv_2_rgb.asm', + 'yuv2yuvX.asm', @@ -6968,12 +8393,13 @@ index 0000000000..553e27c70d + +libswscale_x86_optional_tests = { +} ++ diff --git a/meson.build b/meson.build new file mode 100644 -index 0000000000..904a254cab +index 00000000..7bdf410d --- /dev/null +++ b/meson.build -@@ -0,0 +1,3584 @@ +@@ -0,0 +1,3907 @@ +# Copyright (c) 2018 Mathieu Duponchelle +# Copyright (c) 2023 L. E. Segovia +# @@ -6992,13 +8418,12 @@ index 0000000000..904a254cab +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, see . + -+project('FFmpeg', 'c', -+ meson_version: '>= 0.60', ++project('FFmpeg', 'c', 'cpp', ++ meson_version: '>= 0.64', + license: 'LGPL2.1+', -+ # C11 is needed for Metal support + # Static libraries by default following upstream -+ default_options: [ 'buildtype=debugoptimized', 'c_std=c11', 'cpp_std=c++11', 'default_library=static'], -+ version: '6.0.0', ++ default_options: [ 'buildtype=debugoptimized', 'c_std=c17', 'cpp_std=c++11', 'default_library=static'], ++ version: '7.1', +) + +# HOWTO: @@ -7080,7 +8505,7 @@ index 0000000000..904a254cab +endif + +project_c_args = [ -+ '-D_ISOC99_SOURCE', ++ '-D_ISOC11_SOURCE', + '-D_GNU_SOURCE', + '-D_LARGEFILE_SOURCE', + '-Wno-parentheses', @@ -7103,6 +8528,20 @@ index 0000000000..904a254cab + project_c_args += ['-std=c11'] +endif + ++if not cc.compiles('''#include ++#include ++struct Foo { ++ int a; ++ void *ptr; ++} obj; ++static_assert(offsetof(struct Foo, a) == 0, ++ "First element of struct does not have offset 0"); ++_Static_assert(offsetof(struct Foo, ptr) >= offsetof(struct Foo, a) + sizeof(obj.a), ++ "elements not properly ordered in struct");''', ++ name: 'Supports C11 static assertions') ++ error('Compiler lacks support for C11 static assertions') ++endif ++ +project_c_args = cc.get_supported_arguments(project_c_args) + +thread_dep = dependency('threads') @@ -7154,12 +8593,7 @@ index 0000000000..904a254cab + +arch_list = [ + 'aarch64', -+ 'alpha', + 'arm', -+ 'avr32', -+ 'avr32_ap', -+ 'avr32_uc', -+ 'bfin', + 'ia64', + 'loongarch', + 'loongarch32', @@ -7172,7 +8606,6 @@ index 0000000000..904a254cab + 'ppc64', + 'riscv', + 's390', -+ 'sh4', + 'sparc', + 'sparc64', + 'tilegx', @@ -7188,6 +8621,8 @@ index 0000000000..904a254cab + 'armv6', + 'armv6t2', + 'armv8', ++ 'dotprod', ++ 'i8mm', + 'neon', + 'vfp', + 'vfpv3', @@ -7264,13 +8699,10 @@ index 0000000000..904a254cab +] + +builtin_list = [ -+ 'atomic_cas_ptr', -+ 'machine_rw_barrier', + 'MemoryBarrier', + 'mm_empty', + 'rdtsc', + 'sem_timedwait', -+ 'sync_val_compare_and_swap', +] + +have_list_cmdline = [ @@ -7286,6 +8718,7 @@ index 0000000000..904a254cab + +headers_list = [ + 'arpa_inet_h', ++ 'asm_hwprobe_h', + 'asm_types_h', + 'cdio_paranoia_h', + 'cdio_paranoia_paranoia_h', @@ -7311,6 +8744,8 @@ index 0000000000..904a254cab + 'opencv2_core_core_c_h', + 'OpenGL_gl3_h', + 'poll_h', ++ 'pthread_np_h', ++ 'sys_hwprobe_h', + 'sys_param_h', + 'sys_resource_h', + 'sys_select_h', @@ -7328,6 +8763,7 @@ index 0000000000..904a254cab + +intrinsics_list = [ + 'intrinsics_neon', ++ 'intrinsics_sse2', +] + +math_funcs = [ @@ -7379,6 +8815,7 @@ index 0000000000..904a254cab + 'clock_gettime', + 'closesocket', + 'CommandLineToArgvW', ++ 'elf_aux_info', + 'fcntl', + 'getaddrinfo', + 'getauxval', @@ -7413,6 +8850,8 @@ index 0000000000..904a254cab + 'posix_memalign', + 'prctl', + 'pthread_cancel', ++ 'pthread_set_name_np', ++ 'pthread_setname_np', + 'sched_getaffinity', + 'SecItemImport', + 'SetConsoleTextAttribute', @@ -7423,6 +8862,8 @@ index 0000000000..904a254cab + 'strerror_r', + 'sysconf', + 'sysctl', ++ 'sysctlbyname', ++ 'tempnam', + 'usleep', + 'UTGetOSTypeFromString', + 'VirtualAlloc', @@ -7442,8 +8883,14 @@ index 0000000000..904a254cab + 'w32threads', +] + ++atomics_list = [ ++ 'atomics_win32', ++] ++ +toolchain_features = [ + 'as_arch_directive', ++ 'as_archext_dotprod_directive', ++ 'as_archext_i8mm_directive', + 'as_dn_directive', + 'as_fpu_directive', + 'as_func', @@ -7501,6 +8948,7 @@ index 0000000000..904a254cab + 'struct_sockaddr_storage', + 'struct_stat_st_mtim_tv_nsec', + 'struct_v4l2_frmivalenum_discrete', ++ 'struct_mfxConfigInterface', +] + +asm = get_option('asm') @@ -7510,10 +8958,12 @@ index 0000000000..904a254cab +conf.set10('faan', true) +conf.set10('faandct', true) +conf.set10('faanidct', true) ++conf.set10('iamf', true) +conf.set10('optimizations', get_option('optimization') != '0') +conf.set10('runtime_cpudetect', true) +conf.set10('safe_bitstream_reader', true) +conf.set10('swscale_alpha', true) ++assert_level = get_option('assert_level') + +if inline_asm.allowed() + conf.set10('inline_asm', @@ -7551,17 +9001,19 @@ index 0000000000..904a254cab + 'opencl_dxva2', + 'opencl_vaapi_beignet', + 'opencl_vaapi_intel_media', ++ 'opencl_videotoolbox', + 'perl', + 'pod2man', ++ 'posix_ioctl', + 'texi2html', + 'xmllint', -+ 'zlib_gzip' ++ 'zlib_gzip', +]) + +arch_features = [ + ['aligned_stack', ['aarch64', 'ppc', 'x86']], -+ ['fast_64bit', ['aarch64', 'alpha', 'ia64', 'mips64', 'parisc64', 'ppc64', 'riscv64', 'sparc64', 'x86_64']], -+ ['fast_clz', ['aarch64', 'alpha', 'avr32', 'mips', 'ppc', 'x86']], ++ ['fast_64bit', ['aarch64', 'ia64', 'mips64', 'parisc64', 'ppc64', 'riscv64', 'sparc64', 'x86_64']], ++ ['fast_clz', ['aarch64', 'mips', 'ppc', 'x86']], + ['simd_align_16', ['altivec', 'neon', 'sse']], + ['simd_align_32', ['avx']], + ['simd_align_64', ['avx512']], @@ -7625,6 +9077,8 @@ index 0000000000..904a254cab + 'frei0r', + 'libcdio', + 'libdavs2', ++ 'libdvdnav', ++ 'libdvdread', + 'librubberband', + 'libvidstab', + 'libx264', @@ -7768,6 +9222,8 @@ index 0000000000..904a254cab + +conf.set10('float16', cc.has_type('_Float16', args: project_c_args)) + ++conf.set10('max_align_t', cc.has_type('max_align_t', args: project_c_args)) ++ +if libc_type != '' + conf.set('libc_@0@'.format(libc_type), 1) +endif @@ -7779,6 +9235,9 @@ index 0000000000..904a254cab +conf.set10('winrt', cc.links(cpp_cond.format('windows.h', '!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)'))) + +d3d11va_extra_deps = [] ++d3d12va_extra_deps = [] ++vaapi_win32_extra_deps = [] ++mediafoundation_extra_deps = [] + +conf.set10('uwp', cc.compiles('''#ifdef WINAPI_FAMILY +#include @@ -7791,10 +9250,23 @@ index 0000000000..904a254cab +#error no family set +#endif''', name: 'is UWP')) +if conf.get('uwp') == 1 ++ # In UWP mode, we can't use LoadLibrary+GetProcAddress to conditionally ++ # try to load these APIs at runtime, like we do in regular desktop mode - ++ # therefore, we need to link directly against these APIs. + d3d11va_extra_deps += [ + cc.find_library('dxgi'), + cc.find_library('d3d11') + ] ++ d3d12va_extra_deps += [ ++ cc.find_library('dxgi'), ++ cc.find_library('d3d12') ++ ] ++ vaapi_win32_extra_deps += [ ++ cc.find_library('dxgi'), ++ ] ++ mediafoundation_extra_deps += [ ++ cc.find_library('mfplat'), ++ ] +endif + +check_framework = [ @@ -7831,7 +9303,7 @@ index 0000000000..904a254cab + ['libgme', ['gme/gme.h'], ['gme_new_emu'], {}], + ['gnutls', ['gnutls/gnutls.h'], ['gnutls_global_init'], {}], + ['lcms2', ['lcms2.h'], ['cmsCreateContext'], {'pkg': 'lcms2', 'version': '>= 2.13'}], -+ ['libaom', ['aom/aom_codec.h'], ['aom_codec_version'], {'pkg': 'aom', 'version': '>= 0.1.0'}], ++ ['libaom', ['aom/aom_codec.h'], ['aom_codec_version'], {'pkg': 'aom', 'version': '>= 2.0.0'}], + ['libaribb24', ['aribb24/aribb24.h'], ['arib_instance_new'], {'pkg': 'aribb24', 'version': '> 1.0.3'}], + ['lv2', ['lilv-0/lilv/lilv.h'], ['lilv_world_new'], {'pkg': 'lilv-0'}], + ['libass', ['ass/ass.h'], ['ass_library_init'], {'pkg': 'libass', 'version': '>= 0.11.0'}], @@ -7843,6 +9315,8 @@ index 0000000000..904a254cab + ['libdavs2', ['davs2.h'], ['davs2_decoder_open'], {'pkg': 'davs2', 'version': '>= 1.6.0'}], + ['libdc1394', ['dc1394/dc1394.h'], ['dc1394_new'], {'pkg': 'libdc1394-2'}], + ['libdrm', ['xf86drm.h'], ['drmGetVersion'], {}], ++ ['libdvdnav', ['dvdnav/dvdnav.h'], ['dvdnav_open2'], {'pkg': 'dvdnav', ' version': '>= 6.1.1'}], ++ ['libdvdread', ['dvdread/dvd_reader.h'], ['DVDOpen2'], {'pkg': 'dvdread', ' version': '>= 6.1.2'}], + ['libfdk_aac', ['fdk-aac/aacenc_lib.h'], ['aacEncOpen'], {'pkg': 'fdk-aac'}], + ['libfontconfig', ['fontconfig/fontconfig.h'], ['FcInit'], {'pkg': 'fontconfig'}], + ['libfreetype', ['ft2build.h', 'FT_FREETYPE_H'], ['FT_Init_FreeType'], {'pkg': 'freetype2'}], @@ -7851,12 +9325,14 @@ index 0000000000..904a254cab + ['libjxl', ['jxl/decode.h'], ['JxlDecoderVersion'], {'pkg': 'libjxl', 'version': '>= 0.7.0'}], + ['libklvanc', ['libklvanc/vanc.h'], ['klvanc_context_create'], {}], + ['libkvazaar', ['kvazaar.h'], ['kvz_api_get'], {'pkg': 'kvazaar', 'version': '>= 0.8.1'}], ++ ['liblc3', ['lc3.h'], ['lc3_hr_setup_encoder'], {'pkg': 'lc3', 'version': ['>= 1.1.0']}], + ['liblensfun', ['lensfun.h'], ['lf_db_new'], {'pkg': 'lensfun'}], ++ ['liblcevc_dec', ['LCEVC/lcevc_dec.h'], ['LCEVC_CreateDecoder'], {'pkg': 'lcevc_dec', 'version': ['>= 2.0.0']}], + ['libmfx', ['mfx/mfxvideo.h'], ['MFXInit'], {'pkg': 'libmfx', 'version': ['>= 1.28', '< 2.0']}], + ['libmodplug', ['libmodplug/modplug.h'], ['ModPlug_Load'], {}], + ['libopencv', ['opencv2/core/core_c.h'], ['cvCreateImageHeader'], {'pkg': 'opencv'}], + ['libopencv', ['opencv/cxcore.h'], ['cvCreateImageHeader'], {'pkg': 'opencv'}], -+ ['libopenh264', ['wels/codec_api.h'], ['WelsGetCodecVersion'], {'pkg': 'openh264'}], ++ ['libopenh264', ['wels/codec_api.h'], ['WelsGetCodecVersion'], {'pkg': 'openh264', 'version': '>= 1.3.0'}], + ['libdav1d', ['dav1d/dav1d.h'], ['dav1d_version'], {'pkg': 'dav1d', 'version': '>= 0.4.0'}], + ['libopenjpeg', ['openjpeg.h'], ['opj_version'], {'pkg': 'libopenjp2', + 'version': '>= 2.1.0'}], @@ -7867,6 +9343,8 @@ index 0000000000..904a254cab + ['libopus', ['opus_multistream.h'], ['opus_multistream_decoder_create', 'opus_multistream_surround_encoder_create'], {'pkg': 'opus'}], + ['libplacebo', ['libplacebo/vulkan.h'], ['pl_vulkan_create'], {'pkg': 'libplacebo', 'version': '>= 4.192.0'}], + ['libpulse', ['pulse/pulseaudio.h'], ['pa_context_new'], {}], ++ ['libqrencode', ['qrencode.h'], ['QRcode_encodeString'], {}], ++ ['libquirc', ['quirc.h'], ['quirc_decode'], {}], + ['librabbitmq', ['amqp.h'], ['amqp_new_connection'], {'pkg': 'librabbitmq', 'version': '>= 0.7.1'}], + ['librav1e', ['rav1e.h'], ['rav1e_context_new'], {'pkg': 'rav1e', 'version': '>= 0.5.0'}], + ['librist', ['librist/librist.h'], ['rist_receiver_create'], {'pkg': 'rist', 'version': '>= 0.2.7'}], @@ -7881,26 +9359,24 @@ index 0000000000..904a254cab + ['libsrt', ['srt/srt.h'], ['srt_socket'], {'pkg': 'srt', 'version': '>= 1.2.0'}], + ['libsvtav1', ['EbSvtAv1Enc.h'], ['svt_av1_enc_init_handle'], {'pkg': 'SvtAv1Enc', 'version': '>= 0.9.0'}], + ['libtesseract', ['tesseract/capi.h'], ['TessBaseAPICreate'], {'pkg': 'tesseract'}], ++ # FIXME: libtorch needs a C++ check ++ # with the following libraries: -ltorch -lc10 -ltorch_cpu -lpthread ++ # ['libtorch', ['torch/torch.h'], ['torch::Tensor'], {}], + ['libtls', ['tls.h'], ['tls_configure'], {}], + ['libv4l2', ['libv4l2.h'], ['v4l2_ioctl'], {}], + ['libvidstab', ['vid.stab/libvidstab.h'], ['vsMotionDetectInit'], {'pkg': 'vidstab', 'version': '>= 0.98'}], + ['libvmaf', ['libvmaf.h'], ['compute_vmaf'], {'version': '>= 2.0.0'}], + ['libvorbis', ['vorbis/codec.h'], ['vorbis_info_init'], {'pkg': 'vorbis'}], + ['libvorbisenc', ['vorbis/vorbisenc.h'], ['vorbis_encode_init'], {'pkg': 'vorbisenc'}], -+ ['libvpl', ['mfxvideo.h', 'mfxdispatcher.h'], ['MFXLoad'], {'pkg': 'vpl', 'version': '>= 2.6'}], -+ ['libvpx', ['vpx/vpx_decoder.h', 'vpx/vpx_encoder.h'], [], {'pkg': 'vpx', 'version': '>= 1.4.0'}], -+ ['libvpx_vp8_decoder', ['vpx/vpx_decoder.h', 'vpx/vp8dx.h'], ['vpx_codec_vp8_dx'], {'pkg': 'vpx', 'version': '>= 1.4.0'}], -+ ['libvpx_vp8_encoder', ['vpx/vpx_encoder.h', 'vpx/vp8cx.h'], ['vpx_codec_vp8_cx'], {'pkg': 'vpx', 'version': '>= 1.4.0'}], -+ ['libvpx_vp9_decoder', ['vpx/vpx_decoder.h', 'vpx/vp8dx.h'], ['vpx_codec_vp9_dx'], {'pkg': 'vpx', 'version': '>= 1.4.0'}], -+ ['libvpx_vp9_encoder', ['vpx/vpx_encoder.h', 'vpx/vp8cx.h'], ['vpx_codec_vp9_cx'], {'pkg': 'vpx', 'version': '>= 1.4.0'}], -+ ['libwebp', ['webp/encode.h'], ['WebPGetEncoderVersion'], {'version': '>= 0.2.0'}], -+ ['libwebp_anim_encoder', ['webp/mux.h'], ['WebPAnimEncoderOptionsInit'], {'pkg': 'libwebpmux', 'version': '>= 0.4.0'}], ++ ['libvpl', ['mfxvideo.h', 'mfxdispatcher.h'], ['MFXLoad'], {'pkg': 'vpl', 'version': '>= 2.6', 'c_args': '-DMFX_DEPRECATED_OFF'}], ++ ['libvvenc', ['vvenc/vvenc.h'], ['MFXLoad'], {'pkg': 'vpl', 'version': '>= 1.6.1'}], + ['libx264', ['stdint.h', 'x264.h'], ['x264_encoder_encode'], {'pkg': 'x264'}], + ['libx265', ['x265.h'], ['x265_api_get'], {'pkg': 'x265'}], + ['libxcb', ['xcb/xcb.h'], ['xcb_connect'], {'pkg': 'xcb', 'version': '>= 1.4'}], + ['libxcb_shm', ['xcb/shm.h'], ['xcb_shm_attach'], {'pkg': 'xcb-shm'}], + ['libxcb_shape', ['xcb/shape.h'], ['xcb_shape_get_rectangles'], {'pkg': 'xcb-shape'}], + ['libxcb_xfixes', ['xcb/xfixes.h'], ['xcb_xfixes_get_cursor_image'], {'pkg': 'xcb-xfixes'}], ++ ['libxeve', ['xeve.h'], ['xeve_encode'], {'pkg': 'xeve', 'version': '>= 0.5.1'}], + ['libxml2', ['libxml2/libxml/xmlversion.h'], ['xmlCheckVersion'], {'pkg': 'libxml-2.0'}], + ['libzimg', ['zimg.h'], ['zimg_get_api_version'], {'pkg': 'zimg', 'version': '>= 2.7.0'}], + ['libzmq', ['zmq.h'], ['zmq_ctx_new'], {}], @@ -7915,17 +9391,42 @@ index 0000000000..904a254cab + ['rockchip_mpp', ['rockchip/rk_mpi.h'], ['mpp_create'], {'version': '>= 1.3.7'}], + ['sdl2', ['SDL_events.h'], ['SDL_PollEvent'], {'version': ['>= 2.0.1', '< 3.0.0']}], + ['sndio', ['sndio.h'], ['sio_open'], {'pkg': 'sndio'}], -+ ['vapoursynth', ['VSScript.h'], ['vsscript_init'], {'pkg': 'vapoursynth-script', 'version': '>= 42'}], -+ ['vulkan', ['vulkan/vulkan.h'], ['vkCreateInstance'], {'pkg': 'vulkan', 'version': '>= 1.2.189'}], ++ ['vulkan', ['vulkan/vulkan.h'], ['vkCreateInstance'], {'pkg': 'vulkan', 'version': '>= 1.3.277'}], + ['xlib_x11', ['X11/Xlib.h'], ['XPending'], {'pkg': 'xlib'}], + ['xlib_xext', ['X11/Xlib.h', 'X11/extensions/XShm.h'], ['XShmAttach'], {'pkg': 'xext'}], + ['xlib_xv', ['X11/Xlib.h', 'X11/extensions/Xvlib.h'], ['XvGetPortAttribute'], {'pkg': 'xv'}], ++ ['zlib', ['zlib.h'], ['zlibVersion'], {'pkg': 'zlib'}], +] + ++if get_option('libvpx').allowed() ++ check_pkg_config += [ ++ ['libvpx_vp8_decoder', ['vpx/vpx_decoder.h', 'vpx/vp8dx.h'], ['vpx_codec_vp8_dx'], {'pkg': 'vpx', 'version': '>= 1.4.0'}], ++ ['libvpx_vp8_encoder', ['vpx/vpx_encoder.h', 'vpx/vp8cx.h'], ['vpx_codec_vp8_cx'], {'pkg': 'vpx', 'version': '>= 1.4.0'}], ++ ['libvpx_vp9_decoder', ['vpx/vpx_decoder.h', 'vpx/vp8dx.h'], ['vpx_codec_vp9_dx'], {'pkg': 'vpx', 'version': '>= 1.4.0'}], ++ ['libvpx_vp9_encoder', ['vpx/vpx_encoder.h', 'vpx/vp8cx.h'], ['vpx_codec_vp9_cx'], {'pkg': 'vpx', 'version': '>= 1.4.0'}], ++ ] ++endif ++ ++if get_option('libwebp').allowed() ++ check_pkg_config += [ ++ ['libwebp_encoder', ['webp/encode.h'], ['WebPGetEncoderVersion'], {'version': '>= 0.2.0'}], ++ ['libwebp_anim_encoder', ['webp/mux.h'], ['WebPAnimEncoderOptionsInit'], {'pkg': 'libwebpmux', 'version': '>= 0.4.0'}], ++ ] ++endif ++ +foreach check : check_pkg_config + all_checks += [['pkg-config', check]] +endforeach + ++if get_option('opencl').allowed() and get_option('videotoolbox').allowed() ++ dep = dependency('appleframeworks', modules: ['VideoToolbox', 'OpenCL'], required: false) ++ conf.set10('opencl_videotoolbox', false) ++ if cc.has_function('clCreateImageFromIOSurfaceWithPropertiesAPPLE', prefix: '#include ', dependencies: dep) ++ conf.set10(opencl_videotoolbox, true) ++ common_deps += [dep] ++ endif ++endif ++ +conf.set10('vdpau', cc.has_header('vdpau/vdpau.h') and + cc.get_define('VDP_DECODER_PROFILE_MPEG4_PART2_ASP', prefix: '#include ') != '') + @@ -7945,8 +9446,6 @@ index 0000000000..904a254cab + ['clock_gettime', ['time.h'], ['clock_gettime'], []], + ['clock_gettime', ['time.h'], ['clock_gettime'], ['rt']], + ['cuda_sdk', ['cuda.h'], ['cuCtxCreate'], ['cuda']], -+ # FFmpeg deprecated CrystalHD in 6.0 -+ # ['crystalhd', ['stdint.h', 'libcrystalhd/libcrystalhd_if.h'], ['DtsCrystalHDVersion'], ['crystalhd']], + ['frei0r', ['frei0r.h'], [], []], + ['iconv', ['iconv.h'], ['iconv'], ['iconv']], + ['libgme', ['gme/gme.h'], ['gme_new_emu'], ['gme', 'stdc++']], @@ -7993,10 +9492,10 @@ index 0000000000..904a254cab + ['linux_fb_h', ['linux/fb.h'], [], []], + ['lzma', ['lzma.h'], ['lzma_version_number'], ['lzma']], + ['mbedtls', ['mbedtls/ssl.h'], ['mbedtls_ssl_init'], ['mbedtls', 'mbedx509', 'mbedcrypto']], -+ ['mediandk', ['stdint.h', 'media/NdkImage.h'], ['AImage_delete'], ['mediandk']], ++ ['mediandk', ['stdint.h', 'media/NdkMediaFormat.h'], ['AMediaFormat_new'], ['mediandk']], + ['mmal', ['interface/mmal/mmal.h'], ['mmal_port_connect'], ['mmal_core', 'mmal_util', 'mmal_vc_client', 'bcm_host']], + ['nanosleep', ['time.h'], ['nanosleep'], ['rt']], -+ ['ole32', ['windows.h'], ['CoTaskMemFree'], ['ole32']], ++ ['ole32', ['windows.h', 'objbase.h'], ['CoTaskMemFree'], ['ole32']], + ['omx', ['OMX_Core.h'], [], []], + ['openal', ['AL/al.h'], ['alGetError'], ['openal']], + ['openal', ['AL/al.h'], ['alGetError'], ['OpenAL32']], @@ -8004,6 +9503,8 @@ index 0000000000..904a254cab + ['opencl', ['CL/cl.h'], ['clEnqueueNDRangeKernel'], ['OpenCL', disabler()]], + ['opengl', ['GL/glx.h'], ['glXGetProcAddress'], ['GL']], + ['opengl', ['windows.h'], ['wglGetProcAddress'], ['opengl32', 'gdi32']], ++ ['opengl', ['OpenGL/gl3.h'], ['glGetError'], [], {'frameworks': ['OpenGL']}], ++ ['opengl', ['ES2/gl.h'], ['glGetError'], [], {'frameworks': ['OpenGLES']}], + ['openssl', ['openssl/ssl.h'], ['SSL_library_init'], ['ssl', 'crypto']], + ['openssl', ['openssl/ssl.h'], ['SSL_library_init'], ['ssl32', 'eay32']], + ['openssl', ['openssl/ssl.h'], ['SSL_library_init'], ['ssl', 'crypto', 'ws2_32', 'gdi32']], @@ -8013,7 +9514,6 @@ index 0000000000..904a254cab + ['user32', ['windows.h', 'winuser.h'], ['GetShellWindow'], ['user32']], + ['vfw32', ['windows.h', 'vfw.h'], ['capCreateCaptureWindow'], ['vfw3']], + ['vaapi', ['va/va.h'], ['vaInitialize'], ['va']], -+ ['zlib', ['zlib.h'], ['zlibVersion'], ['z']], + + # Libraries with preconditions + ['vaapi_drm', ['va/va.h', 'va/va_drm.h'], ['vaGetDisplayDRM'], ['va', 'va-drm'], @@ -8065,6 +9565,8 @@ index 0000000000..904a254cab + ['getenv', ['stdlib.h']], + ['lstat', ['sys/stat.h']], + ['getauxval', ['sys/auxv.h']], ++ ['elf_aux_info', ['sys/auxv.h']], ++ ['sysctlbyname', ['sys/sysctl.h']], + ['GetProcessAffinityMask', ['windows.h']], + ['GetProcessTimes', ['windows.h']], + ['GetSystemTimeAsFileTime', ['windows.h']], @@ -8079,8 +9581,6 @@ index 0000000000..904a254cab + ['MFCreateAlignedMemoryBuffer', ['mfapi.h'], {'link_with': ['mfplat', 'mfuuid', 'ole32', 'strmiids']}], + ['CreateDIBSection', ['windows.h'], {'link_with': ['gdi32']}], + ['InitializeSecurityContext', ['windows.h', 'security.h'], {'link_with': ['secur32'], 'c_args': ['-DSECURITY_WIN32']}], -+ ['atomic_cas_ptr', ['atomic.h']], -+ ['machine_rw_barrier', ['mbarrier.h'], {'funcs': ['__machine_rw_barrier']}], + ['MemoryBarrier', ['windows.h']], + ['posix_memalign', ['stdlib.h']], + ['sem_timedwait', ['semaphore.h'], {'preconditions': ['pthreads'], 'extra_deps': ['thread_dep']}], @@ -8112,11 +9612,11 @@ index 0000000000..904a254cab + ['strerror_r'], + ['sysconf'], + ['sysctl'], ++ ['tempnam'], + ['usleep'], + ['pthread_join', {'preconditions': ['pthreads'], 'extra_deps': ['thread_dep']}], + ['pthread_create', {'preconditions': ['pthreads'], 'extra_deps': ['thread_dep']}], + ['pthread_cancel', {'preconditions': ['pthreads'], 'extra_deps': ['thread_dep']}], -+ ['sync_val_compare_and_swap', {'funcs': ['__sync_val_compare_and_swap']}], + ['gmtime_r'], + ['localtime_r'], +] @@ -8127,8 +9627,16 @@ index 0000000000..904a254cab + ['securetransport', ['Security/SecureTransport.h', 'Security/Security.h'], ['SSLCreateContext'], [], {'frameworks': ['CoreFoundation', 'Security']}], + ] + check_funcs += [ -+ ['SecIdentityCreate', {'c_args': ['-Wl,-framework,CoreFoundation', '-Wl,-framework,Security']}], -+ ['SecItemImport', {'c_args': ['-Wl,-framework,CoreFoundation', '-Wl,-framework,Security']}], ++ ['SecIdentityCreate', {'frameworks': ['CoreFoundation', 'Security']}], ++ ['SecItemImport', {'frameworks': ['CoreFoundation', 'Security']}], ++ ] ++endif ++ ++if get_option('videotoolbox').allowed() ++ check_header_funcs += [ ++ ['VTPixelTransferSessionCreate', ['VideoToolbox/VideoToolbox.h'], {'c_args': ['-Werror=unguarded-availability-new'], 'frameworks': ['VideoToolbox']}], ++ ['VTPixelRotationSessionCreate', ['VideoToolbox/VideoToolbox.h'], {'c_args': ['-Werror=unguarded-availability-new'], 'frameworks': ['VideoToolbox']}], ++ ['VTCompressionSessionPrepareToEncodeFrames', ['VideoToolbox/VTCompressionSession.h'], {'c_args': ['-Werror=unguarded-availability-new'], 'frameworks': ['VideoToolbox']}], + ] +endif + @@ -8141,6 +9649,8 @@ index 0000000000..904a254cab + ['IDXGIOutput5', ['windows.h', 'dxgi1_5.h']], + ['ID3D11VideoDecoder', ['windows.h', 'd3d11.h']], + ['ID3D11VideoContext', ['windows.h', 'd3d11.h']], ++ ['ID3D12Device', ['windows.h', 'd3d12.h']], ++ ['ID3D12VideoDecoder', ['windows.h', 'd3d12video.h']], + ['DPI_AWARENESS_CONTEXT', ['windows.h'], {'c_args': ['-D_WIN32_WINNT=0x0A00']}], + ['DXVA2_ConfigPictureDecode', ['d3d9.h', 'dxva2api.h'], {'c_args': ['-D_WIN32_WINNT=0x0602']}], + ['VAPictureParameterBufferHEVC', ['va/va.h', 'va/va_dec_hevc.h']], @@ -8227,9 +9737,12 @@ index 0000000000..904a254cab + ['dxgidebug.h'], + ['dxva.h'], + ['dxva2api.h', {'c_args': ['-D_WIN32_WINNT=0x0600']}], ++ ['linux/fb.h'], ++ ['linux/videodev2.h'], + ['mftransform.h'], + ['msa.h'], + ['net/udplite.h'], ++ ['pthread_np.h'], + ['sys/param.h'], + ['sys/resource.h'], + ['sys/select.h'], @@ -8284,7 +9797,6 @@ index 0000000000..904a254cab + 'libcodec2', + 'libdav1d', + 'libdc1394', -+ 'libdrm', + 'libflite', + 'libfontconfig', + 'libfreetype', @@ -8298,6 +9810,8 @@ index 0000000000..904a254cab + 'libjxl', + 'libklvanc', + 'libkvazaar', ++ 'liblc3', ++ 'liblcevc_dec', + 'libmodplug', + 'libmp3lame', + 'libmysofa', @@ -8309,6 +9823,8 @@ index 0000000000..904a254cab + 'libopus', + 'libplacebo', + 'libpulse', ++ 'libqrencode', ++ 'libquirc', + 'librabbitmq', + 'librav1e', + 'librist', @@ -8326,13 +9842,18 @@ index 0000000000..904a254cab + 'libtensorflow', + 'libtesseract', + 'libtheora', ++ # FIXME enable when C++ checks are implemented ++ # 'libtorch', + 'libtwolame', + 'libuavs3d', + 'libv4l2', + 'libvmaf', + 'libvorbis', + 'libvpx', ++ 'libvvenc', + 'libwebp', ++ 'libxevd', ++ 'libxeve', + 'libxml2', + 'libzimg', + 'libzmq', @@ -8349,13 +9870,14 @@ index 0000000000..904a254cab +hwaccel_autodetect_library_list = [ + 'amf', + 'audiotoolbox', -+ 'crystalhd', + 'cuda', + 'cuda_llvm', + 'cuvid', + 'd3d11va', ++ 'd3d12va', + 'dxva2', + 'ffnvcodec', ++ 'libdrm', + 'nvdec', + 'nvenc', + 'vaapi', @@ -8366,8 +9888,8 @@ index 0000000000..904a254cab +] + +autodetect_libs = ( -+ external_autodetect_library_list + -+ hwaccel_autodetect_library_list + ++ external_autodetect_library_list + ++ hwaccel_autodetect_library_list + + threads_list +) + @@ -8397,9 +9919,8 @@ index 0000000000..904a254cab + 'error_resilience', + 'faan', + 'fast_unaligned', -+ 'fft', ++ 'iamf', + 'lsp', -+ 'mdct', + 'pixelutils', + 'network', + 'rdft', @@ -8439,14 +9960,19 @@ index 0000000000..904a254cab + 'cbs_av1', + 'cbs_h264', + 'cbs_h265', ++ 'cbs_h266', + 'cbs_jpeg', + 'cbs_mpeg2', ++ 'cbs_vp8', + 'cbs_vp9', ++ 'd3d12va_encode', + 'deflate_wrapper', + 'dirac_parse', + 'dnn', -+ 'dovi_rpu', ++ 'dovi_rpudec', ++ 'dovi_rpuenc', + 'dvprofile', ++ 'evcparse', + 'exif', + 'faandct', + 'faanidct', @@ -8469,15 +9995,19 @@ index 0000000000..904a254cab + 'huffman', + 'huffyuvdsp', + 'huffyuvencdsp', ++ 'iamfdec', ++ 'iamfenc', + 'idctdsp', + 'iirfilter', + 'inflate_wrapper', + 'intrax8', + 'iso_media', ++ 'iso_writer', + 'ividsp', + 'jpegtables', + 'lgplv3', + 'libx262', ++ 'libx264_hdr10', + 'llauddsp', + 'llviddsp', + 'llvidencdsp', @@ -8522,6 +10052,7 @@ index 0000000000..904a254cab + 'vp3dsp', + 'vp56dsp', + 'vp8dsp', ++ 'vulkan_encode', + 'wma_freqs', + 'wmv2dsp', +] @@ -8613,11 +10144,12 @@ index 0000000000..904a254cab + ['pragma_deprecated', [], 'int main(void) {_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\""); return 0; }'], + ['const_nan', ['math.h'], 'struct { double d; } static const bar[] = { { NAN } };'], + ['intrinsics_neon', ['arm_neon.h'], 'int16x8_t test = vdupq_n_s16(0);'], ++ ['intrinsics_sse2', ['emmintrin.h'], '__m128i test = _mm_setzero_si128();'], +] + +check_links = [ -+ ['stdatomic', ['stdatomic.h'], 'int main(void) {atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += bar;}', {'link_with': ['atomic']}], -+ ['stdatomic', ['stdatomic.h'], 'int main(void) {atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += bar;}'], ++ ['stdatomic', ['stdatomic.h'], 'int main(void) {atomic_int foo, bar = -1; atomic_store(&foo, 0); foo += bar;}', {'link_with': ['atomic']}], ++ ['stdatomic', ['stdatomic.h'], 'int main(void) {atomic_int foo, bar = -1; atomic_store(&foo, 0); foo += bar;}'], +] + +v4l2m2m_formats = [ @@ -8711,6 +10243,9 @@ index 0000000000..904a254cab + conf.set10(name, have) +endforeach + ++# override_options applies to all targets ++global_overrides = [] ++ +if cc.get_id() == 'clang' + if conf.get('x86_32') == 1 + # Clang doesn't support maintaining alignment without assuming the @@ -8749,6 +10284,19 @@ index 0000000000..904a254cab + '-Oy-' + ]) + endif ++ # In a couple of places there's code like 'if(CONFIG_something) { ... }'. ++ # On MSVC, with optimizations disabled, the supposedly-disabled blocks always ++ # generate code, including references to functions which are not available, ++ # causing link errors. ++ # In other words, optimization is always required to correctly build things - ++ # so enforce optimization in all cases. ++ # (Also note that MSVC doesn't know "levels of optimization" as such, but only ++ # "optimize for size" (1) and "optimize for speed" (2) modes - so might as well ++ # pick '2'.) ++ optimization = get_option('optimization') ++ if optimization in ['', '0', 'g', 'plain'] ++ global_overrides += ['optimization=2'] ++ endif +endif + +conf.set10('static', get_option('default_library') != 'shared') @@ -8781,7 +10329,7 @@ index 0000000000..904a254cab + project_c_args += cc.get_supported_arguments('-DWIN32_LEAN_AND_MEAN', '-wd4005', '-Wp,-w') +endif + -+if ['linux', 'openbsd', 'android'].contains(host_machine.system()) ++if ['linux', 'openbsd', 'android', 'freebsd', 'netbsd'].contains(host_machine.system()) + conf.set('section_data_rel_ro', 1) +endif + @@ -8906,8 +10454,8 @@ index 0000000000..904a254cab + + foreach precondition : preconditions + if precondition in autodetect_libs -+ opt_name = options_map.get(precondition, precondition) -+ if get_option(opt_name).allowed() ++ pre_name = options_map.get(precondition, precondition) ++ if get_option(pre_name).allowed() + found = found and conf.get(precondition, 1) == 1 + else + found = found and conf.get(precondition, 0) == 1 @@ -8940,6 +10488,7 @@ index 0000000000..904a254cab + found = false + endif + ++ internal_dep = false + if found + if check_type == 'framework' + foreach f : frameworks @@ -8974,18 +10523,19 @@ index 0000000000..904a254cab + pkg_name = opts.get('pkg', name) + if opts.has_key('versions') + foreach version: opts['versions'] -+ dep = dependency(pkg_name, required: false, version: version) ++ dep = dependency(pkg_name, required: false, version: version, static: conf.get('static').is_odd()) + endforeach + + if not dep.found() and req.enabled() + error('@0@ @1@ could not be found'.format(pkg_name, opts['versions'])) + endif + elif opts.has_key('version') -+ dep = dependency(pkg_name, required : req, version: opts.get('version')) ++ dep = dependency(pkg_name, required : req, version: opts.get('version'), static: conf.get('static').is_odd()) + else -+ dep = dependency(pkg_name, required : req) ++ dep = dependency(pkg_name, required : req, static: conf.get('static').is_odd()) + endif -+ found = dep.found() and dep.type_name() != 'internal' ++ found = dep.found() ++ internal_dep = dep.type_name() == 'internal' + extra_deps += dep + endif + endif @@ -8999,14 +10549,14 @@ index 0000000000..904a254cab + endif + + if not conf.has(header.underscorify()) -+ has_header = cc.has_header(header, dependencies: extra_deps) ++ has_header = internal_dep or cc.has_header(header, dependencies: extra_deps) + conf.set10(header.underscorify().to_lower(), has_header) + found = found and has_header + endif + endforeach + endif + -+ if found ++ if found and not internal_dep + n_funcs_found = 0 + foreach symbol : funcs + if check_type == 'header-func' @@ -9026,7 +10576,7 @@ index 0000000000..904a254cab + endif + endif + -+ if found ++ if found and not internal_dep + n_defines_found = 0 + foreach symbol : defines + if cc.get_define(symbol, dependencies : extra_deps, prefix: prefix, args : c_args + project_c_args) != '' @@ -9036,15 +10586,15 @@ index 0000000000..904a254cab + found = n_defines_found == defines.length() + endif + -+ if found and compiles != '' ++ if found and compiles != '' and not internal_dep + found = cc.compiles('\n\n'.join([prefix, compiles]), dependencies : extra_deps, args : c_args + project_c_args, name: name) + endif + -+ if found and links != '' ++ if found and links != '' and not internal_dep + found = cc.links('\n\n'.join([prefix, links]), dependencies : extra_deps, args : c_args + project_c_args, name: name) + endif + -+ if found and type != '' ++ if found and type != '' and not internal_dep + found = cc.has_type(type, prefix : prefix, dependencies : extra_deps, args : c_args + project_c_args) + endif + @@ -9099,7 +10649,7 @@ index 0000000000..904a254cab + xcrun = find_program('xcrun', required: true) + + if run_command(xcrun, '-sdk', appleclang_sdk, 'metal', '-v', check: false).returncode() == 0 -+ metalcc = generator(xcrun, ++ metalcc = generator(xcrun, + output : '@BASENAME@.metalair', + arguments: ['-sdk', 'macosx', 'metal', '@INPUT@', '-o', '@OUTPUT@'] + ) @@ -9148,6 +10698,18 @@ index 0000000000..904a254cab + } + ''', name: 'has pthreads semaphores available', dependencies: thread_dep)) + conf.set10('pthread_cancel', cc.has_function('pthread_cancel', dependencies: thread_dep)) ++ if conf.get('pthread_np_h') == 1 ++ thread_prefix = ''' ++ #include ++ #include ++ ''' ++ else ++ thread_prefix = ''' ++ #include ++ ''' ++ endif ++ conf.set10('pthread_set_name_np', cc.has_function('pthread_set_name_np', prefix: thread_prefix, dependencies: thread_dep)) ++ conf.set10('pthread_setname_np', cc.has_function('pthread_setname_np', prefix: thread_prefix, dependencies: thread_dep)) + endif +endif + @@ -9180,9 +10742,12 @@ index 0000000000..904a254cab + error('OpenSSL and mbedTLS must not be enabled at the same time.') +endif + ++# Manual check for fontconfig ++conf.set10('fontconfig', conf.get('libfontconfig').is_odd()) ++ +# Manual check for OpenSSL +if conf.get('openssl') == 1 -+ test_openssl_dep = dependency('openssl', required: false, version: '>= 3.0.0') ++ test_openssl_dep = dependency('openssl', required: false, version: '>= 3.0.0', static: conf.get('static').is_odd()) + if test_openssl_dep.found() + is_blocked_by_license = not get_option('version3').disabled() or get_option('gpl').disabled() or not get_option('nonfree').disabled() + if is_blocked_by_license @@ -9214,22 +10779,42 @@ index 0000000000..904a254cab + endif +endif + ++# Manual check for amf ++if conf.get('amf') == 1 ++ conf.set('amf', cc.links(cpp_cond.format('AMF/core/Version.h', ++ '(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x0001000400210000'), name: 'AMF version')) ++endif ++ ++# Manual patch for d3d12_encoder_feature ++conf.set10('d3d12_encoder_feature', cc.compiles('''#include ++#include ++int main() { ++ D3D12_FEATURE_VIDEO feature = D3D12_FEATURE_VIDEO_ENCODER_CODEC; ++ D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOURCE_REQUIREMENTS req; ++ (void)feature; ++ (void)req; ++ return 0; ++} ++''', name: 'Supports D3D12 encoder')) ++ +# Manual check for libmfx -+if conf.get('libmfx') == 1 ++if conf.get('libmfx') == 1 and conf.get('libvpx') == 1 ++ error('can not use libmfx and libvpl together') ++elif conf.get('libmfx') == 1 + if not cc.links(cpp_cond.format('mfx/mfxdefs.h', 'MFX_VERSION >= 1028 && MFX_VERSION < 2000'), name: 'libmfx version') + error('libmfx version must be >= 1.28 and < 2.0') -+ else -+ warning('build FFmpeg against libmfx 1.x, obsolete features of libmfx such as OPAQUE memory,') -+ warning('multi-frame encode, user plugins and LA_EXT rate control mode are enabled') + endif + conf.set10('MFX_CODEC_VP9'.to_lower(), cc.has_header_symbol('mfxstructures.h', 'MFX_CODEC_VP9')) ++ warning('libmfx is deprecated. Please run meson setup with -Dlibmfx=disabled to use libvpl instead.') ++elif conf.get('libvpl') == 1 ++ conf.set10('struct_mfxConfigInterface'.to_lower(), cc.has_header_symbol('vpl/mfxvideo.h', 'struct mfxConfigInterface', prefix: '#include ')) +endif + +# Manual check for libx264 +if conf.get('libx264') == 1 + if is_msvc -+ if not cc.links(cpp_cond.format('x264.h', 'X264_BUILD >= 122'), name: 'libx264 version') -+ warning('libx264 version must be >= 1.22') ++ if not cc.links(cpp_cond.format('x264.h', 'X264_BUILD >= 155'), name: 'libx264 version') ++ warning('libx264 version must be >= 1.55') + conf.set('libx264', 0) + endif + else @@ -9238,14 +10823,8 @@ index 0000000000..904a254cab + conf.set('libx264', 0) + endif + endif -+endif -+ -+if conf.get('libmfx') == 1 and conf.get('libvpl') == 1 -+ error('can not use libmfx and libvpl together') -+endif -+ -+if conf.get('opengl') == 1 and not cc.has_header('GL/glext.h') -+ conf.set('opengl', 0) ++ conf.set10('libx264_hdr10', cc.links(cpp_cond.format('x264.h', 'X264_BUILD >= 163'), name: 'libx264 version')) ++ conf.set10('libx262', cc.links(cpp_cond.format('x264.h', 'X264_MPEG2'), name: 'supports MPEG2 inside x264')) +endif + +if conf.get('libx265') == 1 @@ -9261,6 +10840,48 @@ index 0000000000..904a254cab + prefix: '#include ', dependencies: libzvbi_extra_deps)) +endif + ++# Manual patch for Cairo ++# https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/265 ++if conf.get('librsvg') == 1 ++ if conf.get('static') == 1 and host_machine.system() == 'windows' ++ project_c_args += ['-DCAIRO_WIN32_STATIC_BUILD'] ++ endif ++endif ++ ++# Manual patch for libass ++# Brings libiconv, but static libiconv on Cerbero is MinGW based, ++# which does not embed mingwex on the archives ++if conf.get('libass') == 1 ++ test_libass_dep = dependency('libass', required: false, version: '>= 0.11.0', static: conf.get('static').is_odd()) ++ if test_libass_dep.found() and cc.has_header('iconv.h', dependencies: test_libass_dep) and host_machine.system() == 'windows' ++ conf.set10('libass', ++ cc.links(''' ++ #include ++ int main() { return iconvlist(NULL, NULL); }''', ++ name: 'libass is properly Windows ABI', ++ dependencies: test_libass_dep ++ ) ++ ) ++ endif ++endif ++ ++conf.set10('struct_v4l2_frmivalenum_discrete', cc.compiles(''' ++ #include ++ int main() { ++ struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0; ++ return 0; ++ } ++''', name: 'supports v4l2 framesize enumeration ioctl')) ++ ++conf.set10('posix_ioctl', cc.compiles(''' ++ #include ++ int main() { int ioctl(int, int, ...); return 0; } ++''', name: 'Supports ioctl(3P)')) ++ ++if get_option('vapoursynth').allowed() ++ conf.set10('vapoursynth', cc.has_header('vapoursynth/VSScript4.h') and cc.has_header('vapoursynth/VapourSynth4.h')) ++endif ++ +foreach req : ['xlib_x11', 'xlib_xext', 'xlib_xv'] + if conf.get(req) == 0 + conf.set10('xlib', false) @@ -9274,14 +10895,24 @@ index 0000000000..904a254cab + +asm_inline_checks = [ + ['"1:\\n"', 'inline_asm_labels'], -+ ['"Label:\\n"', 'inline_asm_nonlocal_labels'] +] + ++# Clang's LTO fails on Windows, when there are references outside ++# of inline assembly to nonlocal labels defined within inline assembly, ++# see https://github.com/llvm/llvm-project/issues/76046. ++# Original bug report: https://github.com/llvm/llvm-project/issues/64127 ++if cc.get_id() != 'clang' or host_machine.system() != 'windows' ++ asm_inline_checks += [ ++ ['"Label:\\n"', 'inline_asm_nonlocal_labels'] ++ ] ++endif ++ +extern_prefix = cc.symbols_have_underscore_prefix() ? '_' : '' + +asm_insn_checks = [] + +asm_as_checks = [] ++asm_arch_ext_checks = [] + +if host_machine.system() == 'windows' + asm_format = conf.get('x86_64') == 1 ? 'win64' : 'win32' @@ -9296,7 +10927,10 @@ index 0000000000..904a254cab + +if conf.get('pic') == 1 + project_c_args += ['-DPIC'] -+ asm_args += ['-DPIC'] ++ if conf.get('x86') == 1 and conf.get('x86_64') == 0 ++ # https://github.com/FFmpeg/FFmpeg/commit/afa471d0efed1df5dca6eeeb2fcdd211ae4cad4e ++ warning('FFmpeg 7.0 has dropped PIC setup for x86 targets. If your build is broken, please report an issue at https://gitlab.freedesktop.org/gstreamer/meson-ports/ffmpeg/-/issues') ++ endif +endif + +if conf.get('x86') == 1 @@ -9310,82 +10944,6 @@ index 0000000000..904a254cab + conf.set10('inline_asm', false) + endif + -+ # Manual: check for binutils enforcing value ranges -+ # https://sourceware.org/bugzilla/show_bug.cgi?id=30578 -+ # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108941 -+ if conf.get('inline_asm') == 1 -+ _binutils_bug_args = [] -+ if get_option('optimization') != '0' -+ _binutils_bug_args += ['-O@0@'.format(get_option('optimization'))] -+ endif -+ if not cc.compiles( -+ ''' -+ #include -+ #include -+ -+ typedef struct GetBitContext { -+ const uint8_t *buffer; -+ int index; -+ } GetBitContext; -+ -+ union unaligned_32 { uint32_t l; } __attribute__((packed)) __attribute__((may_alias)); -+ -+ static __attribute__((always_inline)) inline __attribute__((const)) uint32_t av_bswap32(uint32_t x) -+ { -+ return ((((x) << 8 & 0xff00) | ((x) >> 8 & 0x00ff)) << 16 | ((((x) >> 16) << 8 & 0xff00) | (((x) >> 16) >> 8 & 0x00ff))); -+ } -+ -+ static inline uint32_t NEG_USR32(uint32_t a, int8_t s){ -+ __asm__ ("shrl %1, %0\n\t" -+ : "+r" (a) -+ : "ic" ((uint8_t)(-s)) -+ ); -+ return a; -+ } -+ -+ static inline unsigned int get_bits(GetBitContext *s, int n) -+ { -+ register unsigned int tmp; -+ unsigned int re_index = (s)->index; unsigned int __attribute__((unused)) re_cache; -+ ((void)0); -+ re_cache = av_bswap32((((const union unaligned_32 *) ((s)->buffer + (re_index >> 3)))->l)) << (re_index & 7); -+ tmp = NEG_USR32(re_cache, n); -+ return tmp; -+ } -+ -+ typedef struct AC3HeaderInfo { -+ uint8_t sr_code; -+ } AC3HeaderInfo; -+ -+ typedef enum { -+ AAC_AC3_PARSE_ERROR_SAMPLE_RATE = -0x3030c0a, -+ } AACAC3ParseError; -+ -+ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) -+ { -+ hdr->sr_code = get_bits(gbc, 2); -+ return 0; -+ } -+ -+ ''', -+ name: 'binutils has a working shrl instruction, Sourceware #30578, GCC # 108941', -+ args: _binutils_bug_args -+ ) -+ warning('''Your version of binutils rejects undefined behaviour which -+ FFmpeg relies on, when optimization levels are set to higher than -O0. -+ Please contact the developers and forward these references: -+ -+ https://sourceware.org/bugzilla/show_bug.cgi?id=30578 -+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108941 -+ -+ and the included test case. -+ -+ Disabling inline assembly now, there may be a performance hit. -+ ''') -+ conf.set('inline_asm', 0) -+ endif -+ endif -+ + conf.set10('rdtsc', cc.has_function('__rdtsc', prefix: '#include ')) + conf.set10('mm_empty', cc.has_function('_mm_empty', prefix: '#include ')) + @@ -9413,19 +10971,15 @@ index 0000000000..904a254cab + if host_machine.system() == 'windows' + nasm_version = '>=2.12' + endif -+ x86asm = find_program('nasm', version: nasm_version, required: false) ++ x86asm = find_program('nasm', version: nasm_version, required: host_machine.system() in ['windows', 'darwin']) + x86asm_type = 'nasm' + if not x86asm.found() -+ subproject('win-nasm') -+ x86asm = find_program('nasm', version: nasm_version, required: false) -+ endif -+ if not x86asm.found() + x86asm = find_program('yasm', required: false) + x86asm_type = 'yasm' + endif + conf.set10('x86asm', x86asm.found()) + if x86asm.found() -+ if cc.get_linker_id().contains('lld') and cpu == 'x86' and not ['windows', 'cygwin'].contains(host_machine.system()) ++ if cc.get_linker_id().contains('lld') and cpu == 'x86' and not ['windows', 'cygwin'].contains(host_machine.system()) + # x86inc.asm ignores the PIC flag when compiling for x86 which unfortunately + # causes text relocations in the object files generated by the assembler. We + # must disable the warning to allow linking with lld. Unlike gold, ld which @@ -9436,7 +10990,6 @@ index 0000000000..904a254cab + add_project_link_arguments('-Wl,-z,notext', language: 'c') + endif + x86asm_checks += [ -+ ['CPU amdnop', 'cpunop'], + ['vmovdqa32 [eax]{k1}{z}, zmm0', 'avx512_external'], + ['vpdpwssds zmm31{k1}{z}, zmm29, zmm28', 'avx512icl_external'], + ['vextracti128 xmm0, ymm0, 0', 'avx2_external'], @@ -9476,7 +11029,8 @@ index 0000000000..904a254cab + if meson.is_cross_build() + ebp_available = cc.links(ebp_available_test, name: 'if_ebp_available_this_should_crash') + else -+ ebp_available = cc.run(ebp_available_test, name: 'if_ebp_available_this_should_crash').returncode() != 0 ++ ebp_result = cc.run(ebp_available_test, name: 'if_ebp_available_this_should_crash') ++ ebp_available = ebp_result.compiled() and ebp_result.returncode() != 0 + endif + + # FFmpeg upstream doesn't know that EBP is always unavailable @@ -9511,7 +11065,13 @@ index 0000000000..904a254cab + asm_insn_checks += [ + ['prfm pldl1strm, [x0]', 'armv8'], + ['ext v0.8B, v0.8B, v1.8B, #1', 'neon'], -+ ['fmadd d0, d0, d1, d2', 'vfp'], ++ ] ++ asm_arch_ext_checks += [ ++ ['udot v0.4s, v0.16b, v0.16b', 'dotprod'], ++ ['usdot v0.4s, v0.16b, v0.16b', 'i8mm'], ++ ] ++ asm_as_checks += [ ++ ['.arch armv8-a', 'as_arch_directive'], + ] +elif conf.get('arm') == 1 + if cc.has_argument('-mfp16-format=ieee') @@ -9592,8 +11152,10 @@ index 0000000000..904a254cab + else + debug_format = 'null' + endif ++elif asm_format.startswith('macho') ++ debug_format = 'null' +else -+ # Supported on Linux, BSD, macOS ++ # Supported on Linux, BSD + debug_format = 'dwarf' +endif +# Add the format args @@ -9602,6 +11164,8 @@ index 0000000000..904a254cab + asm_args += ['-g', 'dwarf2'] + elif debug_format == 'cv8' + asm_args += ['-g', 'cv8'] ++ elif debug_format == 'null' ++ asm_args += ['-g', 'null'] + else + asm_args += ['-g', 'null'] + endif @@ -9633,7 +11197,6 @@ index 0000000000..904a254cab +foreach check: x86asm_checks + f = configure_file( + command: [python3, '-c', 'import sys; print(sys.argv[1])', '@0@'.format(check[0])], -+ input: 'configure', + output: '@0@.asm'.format(check[1]), + capture: true, + ) @@ -9660,6 +11223,15 @@ index 0000000000..904a254cab + ] +endforeach + ++asm_archext_list = [] ++foreach check : asm_arch_ext_checks ++ asm_inline_checks += [ ++ ['"@0@"'.format(check[0]), '@0@_inline'.format(check[1])] ++ ] ++ # Separate list of extensions that are handled via .arch_extension ++ asm_archext_list += check[1] ++endforeach ++ +foreach check: asm_inline_checks + if conf.get('inline_asm') == 1 + result = cc.compiles( @@ -9695,7 +11267,7 @@ index 0000000000..904a254cab + ] +endif + -+can_run_asm_checks = false ++can_run_asm_checks = meson.version().version_compare('>=1.2.0') + +foreach check : asm_as_checks + # It is possible to run compile checks on generated files, however, @@ -9705,13 +11277,11 @@ index 0000000000..904a254cab + if can_run_asm_checks + f = configure_file( + command: [python3, '-c', 'import sys; print(sys.argv[1])', '@0@'.format(check[0])], -+ input: 'configure', + output: '@0@.S'.format(check[1]), + capture: true, + ) + conf.set10(check[1], cc.compiles( + f, -+ args: ['-x', 'assembler'], + name: check[1] + )) + else @@ -9719,6 +11289,89 @@ index 0000000000..904a254cab + endif +endforeach + ++as_arch_str = '' ++as_arch_level = '' ++if conf.get('as_arch_directive', 0) == 1 and conf.get('aarch64', 0) == 1 ++ as_arch_level = 'armv8-a' ++ # Check for higher .arch levels. We only need armv8.2-a in order to ++ # enable the extensions we want below - we primarily want to control ++ # them via .arch_extension. However: ++ # ++ # Clang before version 17 (Xcode versions up to and including 15.0) ++ # didn't support controlling the dotprod/i8mm extensions via ++ # .arch_extension; thus try to enable them via the .arch level as well. ++ foreach level : ['armv8.2-a', 'armv8.4-a', 'armv8.6-a'] ++ f = configure_file( ++ command: [python3, '-c', 'import sys; print(sys.argv[1])', '.arch @0@'.format(level)], ++ output: '@0@.S'.format(level), ++ capture: true, ++ ) ++ if cc.compiles( ++ f, ++ name: 'assembler supports @0@'.format(level) ++ ) ++ as_arch_level = level ++ endif ++ endforeach ++ # Clang before version 17 (Xcode versions up to and including 15.0) ++ # also had a bug (https://github.com/llvm/llvm-project/issues/32220) ++ # causing a plain ".arch " to not have any effect unless it ++ # had an extra "+" included - but it was activated on the next ++ # ".arch_extension" directive. Check if we can include "+crc" as dummy ++ # feature to make the .arch directive behave as expected and take ++ # effect right away. ++ f = configure_file( ++ command: [python3, '-c', 'import sys; print(sys.argv[1])', '.arch @0@+crc'.format(as_arch_level)], ++ output: '@0@.S'.format('arch_crc'), ++ capture: true, ++ ) ++ if cc.compiles( ++ f, ++ name: 'assembler supports @0@ with the CRC extension'.format(as_arch_level) ++ ) ++ as_arch_level = as_arch_level + '+crc' ++ endif ++ as_arch_str = '.arch ' + as_arch_level + '\n' ++endif ++ ++foreach check : asm_arch_ext_checks ++ if can_run_asm_checks ++ code = as_arch_str ++ arch_ext_str = '.arch_extension ' + check[1] + '\n' ++ code += arch_ext_str ++ f = configure_file( ++ command: [python3, '-c', 'import sys; print(sys.argv[1])', '@0@'.format(code)], ++ output: '@0@_archext.S'.format(check[1]), ++ capture: true, ++ ) ++ archext_supported = cc.compiles( ++ f, ++ name: 'arch_extension_' + check[1] ++ ) ++ conf.set10('as_archext_' + check[1] + '_directive', archext_supported) ++ ++ code = as_arch_str ++ if archext_supported ++ code += arch_ext_str ++ endif ++ code += check[0] + '\n' ++ f = configure_file( ++ command: [python3, '-c', 'import sys; print(sys.argv[1])', '@0@'.format(code)], ++ output: '@0@.S'.format(check[1]), ++ capture: true, ++ ) ++ conf.set10(check[1] + '_external', false) ++ conf.set10(check[1], cc.compiles( ++ f, ++ name: check[1] ++ )) ++ else ++ conf.set10('as_archext_' + check[1] + '_directive', false) ++ conf.set10(check[1] + '_external', false) ++ conf.set10(check[1], false) ++ endif ++endforeach ++ +if conf.get('x86') == 1 + conf.set10('ebx_available', conf.get('ebx_available_1') == 1 and conf.get('ebx_available_2') == 1) + message('EBX available: @0@'.format(conf.get('ebx_available'))) @@ -9733,6 +11386,10 @@ index 0000000000..904a254cab +# That's apart from the upstream's linux/android check +if not arm_skip_checks or not can_run_asm_checks + foreach ext : arch_ext_list_arm ++ if ext in asm_archext_list ++ # Skip the usual inline || external -> unsuffixed for these extensions. ++ continue ++ endif + inline = '@0@_inline'.format(ext) + external = '@0@_external'.format(ext) + conf.set10(ext, conf.get(inline, 0) == 1 or conf.get(external, 0) == 1) @@ -9745,15 +11402,15 @@ index 0000000000..904a254cab + +extern_things = [ + ['FFOutputFormat', 'muxer', 'libavformat/allformats.c', 'muxer_list'], -+ ['AVInputFormat', 'demuxer', 'libavformat/allformats.c', 'demuxer_list'], ++ ['FFInputFormat', 'demuxer', 'libavformat/allformats.c', 'demuxer_list'], + ['FFCodec', 'encoder', 'libavcodec/allcodecs.c', 'encoder_list'], + ['FFCodec', 'decoder', 'libavcodec/allcodecs.c', 'decoder_list'], + ['AVCodecParser', 'parser', 'libavcodec/parsers.c', 'parser_list'], + ['FFBitStreamFilter', 'bsf', 'libavcodec/bitstream_filters.c', 'bsf_list'], -+ ['AVHWAccel', 'hwaccel', 'libavcodec/hwaccels.h', 'hwaccel_list'], ++ ['FFHWAccel', 'hwaccel', 'libavcodec/hwaccels.h', 'hwaccel_list'], + ['URLProtocol', 'protocol', 'libavformat/protocols.c', 'protocol_list'], + ['FFOutputFormat', 'muxer', 'libavdevice/alldevices.c', 'outdev_list', 'outdev'], -+ ['AVInputFormat', 'demuxer', 'libavdevice/alldevices.c', 'indev_list', 'indev'], ++ ['FFInputFormat', 'demuxer', 'libavdevice/alldevices.c', 'indev_list', 'indev'], +] + +find_things_extern = find_program('find_things_extern.py') @@ -9781,6 +11438,9 @@ index 0000000000..904a254cab + thing_allowed = get_option('@0@s'.format(thing_suffix)).allowed() + + foreach elem : list ++ if elem == '' ++ message('@0@s @1@'.format(thing_suffix, list)) ++ endif + opt = get_option(elem) + conf.set(elem, (opt.enabled() or (opt.allowed() and thing_allowed)).to_int()) + endforeach @@ -9788,6 +11448,17 @@ index 0000000000..904a254cab + set_variable(variable_name, list) +endforeach + ++# FIXME: FFmpeg added the AudioToolbox backend but it uses elements only ++# available in macOS. ++# See e.g. https://developer.apple.com/documentation/coreaudio/kaudioobjectsystemobject ++# https://github.com/FFmpeg/FFmpeg/commit/b737575c76ff33ef5ffd602ebf3e30cc71ec536c ++if conf.get('audiotoolbox') == 1 ++ if cc.get_define('TARGET_OS_IOS', prefix: '#include ') == '1' ++ warning('Disabling AudioToolbox output device as it is not compatible with iOS.\nPlease report this to the upstream developers: https://ffmpeg.org/bugreports.html') ++ conf.set('audiotoolbox_outdev', 0) ++ endif ++endif ++ +find_things = find_program('find_things.py') + +result = run_command(find_things, files('libavfilter/allfilters.c'), check: true) @@ -9906,9 +11577,6 @@ index 0000000000..904a254cab +subdir('libavdevice') +subdir('fftools') + -+util_list = ['cuda', 'd3d11va', 'dxva2', 'libdrm', 'lzo', 'mediacodec', 'opencl', 'qsv', 'vaapi', 'vdpau', 'videotoolbox'] -+ -+ +things_to_print = [ + ['libavcodec/codec_list.c', 'FFCodec', 'codec_list', encoder_list + decoder_list], + ['libavcodec/parser_list.c', 'AVCodecParser', 'parser_list', parser_list], @@ -9955,13 +11623,8 @@ index 0000000000..904a254cab +endforeach + +if conf.get('stdatomic') == 0 -+ if conf.get('atomics_gcc', 0) == 1 -+ common_incs += [include_directories('compat/atomics/gcc')] -+ elif conf.get('atomics_win32', 0) == 1 ++ if conf.get('atomics_win32', 0) == 1 + common_incs += [include_directories('compat/atomics/win32')] -+ elif conf.get('pthreads', 0) == 1 -+ compat_objs += files('compat/atomics/pthread/stdatomic.c') -+ common_incs += [include_directories('compat/atomics/pthread')] + elif conf.get('threads', 0) == 1 + error('Threading is enabled, but no atomics are available') + else @@ -9969,6 +11632,14 @@ index 0000000000..904a254cab + endif +endif + ++if not cc.compiles('''#include ++#include ++static_assert(__STDC_VERSION_STDBIT_H__ >= 202311L, "Compiler lacks stdbit.h") ++int main() { return 0; } ++''', name: 'Compiler has stdbit.h') ++ common_incs += [include_directories('compat/stdbit')] ++endif ++ +add_project_arguments(project_c_args, language: 'c') + +libavcodec_optional_deps = [iconv_extra_deps + android_extra_deps] @@ -10010,6 +11681,14 @@ index 0000000000..904a254cab + +makedef_args += ['--prefix', extern_prefix] + ++if host_machine.system() == 'windows' ++ makedef_args += ['--os', 'win'] ++elif host_machine.system() in ['darwin', 'ios'] ++ makedef_args += ['--os', 'darwin'] ++else ++ makedef_args += ['--os', 'linux'] ++endif ++ +final_conf = configuration_data() + +if meson.version().version_compare('>=1.1.0') @@ -10028,6 +11707,9 @@ index 0000000000..904a254cab +final_conf.set('SWS_MAX_FILTER_SIZE', 256) +final_conf.set('EXTERN_ASM', extern_prefix) +final_conf.set_quoted('EXTERN_PREFIX', extern_prefix) ++if assert_level > 0 ++ final_conf.set10('ASSERT_LEVEL', assert_level) ++endif + +if not get_option('nonfree').disabled() + license = 'nonfree and unredistributable' @@ -10063,9 +11745,23 @@ index 0000000000..904a254cab +endforeach + +foreach have: have_list ++ if have == 'unistd_h' and conf.get(have) == 0 ++ # https://github.com/madler/zlib/issues/787 ++ # Workaround for the `HAVE_UNISTD_H` conflict. Both ffmpeg and zlib define ++ # the same name. While ffmpeg checks for 0/1 using #if, zlib uses #ifdef, so ++ # the 0 case would be incorrectly inferred as if unistd.h is available. As a ++ # workaround, don't define `HAVE_UNISTD_H` at all and rely on the fact that ++ # undefined will be resolved to 0. This may introduce compiler warnings, but ++ # otherwise works correctly. ++ continue ++ endif + final_conf.set('HAVE_@0@'.format(have.to_upper()), conf.get(have.to_lower())) +endforeach + ++if conf.get('aarch64', 0) == 1 ++ final_conf.set('AS_ARCH_LEVEL', as_arch_level) ++endif ++ +foreach config: config_list + config_extra + final_conf.set('CONFIG_@0@'.format(config.to_upper()), conf.get(config.to_lower())) +endforeach @@ -10092,9 +11788,9 @@ index 0000000000..904a254cab + configuration: components_conf, +) + -+rc = find_program('rc_workaround.py', required: host_machine.system() == 'windows') ++build_tests = get_option('tests').allowed() and meson.can_run_host_binaries() + -+build_tests = get_option('tests').allowed() ++fs = import('fs') + +foreach built_lib : built_libs + sources = get_variable('lib@0@_sources'.format(built_lib[0])) + [ffversion_h] @@ -10118,13 +11814,7 @@ index 0000000000..904a254cab + # is the config.h of the *root* project, instead of our config.h. + # This is because -I folder take effect *after* the .rc + # file's directory, and *after* Ninja's build directory. -+ rc_tgt = custom_target( -+ '@0@res.rc'.format(built_lib[0]), -+ input : ['lib@0@/@0@res.rc'.format(built_lib[0])], -+ output : ['@PLAINNAME@'], -+ command : [rc, '@INPUT@', meson.current_build_dir()], -+ capture: true -+ ) ++ rc_tgt = fs.copyfile('lib@0@/@0@res.rc'.format(built_lib[0]), '@0@res.rc'.format(built_lib[0])) + sources += windows.compile_resources( + rc_tgt, + include_directories: ffmpeg_toplevel_inc, @@ -10150,10 +11840,20 @@ index 0000000000..904a254cab + + optional_sources = get_variable('lib@0@_optional_sources'.format(built_lib[0]), {}) + optional_tests = get_variable('lib@0@_optional_tests'.format(built_lib[0]), {}) ++ # https://github.com/FFmpeg/FFmpeg/commit/887a7817b6671cd5dce9ba9bf97b88afdbbe7137 ++ optional_includes = get_variable('lib@0@_optional_includes'.format(built_lib[0]), {}) ++ ++ special_sources = {} + + foreach comp_name, comp_sources : optional_sources -+ if conf.get(comp_name, 0) == 1 -+ sources += comp_sources ++ comp_neg = comp_name.startswith('!') ++ comp_name = comp_name.strip('!') ++ if conf.get(comp_name, 0) == (comp_neg ? 0 : 1) ++ if optional_includes.has_key(comp_name) ++ special_sources += {comp_name: special_sources.get(comp_name, []) + comp_sources} ++ else ++ sources += comp_sources ++ endif + endif + + if languages_map.has_key(comp_name) @@ -10225,6 +11925,7 @@ index 0000000000..904a254cab + + if x86asm_sources.length() > 0 + # FIXME dedup should happen in meson ++ # FIXME dedup should work with file instances from different subdirs + deduped_sources = [] + foreach source : x86asm_sources + if not deduped_sources.contains(source) @@ -10246,32 +11947,69 @@ index 0000000000..904a254cab + gen_objects += asm_gen.process(deduped_sources) + endif + -+ vflag = '-Wl,--version-script,@0@/lib@1@/lib@1@.ver'.format(meson.current_build_dir(), built_lib[0]) -+ c_args = ['-DHAVE_AV_CONFIG_H', '-DBUILDING_@0@'.format(built_lib[0])] ++ version_script = meson.current_build_dir() / 'lib@0@'.format(built_lib[0]) / 'lib@0@.ver'.format(built_lib[0]) ++ if host_machine.system() in ['darwin', 'ios'] ++ vflag = '-Wl,-exported_symbols_list,@0@'.format(version_script) ++ else ++ vflag = '-Wl,--version-script,@0@'.format(version_script) ++ endif + -+ link_args = cc.get_supported_link_arguments([vflag]) ++ c_args = ['-DHAVE_AV_CONFIG_H', '-DBUILDING_@0@'.format(built_lib[0])] + -+ static_link_args = [] ++ link_args = cc.get_supported_link_arguments([ ++ vflag, ++ # Fixes warnings about PIC relocation. ++ # See: ++ # https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3348#note_2308136 ++ # https://github.com/google/ExoPlayer/issues/9933#issuecomment-1029775358 ++ '-Wl,-Bsymbolic' ++ ]) ++ ++ special_files = [] ++ special_includes = [] ++ special_objects = [] ++ ++ foreach k, v : special_sources ++ foreach src : v ++ if not sources.contains(src) ++ special_files += [src] ++ endif ++ endforeach ++ special_includes += optional_includes[k] ++ endforeach + -+ if is_msvc and (get_option('buildtype') == 'debug' or get_option('optimization') == '0') -+ message('Applying MSVC link workaround for Debug mode and static libraries.') -+ static_link_args += cc.get_supported_link_arguments('/FORCE:UNRESOLVED') -+ link_args += cc.get_supported_link_arguments('/FORCE:UNRESOLVED') ++ if special_files.length() > 0 ++ special_static_lib = static_library('@0@-static-special'.format(built_lib[0]), special_files, ++ dependencies: deps, ++ include_directories: common_incs + special_includes, ++ link_with: link_with, ++ c_args: c_args, ++ pic: conf.get('pic') == 1, ++ implicit_include_directories : false, ++ install: false, ++ override_options: global_overrides, ++ ) ++ special_objects = special_static_lib.extract_all_objects(recursive: true) + endif + + static_lib = static_library('@0@-static'.format(built_lib[0]), sources + gen_objects + [config_h, config_components_h], ++ objects: special_objects, + dependencies: deps, + include_directories: common_incs, + link_with: link_with, -+ link_args: static_link_args, + c_args: c_args, + pic: conf.get('pic') == 1, + implicit_include_directories : false, ++ override_options: global_overrides, + ) + + vs_module_def = custom_target('@0@-def'.format(built_lib[0]), + output: '@0@.def'.format(built_lib[0]), -+ command: [makedef_args, '@0@/lib@1@/lib@1@.ver'.format(meson.current_build_dir(), built_lib[0]), static_lib], ++ command: [makedef_args, '--vscript', '@INPUT0@', '@INPUT1@'], ++ input: [ ++ get_variable('lib@0@_ver'.format(built_lib[0])), ++ static_lib ++ ], + capture: true + ) + @@ -10286,6 +12024,7 @@ index 0000000000..904a254cab + pic: conf.get('pic') == 1, + vs_module_defs: vs_module_def, + implicit_include_directories : false, ++ override_options: global_overrides, + install: true, + ) + @@ -10319,10 +12058,10 @@ index 0000000000..904a254cab + c_args: c_args, + dependencies: test_deps, + include_directories: common_incs, -+ link_args: static_link_args, + link_with: [static_lib] + link_with, + implicit_include_directories : false, -+ pie: get_option('b_pie') and (conf.get('pic') == 1) ++ pie: get_option('b_pie') and (conf.get('pic') == 1), ++ override_options: global_overrides, + ) + + test('@0@_@1@'.format(built_lib[0], test_name), exe, @@ -10373,7 +12112,8 @@ index 0000000000..904a254cab + dependencies: deps, + include_directories: common_incs, + implicit_include_directories : false, -+ pie: get_option('b_pie') and (conf.get('pic') == 1) ++ pie: get_option('b_pie') and (conf.get('pic') == 1), ++ override_options: global_overrides, + ) + + set_variable('@0@_exe'.format(built_exe[0]), exe) @@ -10400,7 +12140,15 @@ index 0000000000..904a254cab + pkg.generate(get_variable(libname), + filebase: libname, + description: pkg_info[0], -+ version: get_variable(libname + '_version') ++ version: get_variable(libname + '_version'), ++ libraries_private: cc.get_supported_link_arguments([ ++ # Ensure that consumers link with -Bsymbolic. ++ # Use Libs.private since this affects static-to-shared builds. ++ # See: ++ # https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3348#note_2308136 ++ # https://github.com/google/ExoPlayer/issues/9933#issuecomment-1029775358 ++ '-Wl,-Bsymbolic' ++ ]) + ) +endforeach + @@ -10463,7 +12211,8 @@ index 0000000000..904a254cab +if conf.get('aarch64') == 1 + summary({ + 'NEON': conf.get('neon').is_odd(), -+ 'VFP': conf.get('vfp').is_odd(), ++ 'DOTPROD': conf.get('dotprod').is_odd(), ++ 'I8MM': conf.get('i8mm').is_odd(), + }, section: 'Arm64', bool_yn: true) +endif +if conf.get('arm') == 1 @@ -10560,10 +12309,10 @@ index 0000000000..904a254cab +summary(d, section: 'Components', list_sep: ' ') diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 -index 0000000000..682c774c46 +index 00000000..ab584128 --- /dev/null +++ b/meson_options.txt -@@ -0,0 +1,2397 @@ +@@ -0,0 +1,2487 @@ +# pkg-config options +option('alsa', type: 'feature', value: 'auto') +option('avisynth', type: 'feature', value: 'disabled') @@ -10593,6 +12342,8 @@ index 0000000000..682c774c46 +option('libjxl', type: 'feature', value: 'disabled') +option('libklvanc', type: 'feature', value: 'disabled') +option('libkvazaar', type: 'feature', value: 'disabled') ++option('liblc3', type: 'feature', value: 'disabled') ++option('liblcevc_dec', type: 'feature', value: 'disabled') +option('liblensfun', type: 'feature', value: 'disabled') +option('libglslang', type: 'feature', value: 'disabled') +option('libmfx', type: 'feature', value: 'disabled') @@ -10627,6 +12378,7 @@ index 0000000000..682c774c46 +option('libvorbisenc', type: 'feature', value: 'disabled') +option('libvpl', type: 'feature', value: 'disabled') +option('libvpx', type: 'feature', value: 'disabled') ++option('libvvenc', type: 'feature', value: 'disabled') +option('libwebp', type: 'feature', value: 'disabled') +option('libx264', type: 'feature', value: 'disabled') +option('libx265', type: 'feature', value: 'disabled') @@ -10634,6 +12386,7 @@ index 0000000000..682c774c46 +option('libxcb_shm', type: 'feature', value: 'auto') +option('libxcb_shape', type: 'feature', value: 'auto') +option('libxcb_xfixes', type: 'feature', value: 'auto') ++option('libxeve', type: 'feature', value: 'disabled') +option('libxml2', type: 'feature', value: 'disabled') +option('libzimg', type: 'feature', value: 'disabled') +option('libzmq', type: 'feature', value: 'disabled') @@ -10667,6 +12420,7 @@ index 0000000000..682c774c46 +option('ff_cuda_llvm', type: 'feature', value: 'disabled') # ff_cuda_llvm in ffmpeg +option('ff_cuda_sdk', type: 'feature', value: 'auto') # cuda_sdk in ffmpeg +option('d3d11va', type: 'feature', value: 'auto') ++option('d3d12va', type: 'feature', value: 'auto') +option('dxva2', type: 'feature', value: 'auto') +option('gcrypt', type: 'feature', value: 'disabled') +option('gmp', type: 'feature', value: 'disabled') @@ -10676,6 +12430,8 @@ index 0000000000..682c774c46 +option('libcodec2', type: 'feature', value: 'disabled') +option('libdav1d', type: 'feature', value: 'disabled') +option('libdl', type: 'feature', value: 'auto') ++option('libdvdnav', type: 'feature', value: 'disabled') ++option('libdvdread', type: 'feature', value: 'disabled') +option('libflite', type: 'feature', value: 'disabled') +option('libgsm', type: 'feature', value: 'disabled') +option('libiec61883', type: 'feature', value: 'disabled') @@ -10685,9 +12441,12 @@ index 0000000000..682c774c46 +option('libnpp', type: 'feature', value: 'disabled') +option('libopencore_amrnb', type: 'feature', value: 'disabled') +option('libopencore_amrwb', type: 'feature', value: 'disabled') ++option('libqrencode', type: 'feature', value: 'disabled') ++option('libquirc', type: 'feature', value: 'disabled') +option('libsnappy', type: 'feature', value: 'disabled') +option('libsoxr', type: 'feature', value: 'disabled') +option('libtheora', type: 'feature', value: 'disabled') ++option('libtorch', type: 'feature', value: 'disabled') +option('libtwolame', type: 'feature', value: 'disabled') +option('libuavs3d', type: 'feature', value: 'disabled') +option('libvo_amrwbenc', type: 'feature', value: 'disabled') @@ -10737,8 +12496,10 @@ index 0000000000..682c774c46 +# Generated muxer options +option('a64_muxer', type: 'feature', value: 'auto') +option('ac3_muxer', type: 'feature', value: 'auto') ++option('ac4_muxer', type: 'feature', value: 'auto') +option('adts_muxer', type: 'feature', value: 'auto') +option('adx_muxer', type: 'feature', value: 'auto') ++option('aea_muxer', type: 'feature', value: 'auto') +option('aiff_muxer', type: 'feature', value: 'auto') +option('alp_muxer', type: 'feature', value: 'auto') +option('amr_muxer', type: 'feature', value: 'auto') @@ -10774,10 +12535,10 @@ index 0000000000..682c774c46 +option('dts_muxer', type: 'feature', value: 'auto') +option('dv_muxer', type: 'feature', value: 'auto') +option('eac3_muxer', type: 'feature', value: 'auto') ++option('evc_muxer', type: 'feature', value: 'auto') +option('f4v_muxer', type: 'feature', value: 'auto') +option('ffmetadata_muxer', type: 'feature', value: 'auto') +option('fifo_muxer', type: 'feature', value: 'auto') -+option('fifo_test_muxer', type: 'feature', value: 'auto') +option('filmstrip_muxer', type: 'feature', value: 'auto') +option('fits_muxer', type: 'feature', value: 'auto') +option('flac_muxer', type: 'feature', value: 'auto') @@ -10799,6 +12560,7 @@ index 0000000000..682c774c46 +option('hds_muxer', type: 'feature', value: 'auto') +option('hevc_muxer', type: 'feature', value: 'auto') +option('hls_muxer', type: 'feature', value: 'auto') ++option('iamf_muxer', type: 'feature', value: 'auto') +option('ico_muxer', type: 'feature', value: 'auto') +option('ilbc_muxer', type: 'feature', value: 'auto') +option('image2_muxer', type: 'feature', value: 'auto') @@ -10810,6 +12572,7 @@ index 0000000000..682c774c46 +option('jacosub_muxer', type: 'feature', value: 'auto') +option('kvag_muxer', type: 'feature', value: 'auto') +option('latm_muxer', type: 'feature', value: 'auto') ++option('lc3_muxer', type: 'feature', value: 'auto') +option('lrc_muxer', type: 'feature', value: 'auto') +option('m4v_muxer', type: 'feature', value: 'auto') +option('md5_muxer', type: 'feature', value: 'auto') @@ -10866,6 +12629,7 @@ index 0000000000..682c774c46 +option('pcm_u8_muxer', type: 'feature', value: 'auto') +option('psp_muxer', type: 'feature', value: 'auto') +option('rawvideo_muxer', type: 'feature', value: 'auto') ++option('rcwt_muxer', type: 'feature', value: 'auto') +option('rm_muxer', type: 'feature', value: 'auto') +option('roq_muxer', type: 'feature', value: 'auto') +option('rso_muxer', type: 'feature', value: 'auto') @@ -10898,6 +12662,7 @@ index 0000000000..682c774c46 +option('vc1_muxer', type: 'feature', value: 'auto') +option('vc1t_muxer', type: 'feature', value: 'auto') +option('voc_muxer', type: 'feature', value: 'auto') ++option('vvc_muxer', type: 'feature', value: 'auto') +option('w64_muxer', type: 'feature', value: 'auto') +option('wav_muxer', type: 'feature', value: 'auto') +option('webm_muxer', type: 'feature', value: 'auto') @@ -10917,6 +12682,7 @@ index 0000000000..682c774c46 +option('aac_demuxer', type: 'feature', value: 'auto') +option('aax_demuxer', type: 'feature', value: 'auto') +option('ac3_demuxer', type: 'feature', value: 'auto') ++option('ac4_demuxer', type: 'feature', value: 'auto') +option('ace_demuxer', type: 'feature', value: 'auto') +option('acm_demuxer', type: 'feature', value: 'auto') +option('act_demuxer', type: 'feature', value: 'auto') @@ -10995,11 +12761,13 @@ index 0000000000..682c774c46 +option('dv_demuxer', type: 'feature', value: 'auto') +option('dvbsub_demuxer', type: 'feature', value: 'auto') +option('dvbtxt_demuxer', type: 'feature', value: 'auto') ++option('dvdvideo_demuxer', type: 'feature', value: 'auto') +option('dxa_demuxer', type: 'feature', value: 'auto') +option('ea_demuxer', type: 'feature', value: 'auto') +option('ea_cdata_demuxer', type: 'feature', value: 'auto') +option('eac3_demuxer', type: 'feature', value: 'auto') +option('epaf_demuxer', type: 'feature', value: 'auto') ++option('evc_demuxer', type: 'feature', value: 'auto') +option('ffmetadata_demuxer', type: 'feature', value: 'auto') +option('filmstrip_demuxer', type: 'feature', value: 'auto') +option('fits_demuxer', type: 'feature', value: 'auto') @@ -11029,6 +12797,7 @@ index 0000000000..682c774c46 +option('hevc_demuxer', type: 'feature', value: 'auto') +option('hls_demuxer', type: 'feature', value: 'auto') +option('hnm_demuxer', type: 'feature', value: 'auto') ++option('iamf_demuxer', type: 'feature', value: 'auto') +option('ico_demuxer', type: 'feature', value: 'auto') +option('idcin_demuxer', type: 'feature', value: 'auto') +option('idf_demuxer', type: 'feature', value: 'auto') @@ -11050,9 +12819,11 @@ index 0000000000..682c774c46 +option('ivr_demuxer', type: 'feature', value: 'auto') +option('jacosub_demuxer', type: 'feature', value: 'auto') +option('jv_demuxer', type: 'feature', value: 'auto') ++option('jpegxl_anim_demuxer', type: 'feature', value: 'auto') +option('kux_demuxer', type: 'feature', value: 'auto') +option('kvag_demuxer', type: 'feature', value: 'auto') +option('laf_demuxer', type: 'feature', value: 'auto') ++option('lc3_demuxer', type: 'feature', value: 'auto') +option('lmlm4_demuxer', type: 'feature', value: 'auto') +option('loas_demuxer', type: 'feature', value: 'auto') +option('luodat_demuxer', type: 'feature', value: 'auto') @@ -11103,6 +12874,7 @@ index 0000000000..682c774c46 +option('obu_demuxer', type: 'feature', value: 'auto') +option('ogg_demuxer', type: 'feature', value: 'auto') +option('oma_demuxer', type: 'feature', value: 'auto') ++option('osq_demuxer', type: 'feature', value: 'auto') +option('paf_demuxer', type: 'feature', value: 'auto') +option('pcm_alaw_demuxer', type: 'feature', value: 'auto') +option('pcm_mulaw_demuxer', type: 'feature', value: 'auto') @@ -11125,14 +12897,17 @@ index 0000000000..682c774c46 +option('pcm_u16be_demuxer', type: 'feature', value: 'auto') +option('pcm_u16le_demuxer', type: 'feature', value: 'auto') +option('pcm_u8_demuxer', type: 'feature', value: 'auto') ++option('pdv_demuxer', type: 'feature', value: 'auto') +option('pjs_demuxer', type: 'feature', value: 'auto') +option('pmp_demuxer', type: 'feature', value: 'auto') +option('pp_bnk_demuxer', type: 'feature', value: 'auto') +option('pva_demuxer', type: 'feature', value: 'auto') +option('pvf_demuxer', type: 'feature', value: 'auto') +option('qcp_demuxer', type: 'feature', value: 'auto') ++option('qoa_demuxer', type: 'feature', value: 'auto') +option('r3d_demuxer', type: 'feature', value: 'auto') +option('rawvideo_demuxer', type: 'feature', value: 'auto') ++option('rcwt_demuxer', type: 'feature', value: 'auto') +option('realtext_demuxer', type: 'feature', value: 'auto') +option('redspark_demuxer', type: 'feature', value: 'auto') +option('rka_demuxer', type: 'feature', value: 'auto') @@ -11189,6 +12964,7 @@ index 0000000000..682c774c46 +option('txd_demuxer', type: 'feature', value: 'auto') +option('tty_demuxer', type: 'feature', value: 'auto') +option('ty_demuxer', type: 'feature', value: 'auto') ++option('usm_demuxer', type: 'feature', value: 'auto') +option('v210_demuxer', type: 'feature', value: 'auto') +option('v210x_demuxer', type: 'feature', value: 'auto') +option('vag_demuxer', type: 'feature', value: 'auto') @@ -11202,6 +12978,7 @@ index 0000000000..682c774c46 +option('vpk_demuxer', type: 'feature', value: 'auto') +option('vplayer_demuxer', type: 'feature', value: 'auto') +option('vqf_demuxer', type: 'feature', value: 'auto') ++option('vvc_demuxer', type: 'feature', value: 'auto') +option('w64_demuxer', type: 'feature', value: 'auto') +option('wady_demuxer', type: 'feature', value: 'auto') +option('wavarc_demuxer', type: 'feature', value: 'auto') @@ -11275,7 +13052,6 @@ index 0000000000..682c774c46 +option('asv2_encoder', type: 'feature', value: 'auto') +option('avrp_encoder', type: 'feature', value: 'auto') +option('avui_encoder', type: 'feature', value: 'auto') -+option('ayuv_encoder', type: 'feature', value: 'auto') +option('bitpacked_encoder', type: 'feature', value: 'auto') +option('bmp_encoder', type: 'feature', value: 'auto') +option('cfhd_encoder', type: 'feature', value: 'auto') @@ -11285,6 +13061,7 @@ index 0000000000..682c774c46 +option('dnxhd_encoder', type: 'feature', value: 'auto') +option('dpx_encoder', type: 'feature', value: 'auto') +option('dvvideo_encoder', type: 'feature', value: 'auto') ++option('dxv_encoder', type: 'feature', value: 'auto') +option('exr_encoder', type: 'feature', value: 'auto') +option('ffv1_encoder', type: 'feature', value: 'auto') +option('ffvhuff_encoder', type: 'feature', value: 'auto') @@ -11309,6 +13086,7 @@ index 0000000000..682c774c46 +option('mpeg4_encoder', type: 'feature', value: 'auto') +option('msmpeg4v2_encoder', type: 'feature', value: 'auto') +option('msmpeg4v3_encoder', type: 'feature', value: 'auto') ++option('msrle_encoder', type: 'feature', value: 'auto') +option('msvideo1_encoder', type: 'feature', value: 'auto') +option('pam_encoder', type: 'feature', value: 'auto') +option('pbm_encoder', type: 'feature', value: 'auto') @@ -11455,6 +13233,7 @@ index 0000000000..682c774c46 +option('libgsm_ms_encoder', type: 'feature', value: 'auto') +option('libilbc_encoder', type: 'feature', value: 'auto') +option('libjxl_encoder', type: 'feature', value: 'auto') ++option('liblc3_encoder', type: 'feature', value: 'auto') +option('libmp3lame_encoder', type: 'feature', value: 'auto') +option('libopencore_amrnb_encoder', type: 'feature', value: 'auto') +option('libopenjpeg_encoder', type: 'feature', value: 'auto') @@ -11469,21 +13248,25 @@ index 0000000000..682c774c46 +option('libvorbis_encoder', type: 'feature', value: 'auto') +option('libvpx_vp8_encoder', type: 'feature', value: 'auto') +option('libvpx_vp9_encoder', type: 'feature', value: 'auto') ++option('libvvenc_encoder', type: 'feature', value: 'auto') +option('libwebp_anim_encoder', type: 'feature', value: 'auto') +option('libwebp_encoder', type: 'feature', value: 'auto') +option('libx262_encoder', type: 'feature', value: 'auto') +option('libx264_encoder', type: 'feature', value: 'auto') +option('libx264rgb_encoder', type: 'feature', value: 'auto') +option('libx265_encoder', type: 'feature', value: 'auto') ++option('libxeve_encoder', type: 'feature', value: 'auto') +option('libxavs_encoder', type: 'feature', value: 'auto') +option('libxavs2_encoder', type: 'feature', value: 'auto') +option('libxvid_encoder', type: 'feature', value: 'auto') +option('aac_mf_encoder', type: 'feature', value: 'auto') +option('ac3_mf_encoder', type: 'feature', value: 'auto') +option('h263_v4l2m2m_encoder', type: 'feature', value: 'auto') ++option('av1_mediacodec_encoder', type: 'feature', value: 'auto') +option('av1_nvenc_encoder', type: 'feature', value: 'auto') +option('av1_qsv_encoder', type: 'feature', value: 'auto') +option('av1_amf_encoder', type: 'feature', value: 'auto') ++option('av1_vaapi_encoder', type: 'feature', value: 'auto') +option('libopenh264_encoder', type: 'feature', value: 'auto') +option('h264_amf_encoder', type: 'feature', value: 'auto') +option('h264_mf_encoder', type: 'feature', value: 'auto') @@ -11493,7 +13276,9 @@ index 0000000000..682c774c46 +option('h264_v4l2m2m_encoder', type: 'feature', value: 'auto') +option('h264_vaapi_encoder', type: 'feature', value: 'auto') +option('h264_videotoolbox_encoder', type: 'feature', value: 'auto') ++option('h264_vulkan_encoder', type: 'feature', value: 'auto') +option('hevc_amf_encoder', type: 'feature', value: 'auto') ++option('hevc_d3d12va_encoder', type: 'feature', value: 'auto') +option('hevc_mediacodec_encoder', type: 'feature', value: 'auto') +option('hevc_mf_encoder', type: 'feature', value: 'auto') +option('hevc_nvenc_encoder', type: 'feature', value: 'auto') @@ -11501,17 +13286,21 @@ index 0000000000..682c774c46 +option('hevc_v4l2m2m_encoder', type: 'feature', value: 'auto') +option('hevc_vaapi_encoder', type: 'feature', value: 'auto') +option('hevc_videotoolbox_encoder', type: 'feature', value: 'auto') ++option('hevc_vulkan_encoder', type: 'feature', value: 'auto') +option('libkvazaar_encoder', type: 'feature', value: 'auto') +option('mjpeg_qsv_encoder', type: 'feature', value: 'auto') +option('mjpeg_vaapi_encoder', type: 'feature', value: 'auto') +option('mp3_mf_encoder', type: 'feature', value: 'auto') +option('mpeg2_qsv_encoder', type: 'feature', value: 'auto') +option('mpeg2_vaapi_encoder', type: 'feature', value: 'auto') ++option('mpeg4_mediacodec_encoder', type: 'feature', value: 'auto') +option('mpeg4_omx_encoder', type: 'feature', value: 'auto') +option('mpeg4_v4l2m2m_encoder', type: 'feature', value: 'auto') +option('prores_videotoolbox_encoder', type: 'feature', value: 'auto') ++option('vp8_mediacodec_encoder', type: 'feature', value: 'auto') +option('vp8_v4l2m2m_encoder', type: 'feature', value: 'auto') +option('vp8_vaapi_encoder', type: 'feature', value: 'auto') ++option('vp9_mediacodec_encoder', type: 'feature', value: 'auto') +option('vp9_vaapi_encoder', type: 'feature', value: 'auto') +option('vp9_qsv_encoder', type: 'feature', value: 'auto') +option('vnull_encoder', type: 'feature', value: 'auto') @@ -11537,7 +13326,6 @@ index 0000000000..682c774c46 +option('avrn_decoder', type: 'feature', value: 'auto') +option('avs_decoder', type: 'feature', value: 'auto') +option('avui_decoder', type: 'feature', value: 'auto') -+option('ayuv_decoder', type: 'feature', value: 'auto') +option('bethsoftvid_decoder', type: 'feature', value: 'auto') +option('bfi_decoder', type: 'feature', value: 'auto') +option('bink_decoder', type: 'feature', value: 'auto') @@ -11604,7 +13392,6 @@ index 0000000000..682c774c46 +option('h263p_decoder', type: 'feature', value: 'auto') +option('h263_v4l2m2m_decoder', type: 'feature', value: 'auto') +option('h264_decoder', type: 'feature', value: 'auto') -+option('h264_crystalhd_decoder', type: 'feature', value: 'auto') +option('h264_v4l2m2m_decoder', type: 'feature', value: 'auto') +option('h264_mediacodec_decoder', type: 'feature', value: 'auto') +option('h264_mmal_decoder', type: 'feature', value: 'auto') @@ -11636,6 +13423,7 @@ index 0000000000..682c774c46 +option('kgv1_decoder', type: 'feature', value: 'auto') +option('kmvc_decoder', type: 'feature', value: 'auto') +option('lagarith_decoder', type: 'feature', value: 'auto') ++option('lead_decoder', type: 'feature', value: 'auto') +option('loco_decoder', type: 'feature', value: 'auto') +option('lscr_decoder', type: 'feature', value: 'auto') +option('m101_decoder', type: 'feature', value: 'auto') @@ -11651,13 +13439,11 @@ index 0000000000..682c774c46 +option('mpeg1video_decoder', type: 'feature', value: 'auto') +option('mpeg2video_decoder', type: 'feature', value: 'auto') +option('mpeg4_decoder', type: 'feature', value: 'auto') -+option('mpeg4_crystalhd_decoder', type: 'feature', value: 'auto') +option('mpeg4_v4l2m2m_decoder', type: 'feature', value: 'auto') +option('mpeg4_mmal_decoder', type: 'feature', value: 'auto') +option('mpegvideo_decoder', type: 'feature', value: 'auto') +option('mpeg1_v4l2m2m_decoder', type: 'feature', value: 'auto') +option('mpeg2_mmal_decoder', type: 'feature', value: 'auto') -+option('mpeg2_crystalhd_decoder', type: 'feature', value: 'auto') +option('mpeg2_v4l2m2m_decoder', type: 'feature', value: 'auto') +option('mpeg2_qsv_decoder', type: 'feature', value: 'auto') +option('mpeg2_mediacodec_decoder', type: 'feature', value: 'auto') @@ -11666,7 +13452,6 @@ index 0000000000..682c774c46 +option('msmpeg4v1_decoder', type: 'feature', value: 'auto') +option('msmpeg4v2_decoder', type: 'feature', value: 'auto') +option('msmpeg4v3_decoder', type: 'feature', value: 'auto') -+option('msmpeg4_crystalhd_decoder', type: 'feature', value: 'auto') +option('msp2_decoder', type: 'feature', value: 'auto') +option('msrle_decoder', type: 'feature', value: 'auto') +option('mss1_decoder', type: 'feature', value: 'auto') @@ -11687,6 +13472,7 @@ index 0000000000..682c774c46 +option('pam_decoder', type: 'feature', value: 'auto') +option('pbm_decoder', type: 'feature', value: 'auto') +option('pcx_decoder', type: 'feature', value: 'auto') ++option('pdv_decoder', type: 'feature', value: 'auto') +option('pfm_decoder', type: 'feature', value: 'auto') +option('pgm_decoder', type: 'feature', value: 'auto') +option('pgmyuv_decoder', type: 'feature', value: 'auto') @@ -11714,6 +13500,7 @@ index 0000000000..682c774c46 +option('roq_decoder', type: 'feature', value: 'auto') +option('rpza_decoder', type: 'feature', value: 'auto') +option('rscc_decoder', type: 'feature', value: 'auto') ++option('rtv1_decoder', type: 'feature', value: 'auto') +option('rv10_decoder', type: 'feature', value: 'auto') +option('rv20_decoder', type: 'feature', value: 'auto') +option('rv30_decoder', type: 'feature', value: 'auto') @@ -11763,13 +13550,13 @@ index 0000000000..682c774c46 +option('vbn_decoder', type: 'feature', value: 'auto') +option('vble_decoder', type: 'feature', value: 'auto') +option('vc1_decoder', type: 'feature', value: 'auto') -+option('vc1_crystalhd_decoder', type: 'feature', value: 'auto') +option('vc1image_decoder', type: 'feature', value: 'auto') +option('vc1_mmal_decoder', type: 'feature', value: 'auto') +option('vc1_qsv_decoder', type: 'feature', value: 'auto') +option('vc1_v4l2m2m_decoder', type: 'feature', value: 'auto') +option('vcr1_decoder', type: 'feature', value: 'auto') +option('vmdvideo_decoder', type: 'feature', value: 'auto') ++option('vmix_decoder', type: 'feature', value: 'auto') +option('vmnc_decoder', type: 'feature', value: 'auto') +option('vp3_decoder', type: 'feature', value: 'auto') +option('vp4_decoder', type: 'feature', value: 'auto') @@ -11786,6 +13573,7 @@ index 0000000000..682c774c46 +option('vp9_v4l2m2m_decoder', type: 'feature', value: 'auto') +option('vqa_decoder', type: 'feature', value: 'auto') +option('vqc_decoder', type: 'feature', value: 'auto') ++option('vvc_decoder', type: 'feature', value: 'auto') +option('wbmp_decoder', type: 'feature', value: 'auto') +option('webp_decoder', type: 'feature', value: 'auto') +option('wcmv_decoder', type: 'feature', value: 'auto') @@ -11793,7 +13581,6 @@ index 0000000000..682c774c46 +option('wmv1_decoder', type: 'feature', value: 'auto') +option('wmv2_decoder', type: 'feature', value: 'auto') +option('wmv3_decoder', type: 'feature', value: 'auto') -+option('wmv3_crystalhd_decoder', type: 'feature', value: 'auto') +option('wmv3image_decoder', type: 'feature', value: 'auto') +option('wnv1_decoder', type: 'feature', value: 'auto') +option('xan_wc3_decoder', type: 'feature', value: 'auto') @@ -11884,10 +13671,12 @@ index 0000000000..682c774c46 +option('nellymoser_decoder', type: 'feature', value: 'auto') +option('on2avc_decoder', type: 'feature', value: 'auto') +option('opus_decoder', type: 'feature', value: 'auto') ++option('osq_decoder', type: 'feature', value: 'auto') +option('paf_audio_decoder', type: 'feature', value: 'auto') +option('qcelp_decoder', type: 'feature', value: 'auto') +option('qdm2_decoder', type: 'feature', value: 'auto') +option('qdmc_decoder', type: 'feature', value: 'auto') ++option('qoa_decoder', type: 'feature', value: 'auto') +option('ra_144_decoder', type: 'feature', value: 'auto') +option('ra_288_decoder', type: 'feature', value: 'auto') +option('ralf_decoder', type: 'feature', value: 'auto') @@ -12047,6 +13836,7 @@ index 0000000000..682c774c46 +option('pcm_mulaw_at_decoder', type: 'feature', value: 'auto') +option('qdmc_at_decoder', type: 'feature', value: 'auto') +option('qdm2_at_decoder', type: 'feature', value: 'auto') ++option('libaribcaption_decoder', type: 'feature', value: 'auto') +option('libaribb24_decoder', type: 'feature', value: 'auto') +option('libcelt_decoder', type: 'feature', value: 'auto') +option('libcodec2_decoder', type: 'feature', value: 'auto') @@ -12057,9 +13847,9 @@ index 0000000000..682c774c46 +option('libgsm_ms_decoder', type: 'feature', value: 'auto') +option('libilbc_decoder', type: 'feature', value: 'auto') +option('libjxl_decoder', type: 'feature', value: 'auto') ++option('liblc3_decoder', type: 'feature', value: 'auto') +option('libopencore_amrnb_decoder', type: 'feature', value: 'auto') +option('libopencore_amrwb_decoder', type: 'feature', value: 'auto') -+option('libopenjpeg_decoder', type: 'feature', value: 'auto') +option('libopus_decoder', type: 'feature', value: 'auto') +option('librsvg_decoder', type: 'feature', value: 'auto') +option('libspeex_decoder', type: 'feature', value: 'auto') @@ -12067,10 +13857,14 @@ index 0000000000..682c774c46 +option('libvorbis_decoder', type: 'feature', value: 'auto') +option('libvpx_vp8_decoder', type: 'feature', value: 'auto') +option('libvpx_vp9_decoder', type: 'feature', value: 'auto') ++option('libxevd_decoder', type: 'feature', value: 'auto') +option('libzvbi_teletext_decoder', type: 'feature', value: 'auto') +option('bintext_decoder', type: 'feature', value: 'auto') +option('xbin_decoder', type: 'feature', value: 'auto') +option('idf_decoder', type: 'feature', value: 'auto') ++option('aac_mediacodec_decoder', type: 'feature', value: 'auto') ++option('amrnb_mediacodec_decoder', type: 'feature', value: 'auto') ++option('amrwb_mediacodec_decoder', type: 'feature', value: 'auto') +option('libaom_av1_decoder', type: 'feature', value: 'auto') +option('av1_decoder', type: 'feature', value: 'auto') +option('av1_cuvid_decoder', type: 'feature', value: 'auto') @@ -12082,6 +13876,7 @@ index 0000000000..682c774c46 +option('hevc_mediacodec_decoder', type: 'feature', value: 'auto') +option('mjpeg_cuvid_decoder', type: 'feature', value: 'auto') +option('mjpeg_qsv_decoder', type: 'feature', value: 'auto') ++option('mp3_mediacodec_decoder', type: 'feature', value: 'auto') +option('mpeg1_cuvid_decoder', type: 'feature', value: 'auto') +option('mpeg2_cuvid_decoder', type: 'feature', value: 'auto') +option('mpeg4_cuvid_decoder', type: 'feature', value: 'auto') @@ -12093,6 +13888,7 @@ index 0000000000..682c774c46 +option('vp9_cuvid_decoder', type: 'feature', value: 'auto') +option('vp9_mediacodec_decoder', type: 'feature', value: 'auto') +option('vp9_qsv_decoder', type: 'feature', value: 'auto') ++option('vvc_qsv_decoder', type: 'feature', value: 'auto') +option('vnull_decoder', type: 'feature', value: 'auto') +option('anull_decoder', type: 'feature', value: 'auto') +option('decoders', type: 'feature', value: 'auto', description: 'Enable or disable all decoders') @@ -12119,6 +13915,7 @@ index 0000000000..682c774c46 +option('dvbsub_parser', type: 'feature', value: 'auto') +option('dvdsub_parser', type: 'feature', value: 'auto') +option('dvd_nav_parser', type: 'feature', value: 'auto') ++option('evc_parser', type: 'feature', value: 'auto') +option('flac_parser', type: 'feature', value: 'auto') +option('ftr_parser', type: 'feature', value: 'auto') +option('g723_1_parser', type: 'feature', value: 'auto') @@ -12132,6 +13929,7 @@ index 0000000000..682c774c46 +option('hdr_parser', type: 'feature', value: 'auto') +option('ipu_parser', type: 'feature', value: 'auto') +option('jpeg2000_parser', type: 'feature', value: 'auto') ++option('jpegxl_parser', type: 'feature', value: 'auto') +option('misc4_parser', type: 'feature', value: 'auto') +option('mjpeg_parser', type: 'feature', value: 'auto') +option('mlp_parser', type: 'feature', value: 'auto') @@ -12142,8 +13940,7 @@ index 0000000000..682c774c46 +option('png_parser', type: 'feature', value: 'auto') +option('pnm_parser', type: 'feature', value: 'auto') +option('qoi_parser', type: 'feature', value: 'auto') -+option('rv30_parser', type: 'feature', value: 'auto') -+option('rv40_parser', type: 'feature', value: 'auto') ++option('rv34_parser', type: 'feature', value: 'auto') +option('sbc_parser', type: 'feature', value: 'auto') +option('sipr_parser', type: 'feature', value: 'auto') +option('tak_parser', type: 'feature', value: 'auto') @@ -12152,6 +13949,7 @@ index 0000000000..682c774c46 +option('vp3_parser', type: 'feature', value: 'auto') +option('vp8_parser', type: 'feature', value: 'auto') +option('vp9_parser', type: 'feature', value: 'auto') ++option('vvc_parser', type: 'feature', value: 'auto') +option('webp_parser', type: 'feature', value: 'auto') +option('xbm_parser', type: 'feature', value: 'auto') +option('xma_parser', type: 'feature', value: 'auto') @@ -12166,9 +13964,11 @@ index 0000000000..682c774c46 +option('chomp_bsf', type: 'feature', value: 'auto') +option('dump_extradata_bsf', type: 'feature', value: 'auto') +option('dca_core_bsf', type: 'feature', value: 'auto') ++option('dovi_rpu_bsf', type: 'feature', value: 'auto') +option('dts2pts_bsf', type: 'feature', value: 'auto') +option('dv_error_marker_bsf', type: 'feature', value: 'auto') +option('eac3_core_bsf', type: 'feature', value: 'auto') ++option('evc_frame_merge_bsf', type: 'feature', value: 'auto') +option('extract_extradata_bsf', type: 'feature', value: 'auto') +option('filter_units_bsf', type: 'feature', value: 'auto') +option('h264_metadata_bsf', type: 'feature', value: 'auto') @@ -12181,7 +13981,6 @@ index 0000000000..682c774c46 +option('media100_to_mjpegb_bsf', type: 'feature', value: 'auto') +option('mjpeg2jpeg_bsf', type: 'feature', value: 'auto') +option('mjpega_dump_header_bsf', type: 'feature', value: 'auto') -+option('mp3_header_decompress_bsf', type: 'feature', value: 'auto') +option('mpeg2_metadata_bsf', type: 'feature', value: 'auto') +option('mpeg4_unpack_bframes_bsf', type: 'feature', value: 'auto') +option('mov2textsub_bsf', type: 'feature', value: 'auto') @@ -12193,6 +13992,7 @@ index 0000000000..682c774c46 +option('prores_metadata_bsf', type: 'feature', value: 'auto') +option('remove_extradata_bsf', type: 'feature', value: 'auto') +option('setts_bsf', type: 'feature', value: 'auto') ++option('showinfo_bsf', type: 'feature', value: 'auto') +option('text2movsub_bsf', type: 'feature', value: 'auto') +option('trace_headers_bsf', type: 'feature', value: 'auto') +option('truehd_core_bsf', type: 'feature', value: 'auto') @@ -12200,31 +14000,39 @@ index 0000000000..682c774c46 +option('vp9_raw_reorder_bsf', type: 'feature', value: 'auto') +option('vp9_superframe_bsf', type: 'feature', value: 'auto') +option('vp9_superframe_split_bsf', type: 'feature', value: 'auto') ++option('vvc_metadata_bsf', type: 'feature', value: 'auto') ++option('vvc_mp4toannexb_bsf', type: 'feature', value: 'auto') +option('bsfs', type: 'feature', value: 'auto', description: 'Enable or disable all bsfs') + +# Generated hwaccel options +option('av1_d3d11va_hwaccel', type: 'feature', value: 'auto') +option('av1_d3d11va2_hwaccel', type: 'feature', value: 'auto') ++option('av1_d3d12va_hwaccel', type: 'feature', value: 'auto') +option('av1_dxva2_hwaccel', type: 'feature', value: 'auto') +option('av1_nvdec_hwaccel', type: 'feature', value: 'auto') +option('av1_vaapi_hwaccel', type: 'feature', value: 'auto') +option('av1_vdpau_hwaccel', type: 'feature', value: 'auto') ++option('av1_vulkan_hwaccel', type: 'feature', value: 'auto') +option('h263_vaapi_hwaccel', type: 'feature', value: 'auto') +option('h263_videotoolbox_hwaccel', type: 'feature', value: 'auto') +option('h264_d3d11va_hwaccel', type: 'feature', value: 'auto') +option('h264_d3d11va2_hwaccel', type: 'feature', value: 'auto') ++option('h264_d3d12va_hwaccel', type: 'feature', value: 'auto') +option('h264_dxva2_hwaccel', type: 'feature', value: 'auto') +option('h264_nvdec_hwaccel', type: 'feature', value: 'auto') +option('h264_vaapi_hwaccel', type: 'feature', value: 'auto') +option('h264_vdpau_hwaccel', type: 'feature', value: 'auto') +option('h264_videotoolbox_hwaccel', type: 'feature', value: 'auto') ++option('h264_vulkan_hwaccel', type: 'feature', value: 'auto') +option('hevc_d3d11va_hwaccel', type: 'feature', value: 'auto') +option('hevc_d3d11va2_hwaccel', type: 'feature', value: 'auto') ++option('hevc_d3d12va_hwaccel', type: 'feature', value: 'auto') +option('hevc_dxva2_hwaccel', type: 'feature', value: 'auto') +option('hevc_nvdec_hwaccel', type: 'feature', value: 'auto') +option('hevc_vaapi_hwaccel', type: 'feature', value: 'auto') +option('hevc_vdpau_hwaccel', type: 'feature', value: 'auto') +option('hevc_videotoolbox_hwaccel', type: 'feature', value: 'auto') ++option('hevc_vulkan_hwaccel', type: 'feature', value: 'auto') +option('mjpeg_nvdec_hwaccel', type: 'feature', value: 'auto') +option('mjpeg_vaapi_hwaccel', type: 'feature', value: 'auto') +option('mpeg1_nvdec_hwaccel', type: 'feature', value: 'auto') @@ -12232,8 +14040,9 @@ index 0000000000..682c774c46 +option('mpeg1_videotoolbox_hwaccel', type: 'feature', value: 'auto') +option('mpeg2_d3d11va_hwaccel', type: 'feature', value: 'auto') +option('mpeg2_d3d11va2_hwaccel', type: 'feature', value: 'auto') -+option('mpeg2_nvdec_hwaccel', type: 'feature', value: 'auto') ++option('mpeg2_d3d12va_hwaccel', type: 'feature', value: 'auto') +option('mpeg2_dxva2_hwaccel', type: 'feature', value: 'auto') ++option('mpeg2_nvdec_hwaccel', type: 'feature', value: 'auto') +option('mpeg2_vaapi_hwaccel', type: 'feature', value: 'auto') +option('mpeg2_vdpau_hwaccel', type: 'feature', value: 'auto') +option('mpeg2_videotoolbox_hwaccel', type: 'feature', value: 'auto') @@ -12244,6 +14053,7 @@ index 0000000000..682c774c46 +option('prores_videotoolbox_hwaccel', type: 'feature', value: 'auto') +option('vc1_d3d11va_hwaccel', type: 'feature', value: 'auto') +option('vc1_d3d11va2_hwaccel', type: 'feature', value: 'auto') ++option('vc1_d3d12va_hwaccel', type: 'feature', value: 'auto') +option('vc1_dxva2_hwaccel', type: 'feature', value: 'auto') +option('vc1_nvdec_hwaccel', type: 'feature', value: 'auto') +option('vc1_vaapi_hwaccel', type: 'feature', value: 'auto') @@ -12252,6 +14062,7 @@ index 0000000000..682c774c46 +option('vp8_vaapi_hwaccel', type: 'feature', value: 'auto') +option('vp9_d3d11va_hwaccel', type: 'feature', value: 'auto') +option('vp9_d3d11va2_hwaccel', type: 'feature', value: 'auto') ++option('vp9_d3d12va_hwaccel', type: 'feature', value: 'auto') +option('vp9_dxva2_hwaccel', type: 'feature', value: 'auto') +option('vp9_nvdec_hwaccel', type: 'feature', value: 'auto') +option('vp9_vaapi_hwaccel', type: 'feature', value: 'auto') @@ -12259,6 +14070,7 @@ index 0000000000..682c774c46 +option('vp9_videotoolbox_hwaccel', type: 'feature', value: 'auto') +option('wmv3_d3d11va_hwaccel', type: 'feature', value: 'auto') +option('wmv3_d3d11va2_hwaccel', type: 'feature', value: 'auto') ++option('wmv3_d3d12va_hwaccel', type: 'feature', value: 'auto') +option('wmv3_dxva2_hwaccel', type: 'feature', value: 'auto') +option('wmv3_nvdec_hwaccel', type: 'feature', value: 'auto') +option('wmv3_vaapi_hwaccel', type: 'feature', value: 'auto') @@ -12266,6 +14078,7 @@ index 0000000000..682c774c46 +option('hwaccels', type: 'feature', value: 'auto', description: 'Enable or disable all hwaccels') + +# Generated protocol options ++option('android_content_protocol', type: 'feature', value: 'auto') +option('async_protocol', type: 'feature', value: 'auto') +option('bluray_protocol', type: 'feature', value: 'auto') +option('cache_protocol', type: 'feature', value: 'auto') @@ -12363,6 +14176,7 @@ index 0000000000..682c774c46 +#### --- END GENERATED EXTERN OPTIONS --- #### + +#### --- GENERATED FILTER OPTIONS --- #### ++option('aap_filter', type: 'feature', value: 'auto') +option('abench_filter', type: 'feature', value: 'auto') +option('acompressor_filter', type: 'feature', value: 'auto') +option('acontrast_filter', type: 'feature', value: 'auto') @@ -12412,11 +14226,13 @@ index 0000000000..682c774c46 +option('aperms_filter', type: 'feature', value: 'auto') +option('aphaser_filter', type: 'feature', value: 'auto') +option('aphaseshift_filter', type: 'feature', value: 'auto') ++option('apsnr_filter', type: 'feature', value: 'auto') +option('apsyclip_filter', type: 'feature', value: 'auto') +option('apulsator_filter', type: 'feature', value: 'auto') +option('arealtime_filter', type: 'feature', value: 'auto') +option('aresample_filter', type: 'feature', value: 'auto') +option('areverse_filter', type: 'feature', value: 'auto') ++option('arls_filter', type: 'feature', value: 'auto') +option('arnndn_filter', type: 'feature', value: 'auto') +option('asdr_filter', type: 'feature', value: 'auto') +option('asegment_filter', type: 'feature', value: 'auto') @@ -12428,6 +14244,7 @@ index 0000000000..682c774c46 +option('asettb_filter', type: 'feature', value: 'auto') +option('ashowinfo_filter', type: 'feature', value: 'auto') +option('asidedata_filter', type: 'feature', value: 'auto') ++option('asisdr_filter', type: 'feature', value: 'auto') +option('asoftclip_filter', type: 'feature', value: 'auto') +option('aspectralstats_filter', type: 'feature', value: 'auto') +option('asplit_filter', type: 'feature', value: 'auto') @@ -12501,6 +14318,7 @@ index 0000000000..682c774c46 +option('volumedetect_filter', type: 'feature', value: 'auto') +option('aevalsrc_filter', type: 'feature', value: 'auto') +option('afdelaysrc_filter', type: 'feature', value: 'auto') ++option('afireqsrc_filter', type: 'feature', value: 'auto') +option('afirsrc_filter', type: 'feature', value: 'auto') +option('anoisesrc_filter', type: 'feature', value: 'auto') +option('anullsrc_filter', type: 'feature', value: 'auto') @@ -12534,7 +14352,10 @@ index 0000000000..682c774c46 +option('boxblur_filter', type: 'feature', value: 'auto') +option('boxblur_opencl_filter', type: 'feature', value: 'auto') +option('bwdif_filter', type: 'feature', value: 'auto') ++option('bwdif_cuda_filter', type: 'feature', value: 'auto') ++option('bwdif_vulkan_filter', type: 'feature', value: 'auto') +option('cas_filter', type: 'feature', value: 'auto') ++option('ccrepack_filter', type: 'feature', value: 'auto') +option('chromaber_vulkan_filter', type: 'feature', value: 'auto') +option('chromahold_filter', type: 'feature', value: 'auto') +option('chromakey_filter', type: 'feature', value: 'auto') @@ -12630,6 +14451,7 @@ index 0000000000..682c774c46 +option('freezeframes_filter', type: 'feature', value: 'auto') +option('frei0r_filter', type: 'feature', value: 'auto') +option('fspp_filter', type: 'feature', value: 'auto') ++option('fsync_filter', type: 'feature', value: 'auto') +option('gblur_filter', type: 'feature', value: 'auto') +option('gblur_vulkan_filter', type: 'feature', value: 'auto') +option('geq_filter', type: 'feature', value: 'auto') @@ -12667,10 +14489,12 @@ index 0000000000..682c774c46 +option('kirsch_filter', type: 'feature', value: 'auto') +option('lagfun_filter', type: 'feature', value: 'auto') +option('latency_filter', type: 'feature', value: 'auto') ++option('lcevc_filter', type: 'feature', value: 'auto') +option('lenscorrection_filter', type: 'feature', value: 'auto') +option('lensfun_filter', type: 'feature', value: 'auto') +option('libplacebo_filter', type: 'feature', value: 'auto') +option('libvmaf_filter', type: 'feature', value: 'auto') ++option('libvmaf_cuda_filter', type: 'feature', value: 'auto') +option('limitdiff_filter', type: 'feature', value: 'auto') +option('limiter_filter', type: 'feature', value: 'auto') +option('loop_filter', type: 'feature', value: 'auto') @@ -12703,6 +14527,7 @@ index 0000000000..682c774c46 +option('negate_filter', type: 'feature', value: 'auto') +option('nlmeans_filter', type: 'feature', value: 'auto') +option('nlmeans_opencl_filter', type: 'feature', value: 'auto') ++option('nlmeans_vulkan_filter', type: 'feature', value: 'auto') +option('nnedi_filter', type: 'feature', value: 'auto') +option('noformat_filter', type: 'feature', value: 'auto') +option('noise_filter', type: 'feature', value: 'auto') @@ -12740,6 +14565,8 @@ index 0000000000..682c774c46 +option('psnr_filter', type: 'feature', value: 'auto') +option('pullup_filter', type: 'feature', value: 'auto') +option('qp_filter', type: 'feature', value: 'auto') ++option('qrencode_filter', type: 'feature', value: 'auto') ++option('quirc_filter', type: 'feature', value: 'auto') +option('random_filter', type: 'feature', value: 'auto') +option('readeia608_filter', type: 'feature', value: 'auto') +option('readvitc_filter', type: 'feature', value: 'auto') @@ -12760,6 +14587,7 @@ index 0000000000..682c774c46 +option('scale_npp_filter', type: 'feature', value: 'auto') +option('scale_qsv_filter', type: 'feature', value: 'auto') +option('scale_vaapi_filter', type: 'feature', value: 'auto') ++option('scale_vt_filter', type: 'feature', value: 'auto') +option('scale_vulkan_filter', type: 'feature', value: 'auto') +option('scale2ref_filter', type: 'feature', value: 'auto') +option('scale2ref_npp_filter', type: 'feature', value: 'auto') @@ -12811,6 +14639,7 @@ index 0000000000..682c774c46 +option('thumbnail_filter', type: 'feature', value: 'auto') +option('thumbnail_cuda_filter', type: 'feature', value: 'auto') +option('tile_filter', type: 'feature', value: 'auto') ++option('tiltandshift_filter', type: 'feature', value: 'auto') +option('tinterlace_filter', type: 'feature', value: 'auto') +option('tlut2_filter', type: 'feature', value: 'auto') +option('tmedian_filter', type: 'feature', value: 'auto') @@ -12824,6 +14653,7 @@ index 0000000000..682c774c46 +option('transpose_npp_filter', type: 'feature', value: 'auto') +option('transpose_opencl_filter', type: 'feature', value: 'auto') +option('transpose_vaapi_filter', type: 'feature', value: 'auto') ++option('transpose_vt_filter', type: 'feature', value: 'auto') +option('transpose_vulkan_filter', type: 'feature', value: 'auto') +option('trim_filter', type: 'feature', value: 'auto') +option('unpremultiply_filter', type: 'feature', value: 'auto') @@ -12853,7 +14683,9 @@ index 0000000000..682c774c46 +option('xcorrelate_filter', type: 'feature', value: 'auto') +option('xfade_filter', type: 'feature', value: 'auto') +option('xfade_opencl_filter', type: 'feature', value: 'auto') ++option('xfade_vulkan_filter', type: 'feature', value: 'auto') +option('xmedian_filter', type: 'feature', value: 'auto') ++option('xpsnr_filter', type: 'feature', value: 'auto') +option('xstack_filter', type: 'feature', value: 'auto') +option('yadif_filter', type: 'feature', value: 'auto') +option('yadif_cuda_filter', type: 'feature', value: 'auto') @@ -12868,10 +14700,13 @@ index 0000000000..682c774c46 +option('hstack_qsv_filter', type: 'feature', value: 'auto') +option('vstack_qsv_filter', type: 'feature', value: 'auto') +option('xstack_qsv_filter', type: 'feature', value: 'auto') ++option('pad_vaapi_filter', type: 'feature', value: 'auto') ++option('drawbox_vaapi_filter', type: 'feature', value: 'auto') +option('allrgb_filter', type: 'feature', value: 'auto') +option('allyuv_filter', type: 'feature', value: 'auto') +option('cellauto_filter', type: 'feature', value: 'auto') +option('color_filter', type: 'feature', value: 'auto') ++option('color_vulkan_filter', type: 'feature', value: 'auto') +option('colorchart_filter', type: 'feature', value: 'auto') +option('colorspectrum_filter', type: 'feature', value: 'auto') +option('coreimagesrc_filter', type: 'feature', value: 'auto') @@ -12884,8 +14719,10 @@ index 0000000000..682c774c46 +option('mptestsrc_filter', type: 'feature', value: 'auto') +option('nullsrc_filter', type: 'feature', value: 'enabled') +option('openclsrc_filter', type: 'feature', value: 'auto') ++option('qrencodesrc_filter', type: 'feature', value: 'auto') +option('pal75bars_filter', type: 'feature', value: 'auto') +option('pal100bars_filter', type: 'feature', value: 'auto') ++option('perlin_filter', type: 'feature', value: 'auto') +option('rgbtestsrc_filter', type: 'feature', value: 'auto') +option('sierpinski_filter', type: 'feature', value: 'auto') +option('smptebars_filter', type: 'feature', value: 'auto') @@ -12893,6 +14730,7 @@ index 0000000000..682c774c46 +option('testsrc_filter', type: 'feature', value: 'auto') +option('testsrc2_filter', type: 'feature', value: 'auto') +option('yuvtestsrc_filter', type: 'feature', value: 'auto') ++option('zoneplate_filter', type: 'feature', value: 'auto') +option('nullsink_filter', type: 'feature', value: 'enabled') +option('a3dscope_filter', type: 'feature', value: 'auto') +option('abitscope_filter', type: 'feature', value: 'auto') @@ -12915,10 +14753,10 @@ index 0000000000..682c774c46 +option('avsynctest_filter', type: 'feature', value: 'auto') +option('amovie_filter', type: 'feature', value: 'auto') +option('movie_filter', type: 'feature', value: 'auto') -+option('abuffer_filter', type: 'feature', value: 'auto') -+option('buffer_filter', type: 'feature', value: 'auto') -+option('afifo_filter', type: 'feature', value: 'auto') -+option('fifo_filter', type: 'feature', value: 'auto') ++option('asrc_abuffer_filter', type: 'feature', value: 'auto') ++option('vsrc_buffer_filter', type: 'feature', value: 'auto') ++option('asink_abuffer_filter', type: 'feature', value: 'auto') ++option('vsink_buffer_filter', type: 'feature', value: 'auto') +option('filters', type: 'feature', value: 'auto', description: 'Enable or disable all filters') +#### --- END GENERATED FILTER OPTIONS --- #### + @@ -12961,12 +14799,13 @@ index 0000000000..682c774c46 +option('os2threads', type: 'feature', value: 'disabled', description: 'Enable OS/2 support') +option('tests', type : 'feature', value : 'auto', description : 'Build tests', yield : true) +option('large_tests', type : 'feature', value : 'disabled') ++option('assert_level', type: 'integer', min: 0, max: 2, value: 0) diff --git a/parse_sources.py b/parse_sources.py new file mode 100644 -index 0000000000..858140fe15 +index 00000000..178f04bc --- /dev/null +++ b/parse_sources.py -@@ -0,0 +1,422 @@ +@@ -0,0 +1,449 @@ +# Copyright (c) 2018 Mathieu Duponchelle +# +# This file is part of the FFmpeg Meson build @@ -12987,9 +14826,8 @@ index 0000000000..858140fe15 + +import re +import os ++from pathlib import Path +import io -+import sys -+from pprint import pprint +from collections import defaultdict + +ASM_EXTS = ['asm', 'S', 'c'] @@ -13015,8 +14853,8 @@ index 0000000000..858140fe15 + + +def add_source(f, source: str, prefix='', suffix=''): -+ if not source.startswith(('opencl/', 'metal/', 'cuda/')): -+ source = os.path.basename(source) ++ if not source.startswith(('opencl/', 'metal/', 'cuda/', '../', 'h26x/', 'hevc/')): ++ source = source.split('/', maxsplit=1)[-1] + f.write("%s'%s'%s" % (prefix, source, suffix)) + + @@ -13057,15 +14895,17 @@ index 0000000000..858140fe15 + + if accumulate: + ofiles = l -+ elif re.match('OBJS-.*CONFIG.*\+\=.*', l): -+ label, ofiles = l.split('+=') -+ label = label.split('CONFIG_')[1].rstrip(' )') ++ elif m := re.match('OBJS-\$\((?P!?)(?:CONFIG|HAVE)_(?P