diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index ffa49e9..1bc0d5f 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -1,7 +1,10 @@ name: Test bazel rules on: + pull_request: push: + branches: + - main workflow_call: inputs: use-built-toolchain: diff --git a/.github/workflows/build-toolchain.yml b/.github/workflows/build-toolchain.yml index 58ec442..21ab5d5 100644 --- a/.github/workflows/build-toolchain.yml +++ b/.github/workflows/build-toolchain.yml @@ -1,7 +1,10 @@ name: Build toolchain on: + pull_request: push: + branches: + - main workflow_dispatch: inputs: build_number: diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 89028b6..f807348 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -1,7 +1,10 @@ name: Test CMake rules on: + pull_request: push: + branches: + - main workflow_call: inputs: use-built-toolchain: diff --git a/.github/workflows/cmake_impl.yml b/.github/workflows/cmake_impl.yml index 8a65ff4..0b71a1d 100644 --- a/.github/workflows/cmake_impl.yml +++ b/.github/workflows/cmake_impl.yml @@ -38,6 +38,7 @@ jobs: run: | echo "PORTABLE_CC_TOOLCHAIN_LLVM=`pwd`/llvm-${{ inputs.host }}.tar.xz" >> $GITHUB_ENV echo "PORTABLE_CC_TOOLCHAIN_SYSROOT=`pwd`/sysroot-${{ inputs.target }}.tar.xz" >> $GITHUB_ENV + echo "PORTABLE_CC_TOOLCHAIN_COMPILER_RT_LINUX=`pwd`/compiler-rt-linux.tar.xz" >> $GITHUB_ENV - name: Build and Test (Debug) working-directory: cmake/test diff --git a/.gitignore b/.gitignore index 0fc0918..250893b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ bazel-* -wut-build-volume -.docker_cache +build diff --git a/scripts/Dockerfile.linux b/scripts/Dockerfile.linux new file mode 100644 index 0000000..8b5a43c --- /dev/null +++ b/scripts/Dockerfile.linux @@ -0,0 +1,31 @@ +FROM ubuntu:22.04 + +# Prevent interactive prompts during package installation +ENV DEBIAN_FRONTEND=noninteractive + +# Install crosstool-ng build dependencies +RUN apt-get update && apt-get install -y \ + cmake \ + build-essential \ + git \ + autoconf \ + automake \ + bison \ + flex \ + gawk \ + help2man \ + libncurses5-dev \ + libtool \ + libtool-bin \ + texinfo \ + unzip \ + wget \ + xz-utils \ + python3 \ + file \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /workspace/toolchain/gcc + +# Default command +CMD ["/bin/bash"] \ No newline at end of file diff --git a/scripts/dev b/scripts/dev new file mode 100755 index 0000000..94e3755 --- /dev/null +++ b/scripts/dev @@ -0,0 +1,78 @@ +#!/bin/bash +# Generic development script entrypoint + +set -e + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +COMMAND=$1 +shift || true + +# Show help +if [ -z "$COMMAND" ]; then + cat << 'EOF' +Usage: ./scripts/dev [docker] [args...] + +Commands: + build [args] Build CMake target + ct-ng:menuconfig Interactive GCC configuration + ct-ng:olddefconfig Update all GCC defconfigs + +Docker: + docker [args] Run command in Docker + docker shell Interactive Docker shell + +Examples: + ./scripts/dev build llvm-x86_64-unknown-linux-gnu + ./scripts/dev ct-ng:menuconfig x86_64-unknown-linux-gnu + ./scripts/dev docker build llvm-arm64-apple-macos + ./scripts/dev docker ct-ng:menuconfig x86_64-unknown-linux-gnu + ./scripts/dev docker shell + ./scripts/dev docker ct-ng --version +EOF + exit 1 +fi + +# Check if first arg is "docker" +if [ "$COMMAND" = "docker" ]; then + COMMAND=$1 + shift || true + [ -z "$COMMAND" ] && { echo "Error: docker requires a command" >&2; exit 1; } + + # Route commands through docker + case "$COMMAND" in + build) + exec "$SCRIPT_DIR/lib/docker-runner.sh" /workspace/scripts/lib/build.sh "$@" + ;; + ct-ng:menuconfig) + exec "$SCRIPT_DIR/lib/docker-runner.sh" /workspace/scripts/lib/ct-ng-menuconfig.sh "$@" + ;; + ct-ng:olddefconfig) + exec "$SCRIPT_DIR/lib/docker-runner.sh" /workspace/scripts/lib/ct-ng-olddefconfig.sh "$@" + ;; + shell) + exec "$SCRIPT_DIR/lib/docker-runner.sh" bash + ;; + *) + # Pass through arbitrary commands + exec "$SCRIPT_DIR/lib/docker-runner.sh" "$COMMAND" "$@" + ;; + esac +else + # Native execution + case "$COMMAND" in + build) + exec "$SCRIPT_DIR/lib/build.sh" "$@" + ;; + ct-ng:menuconfig) + exec "$SCRIPT_DIR/lib/ct-ng-menuconfig.sh" "$@" + ;; + ct-ng:olddefconfig) + exec "$SCRIPT_DIR/lib/ct-ng-olddefconfig.sh" "$@" + ;; + *) + echo "Error: Unknown command '$COMMAND'" >&2 + echo "Run './scripts/dev' for help" >&2 + exit 1 + ;; + esac +fi \ No newline at end of file diff --git a/scripts/lib/build.sh b/scripts/lib/build.sh new file mode 100755 index 0000000..f656312 --- /dev/null +++ b/scripts/lib/build.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# Build a CMake target + +set -e + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +source "$SCRIPT_DIR/common.sh" + +BUILD_DIR=${BUILD_DIR:-"build"} +TARGET=$1 +shift || true + +if [ -z "$TARGET" ]; then + echo "Usage: $0 [cmake-args...]" >&2 + exit 1 +fi + +ensure_cmake_configured toolchain +cmake_build_target "$TARGET" "$@" diff --git a/scripts/lib/common.sh b/scripts/lib/common.sh new file mode 100644 index 0000000..8cf518d --- /dev/null +++ b/scripts/lib/common.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Common functions for build scripts + +# Ensure CMake is configured, reconfiguring if needed +# Usage: ensure_cmake_configured [build_dir] +ensure_cmake_configured() { + local source_dir=$1 + local build_dir=${2:-${BUILD_DIR:-"build"}} + local cache="$build_dir/CMakeCache.txt" + + if [ ! -f "$cache" ] || \ + [ -n "$(find toolchain -name '*.cmake' -o -name 'CMakeLists.txt' -newer "$cache" 2>/dev/null)" ]; then + cmake -S "$source_dir" -B "$build_dir" + fi +} + +# Build a CMake target +# Usage: cmake_build_target [args...] +cmake_build_target() { + local target=$1 + shift || true + local build_dir=${BUILD_DIR:-"build"} + + cmake --build "$build_dir" --target "$target" "$@" +} \ No newline at end of file diff --git a/scripts/lib/ct-ng-menuconfig.sh b/scripts/lib/ct-ng-menuconfig.sh new file mode 100755 index 0000000..28da3e7 --- /dev/null +++ b/scripts/lib/ct-ng-menuconfig.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# Interactive configuration using crosstool-ng menuconfig + +set -e + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +source "$SCRIPT_DIR/common.sh" + +BUILD_DIR=${BUILD_DIR:-"build"} +GCC_DIR="toolchain/gcc" +TARGET=$1 + +if [ -z "$TARGET" ]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +TARGET_DIR="$GCC_DIR/targets/$TARGET" +if [ ! -d "$TARGET_DIR" ]; then + echo "Error: Target '$TARGET' not found in $GCC_DIR/targets/" >&2 + exit 1 +fi + +ensure_cmake_configured "$GCC_DIR" >/dev/null +cmake_build_target crosstool-ng >/dev/null + +CT_NG="$(pwd)/$BUILD_DIR/crosstool-ng-prefix/bin/ct-ng" + +# Run menuconfig workflow +WORK_DIR="$BUILD_DIR/$TARGET-menuconfig" +mkdir -p "$WORK_DIR" + +( + cd "$WORK_DIR" + cp "$TARGET_DIR/defconfig" defconfig + "$CT_NG" defconfig >/dev/null + "$CT_NG" menuconfig + "$CT_NG" savedefconfig >/dev/null + cp defconfig "$TARGET_DIR/defconfig" +) + +echo "✓ Updated $TARGET_DIR/defconfig" \ No newline at end of file diff --git a/scripts/lib/ct-ng-olddefconfig.sh b/scripts/lib/ct-ng-olddefconfig.sh new file mode 100755 index 0000000..a815f8a --- /dev/null +++ b/scripts/lib/ct-ng-olddefconfig.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# Update all defconfigs using crosstool-ng olddefconfig + +set -e + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +source "$SCRIPT_DIR/common.sh" + +BUILD_DIR=${BUILD_DIR:-"build"} +GCC_DIR="toolchain/gcc" + +TARGETS=($(ls -1 "$GCC_DIR/targets/" 2>/dev/null)) +[ ${#TARGETS[@]} -eq 0 ] && { echo "Error: No targets found" >&2; exit 1; } + +ensure_cmake_configured "$GCC_DIR" >/dev/null +cmake_build_target crosstool-ng >/dev/null + +CT_NG="$(pwd)/$BUILD_DIR/crosstool-ng-prefix/bin/ct-ng" + +for TARGET in "${TARGETS[@]}"; do + TARGET_DIR="$GCC_DIR/targets/$TARGET" + [ ! -f "$TARGET_DIR/defconfig" ] && continue + + WORK_DIR="$BUILD_DIR/$TARGET-defconfig-update" + mkdir -p "$WORK_DIR" + + cp "$TARGET_DIR/defconfig" "$WORK_DIR/defconfig" + + ( + cd "$WORK_DIR" + "$CT_NG" defconfig >/dev/null 2>&1 + "$CT_NG" olddefconfig >/dev/null 2>&1 + "$CT_NG" savedefconfig >/dev/null 2>&1 + ) || continue + + cp "$WORK_DIR/defconfig" "$TARGET_DIR/defconfig" + echo "✓ $TARGET" +done \ No newline at end of file diff --git a/scripts/lib/docker-runner.sh b/scripts/lib/docker-runner.sh new file mode 100755 index 0000000..81705f2 --- /dev/null +++ b/scripts/lib/docker-runner.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# Generic Docker wrapper for running commands in Linux environment + +set -e + +[ $# -eq 0 ] && { echo "Usage: $0 [args...]" >&2; exit 1; } + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" + +DOCKER_IMAGE=${DOCKER_IMAGE:-"cpp-toolchain-linux"} +DOCKERFILE="$PROJECT_ROOT/scripts/Dockerfile.linux" + +# Build Docker image if needed +docker image inspect "$DOCKER_IMAGE" >/dev/null 2>&1 || + docker build -f "$DOCKERFILE" -t "$DOCKER_IMAGE" "$PROJECT_ROOT/scripts" >/dev/null + +# Setup SSL certificate configuration +SSL_CONFIG=() +if [ -n "$SSL_CERT_FILE" ] && [ -f "$SSL_CERT_FILE" ]; then + SSL_CONFIG+=(-v "$SSL_CERT_FILE:$SSL_CERT_FILE:ro") + SSL_CONFIG+=(-e "SSL_CERT_FILE=$SSL_CERT_FILE") + SSL_CONFIG+=(-e "REQUESTS_CA_BUNDLE=$SSL_CERT_FILE") + SSL_CONFIG+=(-e "CURL_CA_BUNDLE=$SSL_CERT_FILE") + SSL_CONFIG+=(-e "GIT_SSL_CAINFO=$SSL_CERT_FILE") +fi + +# Run command +docker run -it --rm \ + -v "$PROJECT_ROOT:/workspace" \ + "${SSL_CONFIG[@]}" \ + -w /workspace \ + -e BUILD_DIR \ + "$DOCKER_IMAGE" \ + "$@" \ No newline at end of file diff --git a/toolchain/CMakeLists.txt b/toolchain/CMakeLists.txt index 3390d88..a3e5288 100644 --- a/toolchain/CMakeLists.txt +++ b/toolchain/CMakeLists.txt @@ -9,7 +9,7 @@ include(FetchContent) include(${CMAKE_SOURCE_DIR}/cmake/host-triple.cmake) # Download LLVM here, because we use it in multiple ExternalProjects -set(llvm_version 20.1.8) +set(llvm_version 22.1.8) string(REGEX MATCH "^([0-9]+)" llvm_major_version ${llvm_version}) FetchContent_Declare(llvm-source diff --git a/toolchain/gcc/CMakeLists.txt b/toolchain/gcc/CMakeLists.txt index c6ae1de..0ee662a 100644 --- a/toolchain/gcc/CMakeLists.txt +++ b/toolchain/gcc/CMakeLists.txt @@ -13,7 +13,7 @@ set(toolchain_targets ExternalProject_Add(crosstool-ng GIT_REPOSITORY https://github.com/crosstool-ng/crosstool-ng.git - GIT_TAG ec7070da386b6526d7fbd0246adcccb9cc095d8b + GIT_TAG 203a48cb11ebb39e288b386e9c35d99ab4e7714b UPDATE_COMMAND "" CONFIGURE_COMMAND ./bootstrap && ./configure --prefix=