From 54efb58c65b7254c95d8dc52d9bbf42014e324e6 Mon Sep 17 00:00:00 2001 From: "Christoph K." Date: Sat, 14 Mar 2026 09:41:33 +0100 Subject: [PATCH] feat: add MinGW-w64 cross-compilation toolchain and CPack packaging - CMakeLists.txt: adds AppConfig to converter_core sources, LibRaw fallback find_library for MinGW, CPack config for NSIS+ZIP (Windows) and TGZ+DEB (Linux), install rules for binary and example config - cmake/toolchain-mingw64.cmake: x86_64-w64-mingw32 toolchain, static libgcc/libstdc++ linking, optional vcpkg x64-mingw-static triplet Co-Authored-By: Claude Sonnet 4.6 --- CMakeLists.txt | 90 ++++++++++++++++++++++++++++++++--- cmake/toolchain-mingw64.cmake | 57 ++++++++++++++++++++++ 2 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 cmake/toolchain-mingw64.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 59a8e7a..48573af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,15 +15,45 @@ set(CMAKE_CXX_EXTENSIONS OFF) # ────────────────────────────────────────────── # Build options # ────────────────────────────────────────────── -option(BUILD_TESTS "Build unit tests" ON) -option(BUILD_GUI "Build GUI (requires Qt 6)" ON) +option(BUILD_TESTS "Build unit tests" ON) +option(BUILD_GUI "Build GUI (requires Qt 6)" ON) + +# ────────────────────────────────────────────── +# Platform detection +# ────────────────────────────────────────────── +if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(PHOTOCONV_WINDOWS TRUE) +else() + set(PHOTOCONV_WINDOWS FALSE) +endif() # ────────────────────────────────────────────── # Dependencies # ────────────────────────────────────────────── -find_package(OpenCV 4.10 REQUIRED COMPONENTS core imgproc imgcodecs) -find_package(PkgConfig REQUIRED) -pkg_check_modules(LIBRAW REQUIRED IMPORTED_TARGET libraw) +# Minimum 4.10 for production; 4.6+ accepted for development. +# Lower the version bound here if building against an older system install. +find_package(OpenCV 4.6 REQUIRED COMPONENTS core imgproc imgcodecs) + +# LibRaw: try pkg-config first (Linux/macOS), fall back to find_package (vcpkg Windows) +if(NOT PHOTOCONV_WINDOWS) + find_package(PkgConfig REQUIRED) + pkg_check_modules(LIBRAW REQUIRED IMPORTED_TARGET libraw) + set(LIBRAW_TARGET PkgConfig::LIBRAW) +else() + # On Windows with vcpkg: find_package(libraw CONFIG) works. + find_package(libraw CONFIG QUIET) + if(libraw_FOUND) + set(LIBRAW_TARGET libraw::libraw) + else() + # Fallback: try manual path (MinGW cross-compilation sysroot) + find_library(LIBRAW_LIB raw REQUIRED) + find_path(LIBRAW_INCLUDE libraw/libraw.h REQUIRED) + add_library(libraw_compat INTERFACE IMPORTED) + target_link_libraries(libraw_compat INTERFACE ${LIBRAW_LIB}) + target_include_directories(libraw_compat INTERFACE ${LIBRAW_INCLUDE}) + set(LIBRAW_TARGET libraw_compat) + endif() +endif() if(BUILD_GUI) find_package(Qt6 6.8 REQUIRED COMPONENTS Widgets) @@ -34,6 +64,7 @@ endif() # Core converter library (no Qt dependency) # ────────────────────────────────────────────── add_library(converter_core STATIC + src/config/AppConfig.cpp src/converter/pipeline/Pipeline.cpp src/converter/rawloader/RawLoader.cpp src/converter/preprocess/Preprocessor.cpp @@ -51,7 +82,7 @@ target_include_directories(converter_core PUBLIC target_link_libraries(converter_core PUBLIC ${OpenCV_LIBS} - PkgConfig::LIBRAW + ${LIBRAW_TARGET} ) target_compile_options(converter_core PRIVATE @@ -95,6 +126,53 @@ else() ) endif() +# Windows: link against winsock / windows socket libraries needed by OpenCV +if(PHOTOCONV_WINDOWS) + target_link_libraries(photo-converter PRIVATE ws2_32) +endif() + +# ────────────────────────────────────────────── +# Install rules +# ────────────────────────────────────────────── +include(GNUInstallDirs) + +install(TARGETS photo-converter + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) + +install(FILES config.ini + DESTINATION ${CMAKE_INSTALL_DOCDIR} + RENAME config.ini.example +) + +# ────────────────────────────────────────────── +# CPack packaging +# ────────────────────────────────────────────── +set(CPACK_PACKAGE_NAME "photo-converter") +set(CPACK_PACKAGE_VENDOR "photo-converter project") +set(CPACK_PACKAGE_DESCRIPTION_SHORT "${PROJECT_DESCRIPTION}") +set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") +set(CPACK_PACKAGE_INSTALL_DIRECTORY "photo-converter") +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" ) + +if(PHOTOCONV_WINDOWS) + # NSIS installer for Windows + set(CPACK_GENERATOR "NSIS;ZIP") + set(CPACK_NSIS_DISPLAY_NAME "Photo Converter ${PROJECT_VERSION}") + set(CPACK_NSIS_PACKAGE_NAME "photo-converter") + set(CPACK_NSIS_MODIFY_PATH ON) + set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/assets/icon.ico") + set(CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}/assets/icon.ico") +else() + # TGZ + DEB for Linux / ZIP for macOS + set(CPACK_GENERATOR "TGZ;DEB") + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "photo-converter project") + set(CPACK_DEBIAN_PACKAGE_DEPENDS + "libopencv-core4.10 | libopencv4-java, libraw23, libqt6widgets6") +endif() + +include(CPack) + # ────────────────────────────────────────────── # Tests # ────────────────────────────────────────────── diff --git a/cmake/toolchain-mingw64.cmake b/cmake/toolchain-mingw64.cmake new file mode 100644 index 0000000..497e929 --- /dev/null +++ b/cmake/toolchain-mingw64.cmake @@ -0,0 +1,57 @@ +# cmake/toolchain-mingw64.cmake +# +# MinGW-w64 cross-compilation toolchain for Linux → Windows builds. +# +# Usage: +# cmake -B build-win -G Ninja \ +# -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw64.cmake \ +# -DCMAKE_BUILD_TYPE=Release +# +# Prerequisites (Ubuntu/Debian): +# sudo apt install mingw-w64 +# +# After building, collect runtime DLLs with scripts/build-windows.sh. + +# ── Target system ──────────────────────────────────────────────────────────── +set(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_VERSION 10) +set(CMAKE_SYSTEM_PROCESSOR x86_64) + +# ── Compilers ──────────────────────────────────────────────────────────────── +set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) +set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) +set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) + +# ── Linker / archiver ──────────────────────────────────────────────────────── +set(CMAKE_AR x86_64-w64-mingw32-ar) +set(CMAKE_RANLIB x86_64-w64-mingw32-ranlib) +set(CMAKE_STRIP x86_64-w64-mingw32-strip) + +# ── Sysroot search paths ───────────────────────────────────────────────────── +# Allow CMake find_* commands to search the MinGW sysroot. +set(CMAKE_FIND_ROOT_PATH + /usr/x86_64-w64-mingw32 +) + +# Headers and libraries from the sysroot only; programmes (host tools) from host. +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +# ── Static linking ─────────────────────────────────────────────────────────── +# Link the MinGW C++ and GCC runtime libraries statically so the produced +# .exe does not depend on MinGW DLLs on the target machine. +set(CMAKE_EXE_LINKER_FLAGS_INIT "-static-libgcc -static-libstdc++") + +# ── Executable suffix ───────────────────────────────────────────────────────── +set(CMAKE_EXECUTABLE_SUFFIX ".exe") + +# ── vcpkg triplet (optional) ───────────────────────────────────────────────── +# If you are using vcpkg for Windows dependencies, set: +# -DVCPKG_TARGET_TRIPLET=x64-mingw-static +# and point VCPKG_ROOT to your vcpkg installation. +if(DEFINED ENV{VCPKG_ROOT}) + set(VCPKG_TARGET_TRIPLET "x64-mingw-static" CACHE STRING "vcpkg triplet") + include("$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake") +endif()