diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml new file mode 100644 index 00000000..07932bba --- /dev/null +++ b/.github/actions/build/action.yml @@ -0,0 +1,49 @@ +name: CMake build +description: CMake Composite Action + +inputs: + preset: + required: true + description: vcpkg build preset, e.g, windows-arm64 + + config: + default: Release + description: build type + + target: + default: bundle + description: cmake build target + + test_id: + description: Ziti Test Identity + +runs: + using: "composite" + steps: + - name: simple build + run: echo "preset = ${{ inputs.preset }}" + shell: bash + + - name: install contemporary cmake + uses: lukka/get-cmake@latest + + - uses: lukka/run-vcpkg@v10 + with: + # use 2023.02.24 vcpkg baseline, + # see https://learn.microsoft.com/en-us/vcpkg/users/examples/versioning.getting-started#builtin-baseline + vcpkgGitCommitId: 'a7b6122f6b6504d16d96117336a0562693579933' + + - uses: lukka/run-cmake@v10 + name: Configure CMake + with: + configurePreset: ci-${{ inputs.preset }} + configurePresetAdditionalArgs: "[ `-B`, `./build` ]" + + - name: build ziti-edge-tunnel + shell: bash + run: | + cmake \ + --build ./build \ + --config ${{ inputs.config }} \ + --target ${{ inputs.target }} \ + --verbose diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 1fab2fa4..f1ebad42 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -6,13 +6,17 @@ on: workflow_dispatch: workflow_call: +# cancel older, redundant runs of same workflow on same branch +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }} + cancel-in-progress: true + jobs: build: runs-on: ${{ matrix.os }} container: ${{ matrix.container }} - name: build ${{ matrix.target }} - env: - common_ubuntu_deps: curl doxygen libssl-dev libsystemd-dev pkg-config zlib1g-dev zip + name: build ${{ matrix.preset }} + env: {} strategy: fail-fast: false @@ -20,106 +24,46 @@ jobs: include: - os: macOS-11 name: macOS x86_64 - target: macOS-x64 + preset: macOS-x64 - os: macOS-11 name: macOS arm64 - target: macOS-arm64 + preset: macOS-arm64 - os: windows-latest name: Windows x86_64 - target: windows-x64 + preset: windows-x64 - os: windows-latest name: Windows arm64 - target: windows-arm64 + preset: windows-arm64 - os: ubuntu-20.04 - container: ubuntu:18.04 + container: openziti/ziti-builder name: Linux x86_64 - install: $common_ubuntu_deps build-essential - # build current openssl libs instead of using old versions provided by apt on ubuntu 18 - cmake_opts: "`-DVCPKG_OVERLAY_PORTS=./vcpkg-overlays/linux-syslibs/ubuntu18`" - target: linux-x64 + preset: linux-x64 - os: ubuntu-20.04 - container: ubuntu:18.04 + container: openziti/ziti-builder name: Linux arm - # build current openssl libs instead of using old versions provided by apt on ubuntu 18 - install: $common_ubuntu_deps crossbuild-essential-armhf - cmake_opts: "`-DVCPKG_OVERLAY_PORTS=./vcpkg-overlays/linux-syslibs/ubuntu18`" - target: linux-arm + preset: linux-arm - os: ubuntu-20.04 - container: ubuntu:18.04 + container: openziti/ziti-builder name: Linux arm64 - install: $common_ubuntu_deps crossbuild-essential-arm64 - # build current openssl libs instead of using old versions provided by apt on ubuntu 18 - cmake_opts: "`-DVCPKG_OVERLAY_PORTS=./vcpkg-overlays/linux-syslibs/ubuntu18`" - target: linux-arm64 + preset: linux-arm64 steps: - - name: install tools - if: ${{ matrix.install != null }} - run: | - apt -y update - apt -y install ${{ matrix.install }} - - - name: install contemporary git - if: ${{ matrix.container != null }} - run: | - apt -y update - apt -y install software-properties-common - add-apt-repository -y ppa:git-core/ppa - apt -y update - apt -y install git - git config --global --add safe.directory $GITHUB_WORKSPACE - git --version - - # run this step if Linux and arm or arm64 - - name: subscribe to apt multiarch ports and install libssl-dev for target arch - if: matrix.container != null && matrix.target != 'linux-x64' - run: | - case ${{ matrix.target }} in - linux-arm) TARGETARCH=armhf;; - linux-arm64) TARGETARCH=arm64;; - esac - dpkg --add-architecture ${TARGETARCH} - cat < /etc/apt/sources.list.d/crossbuild.list - deb [arch=${TARGETARCH}] http://ports.ubuntu.com/ bionic main restricted - deb [arch=${TARGETARCH}] http://ports.ubuntu.com/ bionic-updates main restricted - deb [arch=${TARGETARCH}] http://ports.ubuntu.com/ bionic universe - deb [arch=${TARGETARCH}] http://ports.ubuntu.com/ bionic-updates universe - deb [arch=${TARGETARCH}] http://ports.ubuntu.com/ bionic multiverse - deb [arch=${TARGETARCH}] http://ports.ubuntu.com/ bionic-updates multiverse - deb [arch=${TARGETARCH}] http://ports.ubuntu.com/ bionic-backports main restricted universe multiverse - EOF - sed -Ei 's/^deb/deb [arch=amd64]/g' /etc/apt/sources.list - apt-get update - apt-get -y install libssl-dev:${TARGETARCH} zlib1g-dev:${TARGETARCH} - - name: checkout workspace uses: actions/checkout@v3 with: fetch-depth: 0 - - name: install contemporary cmake - uses: lukka/get-cmake@latest - - - uses: lukka/run-vcpkg@v10 - with: - # use 2023.02.24 vcpkg baseline, - # see https://learn.microsoft.com/en-us/vcpkg/users/examples/versioning.getting-started#builtin-baseline - vcpkgGitCommitId: 'a7b6122f6b6504d16d96117336a0562693579933' - - - uses: lukka/run-cmake@v10 - name: Configure CMake + - name: Run CMake Composite Action + uses: ./.github/actions/build with: - configurePreset: ci-${{ matrix.target }} - configurePresetAdditionalArgs: "[ `-B`, `./build`, ${{ matrix.cmake_opts }} ]" - - - name: build ziti-edge-tunnel bundle target - run: cmake --build ./build --target bundle --verbose + preset: ${{ matrix.preset }} + target: bundle - name: list bundle artifacts run: ls -R @@ -132,7 +76,7 @@ jobs: - name: upload bundle artifacts uses: actions/upload-artifact@v3 with: - name: ${{ matrix.target }} + name: ${{ matrix.preset }} path: | ./build/bundle/ziti-edge-tunnel-*.zip if-no-files-found: error \ No newline at end of file diff --git a/.gitignore b/.gitignore index 591d1be8..987ea756 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,11 @@ .vs gcc -build-*/ -build/ +/build-*/ +/build/ /cmake-build-*/ +# created by following build instructions to download the CMake installer script in current dir +/cmake.sh install/ .vscode/ diff --git a/BUILD.md b/BUILD.md index b75b964c..4d31abcf 100644 --- a/BUILD.md +++ b/BUILD.md @@ -10,7 +10,7 @@ is. To use this library it is also required to have a functioning Ziti Network a To learn more about what Ziti is or how to learn how to setup a Ziti Network head over to [the official documentation site](https://openziti.github.io/ziti/overview.html). -## Building Requirements +### Building Requirements * [cmake](https://cmake.org/install/) * make sure cmake is on your path or replace the following `cmake` commands with the fully qualified path to the binary @@ -144,3 +144,23 @@ threads your CPU has. You may also want to add that to your preset using the [1]: https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html [2]: https://cmake.org/download/ + +## Docker Crossbuilder Image + +The CI job which also runs the included `ziti-builder.sh` builds this project inside a Docker container. The script will run the necessary container image if needed. The container image has the tools to cross-compile for target architectures arm, arm64. This script works for Linux, macOS, and WSL2 on Windows. Arm architecture hosts will experience slower build times due to emulation of this x86_64 container image. + +Without any arguments, the `ziti-builder.sh` script will build the `bundle` target with the `ci-linux-x64` (amd64) preset, placing the resulting ZIP archive in `./build/bundle`. + +```bash +./ziti-builder.sh +``` + +To build for a specific target architecture, use the `-p` argument to specify the vcpkg preset. + +```bash +./ziti-builder.sh -p ci-linux-arm64 +``` + +```bash +./cmake help +``` diff --git a/scripts/ziti-builder.sh b/scripts/ziti-builder.sh new file mode 100755 index 00000000..eb4f6bed --- /dev/null +++ b/scripts/ziti-builder.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +# +# build this project in the ziti-builder container +# + +set -euo pipefail + +BASENAME="$(basename "${0}")" +BASEDIR="$(cd "$(dirname "${0}")" && pwd)" +# set in ziti-builder image, but this default allows hacking the script to run +# outside the ziti-builder container +: "${GIT_CONFIG_GLOBAL:=/tmp/ziti-builder-gitconfig}" + +[[ ${1:-} =~ -h|(--)?help ]] && { + echo -e "\nUsage: ${BASENAME} [CMD] [ARGS...]"\ + "\n\nRuns CMD in the ziti-builder container, and builds the"\ + "\ndefault target if no CMD is specified\n"\ + "\n -c [Release|Debug] set CMAKE_BUILD_TYPE (default: Release)"\ + "\n -p CMAKE_PRESET set CMAKE_TOOLCHAIN_FILE preset (default: ci-linux-x64)"\ + "\n -t [bundle|package] set CMAKE_TARGET (default: bundle)" + exit 0 +} + +function set_git_safe_dirs() { + # workspace dir for each build env is added to "safe" dirs in global config + # so both runner and builder containers trust these dirs owned by different + # UIDs from that of Git's EUID. This is made necessary by newly-enforced + # directory boundaries in Git v2.35.2 ref: + # https://lore.kernel.org/git/xmqqv8veb5i6.fsf@gitster.g/ + local -a SAFE_DIRS=( + "/github/workspace" + ) + # the container environment defines GIT_CONFIG_GLOBAL=/tmp/gitconfig + for SAFE in "${SAFE_DIRS[@]}" "${@}"; do + git config --file "$GIT_CONFIG_GLOBAL" --add safe.directory "${SAFE}" + done +} + +function set_workspace(){ + # let GitHub Actions override the workspace dir + if [[ -n "${GITHUB_WORKSPACE:-}" ]]; then + WORKDIR="${GITHUB_WORKSPACE}" + else + export WORKDIR="/github/workspace" + fi + + # if project is mounted on WORKDIR then build, else restart in container + if [[ -x "${WORKDIR}/${BASENAME}" ]]; then + # container environment defines BUILD_ENVIRONMENT=ziti-builder-docker + if [[ "${BUILD_ENVIRONMENT:-}" == "ziti-builder-docker" ]]; then + echo "INFO: running in ziti-builder container" + set_git_safe_dirs "${WORKDIR}" + else + echo "ERROR: not running in ziti-builder container" >&2 + exit 1 + fi + else + echo -e "INFO: project not mounted on ${WORKDIR}, re-running in container"\ + "\nINFO: 'docker run --user ${UID} --volume ${BASEDIR}:${WORKDIR} openziti/ziti-builder ${WORKDIR}/${BASENAME} ${*}'" + exec docker run \ + --rm \ + --user "${UID}" \ + --volume "${BASEDIR}:${WORKDIR}" \ + --platform "linux/amd64" \ + openziti/ziti-builder \ + "${WORKDIR}/${BASENAME}" "${@}" + fi +} + +function main() { + echo "INFO: GIT_DISCOVERY_ACROSS_FILESYSTEM=${GIT_DISCOVERY_ACROSS_FILESYSTEM:-}" + echo "INFO: WORKDIR=${PWD}" + echo "INFO: $(git --version)" + echo "INFO: GIT_CONFIG_GLOBAL=${GIT_CONFIG_GLOBAL:-}" + # use this value to detect whether any options were passed so we can warn if + # they're being ignored when an override command is sent at the same time + : "${OPTS:=0}" + + while getopts 'c::p:t:' OPT; do + case "${OPT}" in + c) CMAKE_CONFIG="${OPTARG}" + OPTS=1 + ;; + p) CMAKE_PRESET="${OPTARG}" + OPTS=1 + ;; + t) CMAKE_TARGET="${OPTARG}" + OPTS=1 + if [[ ${CMAKE_TARGET} == package ]]; then + BUILD_DIST_PACKAGES=ON + fi + ;; + *) echo "ERROR: invalid option: ${OPT}" >&2 + return 1 + ;; + esac + done + shift $((OPTIND-1)) + # if args then run them, else clean build output dir and build default target + if (( $# )); then + if (( OPTS )); then + echo "WARN: ignoring options because override command is present" >&2 + fi + exec "${@}" + else + [[ -d ./build ]] && rm -rf ./build + cmake \ + -E make_directory \ + ./build + cmake \ + --preset "${CMAKE_PRESET:-ci-linux-x64}" \ + -DCMAKE_BUILD_TYPE="${CMAKE_CONFIG:-Release}" \ + -DBUILD_DIST_PACKAGES="${BUILD_DIST_PACKAGES:-OFF}" \ + -DVCPKG_OVERLAY_PORTS="./vcpkg-overlays/linux-syslibs/ubuntu18" \ + -S . \ + -B ./build + cmake \ + --build ./build \ + --config "${CMAKE_CONFIG:-Release}" \ + --target "${CMAKE_TARGET:-bundle}" \ + --verbose + fi +} + +# set global WORKDIR +set_workspace "${@}" + +# run main() in WORKDIR +cd "${WORKDIR}" +main "${@}" \ No newline at end of file