Last active
May 15, 2026 03:28
-
-
Save danwald/c566caf19a8ea06ca818c26ba0f4d477 to your computer and use it in GitHub Desktop.
Build hugin (2025) from source
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # build-hugin-macos.sh — Build Hugin 2025.0.1 from source on macOS Apple Silicon | |
| # | |
| # Usage: | |
| # bash build-hugin-macos.sh | |
| # | |
| # Output: Hugin-2025.0.1-arm64.dmg in the current directory | |
| # Install: open the DMG and drag Hugin.app to /Applications | |
| # | |
| # Tested on: macOS 15+ (Apple Silicon, M1/M2/M3/M4) | |
| # Requirements: Homebrew, Xcode Command Line Tools | |
| set -euo pipefail | |
| HUGIN_VERSION="2025.0.1" | |
| TARBALL="hugin-${HUGIN_VERSION}.tar.bz2" | |
| TARBALL_URL="https://sourceforge.net/projects/hugin/files/hugin/hugin-2025.0/${TARBALL}/download" | |
| SRCDIR="hugin-${HUGIN_VERSION}" | |
| BUILDDIR="build" | |
| PATCHFILE="hugin-${HUGIN_VERSION}-macos.patch" | |
| DMG="Hugin-${HUGIN_VERSION}-arm64.dmg" | |
| log() { echo "==> $*"; } | |
| # ── 1. Preflight checks ────────────────────────────────────────────────────── | |
| log "Checking prerequisites..." | |
| command -v brew >/dev/null || { echo "ERROR: Homebrew not found — install from https://brew.sh"; exit 1; } | |
| command -v cmake >/dev/null || { echo "ERROR: cmake not found (brew install cmake)"; exit 1; } | |
| command -v git >/dev/null || { echo "ERROR: git not found"; exit 1; } | |
| command -v curl >/dev/null || { echo "ERROR: curl not found"; exit 1; } | |
| # ── 2. Download source tarball ─────────────────────────────────────────────── | |
| if [ ! -f "$TARBALL" ]; then | |
| log "Downloading $TARBALL from SourceForge (~70 MB)..." | |
| curl -L --progress-bar -o "$TARBALL" "$TARBALL_URL" | |
| else | |
| log "Source tarball already present, skipping download." | |
| fi | |
| # ── 3. Write patch file ────────────────────────────────────────────────────── | |
| log "Writing patch file..." | |
| cat > "$PATCHFILE" << 'ENDOFPATCH' | |
| --- hugin-orig-extract/hugin-2025.0.1/CMakeLists.txt 2025-12-10 22:35:48 | |
| +++ hugin-modified/CMakeLists.txt 2026-05-12 21:09:33 | |
| @@ -19,7 +19,8 @@ | |
| endif() | |
| if(APPLE) | |
| - set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9") | |
| + # AIDEV-NOTE: bumped from 10.9 to 10.15; std::filesystem requires 10.15+ | |
| + set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15") | |
| if (MAC_SELF_CONTAINED_BUNDLE) | |
| set(CMAKE_LIBRARY_PATH ${CMAKE_SOURCE_DIR}/mac/ExternalPrograms/repository/lib) | |
| set(CMAKE_INCLUDE_PATH ${CMAKE_SOURCE_DIR}/mac/ExternalPrograms/repository/include ${CMAKE_SOURCE_DIR}/mac/ExternalPrograms/repository/bin) | |
| --- hugin-orig-extract/hugin-2025.0.1/CMakeModules/FindVIGRA.cmake 2021-08-21 18:43:52 | |
| +++ hugin-modified/CMakeModules/FindVIGRA.cmake 2026-05-12 21:09:33 | |
| @@ -27,15 +27,16 @@ | |
| ) | |
| ELSE(WIN32) | |
| FIND_PATH(VIGRA_INCLUDE_DIR vigra/gaborfilter.hxx | |
| + /opt/homebrew/include | |
| /usr/local/include | |
| /usr/include | |
| /opt/local/include | |
| ) | |
| FIND_LIBRARY(VIGRA_LIBRARIES | |
| - NAMES vigraimpex libvigraimpex | |
| - PATHS /usr/lib /usr/local/lib /opt/local/lib | |
| - ) | |
| + NAMES vigraimpex libvigraimpex | |
| + PATHS /opt/homebrew/lib /usr/lib /usr/local/lib /opt/local/lib | |
| + ) | |
| ENDIF(WIN32) | |
| @@ -53,9 +54,15 @@ | |
| IF(NOT VIGRA_CONFIG_VERSION_HXX) | |
| MESSAGE(FATAL_ERROR "Could not find vigra/configVersion.hxx or vigra/config_version.hxx. Your vigra installation seems to be corrupt.") | |
| ENDIF() | |
| - FILE(STRINGS "${VIGRA_CONFIG_VERSION_HXX}" VIGRA_VERSION_HXX REGEX ".*#define +VIGRA_VERSION +\"") | |
| - STRING(REGEX REPLACE ".*#define +VIGRA_VERSION +\"([.0-9]+).*" "\\1" VIGRA_VERSION "${VIGRA_VERSION_HXX}") | |
| - IF(${VIGRA_VERSION} VERSION_EQUAL VIGRA_FIND_VERSION OR ${VIGRA_VERSION} VERSION_GREATER VIGRA_FIND_VERSION) | |
| + # AIDEV-NOTE: config_version.hxx uses macro-based version (not a string literal); extract major/minor/patch individually | |
| + FILE(STRINGS "${VIGRA_CONFIG_VERSION_HXX}" VIGRA_VERSION_MAJOR_LINE REGEX "#define +VIGRA_VERSION_MAJOR +[0-9]+") | |
| + FILE(STRINGS "${VIGRA_CONFIG_VERSION_HXX}" VIGRA_VERSION_MINOR_LINE REGEX "#define +VIGRA_VERSION_MINOR +[0-9]+") | |
| + FILE(STRINGS "${VIGRA_CONFIG_VERSION_HXX}" VIGRA_VERSION_PATCH_LINE REGEX "#define +VIGRA_VERSION_PATCH +[0-9]+") | |
| + STRING(REGEX REPLACE ".*#define +VIGRA_VERSION_MAJOR +([0-9]+).*" "\\1" VIGRA_VERSION_MAJOR "${VIGRA_VERSION_MAJOR_LINE}") | |
| + STRING(REGEX REPLACE ".*#define +VIGRA_VERSION_MINOR +([0-9]+).*" "\\1" VIGRA_VERSION_MINOR "${VIGRA_VERSION_MINOR_LINE}") | |
| + STRING(REGEX REPLACE ".*#define +VIGRA_VERSION_PATCH +([0-9]+).*" "\\1" VIGRA_VERSION_PATCH "${VIGRA_VERSION_PATCH_LINE}") | |
| + SET(VIGRA_VERSION "${VIGRA_VERSION_MAJOR}.${VIGRA_VERSION_MINOR}.${VIGRA_VERSION_PATCH}") | |
| + IF("${VIGRA_VERSION}" VERSION_GREATER_EQUAL "${VIGRA_FIND_VERSION}") | |
| SET(VIGRA_VERSION_CHECK TRUE) | |
| MESSAGE(STATUS "VIGRA version: ${VIGRA_VERSION}") | |
| ELSE() | |
| --- hugin-orig-extract/hugin-2025.0.1/src/hugin1/base_wx/Executor.cpp 2025-09-16 18:55:30 | |
| +++ hugin-modified/src/hugin1/base_wx/Executor.cpp 2026-05-14 22:16:59 | |
| @@ -128,19 +128,9 @@ | |
| // return path in internal program (program that is shipped with Hugin) | |
| wxString GetInternalProgram(const wxString& bindir, const wxString& name) | |
| { | |
| -#if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE | |
| - CFStringRef filename = MacCreateCFStringWithWxString(name); | |
| - wxString fn = MacGetPathToBundledExecutableFile(filename); | |
| - CFRelease(filename); | |
| - if (fn == wxEmptyString) | |
| - { | |
| - std::cerr << wxString::Format(_("External program %s not found in the bundle, reverting to system path"), name.c_str()) << std::endl; | |
| - return name; | |
| - } | |
| - return fn; | |
| -#else | |
| + // AIDEV-NOTE: Use bindir directly on all platforms — avoids CF bundle lookup | |
| + // failures in child processes (e.g. hugin_executor) on macOS. | |
| return bindir + name; | |
| -#endif | |
| }; | |
| // return name of external program (can be program bundeled with Hugin, or an external program | |
| @@ -174,15 +164,11 @@ | |
| }; | |
| }; | |
| - CFStringRef filename = MacCreateCFStringWithWxString(name); | |
| - wxString fn = MacGetPathToBundledExecutableFile(filename); | |
| - CFRelease(filename); | |
| - if (fn == wxEmptyString) | |
| - { | |
| - std::cerr << wxString::Format(_("WARNING: External program %s not found in the bundle, reverting to system path"), name.c_str()) << std::endl; | |
| - return name; | |
| - }; | |
| - return fn; | |
| + // AIDEV-NOTE: Use bindir (Contents/MacOS/) directly — reliable for both the main | |
| + // Hugin process and child processes (e.g. hugin_executor) where | |
| + // CFBundleCopyAuxiliaryExecutableURL fails. All external tools are co-located | |
| + // with the Hugin executable in Contents/MacOS/. | |
| + return bindir + name; | |
| #else | |
| if (config->Read(name + "/Custom", 0l)) | |
| { | |
| --- hugin-orig-extract/hugin-2025.0.1/src/hugin1/executor/hugin_executor.cpp 2025-09-16 18:57:59 | |
| +++ hugin-modified/src/hugin1/executor/hugin_executor.cpp 2026-05-14 22:24:15 | |
| @@ -95,6 +95,21 @@ | |
| setlocale(LC_ALL, ""); | |
| // initialize i18n | |
| int localeID = config->Read("language", (long)HUGIN_LANGUAGE); | |
| + // AIDEV-NOTE: hugin_executor uses wxApp on macOS (can show dialogs), so the | |
| + // same locale pre-check as huginApp.cpp is needed here. Without it, an | |
| + // unsupported system locale (e.g. en_AE) causes an invisible blocking modal. | |
| + if (localeID == wxLANGUAGE_DEFAULT || localeID == wxLANGUAGE_UNKNOWN) | |
| + { | |
| + int sysLang = wxLocale::GetSystemLanguage(); | |
| + const wxLanguageInfo* info = wxLocale::GetLanguageInfo(sysLang); | |
| + if (info) | |
| + { | |
| + wxString name = info->CanonicalName + ".UTF-8"; | |
| + if (!setlocale(LC_ALL, name.mb_str())) | |
| + localeID = wxLANGUAGE_ENGLISH_US; | |
| + setlocale(LC_ALL, ""); // restore | |
| + } | |
| + } | |
| m_locale.Init(localeID); | |
| // set the name of locale recource to look for | |
| m_locale.AddCatalog("hugin"); | |
| --- hugin-orig-extract/hugin-2025.0.1/src/hugin1/hugin/huginApp.cpp 2025-10-27 20:56:09 | |
| +++ hugin-modified/src/hugin1/hugin/huginApp.cpp 2026-05-12 21:10:01 | |
| @@ -300,6 +300,25 @@ | |
| int localeID = config->Read("language", (long) HUGIN_LANGUAGE); | |
| DEBUG_TRACE("localeID: " << localeID); | |
| { | |
| + // AIDEV-NOTE: wxLocale::Init() shows an error dialog if the system locale | |
| + // (e.g. en_AE on UAE-region systems) is unknown to the C runtime. | |
| + // Pre-check via setlocale() and silently fall back to English US so the | |
| + // dialog never appears. Translations still work for explicitly chosen languages. | |
| + if (localeID == wxLANGUAGE_DEFAULT || localeID == wxLANGUAGE_UNKNOWN) | |
| + { | |
| + int sysLang = wxLocale::GetSystemLanguage(); | |
| + const wxLanguageInfo* info = wxLocale::GetLanguageInfo(sysLang); | |
| + if (info) | |
| + { | |
| + wxString name = info->CanonicalName + ".UTF-8"; | |
| + if (!setlocale(LC_ALL, name.mb_str())) | |
| + { | |
| + // System locale not supported by C runtime; use English US silently. | |
| + localeID = wxLANGUAGE_ENGLISH_US; | |
| + } | |
| + setlocale(LC_ALL, ""); // restore | |
| + } | |
| + } | |
| bool bLInit; | |
| bLInit = locale.Init(localeID); | |
| if (bLInit) { | |
| --- hugin-orig-extract/hugin-2025.0.1/src/hugin1/ptbatcher/CMakeLists.txt 2025-12-03 20:18:53 | |
| +++ hugin-modified/src/hugin1/ptbatcher/CMakeLists.txt 2026-05-12 21:09:33 | |
| @@ -29,11 +29,9 @@ | |
| IF(MAC_SELF_CONTAINED_BUNDLE) | |
| - # Tools | |
| + # AIDEV-NOTE: enblend/enfuse removed — not available via Homebrew; install separately if needed | |
| set( TOOLS ${CMAKE_BINARY_DIR}/src/tools/align_image_stack ${CMAKE_BINARY_DIR}/src/tools/nona | |
| ${CMAKE_BINARY_DIR}/src/tools/hugin_hdrmerge ${CMAKE_BINARY_DIR}/src/tools/verdandi | |
| - ${CMAKE_SOURCE_DIR}/mac/ExternalPrograms/repository/bin/enblend | |
| - ${CMAKE_SOURCE_DIR}/mac/ExternalPrograms/repository/bin/enfuse | |
| ) | |
| FOREACH(_file ${TOOLS}) | |
| --- hugin-orig-extract/hugin-2025.0.1/src/hugin1/ptbatcher/PTBatcherGUI.cpp 2025-10-08 23:00:21 | |
| +++ hugin-modified/src/hugin1/ptbatcher/PTBatcherGUI.cpp 2026-05-14 22:30:46 | |
| @@ -73,7 +73,21 @@ | |
| int localeID = wxConfigBase::Get()->Read("language", (long) wxLANGUAGE_DEFAULT); | |
| m_locale.Init(localeID); | |
| #else | |
| - m_locale.Init(wxLANGUAGE_DEFAULT); | |
| + // AIDEV-NOTE: pre-check locale support to avoid invisible blocking modal on | |
| + // systems with unsupported locales (e.g. en_AE). Same fix as huginApp.cpp. | |
| + { | |
| + int localeID = wxLANGUAGE_DEFAULT; | |
| + int sysLang = wxLocale::GetSystemLanguage(); | |
| + const wxLanguageInfo* info = wxLocale::GetLanguageInfo(sysLang); | |
| + if (info) | |
| + { | |
| + wxString localeName = info->CanonicalName + ".UTF-8"; | |
| + if (!setlocale(LC_ALL, localeName.mb_str())) | |
| + localeID = wxLANGUAGE_ENGLISH_US; | |
| + setlocale(LC_ALL, ""); | |
| + } | |
| + m_locale.Init(localeID); | |
| + } | |
| #endif | |
| // initialize help provider | |
| wxHelpControllerHelpProvider* provider = new wxHelpControllerHelpProvider; | |
| --- hugin-orig-extract/hugin-2025.0.1/src/hugin1/stitch_project/CMakeLists.txt 2025-10-02 20:18:43 | |
| +++ hugin-modified/src/hugin1/stitch_project/CMakeLists.txt 2026-05-12 21:09:33 | |
| @@ -21,11 +21,9 @@ | |
| IF(MAC_SELF_CONTAINED_BUNDLE) | |
| - # Tools | |
| + # AIDEV-NOTE: enblend/enfuse removed — not available via Homebrew; install separately if needed | |
| set( TOOLS ${CMAKE_BINARY_DIR}/src/tools/align_image_stack ${CMAKE_BINARY_DIR}/src/tools/nona | |
| ${CMAKE_BINARY_DIR}/src/tools/hugin_hdrmerge ${CMAKE_BINARY_DIR}/src/tools/verdandi | |
| - ${CMAKE_SOURCE_DIR}/mac/ExternalPrograms/repository/bin/enblend | |
| - ${CMAKE_SOURCE_DIR}/mac/ExternalPrograms/repository/bin/enfuse | |
| ) | |
| FOREACH(_file ${TOOLS}) | |
| --- hugin-orig-extract/hugin-2025.0.1/src/hugin1/stitch_project/hugin_stitch_project.cpp 2025-12-03 20:18:53 | |
| +++ hugin-modified/src/hugin1/stitch_project/hugin_stitch_project.cpp 2026-05-14 22:30:46 | |
| @@ -313,7 +313,21 @@ | |
| int localeID = wxConfigBase::Get()->Read("language", (long) wxLANGUAGE_DEFAULT); | |
| m_locale.Init(localeID); | |
| #else | |
| - m_locale.Init(wxLANGUAGE_DEFAULT); | |
| + // AIDEV-NOTE: pre-check locale support to avoid invisible blocking modal on | |
| + // systems with unsupported locales (e.g. en_AE). Same fix as huginApp.cpp. | |
| + { | |
| + int localeID = wxLANGUAGE_DEFAULT; | |
| + int sysLang = wxLocale::GetSystemLanguage(); | |
| + const wxLanguageInfo* info = wxLocale::GetLanguageInfo(sysLang); | |
| + if (info) | |
| + { | |
| + wxString localeName = info->CanonicalName + ".UTF-8"; | |
| + if (!setlocale(LC_ALL, localeName.mb_str())) | |
| + localeID = wxLANGUAGE_ENGLISH_US; | |
| + setlocale(LC_ALL, ""); | |
| + } | |
| + m_locale.Init(localeID); | |
| + } | |
| #endif | |
| // setup the environment for the different operating systems | |
| ENDOFPATCH | |
| # ── 4. Homebrew dependencies ───────────────────────────────────────────────── | |
| log "Installing Homebrew dependencies..." | |
| brew install cmake pkg-config libtiff jpeg-turbo libpng exiv2 libpano \ | |
| little-cms2 boost libomp fftw wxwidgets glew libepoxy \ | |
| gsl exiftool 2>/dev/null || true | |
| # ── 5. Build VIGRA from source (not in Homebrew) ───────────────────────────── | |
| VIGRA_PREFIX="/opt/homebrew" | |
| if [ ! -f "${VIGRA_PREFIX}/include/vigra/gaborfilter.hxx" ]; then | |
| log "Building VIGRA from source (~2 min)..." | |
| VIGRA_SRC="/tmp/vigra-src" | |
| VIGRA_BUILD="/tmp/vigra-build" | |
| rm -rf "$VIGRA_SRC" "$VIGRA_BUILD" | |
| git clone --depth 1 https://github.com/ukoethe/vigra.git "$VIGRA_SRC" | |
| mkdir -p "$VIGRA_BUILD" | |
| cmake -S "$VIGRA_SRC" -B "$VIGRA_BUILD" \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_INSTALL_PREFIX="$VIGRA_PREFIX" \ | |
| -DWITH_OPENEXR=OFF \ | |
| -DWITH_HDF5=OFF \ | |
| -DWITH_VIGRANUMPY=OFF \ | |
| -DDOCINSTALL=OFF | |
| make -C "$VIGRA_BUILD" -j"$(sysctl -n hw.logicalcpu)" | |
| make -C "$VIGRA_BUILD" install | |
| log "VIGRA installed." | |
| else | |
| log "VIGRA already installed, skipping." | |
| fi | |
| # ── 6. Build enblend/enfuse from source (not in Homebrew) ──────────────────── | |
| ENBLEND_BIN="/tmp/enblend-build/bin/enblend" | |
| if [ ! -x "$ENBLEND_BIN" ]; then | |
| log "Building enblend/enfuse from source (~3 min)..." | |
| ENBLEND_SRC="/tmp/enblend-src" | |
| ENBLEND_BUILD="/tmp/enblend-build" | |
| rm -rf "$ENBLEND_SRC" "$ENBLEND_BUILD" | |
| git clone --depth 1 https://github.com/jackmitch/enblend-enfuse.git "$ENBLEND_SRC" | |
| mkdir -p "$ENBLEND_BUILD" | |
| cmake -S "$ENBLEND_SRC" -B "$ENBLEND_BUILD" \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_PREFIX_PATH="$(brew --prefix)" \ | |
| -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 \ | |
| -DENABLE_OPENCL=OFF \ | |
| -DENABLE_OPENMP=OFF \ | |
| -DDOC=OFF | |
| make -C "$ENBLEND_BUILD" -j"$(sysctl -n hw.logicalcpu)" enblend enfuse | |
| log "enblend/enfuse built." | |
| else | |
| log "enblend/enfuse already built, skipping." | |
| fi | |
| # ── 7. Extract source ───────────────────────────────────────────────────────── | |
| log "Extracting $TARBALL..." | |
| rm -rf "$SRCDIR" | |
| tar xjf "$TARBALL" | |
| # ── 8. Apply patch ──────────────────────────────────────────────────────────── | |
| log "Applying patch..." | |
| patch -p1 -l -d "$SRCDIR" < "$PATCHFILE" | |
| # ── 9. Configure ───────────────────────────────────────────────────────────── | |
| log "Configuring CMake..." | |
| rm -rf "$BUILDDIR" | |
| mkdir -p "$BUILDDIR" | |
| cmake -S "$SRCDIR" -B "$BUILDDIR" \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_PREFIX_PATH="$(brew --prefix)" \ | |
| -DMAC_SELF_CONTAINED_BUNDLE=ON | |
| # ── 10. Build ───────────────────────────────────────────────────────────────── | |
| log "Building Hugin (~5 min)..." | |
| make -C "$BUILDDIR" -j"$(sysctl -n hw.logicalcpu)" \ | |
| Hugin PTBatcherGUI HuginStitchProject calibrate_lens_gui | |
| # ── 11. Assemble complete Hugin.app bundle ─────────────────────────────────── | |
| log "Assembling app bundle..." | |
| HUGIN_APP="${BUILDDIR}/src/hugin1/hugin/Hugin.app" | |
| MACOS="${HUGIN_APP}/Contents/MacOS" | |
| # Core tools built above but not auto-copied into bundle | |
| for t in nona hugin_hdrmerge verdandi; do | |
| cp "${BUILDDIR}/src/tools/$t" "$MACOS/" | |
| chmod +x "$MACOS/$t" | |
| done | |
| # enblend / enfuse — Mach-O binaries (locale is fixed in source; no wrapper needed) | |
| cp /tmp/enblend-build/bin/enblend "$MACOS/enblend" | |
| cp /tmp/enblend-build/bin/enfuse "$MACOS/enfuse" | |
| chmod +x "$MACOS/enblend" "$MACOS/enfuse" | |
| # exiftool (Perl script from Homebrew) | |
| cp "$(brew --prefix)/bin/exiftool" "$MACOS/" | |
| chmod +x "$MACOS/exiftool" | |
| # Patch Info.plist to set locale env for all child processes | |
| PLIST="${HUGIN_APP}/Contents/Info.plist" | |
| /usr/libexec/PlistBuddy -c "Add :LSEnvironment dict" "$PLIST" 2>/dev/null || true | |
| /usr/libexec/PlistBuddy -c "Add :LSEnvironment:LANG string en_US.UTF-8" "$PLIST" 2>/dev/null || true | |
| /usr/libexec/PlistBuddy -c "Add :LSEnvironment:LC_ALL string en_US.UTF-8" "$PLIST" 2>/dev/null || true | |
| # ── 12. Verify bundle ───────────────────────────────────────────────────────── | |
| log "Verifying bundle tools..." | |
| REQUIRED=( | |
| enblend enfuse nona hugin_hdrmerge verdandi | |
| align_image_stack autooptimiser cpfind celeste_standalone | |
| fulla pano_modify pano_trafo pto_gen pto_lensstack pto_mask | |
| pto_merge pto_move pto_template pto_var tca_correct vig_optimize | |
| cpclean icpfind linefind geocpset checkpto hugin_stacker | |
| hugin_executor hugin_lensdb deghosting_mask exiftool | |
| ) | |
| MISSING=0 | |
| for t in "${REQUIRED[@]}"; do | |
| if [ ! -x "$MACOS/$t" ]; then | |
| echo " MISSING: $t" | |
| ((MISSING++)) | |
| fi | |
| done | |
| [ "$MISSING" -eq 0 ] || { echo "ERROR: $MISSING tools missing from bundle"; exit 1; } | |
| log "All ${#REQUIRED[@]} tools present." | |
| # ── 13. Package DMG ─────────────────────────────────────────────────────────── | |
| log "Creating DMG..." | |
| STAGE="$(mktemp -d)" | |
| cp -R "${BUILDDIR}/src/hugin1/hugin/Hugin.app" "$STAGE/" | |
| cp -R "${BUILDDIR}/src/hugin1/ptbatcher/PTBatcherGUI.app" "$STAGE/" | |
| cp -R "${BUILDDIR}/src/hugin1/calibrate_lens/calibrate_lens_gui.app" "$STAGE/" | |
| cp -R "${BUILDDIR}/src/hugin1/stitch_project/HuginStitchProject.app" "$STAGE/" | |
| ln -sf /Applications "$STAGE/Applications" | |
| rm -f "$DMG" | |
| hdiutil create \ | |
| -volname "Hugin ${HUGIN_VERSION}" \ | |
| -srcfolder "$STAGE" \ | |
| -ov -format UDZO \ | |
| "$DMG" | |
| rm -rf "$STAGE" | |
| log "Done! DMG: $(pwd)/$DMG" | |
| log "Open the DMG and drag Hugin.app to /Applications to install." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment