diff --git a/Earthfile b/Earthfile index ad1893d9..f2c2af91 100644 --- a/Earthfile +++ b/Earthfile @@ -8,6 +8,7 @@ ARG --global outputDir = "./dist" # The list of rust targets we support. They will be automatically converted # to GOOS, GOARCH and GOARM when building go binaries. See the +RUST_TO_GO_ARCH_STRING # helper method at the bottom of the file. + ARG --global architectures = "x86_64-unknown-linux-gnu" \ "aarch64-unknown-linux-gnu" \ "armv7-unknown-linux-gnueabihf" \ @@ -22,6 +23,9 @@ go-deps: FROM golang:${go_version}-${distro} WORKDIR /go-workdir + # We need the git cli to extract version information for go-builds + RUN apk add git + # These cache dirs will be used in later test and build targets # to persist cached go packages. # @@ -54,6 +58,18 @@ go-base: # ./assets COPY assets ./assets + # Copy the git folder and extract version information + COPY .git ./.git + + LET version = $(git tag --points-at) + IF [ "${version}" = "" ] + SET version = $(git describe --tags --abbrev=0) + END + ENV VERSION="${version}" + + LET source = $(git remote -v | cut -f2 | cut -d" " -f1 | head -n 1) + ENV SOURCE="${source}" + # updates all go dependencies and runs go mod tidy, saving go.mod and go.sum locally. update-go-deps: FROM +go-base @@ -82,9 +98,6 @@ build-go: ARG GOARM ARG CMDS=portmaster-start portmaster-core hub notifier - # Get the current version - DO +GET_VERSION - CACHE --sharing shared "$GOCACHE" CACHE --sharing shared "$GOMODCACHE" @@ -97,12 +110,12 @@ build-go: # Build all go binaries from the specified in CMDS FOR bin IN $CMDS - RUN go build -o "/tmp/build/" ./cmds/${bin} + RUN go build -ldflags="-X github.com/safing/portbase/info.version=${VERSION} -X github.com/safing/portbase/info.buildSource=${SOURCE}" -o "/tmp/build/" ./cmds/${bin} END - FOR bin IN $(ls -1 "/tmp/build/") - DO +GO_ARCH_STRING --goos="${GOOS}" --goarch="${GOARCH}" --goarm="${GOARM}" + DO +GO_ARCH_STRING --goos="${GOOS}" --goarch="${GOARCH}" --goarm="${GOARM}" + FOR bin IN $(ls -1 "/tmp/build/") SAVE ARTIFACT "/tmp/build/${bin}" AS LOCAL "${outputDir}/${GO_ARCH_STRING}/${bin}" END @@ -129,7 +142,8 @@ test-go: END test-go-all-platforms: - LOCALLY + FROM alpine:3.18 + FOR arch IN ${architectures} DO +RUST_TO_GO_ARCH_STRING --rustTarget="${arch}" BUILD +test-go --GOARCH="${GOARCH}" --GOOS="${GOOS}" --GOARM="${GOARM}" @@ -137,9 +151,19 @@ test-go-all-platforms: # Builds portmaster-start, portmaster-core, hub and notifier for all supported platforms build-go-release: - LOCALLY + FROM alpine:3.18 + FOR arch IN ${architectures} DO +RUST_TO_GO_ARCH_STRING --rustTarget="${arch}" + + IF [ -z GOARCH ] + RUN echo "Failed to extract GOARCH for ${arch}"; exit 1 + END + + IF [ -z GOOS ] + RUN echo "Failed to extract GOOS for ${arch}"; exit 1 + END + BUILD +build-go --GOARCH="${GOARCH}" --GOOS="${GOOS}" --GOARM="${GOARM}" END @@ -207,7 +231,12 @@ angular-dev: rust-base: FROM rust:1.76-bookworm + RUN dpkg --add-architecture armhf + RUN dpkg --add-architecture arm64 + RUN apt-get update -qq + + # Tools and libraries required for cross-compilation RUN apt-get install --no-install-recommends -qq \ autoconf \ autotools-dev \ @@ -215,28 +244,66 @@ rust-base: clang \ cmake \ bsdmainutils \ + gcc-multilib \ + linux-libc-dev \ + linux-libc-dev-amd64-cross \ + linux-libc-dev-arm64-cross \ + linux-libc-dev-armel-cross \ + linux-libc-dev-armhf-cross \ + build-essential \ + curl \ + wget \ + file \ + libsoup-3.0-dev \ + libwebkit2gtk-4.1-dev + + # Install library dependencies for all supported architectures + # required for succesfully linking. + FOR arch IN amd64 arm64 armhf + RUN apt-get install --no-install-recommends -qq \ + libsoup-3.0-0:${arch} \ + libwebkit2gtk-4.1-0:${arch} \ + libssl3:${arch} \ + libayatana-appindicator3-1:${arch} \ + librsvg2-bin:${arch} \ + libgtk-3-0:${arch} \ + libjavascriptcoregtk-4.1-0:${arch} \ + libssl-dev:${arch} \ + libayatana-appindicator3-dev:${arch} \ + librsvg2-dev:${arch} \ + libgtk-3-dev:${arch} \ + libjavascriptcoregtk-4.1-dev:${arch} + END + + # Note(ppacher): I've no idea why we need to explicitly create those symlinks: + # Some how all the other libs work but libsoup and libwebkit2gtk do not create the link file + RUN cd /usr/lib/aarch64-linux-gnu && \ + ln -s libwebkit2gtk-4.1.so.0 libwebkit2gtk-4.1.so && \ + ln -s libsoup-3.0.so.0 libsoup-3.0.so + + RUN cd /usr/lib/arm-linux-gnueabihf && \ + ln -s libwebkit2gtk-4.1.so.0 libwebkit2gtk-4.1.so && \ + ln -s libsoup-3.0.so.0 libsoup-3.0.so + + # For what ever reason trying to install the gcc compilers together with the above + # command makes apt fail due to conflicts with gcc-multilib. Installing in a separate + # step seems to work ... + RUN apt-get install --no-install-recommends -qq \ g++-mingw-w64-x86-64 \ gcc-aarch64-linux-gnu \ gcc-arm-none-eabi \ gcc-arm-linux-gnueabi \ gcc-arm-linux-gnueabihf \ - libgtk-3-dev \ - libjavascriptcoregtk-4.1-dev \ - libsoup-3.0-dev \ - libwebkit2gtk-4.1-dev \ - build-essential \ - curl \ - wget \ - file \ - libssl-dev \ - libayatana-appindicator3-dev \ - librsvg2-dev + libc6-dev-arm64-cross \ + libc6-dev-armel-cross \ + libc6-dev-armhf-cross \ + libc6-dev-amd64-cross # Add some required rustup components RUN rustup component add clippy RUN rustup component add rustfmt - # Install toolchains and targets + # Install architecture targets FOR arch IN ${architectures} RUN rustup target add ${arch} END @@ -246,6 +313,9 @@ rust-base: # For now we need tauri-cli 1.5 for bulding DO rust+CARGO --args="install tauri-cli --version ^1.5.11" + # Required for cross compilation to work. + ENV PKG_CONFIG_ALLOW_CROSS=1 + tauri-src: FROM +rust-base @@ -268,28 +338,34 @@ build-tauri: # we need to do some magic here because tauri expects the binaries to include the rust target tripple. # We already knwo that triple because it's a required argument. From that triple, we use +RUST_TO_GO_ARCH_STRING # function from below to parse the triple and guess wich GOOS and GOARCH we need. - IF [ "${bundle}" != "none" ] - RUN mkdir /tmp/gobuild - RUN mkdir ./binaries + RUN mkdir /tmp/gobuild + RUN mkdir ./binaries - DO +RUST_TO_GO_ARCH_STRING --rustTarget="${target}" - RUN echo "GOOS=${GOOS} GOARCH=${GOARCH} GOARM=${GOARM} GO_ARCH_STRING=${GO_ARCH_STRING}" + DO +RUST_TO_GO_ARCH_STRING --rustTarget="${target}" + RUN echo "GOOS=${GOOS} GOARCH=${GOARCH} GOARM=${GOARM} GO_ARCH_STRING=${GO_ARCH_STRING}" - COPY (+build-go/output --GOOS="${GOOS}" --CMDS="portmaster-start portmaster-core" --GOARCH="${GOARCH}" --GOARM="${GOARM}") /tmp/gobuild + # Our tauri app has externalBins configured so tauri will try to embed them when it finished compiling + # the app. Make sure we copy portmaster-start and portmaster-core in all architectures supported. + # See documentation for externalBins for more information on how tauri searches for the binaries. - LET dest="" - FOR bin IN $(ls /tmp/gobuild) - SET dest="./binaries/${bin}-${target}" + COPY (+build-go/output --GOOS="${GOOS}" --CMDS="portmaster-start portmaster-core" --GOARCH="${GOARCH}" --GOARM="${GOARM}") /tmp/gobuild - IF [ -z "${bin##*.exe}" ] - SET dest = "./binaries/${bin%.*}-${target}.exe" - END + # Place them in the correct folder with the rust target tripple attached. + LET dest="" + FOR bin IN $(ls /tmp/gobuild) + SET dest="./binaries/${bin}-${target}" - RUN echo "Copying ${bin} to ${dest}" - RUN cp "/tmp/gobuild/${bin}" "${dest}" + IF [ -z "${bin##*.exe}" ] + SET dest = "./binaries/${bin%.*}-${target}.exe" END + + RUN echo "Copying ${bin} to ${dest}" + RUN cp "/tmp/gobuild/${bin}" "${dest}" END + # Just for debugging ... + RUN ls -R ./binaries + # The following is exected to work but doesn't. for whatever reason cargo-sweep errors out on the windows-toolchain. # # DO rust+CARGO --args="tauri build --bundles none --ci --target=${target}" --output="release/[^/\.]+" @@ -300,10 +376,23 @@ build-tauri: RUN --mount=$EARTHLY_RUST_TARGET_CACHE cargo tauri build --bundles "${bundle}" --ci --target="${target}" DO rust+COPY_OUTPUT --output="${output}" + # BUG(cross-compilation): + # + # The above command seems to correctly compile for all architectures we want to support but fails during + # linking since the target libaries are not available for the requested platforms. Maybe we need to download + # the, manually ... + # + # The earthly rust lib also has support for using cross-rs for cross-compilation but that fails due to the + # fact that cross-rs base docker images used for building are heavily outdated (latest = ubunut:16.0, main = ubuntu:20.04) + # which does not ship recent enough glib versions (our glib dependency needs glib>2.70 but ubunut:20.04 only ships 2.64) + # + # The following would use the CROSS function from the earthly lib, this + # DO rust+CROSS --target="${target}" + RUN ls target tauri-release: - LOCALLY + FROM alpine:3.18 ARG bundle="none" @@ -311,9 +400,18 @@ tauri-release: BUILD +build-tauri --target="${arch}" --bundle="${bundle}" END -release: +build-all: BUILD +build-go-release - BUILD +angular-release + BUILD +tauri-release + +release: + LOCALLY + + IF ! git diff --quiet + RUN echo -e "\033[1;31m Refusing to release a dirty git repository. Please commit your local changes first! \033[0m" ; exit 1 + END + + BUILD +build-all # Takes GOOS, GOARCH and optionally GOARM and creates a string representation for file-names. @@ -375,22 +473,3 @@ RUST_TO_GO_ARCH_STRING: ENV GOARM="${goarm}" DO +GO_ARCH_STRING --goos="${goos}" --goarch="${goarch}" --goarm="${goarm}" - -GET_VERSION: - FUNCTION - LOCALLY - - LET VERSION=$(git tag --points-at) - IF [ -z "${VERSION}"] - SET VERSION=$(git describe --tags --abbrev=0)§dev§build - ELSE IF ! git diff --quite - SET VERSION="${VERSION}§dev§build" - END - - RUN echo "Version is ${VERSION}" - ENV VERSION="${VERSION}" - -test: - LOCALLY - - DO +GET_VERSION \ No newline at end of file diff --git a/cmds/portmaster-core/build b/cmds/portmaster-core/build deleted file mode 100755 index 355e661e..00000000 --- a/cmds/portmaster-core/build +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash - -# get build data -if [[ "$BUILD_COMMIT" == "" ]]; then - BUILD_COMMIT=$(git describe --all --long --abbrev=99 --dirty 2>/dev/null) -fi -if [[ "$BUILD_USER" == "" ]]; then - BUILD_USER=$(id -un) -fi -if [[ "$BUILD_HOST" == "" ]]; then - BUILD_HOST=$(hostname -f) -fi -if [[ "$BUILD_DATE" == "" ]]; then - BUILD_DATE=$(date +%d.%m.%Y) -fi -if [[ "$BUILD_SOURCE" == "" ]]; then - BUILD_SOURCE=$(git remote -v | grep origin | cut -f2 | cut -d" " -f1 | head -n 1) -fi -if [[ "$BUILD_SOURCE" == "" ]]; then - BUILD_SOURCE=$(git remote -v | cut -f2 | cut -d" " -f1 | head -n 1) -fi -BUILD_BUILDOPTIONS=$(echo $* | sed "s/ /§/g") - -# check -if [[ "$BUILD_COMMIT" == "" ]]; then - echo "could not automatically determine BUILD_COMMIT, please supply manually as environment variable." - exit 1 -fi -if [[ "$BUILD_USER" == "" ]]; then - echo "could not automatically determine BUILD_USER, please supply manually as environment variable." - exit 1 -fi -if [[ "$BUILD_HOST" == "" ]]; then - echo "could not automatically determine BUILD_HOST, please supply manually as environment variable." - exit 1 -fi -if [[ "$BUILD_DATE" == "" ]]; then - echo "could not automatically determine BUILD_DATE, please supply manually as environment variable." - exit 1 -fi -if [[ "$BUILD_SOURCE" == "" ]]; then - echo "could not automatically determine BUILD_SOURCE, please supply manually as environment variable." - exit 1 -fi - -echo "Please notice, that this build script includes metadata into the build." -echo "This information is useful for debugging and license compliance." -echo "Run the compiled binary with the -version flag to see the information included." - -if [[ $1 == "dev" ]]; then - shift - export CGO_ENABLED=1 - DEV="-race" -else - export CGO_ENABLED=0 -fi - -# build -BUILD_PATH="github.com/safing/portbase/info" -go build $DEV -ldflags "-X ${BUILD_PATH}.commit=${BUILD_COMMIT} -X ${BUILD_PATH}.buildOptions=${BUILD_BUILDOPTIONS} -X ${BUILD_PATH}.buildUser=${BUILD_USER} -X ${BUILD_PATH}.buildHost=${BUILD_HOST} -X ${BUILD_PATH}.buildDate=${BUILD_DATE} -X ${BUILD_PATH}.buildSource=${BUILD_SOURCE}" "$@" diff --git a/cmds/portmaster-core/pack b/cmds/portmaster-core/pack deleted file mode 100755 index 5bdc4c6f..00000000 --- a/cmds/portmaster-core/pack +++ /dev/null @@ -1,123 +0,0 @@ -#!/bin/bash - -baseDir="$( cd "$(dirname "$0")" && pwd )" -cd "$baseDir" - -COL_OFF="\033[0m" -COL_BOLD="\033[01;01m" -COL_RED="\033[31m" -COL_GREEN="\033[32m" -COL_YELLOW="\033[33m" - -destDirPart1="../../dist" -destDirPart2="core" - -function prep { - # output - output="portmaster-core" - # get version - version=$(grep "info.Set" main.go | cut -d'"' -f4) - # build versioned file name - filename="portmaster-core_v${version//./-}" - # platform - platform="${GOOS}_${GOARCH}" - if [[ $GOOS == "windows" ]]; then - filename="${filename}.exe" - output="${output}.exe" - fi - # build destination path - destPath=${destDirPart1}/${platform}/${destDirPart2}/$filename -} - -function check { - prep - - # check if file exists - if [[ -f $destPath ]]; then - echo "[core] $platform v$version already built" - else - echo -e "${COL_BOLD}[core] $platform v$version${COL_OFF}" - fi -} - -function build { - prep - - # check if file exists - if [[ -f $destPath ]]; then - echo "[core] $platform already built in v$version, skipping..." - return - fi - - # build - ./build - if [[ $? -ne 0 ]]; then - echo -e "\n${COL_BOLD}[core] $platform v$version: ${COL_RED}BUILD FAILED.${COL_OFF}" - exit 1 - fi - mkdir -p $(dirname $destPath) - cp $output $destPath - echo -e "\n${COL_BOLD}[core] $platform v$version: ${COL_GREEN}successfully built.${COL_OFF}" -} - -function reset { - prep - - # delete if file exists - if [[ -f $destPath ]]; then - rm $destPath - echo "[core] $platform v$version deleted." - fi -} - -function check_all { - GOOS=linux GOARCH=amd64 check - GOOS=windows GOARCH=amd64 check - GOOS=darwin GOARCH=amd64 check - GOOS=linux GOARCH=arm64 check - GOOS=windows GOARCH=arm64 check - GOOS=darwin GOARCH=arm64 check -} - -function build_all { - GOOS=linux GOARCH=amd64 build - GOOS=windows GOARCH=amd64 build - GOOS=darwin GOARCH=amd64 build - GOOS=linux GOARCH=arm64 build - GOOS=windows GOARCH=arm64 build - GOOS=darwin GOARCH=arm64 build -} - -function reset_all { - GOOS=linux GOARCH=amd64 reset - GOOS=windows GOARCH=amd64 reset - GOOS=darwin GOARCH=amd64 reset - GOOS=linux GOARCH=arm64 reset - GOOS=windows GOARCH=arm64 reset - GOOS=darwin GOARCH=arm64 reset -} - -case $1 in - "check" ) - check_all - ;; - "build" ) - build_all - ;; - "reset" ) - reset_all - ;; - * ) - echo "" - echo "build list:" - echo "" - check_all - echo "" - read -p "press [Enter] to start building" x - echo "" - build_all - echo "" - echo "finished building." - echo "" - ;; -esac diff --git a/desktop/tauri/.cargo/config.toml b/desktop/tauri/.cargo/config.toml new file mode 100644 index 00000000..707bafa6 --- /dev/null +++ b/desktop/tauri/.cargo/config.toml @@ -0,0 +1,7 @@ +[target.aarch64-unknown-linux-gnu] +linker = "aarch64-linux-gnu-gcc" +rustflags = ["-C", "link-args=-L/usr/lib/aarch64-linux-gnu/"] + +[target.armv7-unknown-linux-gnueabihf] +linker = "arm-linux-gnueabihf-gcc" +rustflags = ["-C", "link-args=-L/usr/lib/arm-linux-gnueabihf/"] diff --git a/desktop/tauri/src-tauri/Cross.toml b/desktop/tauri/src-tauri/Cross.toml new file mode 100644 index 00000000..28e01087 --- /dev/null +++ b/desktop/tauri/src-tauri/Cross.toml @@ -0,0 +1,7 @@ +[target.aarch64-unknown-linux-gnu] +image = "ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main" + +pre-build = [ + "dpkg --add-architecture $CROSS_DEB_ARCH", + "apt-get update && apt-get --assume-yes install libssl-dev:$CROSS_DEB_ARCH libjavascriptcoregtk-4.0-dev:$CROSS_DEB_ARCH librsvg2-dev libayatana-appindicator3-dev libwebkit2gtk-4.0-dev libsoup2.4-dev libgtk-3-dev" +] diff --git a/desktop/tauri/src-tauri/src/xdg/mod.rs b/desktop/tauri/src-tauri/src/xdg/mod.rs index b1fa9089..a07dd47e 100644 --- a/desktop/tauri/src-tauri/src/xdg/mod.rs +++ b/desktop/tauri/src-tauri/src/xdg/mod.rs @@ -404,7 +404,7 @@ fn get_icon_as_png_dataurl(name: &str, size: i8) -> Result<(String, String)> { let icon_info = gtk_icon_theme_lookup_icon( GTK_DEFAULT_THEME.unwrap(), - c_str.as_ptr() as *const i8, + c_str.as_ptr() as *const u8, size as c_int, 0, ); diff --git a/desktop/tauri/src-tauri/tauri.conf.json b/desktop/tauri/src-tauri/tauri.conf.json index 0fca6f4f..fbdc6578 100644 --- a/desktop/tauri/src-tauri/tauri.conf.json +++ b/desktop/tauri/src-tauri/tauri.conf.json @@ -47,8 +47,8 @@ "depends": [] }, "externalBin": [ - "binaries/portmaster-start", - "binaries/portmaster-core" + "../binaries/portmaster-start", + "../binaries/portmaster-core" ], "icon": [ "../assets/icons/pm_dark_512.png",