Skip to content

Commit

Permalink
Clean up code and add comments to help contributors.
Browse files Browse the repository at this point in the history
  • Loading branch information
afinetooth committed Sep 19, 2024
1 parent 2dd37ae commit a8fddb8
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 13 deletions.
48 changes: 39 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# ---
# Special thanks to luislavena for this approach to cross-compiling Crystal apps with Zig.
# Source: https://forum.crystal-lang.org/t/cross-compiling-crystal-applications-part-1/6956
# Repo: https://github.com/luislavena/crystal-xbuild-container
# Background Crystal Lang Docs on:
# - Cross-Compilation: https://crystal-lang.org/reference/1.13/syntax_and_semantics/cross-compilation.html
# - Static Linking: https://crystal-lang.org/reference/1.13/guides/static_linking.html
#
# NOTE:
# We've modified the original approach here as necessary for coverage-reporter:
# - Installed additional dependencies for our target architectures
# - Made a few tweaks to address recurring issues with our target architectures
# - Populated our Makefile with convenience targets for our use case
# - Leveraging those targets to extended this approach to our CI/CD for releases
# ---

# Base image from luislavena's hydrofoil-crystal image
FROM ghcr.io/luislavena/hydrofoil-crystal:1.13 AS base

Expand Down Expand Up @@ -46,6 +62,10 @@ RUN --mount=type=cache,sharing=private,target=/var/cache/apk \

# ---
# Alpine Linux libraries for multi-arch cross-compilation
#
# NOTE:
# We are cross-compiling for `x86_64` and `aarch64` at this time.
# ---

