set(WINUAE_QEMU_UAE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../qemu-uae-v11.0"
CACHE PATH "QEMU-UAE plugin source directory")
set(WINUAE_QEMU_UAE_PLUGIN_FILE "" CACHE FILEPATH "Prebuilt qemu-uae.so plugin to install or bundle")
+set(WINUAE_QEMU_UAE_BUILDER_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../uae-ppc-plugin"
+ CACHE PATH "uae-ppc-plugin builder checkout used to build qemu-uae.so")
+set(WINUAE_QEMU_UAE_BUILDER_URL "https://github.com/reinauer/uae-ppc-plugin.git"
+ CACHE STRING "Git URL cloned at build time when the builder checkout is missing")
+option(WINUAE_QEMU_UAE_BUILDER_FETCH "Clone the uae-ppc-plugin builder when no local copy is found" ON)
+set(WINUAE_QEMU_UAE_QEMU_TARBALL "" CACHE FILEPATH
+ "Local QEMU source tarball for offline qemu-uae plugin builds")
set(WINUAE_UNIX_INSTALL_PLUGINDIR_RELATIVE "${CMAKE_INSTALL_LIBDIR}/winuae/plugins"
CACHE STRING "Relative Unix install directory for runtime plugins")
else()
set(WINUAE_QEMU_UAE_PLUGIN_PATH "${CMAKE_BINARY_DIR}/qemu-uae.so")
endif()
+# On Linux the plugin is part of the default build so that plain
+# `cmake --build` + `cmake --install` flows (distro packaging) always
+# produce the mandatory qemu-uae.so. macOS keeps it behind the app/dmg
+# and package targets.
+set(WINUAE_QEMU_UAE_PLUGIN_ALL)
+if(UNIX AND NOT APPLE)
+ set(WINUAE_QEMU_UAE_PLUGIN_ALL ALL)
+endif()
if(UNIX
AND WINUAE_UNIX_WITH_PPC_QEMU
AND WINUAE_UNIX_BUILD_QEMU_UAE_PLUGIN
- AND EXISTS "${WINUAE_QEMU_UAE_SOURCE_DIR}/configure-qemu-uae")
- add_custom_target(winuae_unix_qemu_uae_plugin
- COMMAND "${CMAKE_COMMAND}" -E env
- "WINUAE_MACOS_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}"
- "QEMU_UAE_DEPS_PREFIX=${WINUAE_QEMU_UAE_DEPS_PREFIX}"
- "${CMAKE_CURRENT_SOURCE_DIR}/tools/build-qemu-uae.sh"
- "${WINUAE_QEMU_UAE_SOURCE_DIR}"
- "${WINUAE_QEMU_UAE_PLUGIN_PATH}"
- WORKING_DIRECTORY "${WINUAE_QEMU_UAE_SOURCE_DIR}"
- COMMENT "Building QEMU-UAE PPC plugin"
- VERBATIM
- )
+ AND NOT WINUAE_QEMU_UAE_PLUGIN_FILE)
+ if(EXISTS "${WINUAE_QEMU_UAE_SOURCE_DIR}/configure-qemu-uae")
+ message(STATUS
+ "QEMU-UAE plugin: building from sibling source ${WINUAE_QEMU_UAE_SOURCE_DIR}")
+ add_custom_target(winuae_unix_qemu_uae_plugin ${WINUAE_QEMU_UAE_PLUGIN_ALL}
+ COMMAND "${CMAKE_COMMAND}" -E env
+ "WINUAE_MACOS_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}"
+ "QEMU_UAE_DEPS_PREFIX=${WINUAE_QEMU_UAE_DEPS_PREFIX}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/tools/build-qemu-uae.sh"
+ "${WINUAE_QEMU_UAE_SOURCE_DIR}"
+ "${WINUAE_QEMU_UAE_PLUGIN_PATH}"
+ WORKING_DIRECTORY "${WINUAE_QEMU_UAE_SOURCE_DIR}"
+ COMMENT "Building QEMU-UAE PPC plugin"
+ VERBATIM
+ )
+ elseif(EXISTS "${WINUAE_QEMU_UAE_BUILDER_DIR}/build-qemu-uae-plugin.sh"
+ OR WINUAE_QEMU_UAE_BUILDER_FETCH)
+ if(EXISTS "${WINUAE_QEMU_UAE_BUILDER_DIR}/build-qemu-uae-plugin.sh")
+ message(STATUS
+ "QEMU-UAE plugin: building through ${WINUAE_QEMU_UAE_BUILDER_DIR}")
+ else()
+ message(STATUS
+ "QEMU-UAE plugin: builder will be cloned from ${WINUAE_QEMU_UAE_BUILDER_URL}")
+ endif()
+ # OUTPUT-based so repeated `all` builds (e.g. the CPack preinstall
+ # step) skip the builder once the plugin exists; the external
+ # builder's configure step is not re-entrant.
+ add_custom_command(OUTPUT "${WINUAE_QEMU_UAE_PLUGIN_PATH}"
+ COMMAND "${CMAKE_COMMAND}" -E env
+ "WINUAE_MACOS_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}"
+ "QEMU_UAE_DEPS_PREFIX=${WINUAE_QEMU_UAE_DEPS_PREFIX}"
+ "QEMU_UAE_WORK_DIR=${CMAKE_BINARY_DIR}/_deps/qemu-uae"
+ "WINUAE_QEMU_UAE_BUILDER_DIR=${WINUAE_QEMU_UAE_BUILDER_DIR}"
+ "WINUAE_QEMU_UAE_BUILDER_URL=${WINUAE_QEMU_UAE_BUILDER_URL}"
+ "WINUAE_QEMU_UAE_BUILDER_FETCH=$<BOOL:${WINUAE_QEMU_UAE_BUILDER_FETCH}>"
+ "WINUAE_QEMU_UAE_QEMU_TARBALL=${WINUAE_QEMU_UAE_QEMU_TARBALL}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/tools/build-qemu-uae-via-builder.sh"
+ "${WINUAE_QEMU_UAE_PLUGIN_PATH}"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/tools/build-qemu-uae-via-builder.sh"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ COMMENT "Building QEMU-UAE PPC plugin through uae-ppc-plugin"
+ VERBATIM
+ )
+ add_custom_target(winuae_unix_qemu_uae_plugin ${WINUAE_QEMU_UAE_PLUGIN_ALL}
+ DEPENDS "${WINUAE_QEMU_UAE_PLUGIN_PATH}"
+ )
+ endif()
endif()
-if(WINUAE_UNIX_WITH_PPC_QEMU)
+if(UNIX AND WINUAE_UNIX_WITH_PPC_QEMU)
if(WINUAE_QEMU_UAE_PLUGIN_FILE)
if(NOT EXISTS "${WINUAE_QEMU_UAE_PLUGIN_PATH}")
message(FATAL_ERROR
"WINUAE_QEMU_UAE_PLUGIN_FILE does not exist: "
"${WINUAE_QEMU_UAE_PLUGIN_PATH}")
endif()
+ message(STATUS
+ "QEMU-UAE plugin: using prebuilt ${WINUAE_QEMU_UAE_PLUGIN_PATH}")
+ elseif(NOT TARGET winuae_unix_qemu_uae_plugin)
+ message(FATAL_ERROR
+ "WINUAE_UNIX_WITH_PPC_QEMU requires the QEMU-UAE PPC plugin, but no "
+ "way to provide qemu-uae.so was found. Provide one of:\n"
+ " -DWINUAE_QEMU_UAE_PLUGIN_FILE=/path/to/qemu-uae.so (prebuilt plugin)\n"
+ " -DWINUAE_QEMU_UAE_BUILDER_DIR=/path/to/uae-ppc-plugin (builder checkout; "
+ "offline builds also want -DWINUAE_QEMU_UAE_QEMU_TARBALL=/path/to/qemu-11.0.1.tar.xz)\n"
+ " -DWINUAE_QEMU_UAE_BUILDER_FETCH=ON to clone ${WINUAE_QEMU_UAE_BUILDER_URL} at build time\n"
+ " a qemu-uae source tree at ${WINUAE_QEMU_UAE_SOURCE_DIR}")
endif()
set(WINUAE_UNIX_QEMU_UAE_PACKAGE_CHECK_DEPS)
if(TARGET winuae_unix_qemu_uae_plugin)
SHA-verified `lzma1604.7z` archive. Pass `-DWINUAE_LZMA_SDK_FETCH=OFF` for
offline distribution builds.
-To build a package from a prebuilt QEMU-UAE plugin, pass:
-
-```sh
-tools/debian-build-package.sh -- \
- -DWINUAE_QEMU_UAE_PLUGIN_FILE=/path/to/qemu-uae.so \
- -DWINUAE_UNIX_BUILD_QEMU_UAE_PLUGIN=OFF
-```
-
-Package builds fail when `WINUAE_UNIX_WITH_PPC_QEMU=ON` and the resolved
-`qemu-uae.so` path does not exist. Disable `WINUAE_UNIX_WITH_PPC_QEMU` for a
-deliberately reduced package without PPC plugin support.
+The `qemu-uae.so` PPC plugin is a mandatory part of Unix packages. CMake
+resolves it at configure time, in this order, and fails the configure with
+instructions when none applies:
+
+1. `-DWINUAE_QEMU_UAE_PLUGIN_FILE=/path/to/qemu-uae.so` — a prebuilt plugin.
+2. A patched `qemu-uae` source tree at `WINUAE_QEMU_UAE_SOURCE_DIR`
+ (default: sibling `../qemu-uae-v11.0`) — the developer path.
+3. The `uae-ppc-plugin` builder at `WINUAE_QEMU_UAE_BUILDER_DIR`
+ (default: sibling `../uae-ppc-plugin`). The builder downloads a
+ SHA-verified QEMU source tarball, applies the UAE patch deck, and builds
+ the plugin during the WinUAE build. For offline builds (distribution
+ packaging), declare the QEMU tarball as a package source and pass
+ `-DWINUAE_QEMU_UAE_QEMU_TARBALL=/path/to/qemu-11.0.1.tar.xz`.
+4. When no builder checkout is found and `WINUAE_QEMU_UAE_BUILDER_FETCH` is
+ `ON` (the default), the builder is cloned at build time from
+ `WINUAE_QEMU_UAE_BUILDER_URL`.
+
+On Linux the plugin target is part of the default build, so plain
+`cmake --build` + `cmake --install` flows always produce and install the
+plugin. A distribution package build needs `meson`, `ninja`, GLib and libfdt
+development headers for the embedded QEMU build, plus the builder checkout
+and QEMU tarball as additional sources when the build host has no network
+access.
The Linux install/package metadata can be checked on any Unix host:
cmake --build /tmp/winuae_cmake_build --target winuae_unix_qemu_uae_plugin -j
```
-`WINUAE_UNIX_BUILD_QEMU_UAE_PLUGIN` controls whether the sibling plugin target
+`WINUAE_UNIX_BUILD_QEMU_UAE_PLUGIN` controls whether the plugin build target
is enabled, and `WINUAE_QEMU_UAE_SOURCE_DIR` can point at a different
`qemu-uae` source tree. `WINUAE_QEMU_UAE_PLUGIN_FILE` can point at an already
-built plugin, which is useful for CI jobs that build the plugin through the
-release-oriented `uae-ppc-plugin` wrapper. `WINUAE_QEMU_UAE_DEPS_PREFIX`
+built plugin. Without a patched source tree, the target builds through the
+release-oriented `uae-ppc-plugin` builder (`WINUAE_QEMU_UAE_BUILDER_DIR`,
+cloned from `WINUAE_QEMU_UAE_BUILDER_URL` when missing and
+`WINUAE_QEMU_UAE_BUILDER_FETCH` is enabled; `WINUAE_QEMU_UAE_QEMU_TARBALL`
+supplies a local QEMU tarball for offline builds). `WINUAE_QEMU_UAE_DEPS_PREFIX`
defaults to the private macOS dependency prefix and is passed to the plugin
helper as `QEMU_UAE_DEPS_PREFIX`. Set `QEMU_UAE_NINJA=/path/to/ninja` if QEMU
configure cannot find Ninja itself. On macOS, the app bundler copies
--- /dev/null
+#!/usr/bin/env bash
+set -euo pipefail
+
+usage() {
+ cat <<EOF
+Usage: $0 <output-plugin>
+
+Builds qemu-uae.so through the external uae-ppc-plugin builder, which
+downloads a SHA-verified QEMU source tarball (or uses a local one),
+applies the UAE patch deck, and builds the plugin.
+
+Environment:
+ WINUAE_QEMU_UAE_BUILDER_DIR uae-ppc-plugin checkout. When missing and
+ fetching is allowed, it is cloned.
+ WINUAE_QEMU_UAE_BUILDER_URL Clone URL. Defaults to the reinauer repo.
+ WINUAE_QEMU_UAE_BUILDER_FETCH 0 disables cloning a missing builder.
+ WINUAE_QEMU_UAE_BUILDER_CLONE_DIR
+ Clone destination. Defaults to
+ <work-dir>/uae-ppc-plugin.
+ WINUAE_QEMU_UAE_QEMU_TARBALL Local QEMU source tarball for offline
+ builds; passed to the builder as --tarball.
+ WINUAE_QEMU_UAE_STRIP 0 keeps symbols in the built plugin.
+ QEMU_UAE_WORK_DIR Builder working directory.
+ QEMU_UAE_DEPS_PREFIX Private GLib/libslirp dependency prefix.
+ WINUAE_MACOS_DEPLOYMENT_TARGET macOS deployment target for the plugin.
+EOF
+}
+
+if [[ "${1:-}" == "-h" || "${1:-}" == "--help" || $# -lt 1 ]]; then
+ usage
+ [[ $# -lt 1 ]] && exit 2
+ exit 0
+fi
+
+output_plugin="$1"
+builder_dir="${WINUAE_QEMU_UAE_BUILDER_DIR:-}"
+builder_url="${WINUAE_QEMU_UAE_BUILDER_URL:-https://github.com/reinauer/uae-ppc-plugin.git}"
+builder_fetch="${WINUAE_QEMU_UAE_BUILDER_FETCH:-1}"
+work_dir="${QEMU_UAE_WORK_DIR:-$(pwd)/qemu-uae-work}"
+clone_dir="${WINUAE_QEMU_UAE_BUILDER_CLONE_DIR:-${work_dir}/uae-ppc-plugin}"
+tarball="${WINUAE_QEMU_UAE_QEMU_TARBALL:-}"
+
+builder_script() {
+ printf '%s/build-qemu-uae-plugin.sh' "$1"
+}
+
+if [[ -z "${builder_dir}" || ! -x "$(builder_script "${builder_dir}")" ]]; then
+ if [[ -x "$(builder_script "${clone_dir}")" ]]; then
+ builder_dir="${clone_dir}"
+ elif [[ "${builder_fetch}" != "0" ]]; then
+ echo "Cloning QEMU-UAE plugin builder from ${builder_url}"
+ mkdir -p "$(dirname "${clone_dir}")"
+ git clone --depth 1 "${builder_url}" "${clone_dir}"
+ builder_dir="${clone_dir}"
+ else
+ echo "error: uae-ppc-plugin builder not found" >&2
+ echo "hint: set WINUAE_QEMU_UAE_BUILDER_DIR to a checkout of" >&2
+ echo " ${builder_url}, or allow cloning" >&2
+ exit 1
+ fi
+fi
+
+args=( --output "${output_plugin}" )
+if [[ -n "${tarball}" ]]; then
+ if [[ ! -f "${tarball}" ]]; then
+ echo "error: WINUAE_QEMU_UAE_QEMU_TARBALL does not exist: ${tarball}" >&2
+ exit 1
+ fi
+ args+=( --tarball "${tarball}" )
+fi
+
+export QEMU_UAE_WORK_DIR="${work_dir}"
+"$(builder_script "${builder_dir}")" "${args[@]}"
+
+if [[ "${WINUAE_QEMU_UAE_STRIP:-1}" != "0" ]]; then
+ if [[ "$(uname -s)" == "Darwin" ]]; then
+ strip -x "${output_plugin}"
+ else
+ strip --strip-unneeded "${output_plugin}"
+ fi
+fi