157 lines
6.9 KiB
Bash
Executable File
157 lines
6.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
# build-windows.sh
|
||
#
|
||
# Cross-compiles negative-converter for Windows (x86_64) using MinGW-w64.
|
||
# Produces a self-contained directory with negative-converter.exe and all
|
||
# required DLLs ready for distribution.
|
||
#
|
||
# Prerequisites (Ubuntu/Debian):
|
||
# sudo apt install mingw-w64 cmake ninja-build
|
||
# # Install MinGW-w64 cross builds of OpenCV, LibRaw, Qt6:
|
||
# # Option A – compile from source with the MinGW toolchain.
|
||
# # Option B – use an MXE (M cross environment) prefix.
|
||
# # https://mxe.cc/
|
||
# # Option C – use pre-built MinGW packages from a provider such as
|
||
# # https://github.com/brechtsanders/winlibs_mingw
|
||
#
|
||
# Usage:
|
||
# bash scripts/build-windows.sh [BUILD_TYPE] [DEPS_PREFIX]
|
||
#
|
||
# BUILD_TYPE Release (default) | Debug | RelWithDebInfo
|
||
# DEPS_PREFIX Path to cross-compiled dependencies
|
||
# (default: /usr/x86_64-w64-mingw32)
|
||
#
|
||
# Example with a custom MXE prefix:
|
||
# bash scripts/build-windows.sh Release /opt/mxe/usr/x86_64-w64-mingw32.static
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
|
||
set -euo pipefail
|
||
|
||
# ── Configuration ─────────────────────────────────────────────────────────────
|
||
BUILD_TYPE="${1:-Release}"
|
||
DEPS_PREFIX="${2:-/usr/x86_64-w64-mingw32}"
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||
BUILD_DIR="${PROJECT_ROOT}/build-windows"
|
||
DIST_DIR="${PROJECT_ROOT}/dist-windows"
|
||
|
||
TOOLCHAIN="${PROJECT_ROOT}/cmake/toolchain-mingw64.cmake"
|
||
|
||
echo "========================================================"
|
||
echo " negative-converter Windows Cross-Compilation"
|
||
echo "========================================================"
|
||
echo " Project root : ${PROJECT_ROOT}"
|
||
echo " Build dir : ${BUILD_DIR}"
|
||
echo " Build type : ${BUILD_TYPE}"
|
||
echo " Deps prefix : ${DEPS_PREFIX}"
|
||
echo "========================================================"
|
||
|
||
# ── Verify prerequisites ──────────────────────────────────────────────────────
|
||
for tool in x86_64-w64-mingw32-g++ cmake ninja; do
|
||
if ! command -v "${tool}" &>/dev/null; then
|
||
echo "ERROR: '${tool}' not found in PATH." >&2
|
||
echo "Install with: sudo apt install mingw-w64 cmake ninja-build" >&2
|
||
exit 1
|
||
fi
|
||
done
|
||
|
||
# ── CMake configure ──────────────────────────────────────────────────────────
|
||
cmake \
|
||
-B "${BUILD_DIR}" \
|
||
-G Ninja \
|
||
-DCMAKE_TOOLCHAIN_FILE="${TOOLCHAIN}" \
|
||
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
|
||
-DCMAKE_INSTALL_PREFIX="${DIST_DIR}" \
|
||
-DCMAKE_PREFIX_PATH="${DEPS_PREFIX}" \
|
||
-DBUILD_TESTS=OFF \
|
||
-DBUILD_GUI=ON \
|
||
"${PROJECT_ROOT}"
|
||
|
||
# ── Build ─────────────────────────────────────────────────────────────────────
|
||
cmake --build "${BUILD_DIR}" -- -j"$(nproc)"
|
||
|
||
# ── Install to dist dir ───────────────────────────────────────────────────────
|
||
cmake --install "${BUILD_DIR}"
|
||
|
||
# ── Collect runtime DLLs ─────────────────────────────────────────────────────
|
||
# MinGW runtime and dependency DLLs must ship alongside the .exe.
|
||
BIN_DIR="${DIST_DIR}/bin"
|
||
mkdir -p "${BIN_DIR}"
|
||
|
||
echo ""
|
||
echo "Collecting runtime DLLs..."
|
||
|
||
# Helper: copy a DLL if it exists in the sysroot.
|
||
copy_dll() {
|
||
local dll_name="$1"
|
||
local search_paths=(
|
||
"${DEPS_PREFIX}/bin"
|
||
"${DEPS_PREFIX}/lib"
|
||
"/usr/lib/gcc/x86_64-w64-mingw32"
|
||
"/usr/x86_64-w64-mingw32/lib"
|
||
)
|
||
for dir in "${search_paths[@]}"; do
|
||
if [[ -f "${dir}/${dll_name}" ]]; then
|
||
cp -v "${dir}/${dll_name}" "${BIN_DIR}/"
|
||
return 0
|
||
fi
|
||
done
|
||
echo " WARNING: ${dll_name} not found (may be statically linked)" >&2
|
||
return 0
|
||
}
|
||
|
||
# MinGW runtime DLLs (may be statically linked via -static-libgcc/-static-libstdc++)
|
||
copy_dll "libgcc_s_seh-1.dll" || true
|
||
copy_dll "libstdc++-6.dll" || true
|
||
copy_dll "libwinpthread-1.dll" || true
|
||
|
||
# OpenCV DLLs (names include version number – use glob)
|
||
for dll in "${DEPS_PREFIX}/bin"/libopencv_*.dll; do
|
||
[[ -f "${dll}" ]] && cp -v "${dll}" "${BIN_DIR}/"
|
||
done
|
||
|
||
# LibRaw
|
||
copy_dll "libraw.dll" || true
|
||
copy_dll "libraw-23.dll" || true
|
||
|
||
# Qt6 DLLs
|
||
for qt_dll in Qt6Core Qt6Gui Qt6Widgets; do
|
||
copy_dll "${qt_dll}.dll" || true
|
||
done
|
||
|
||
# Qt platform plugin
|
||
QT_PLATFORMS_SRC="${DEPS_PREFIX}/share/qt6/plugins/platforms"
|
||
if [[ -d "${QT_PLATFORMS_SRC}" ]]; then
|
||
mkdir -p "${BIN_DIR}/platforms"
|
||
cp -v "${QT_PLATFORMS_SRC}/qwindows.dll" "${BIN_DIR}/platforms/" 2>/dev/null || true
|
||
fi
|
||
|
||
# ── Strip release binaries ────────────────────────────────────────────────────
|
||
if [[ "${BUILD_TYPE}" == "Release" ]]; then
|
||
echo ""
|
||
echo "Stripping debug symbols from release binaries..."
|
||
x86_64-w64-mingw32-strip --strip-all "${BIN_DIR}/negative-converter.exe" 2>/dev/null || true
|
||
find "${BIN_DIR}" -name "*.dll" -exec x86_64-w64-mingw32-strip --strip-unneeded {} \; 2>/dev/null || true
|
||
fi
|
||
|
||
# ── Copy example config ───────────────────────────────────────────────────────
|
||
cp -v "${PROJECT_ROOT}/config.ini" "${DIST_DIR}/config.ini.example"
|
||
|
||
# ── Create ZIP archive ────────────────────────────────────────────────────────
|
||
ARCHIVE="${PROJECT_ROOT}/negative-converter-windows-x64-${BUILD_TYPE}.zip"
|
||
if command -v zip &>/dev/null; then
|
||
(cd "${PROJECT_ROOT}" && zip -r "${ARCHIVE}" "dist-windows/")
|
||
echo ""
|
||
echo "Archive: ${ARCHIVE}"
|
||
else
|
||
echo "(zip not available; skipping archive creation)"
|
||
fi
|
||
|
||
echo ""
|
||
echo "========================================================"
|
||
echo " Build complete!"
|
||
echo " Output: ${DIST_DIR}"
|
||
echo " Run: wine ${BIN_DIR}/negative-converter.exe --help"
|
||
echo "========================================================"
|