# Set the library path to include both /lib and /opt/multiarch-libs
ENV LIBRARY_PATH="/lib:/opt/multiarch-libs/aarch64-linux-musl/lib:/opt/multiarch-libs/x86_64-linux-musl/lib"
Expand Down Expand Up @@ -104,27 +124,37 @@ RUN --mount=type=cache,sharing=private,target=/var/cache/apk \
cp $target_path/lib/libz.a /opt/multiarch-libs/x86_64-linux-musl/lib/; \
fi; \
# Verify the installed libz.a for each $target_arch
echo "DEBUG: Checking installed libz.a for $target_arch"; \
# echo "DEBUG: Checking installed libz.a for $target_arch"; \
ls -al /tmp/$target_arch-apk-chroot/lib/libz.a; \
# Debug: List the contents of $target_path/usr/lib/
echo "DEBUG: Listing contents of $target_path/usr/lib/"; \
# echo "DEBUG: Listing contents of $target_path/usr/lib/"; \
pkg_path="/opt/multiarch-libs/$target_arch-linux-musl"; \
ls -al $target_path/usr/lib/; \
mkdir -p $pkg_path/lib/pkgconfig; \
# copy the static libs & .pc files
cp $target_path/usr/lib/*.a $pkg_path/lib/; \
cp $target_path/usr/lib/pkgconfig/*.pc $pkg_path/lib/pkgconfig/; \
# Debug: List the contents of /opt/multiarch-libs/$target_arch-linux-musl/
echo "DEBUG: Installed libraries for $target_arch"; \
echo "DEBUG: Listing contents of $pkg_path"; \
# echo "DEBUG: Installed libraries for $target_arch"; \
# echo "DEBUG: Listing contents of $pkg_path"; \
ls -al $pkg_path/lib/; \
done; \
}

# ---
# macOS
# MacOS
#
# NOTE:
# We are not using this script to cross-compile for MacOS at this time
# (you'll notice we have no accompanying target in our Makefile for a MacOS build).
# Instead, we're continuing to leverage our Homebrew formula ("bottle") here: https://github.com/coverallsapp/homebrew-coveralls
# (which our `build.yml` workflow updates using the `homebrew-bump-formula` GitHub Action).
#
# That said, we're continuing to build the MacOS dependencies here in case we decide to
# switch to this method for cross-compiling MacOS binaries in the future.
# ---

# macOS dependencies are installed in separate target
# MacOS dependencies are installed in separate target
FROM base AS macos-packages
COPY ./scripts/homebrew-downloader.cr /homebrew-downloader.cr

Expand All @@ -150,11 +180,11 @@ RUN --mount=type=cache,sharing=private,target=/var/cache/apk \
; \
}

# copy macOS dependencies back into `base`
# Copy macOS dependencies back into `base`
FROM base
COPY --from=macos-packages /opt/multiarch-libs/aarch64-apple-darwin /opt/multiarch-libs/aarch64-apple-darwin

# install macOS SDK
# Install macOS SDK
RUN --mount=type=cache,sharing=private,target=/var/cache/apk \
--mount=type=tmpfs,target=/tmp \
set -eux -o pipefail; \
Expand All @@ -173,5 +203,5 @@ RUN --mount=type=cache,sharing=private,target=/var/cache/apk \
ln -nfs /opt/multiarch-libs/MacOSX${MACOS_SDK_VERSION}.sdk /opt/multiarch-libs/MacOSX${MACOS_SDK_MAJOR_VERSION}.sdk; \
}

# copy xbuild helper
# Copy xbuild helper
COPY ./scripts/xbuild.sh /usr/local/bin/xbuild
30 changes: 26 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@ BINARY_X86_64 := build/x86_64-linux-musl/coveralls-linux-x86_64
BINARY_LINUX := build/x86_64-linux-musl/coveralls-linux

DIST_DIR := dist
# Developers, if you intend to run these targets on on macOS,
# install gnu-tar with `brew install gnu-tar`as it supports the --transform option

# DEV NOTE:
# If you intend to run these targets on on MacOS, you'll want to install `gnu-tar` with `brew install gnu-tar`,
# since it supports the `--transform` option we use with `tar` below in our `package` target.
# Otherwise, on MacOS systems, this script will use `gtar` instead of `tar` and, if not installed,
# you can expect it to fail with a related error.
TAR := $(shell if [ $(shell uname) = Darwin ]; then echo gtar; else echo tar; fi)

# Targets for ci.yml (build and test app)
# ---
# Targets for `ci.yml` (standard CI: build & test app)
# ---

.PHONY: build
build:
shards build coveralls --progress --error-trace
Expand All @@ -29,7 +36,10 @@ test:
lint:
bin/ameba

# Targets for build.yml (cross-compile linux binaries for release)
# ---
# Targets for `build.yml` (build binaries for releases: `build-linux` job)
# ---

.PHONY: build-xbuild-container
build-xbuild-container: $(DOCKERFILE)
docker build -t ${IMAGE_NAME}:${VERSION} -f ${DOCKERFILE} .
Expand All @@ -42,6 +52,11 @@ run-xbuild-container: $(DOCKERFILE)
compile-x86_64:
docker run --rm -v $(shell pwd):/app -w /app ${IMAGE_NAME}:${VERSION} xbuild src/cli.cr coveralls-linux-x86_64 x86_64-linux-musl

# NOTE:
# There is a known, unavoidable warning that will appear in STDOUT when cross-compiling for `aarch64`.
# It's due to the version of `clang` used by `zig`. The warning is harmless and can be ignored.
# We're supposed to be able to suppress the warning with the `-Wno-deprecated-non-prototype` flag,
# but unfortunately, it doesn't work as expected. ZigLang tracking issue here: https://github.com/ziglang/zig/issues/13385
.PHONY: compile-aarch64
compile-aarch64:
docker run --rm -v $(shell pwd):/app -w /app ${IMAGE_NAME}:${VERSION} xbuild src/cli.cr coveralls-linux-aarch64 aarch64-linux-musl
Expand Down Expand Up @@ -74,7 +89,10 @@ package: $(DIST_DIR)
$(TAR) -czf $(DIST_DIR)/coveralls-$$arch.tar.gz -C $(DIST_DIR) --transform="s/coveralls-$$arch/coveralls/" coveralls-$$arch; \
done

# ---
# Test containers for different architectures
# ---

# Ubuntu 22.04 (amd64)
.PHONY: ubuntu-amd64
ubuntu-amd64:
Expand All @@ -85,6 +103,10 @@ ubuntu-amd64:
ubuntu-aarch64:
docker run -it --rm -u $(UUID):$(GUID) --platform linux/aarch64 -v .:/app -w /app ubuntu:22.04 bash -i

# ---
# Used for releasing new versions
# ---

# Creates and pushes new tag with annotation for new release
.ONESHELL:
new_version:
Expand Down
4 changes: 4 additions & 0 deletions scripts/xbuild.sh
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ esac
echo "Linking with: $libs"

# link the object_file with the supplied libraries
# NOTE:
# There is an unavoidable warning that appears in STDOUT when compiling for `aarch64`.
# The warning is harmless and can be ignored.
# See our comment above the `compile-aarch64` target in the Makefile for more info.
link_output=$(zig cc -target "$link_platform" -Wno-deprecated-non-prototype "$object_file" -o "$executable_name" $link_paths $libs)

if [ $? -ne 0 ]; then
Expand Down

0 comments on commit a8fddb8

Please sign in to comment.