diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index a1aeec95..9b239d7e 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -6,48 +6,75 @@ on: - '*' paths: - .github/workflows/build-macos.yml + - contrib/static/build-macos.sh - daemon/** - i18n/** - libi2pd/** - libi2pd_client/** - Makefile - Makefile.homebrew - tags: - - '*' pull_request: branches: - '*' + workflow_call: jobs: build: - name: Build on ${{ matrix.target-name }} - runs-on: ${{ matrix.target }} - - strategy: - fail-fast: true - matrix: - include: - - target: macos-15 - target-name: ARM64 - - target: macos-15-intel - target-name: Intel x86_64 + name: Build universal binary + runs-on: macos-15 steps: - name: Checkout uses: actions/checkout@v4 - - name: Install required formulae - run: | - find /usr/local/bin -lname '*/Library/Frameworks/Python.framework/*' -delete - brew update - brew install boost miniupnpc openssl@3.5 - - - name: List installed formulae - run: brew list - - name: Build application - run: make HOMEBREW=1 USE_UPNP=yes USE_STATIC=yes PREFIX=$GITHUB_WORKSPACE/output -j3 + run: sh contrib/static/build-macos.sh - - name: Print binary linking - run: otool -L i2pd - + - name: Check binary + run: | + lipo -archs i2pd | grep -w arm64 + lipo -archs i2pd | grep -w x86_64 + otool -L i2pd + test -z "$(otool -L i2pd | grep -E '^[[:space:]]' | grep -vE '^[[:space:]]+(/usr/lib/|/System/Library/)')" + vtool -show-build i2pd | grep -E 'architecture|minos|sdk' + test "$(vtool -show-build i2pd | grep -c 'minos 12\.0$')" = 2 + ./i2pd --version + ./i2pd --version | grep -E '^OpenSSL (3\.([5-9]|[1-9][0-9])|[4-9])\.' + ./i2pd --version | grep -E '^Boost version 1\.(8[1-9]|9[0-9])\.' + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: i2pd-macos + path: i2pd + + test: + name: Run on ${{ matrix.target-name }} + needs: build + runs-on: ${{ matrix.target }} + + strategy: + fail-fast: false + matrix: + include: + - target: macos-14 + target-name: macOS 14 ARM64 + - target: macos-15-intel + target-name: macOS 15 Intel x86_64 + + steps: + - name: Download binary + uses: actions/download-artifact@v4 + with: + name: i2pd-macos + + - name: Run + run: | + chmod +x i2pd + ./i2pd --version + mkdir datadir + ./i2pd --datadir=datadir --log=file --logfile=datadir/i2pd.log --loglevel=info & + sleep 15 + kill -0 $! + grep 'Daemon: Starting NetDB' datadir/i2pd.log + kill -9 $! diff --git a/contrib/static/build-macos.sh b/contrib/static/build-macos.sh new file mode 100755 index 00000000..f07fe6ee --- /dev/null +++ b/contrib/static/build-macos.sh @@ -0,0 +1,67 @@ +#!/bin/sh +# Universal i2pd for macOS with OpenSSL, Boost and miniupnpc built from source and linked statically +set -e + +OPENSSL_VERSION=3.5.8 +BOOST_VERSION=1.92.0 +BOOST_SHA256=ea7b982002cc9dfbe59b0b217b206f470dc75f3de0bb2973d844118934d82411 +MINIUPNPC_VERSION=2.3.3 +MINIUPNPC_SHA256=d52a0afa614ad6c088cc9ddff1ae7d29c8c595ac5fdd321170a05f41e634bd1a +ARCHS="arm64 x86_64" +JOBS=4 +export MACOSX_DEPLOYMENT_TARGET=12.0 + +SRC=$(pwd) +WORK=${TMPDIR:-/tmp}/i2pd-macos +mkdir -p "$WORK" +cd "$WORK" + +fetch() { + curl -fsSL -o "$3" "$1" + echo "$2 $3" | shasum -a 256 -c - +} + +OPENSSL=openssl-$OPENSSL_VERSION +curl -fsSLO https://github.com/openssl/openssl/releases/download/$OPENSSL/$OPENSSL.tar.gz +curl -fsSLO https://github.com/openssl/openssl/releases/download/$OPENSSL/$OPENSSL.tar.gz.sha256 +echo "$(cut -d' ' -f1 $OPENSSL.tar.gz.sha256) $OPENSSL.tar.gz" | shasum -a 256 -c - +fetch https://github.com/boostorg/boost/releases/download/boost-$BOOST_VERSION/boost-$BOOST_VERSION-b2-nodocs.tar.xz $BOOST_SHA256 boost.tar.xz +fetch https://github.com/miniupnp/miniupnp/releases/download/miniupnpc_$(echo $MINIUPNPC_VERSION | tr . _)/miniupnpc-$MINIUPNPC_VERSION.tar.gz $MINIUPNPC_SHA256 miniupnpc.tar.gz +tar xzf $OPENSSL.tar.gz +tar xJf boost.tar.xz +tar xzf miniupnpc.tar.gz +(cd boost-$BOOST_VERSION && ./bootstrap.sh) + +for ARCH in $ARCHS; do + PREFIX=$WORK/$ARCH + ( + cd $OPENSSL + make distclean >/dev/null 2>&1 || true + # no-autoload-config: a static binary must not read the host's openssl.cnf + ./Configure darwin64-$ARCH-cc --prefix=$PREFIX --libdir=lib --openssldir=/nonexistent \ + no-autoload-config no-shared no-module no-dso no-engine no-tests no-docs + make -j$JOBS build_libs + make install_dev + ) + ( + cd boost-$BOOST_VERSION + ./b2 -j$JOBS --build-dir=$WORK/boost-build-$ARCH --prefix=$PREFIX \ + --with-program_options --with-json --with-url link=static variant=release \ + cxxflags="-arch $ARCH" linkflags="-arch $ARCH" install + ) + cmake -S miniupnpc-$MINIUPNPC_VERSION -B miniupnpc-build-$ARCH -DCMAKE_OSX_ARCHITECTURES=$ARCH \ + -DCMAKE_INSTALL_PREFIX=$PREFIX -DUPNPC_BUILD_SHARED=OFF -DUPNPC_BUILD_TESTS=OFF -DUPNPC_BUILD_SAMPLE=OFF + cmake --build miniupnpc-build-$ARCH -j $JOBS + cmake --install miniupnpc-build-$ARCH + ( + cd "$SRC" + make clean >/dev/null + make -j$JOBS HOMEBREW=1 USE_STATIC=yes USE_UPNP=yes DEBUG=no CXX="clang++ -arch $ARCH" \ + SSLROOT=$PREFIX BOOSTROOT=$PREFIX UPNPROOT=$PREFIX i2pd + mv i2pd i2pd-$ARCH + ) +done + +cd "$SRC" +lipo -create -output i2pd i2pd-arm64 i2pd-x86_64 +rm i2pd-arm64 i2pd-x86_64