MacOSX release build #813
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
| env: | |
| QT_VERSION: '6.5.3' | |
| TCL_VERSION: '8.6.17' | |
| PYTHON_VERSION: '3.13' | |
| ICU_VERSION: '76.1' | |
| ICU_URL: 'https://github.com/unicode-org/icu/archive/refs/tags/release-76-1.tar.gz' | |
| SQLITE_VERSION: '3530200' | |
| PORTABLE_DIR: ${{ github.workspace }}/output/portable/Letos | |
| BRANCH_NAME: ${{ github.head_ref || github.ref_name }} | |
| name: MacOSX release build | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| use_ccache: | |
| description: 'Use ccache (for workflow debugging only!)' | |
| required: false | |
| type: boolean | |
| DEBUG: | |
| description: 'Enable workflow debug messages' | |
| required: false | |
| type: boolean | |
| default: false | |
| debug_ssh: | |
| description: "Open SSH tunnel at the end" | |
| type: boolean | |
| default: false | |
| debug_on_failure: | |
| description: "Open SSH tunnel if job fails" | |
| type: boolean | |
| default: false | |
| schedule: | |
| - cron: '0 3 * * 1' # run at 3 AM UTC every Monday | |
| jobs: | |
| build: | |
| runs-on: macos-15 | |
| steps: | |
| - name: Install coreutils | |
| run: | | |
| brew install coreutils | |
| - name: Initial config | |
| run: | | |
| MACOSX_DEPLOYMENT_TARGET=11.0 | |
| echo "CFLAGS=$CFLAGS -mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET" >> $GITHUB_ENV | |
| echo "CXXFLAGS=$CXXFLAGS -mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET" >> $GITHUB_ENV | |
| echo "LDFLAGS=$LDFLAGS -mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET" >> $GITHUB_ENV | |
| echo "MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET" >> $GITHUB_ENV | |
| echo "TCL_ROOT_DIR=$(grealpath -m $GITHUB_WORKSPACE/../.cache/tcl-universal)" >> $GITHUB_ENV | |
| echo "ICU_ROOT_DIR=$(grealpath -m $GITHUB_WORKSPACE/../.cache/icu-universal)" >> $GITHUB_ENV | |
| - name: Cache Tcl | |
| id: cache-tcl | |
| uses: actions/cache@v5 | |
| with: | |
| path: ${{ env.TCL_ROOT_DIR }} | |
| key: tcl-${{ env.TCL_VERSION }}-macos-universal-cache-id-4 | |
| - name: Build Tcl universal | |
| if: steps.cache-tcl.outputs.cache-hit != 'true' | |
| run: | | |
| if brew list tcl-tk 2>/dev/null; then | |
| brew uninstall tcl-tk r | |
| fi | |
| set -euo pipefail | |
| curl -fsSL -O https://prdownloads.sourceforge.net/tcl/tcl${TCL_VERSION}-src.tar.gz | |
| tar xf tcl${TCL_VERSION}-src.tar.gz | |
| cd tcl${TCL_VERSION}/unix | |
| GLOBAL_CFLAGS=$CFLAGS | |
| GLOBAL_LDFLAGS=$LDFLAGS | |
| BUILD_TRIPLET="$(clang -dumpmachine)" | |
| # arm64 | |
| CC="clang -arch arm64" \ | |
| CFLAGS="-arch arm64 $GLOBAL_CFLAGS" \ | |
| LDFLAGS="-arch arm64 $GLOBAL_LDFLAGS" \ | |
| ./configure \ | |
| --build="$BUILD_TRIPLET" \ | |
| --prefix=$TCL_ROOT_DIR | |
| make -j$(sysctl -n hw.ncpu) | |
| make install | |
| make distclean | |
| # x86_64 | |
| CC="clang -arch x86_64" \ | |
| CFLAGS="-arch x86_64 $GLOBAL_CFLAGS" \ | |
| LDFLAGS="-arch x86_64 $GLOBAL_LDFLAGS" \ | |
| ./configure \ | |
| --build="$BUILD_TRIPLET" \ | |
| --prefix=$PWD/build-x86_64 | |
| make -j$(sysctl -n hw.ncpu) | |
| make install | |
| lipo -create \ | |
| $TCL_ROOT_DIR/lib/libtcl*.dylib \ | |
| build-x86_64/lib/libtcl*.dylib \ | |
| -output $TCL_ROOT_DIR/lib/libtcl${TCL_VERSION%.*}.dylib.new | |
| #rm $TCL_ROOT_DIR/$TCL_ROOT_DIR/lib/libtcl${TCL_VERSION%.*}.dylib | |
| mv $TCL_ROOT_DIR/lib/libtcl${TCL_VERSION%.*}.dylib.new $TCL_ROOT_DIR/lib/libtcl${TCL_VERSION%.*}.dylib | |
| echo "include:" | |
| ls -l $TCL_ROOT_DIR/include | |
| echo "lib:" | |
| ls -l $TCL_ROOT_DIR/lib | |
| file $TCL_ROOT_DIR/lib/libtcl*.dylib | |
| echo "lipo archs:" | |
| lipo -archs $TCL_ROOT_DIR/lib/libtcl*.dylib | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| architecture: 'arm64' | |
| - name: Qt installation dir | |
| id: qt-installation-dir | |
| run: echo "DIR=$(readlink -f ${{ github.workspace }}/..)" >> $GITHUB_OUTPUT | |
| - name: Install Qt | |
| uses: jurplel/install-qt-action@v4 | |
| with: | |
| cache: true | |
| version: ${{ env.QT_VERSION }} | |
| host: 'mac' | |
| dir: ${{ steps.qt-installation-dir.outputs.DIR }} | |
| setup-python: 'false' | |
| extra: '--external 7z' | |
| - name: Cache ICU | |
| id: cache-icu | |
| uses: actions/cache@v5 | |
| with: | |
| path: ${{ env.ICU_ROOT_DIR }} | |
| key: icu-macos-${{ env.ICU_VERSION }}-universal-cache-id-3 | |
| - name: Build ICU universal | |
| if: steps.cache-icu.outputs.cache-hit != 'true' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| curl -fsSL -o icu-src.tgz "${ICU_URL}" | |
| tar xf icu-src.tgz | |
| cd icu-*/icu4c/source | |
| GLOBAL_CFLAGS=$CFLAGS | |
| GLOBAL_CXXFLAGS=$CXXFLAGS | |
| GLOBAL_LDFLAGS=$LDFLAGS | |
| BUILD_TRIPLET="$(clang -dumpmachine)" | |
| echo "Triplet: $BUILD_TRIPLET" | |
| # arm64 | |
| mkdir build-arm64 && cd build-arm64 | |
| CC="clang -arch arm64" \ | |
| CFLAGS="-arch arm64 $GLOBAL_CFLAGS" \ | |
| CXXFLAGS="-arch arm64 $GLOBAL_CXXFLAGS" \ | |
| LDFLAGS="-arch arm64 $GLOBAL_LDFLAGS" \ | |
| ../configure \ | |
| --build="$BUILD_TRIPLET" \ | |
| --prefix="$PWD/install" | |
| make -j$(sysctl -n hw.ncpu) | |
| make install | |
| cd .. | |
| # x86_64 | |
| mkdir build-x86_64 && cd build-x86_64 | |
| CC="clang -arch x86_64" \ | |
| CFLAGS="-arch x86_64 $GLOBAL_CFLAGS" \ | |
| CXXFLAGS="-arch x86_64 $GLOBAL_CXXFLAGS" \ | |
| LDFLAGS="-arch x86_64 $GLOBAL_LDFLAGS" \ | |
| ../configure \ | |
| --build="$BUILD_TRIPLET" \ | |
| --prefix="$PWD/install" | |
| make -j$(sysctl -n hw.ncpu) | |
| make install | |
| cd .. | |
| # assemble universal | |
| mkdir -p "$ICU_ROOT_DIR/lib" "$ICU_ROOT_DIR/include" | |
| cp -R build-arm64/install/include/* "$ICU_ROOT_DIR/include/" | |
| for lib in build-arm64/install/lib/*.dylib; do | |
| name=$(basename "$lib") | |
| lipo -create \ | |
| "build-arm64/install/lib/$name" \ | |
| "build-x86_64/install/lib/$name" \ | |
| -output "$ICU_ROOT_DIR/lib/$name" | |
| done | |
| echo "ICU installed to $ICU_ROOT_DIR" | |
| ls -l "$ICU_ROOT_DIR/include" | |
| ls -l "$ICU_ROOT_DIR/lib" | |
| - name: Compiler config for our source code | |
| run: | | |
| echo "CFLAGS=$CFLAGS -arch arm64 -arch x86_64" >> $GITHUB_ENV | |
| echo "CXXFLAGS=$CXXFLAGS -arch arm64 -arch x86_64" >> $GITHUB_ENV | |
| echo "LDFLAGS=-arch x86_64 -arch x86_64" >> $GITHUB_ENV | |
| - name: Clone GH scripts | |
| uses: actions/checkout@v6 | |
| with: | |
| repository: pawelsalawa/gh-action-scripts | |
| ref: main | |
| path: gh-scripts | |
| - name: Setup GH scripts path | |
| shell: bash | |
| run: | | |
| mv gh-scripts .. | |
| cd .. | |
| chmod +x gh-scripts/scripts/*.sh | |
| echo "GH_SCRIPTS=$(pwd)/gh-scripts/scripts" >> $GITHUB_ENV | |
| echo "DEBUG=${{ inputs.DEBUG }}" >> $GITHUB_ENV | |
| - name: Clone repo | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ env.BRANCH_NAME }} | |
| - name: Determine Letos version | |
| run: | | |
| LETOS_VERSION=$(scripts/version_from_source.sh) | |
| echo "LETOS_VERSION=$LETOS_VERSION" >> $GITHUB_ENV | |
| echo "PACKAGE_VERSION=${LETOS_VERSION}-macos-universal" >> $GITHUB_ENV | |
| - name: Prepare ccache | |
| if: inputs.use_ccache || false | |
| uses: hendrikmuhs/ccache-action@v1.2 | |
| with: | |
| key: ${{ matrix.binary_compatibility }} | |
| max-size: "32M" | |
| - name: Configure ccache | |
| if: inputs.use_ccache || false | |
| run: | | |
| echo "PATH=/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" >> $GITHUB_ENV | |
| - name: Install SQLite3 | |
| run: | | |
| SQLITE_DOT_VERSION=$($GH_SCRIPTS/convert_int_ver.sh $SQLITE_VERSION) | |
| echo "SQLITE_DOT_VERSION=$SQLITE_DOT_VERSION" >> $GITHUB_ENV | |
| cd .. | |
| SQLITE3_ZIP=sqlite3-macos-universal-$SQLITE_VERSION.zip | |
| curl -L https://github.com/pawelsalawa/sqlite3-letos/releases/download/v$SQLITE_DOT_VERSION/$SQLITE3_ZIP --output $SQLITE3_ZIP | |
| unzip $SQLITE3_ZIP libsqlite3.0.dylib sqlite3.h sqlite3ext.h -d sqlite | |
| cd sqlite | |
| ln -f -s libsqlite3.0.dylib libsqlite3.dylib | |
| echo "DYLD_LIBRARY_PATH=$(pwd)" >> $GITHUB_ENV | |
| ls -l | |
| - name: Compile additional SQLite3 extensions | |
| shell: bash | |
| run: | | |
| cd .. | |
| mkdir ext | |
| curl -L https://github.com/pawelsalawa/sqlite3-letos/releases/download/v$SQLITE_DOT_VERSION/sqlite3-extensions-src-$SQLITE_VERSION.zip --output sqlite3-extensions-src-$SQLITE_VERSION.zip | |
| ls -l | |
| mkdir ext-src | |
| unzip sqlite3-extensions-src-$SQLITE_VERSION.zip -d ext-src | |
| cd ext-src | |
| ls -l | |
| FLAGS="$CFLAGS -ldl -Os -fpic -shared -I../sqlite -L../sqlite -lsqlite3" | |
| set -x | |
| for f in compress sqlar; do | |
| gcc misc/$f.c -Imisc $FLAGS -lz -o ../ext/$f.dylib | |
| done | |
| for f in csv decimal eval ieee754 percentile rot13 series uint uuid zorder; do | |
| gcc misc/$f.c -Imisc $FLAGS -o ../ext/$f.dylib | |
| done | |
| for f in icu; do | |
| ICU_FLAGS="-I$ICU_ROOT_DIR/include -L$ICU_ROOT_DIR/lib -licuio -licui18n -licuuc -licudata" | |
| gcc icu/$f.c -Iicu $ICU_FLAGS $FLAGS -o ../ext/$f.dylib | |
| done | |
| set +x | |
| ls -l ../ext/ | |
| - name: Prepare deps | |
| run: | | |
| mkdir ../lib ../include | |
| cp $ICU_ROOT_DIR/lib/libicuio.dylib \ | |
| $ICU_ROOT_DIR/lib/libicui18n.dylib \ | |
| $ICU_ROOT_DIR/lib/libicuuc.dylib \ | |
| $ICU_ROOT_DIR/lib/libicudata.dylib \ | |
| ../sqlite/libsqlite3*.dylib \ | |
| ../lib | |
| cp $TCL_ROOT_DIR/lib/libtcl*.dylib ../lib | |
| - name: Prepare output dir | |
| run: mkdir output output/build output/build-plugins | |
| - name: Compile Letos | |
| working-directory: output/build | |
| run: | | |
| cmake ../../Letos -G Ninja \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_OSX_ARCHITECTURE="x86_64;arm64" \ | |
| -DCMAKE_OSX_DEPLOYMENT_TARGET="$MACOSX_DEPLOYMENT_TARGET" \ | |
| -DCMAKE_PREFIX_PATH="$QT_ROOT_DIR" \ | |
| -DCMAKE_INSTALL_PREFIX=../Letos \ | |
| -DCUSTOM_SQLITE3=$GITHUB_WORKSPACE/../sqlite \ | |
| -DWITH_PORTABLE=1 \ | |
| -DWITH_UPDATER=1 \ | |
| -DBUILD_TESTING=0 | |
| cmake --build . --verbose | |
| cmake --install . --verbose | |
| - name: Compile Plugins | |
| working-directory: output/build-plugins | |
| run: | | |
| cmake ../../Plugins -G Ninja \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_OSX_ARCHITECTURE="x86_64;arm64" \ | |
| -DCMAKE_OSX_DEPLOYMENT_TARGET="$MACOSX_DEPLOYMENT_TARGET" \ | |
| -DCMAKE_PREFIX_PATH="${{ env.QT_ROOT_DIR }}:${{ env.Python3_ROOT_DIR }}" \ | |
| -DCMAKE_INSTALL_PREFIX=../Letos \ | |
| -DCUSTOM_SQLITE3=$GITHUB_WORKSPACE/../sqlite \ | |
| -DWITH_PORTABLE=1 \ | |
| -DWITH_DYNAMIC_PYTHON=1 \ | |
| -DWITH_ALL_PLUGINS=1 | |
| cmake --build . --verbose | |
| cmake --install . --verbose | |
| - name: Copy SQLite extensions to output dir | |
| shell: bash | |
| run: | | |
| cp -R ../ext output/Letos/Letos.app/Contents/extensions | |
| - name: Build packages | |
| run: | | |
| chmod +x scripts/macos/create_macosx_bundle.sh | |
| export DEP_LIB_DIR="$(cd ../lib && pwd)" | |
| DEBUG_LEVEL=3 scripts/macos/create_macosx_bundle.sh output $QT_ROOT_DIR dist | |
| - name: Determine Letos version | |
| working-directory: output/Letos | |
| run: | | |
| echo "All files in boundle:" | |
| find Letos.app | |
| echo "Listing architecture for files." | |
| find Letos.app -type f -name "*.dylib" -print0 | while IFS= read -r -d '' FILE; do | |
| echo "Arch for: $FILE" | |
| lipo -archs "$FILE" | |
| done | |
| echo "Arch for: Letos.app/Contents/MacOS/letos" | |
| lipo -archs Letos.app/Contents/MacOS/letos | |
| - name: Rename portable package | |
| working-directory: output/Letos | |
| run: | | |
| mv Letos-${{ env.LETOS_VERSION }}.dmg letos-${{ env.PACKAGE_VERSION }}.dmg | |
| - name: SHA256 checksums | |
| shell: bash | |
| run: | | |
| sha256sum output/Letos/letos-${{ env.PACKAGE_VERSION }}.dmg | |
| - name: Upload package artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: letos-${{ env.PACKAGE_VERSION }}.dmg | |
| path: output/Letos/letos-${{ env.PACKAGE_VERSION }}.dmg | |
| - name: Install Midnight Commander | |
| if: > | |
| ${{ | |
| github.repository_owner == 'pawelsalawa' | |
| && (inputs.debug_ssh || (failure() && inputs.debug_on_failure)) | |
| }} | |
| run: brew install mc | |
| - name: Setup debugging SSH | |
| if: > | |
| ${{ | |
| github.repository_owner == 'pawelsalawa' | |
| && (inputs.debug_ssh || (failure() && inputs.debug_on_failure)) | |
| }} | |
| uses: owenthereal/action-upterm@v1 | |
| with: | |
| wait-timeout-minutes: 10 |