diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..352df6e --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,96 @@ +# We build qemu in a separate stage to avoid installing a bunch of build dependencies in the final image +FROM fedora:latest AS qemu-builder + +RUN dnf update -y && \ + dnf install -y --setopt=keepcache=0 \ + @development-tools \ + git \ + clang \ + python3 \ + python3-pip \ + python3-setuptools \ + python3-wheel \ + ninja-build \ + clang \ + glib2-devel \ + flex \ + bison \ + zlib-devel \ + meson \ + pixman-devel \ + dtc && \ + ln -sf /usr/bin/clang /usr/bin/cc && \ + ln -sf /usr/bin/clang++ /usr/bin/c++ + +RUN git clone --depth 1 https://github.com/thomasw04/qemu.git /tmp/qemu && \ + cd /tmp/qemu && \ + python3 -m venv .venv && \ + . .venv/bin/activate && \ + pip install --no-cache-dir tomli sphinx && \ + mkdir build && cd build && \ + ../configure --disable-werror --extra-cflags="-Wno-error -fdeclspec" --target-list=arm-softmmu,arm-linux-user --enable-kvm && \ + make -j$(nproc) && \ + make install && \ + cd / && \ + rm -rf /tmp/qemu + +# This is the final image +FROM fedora:latest AS devcontainer + +RUN dnf update -y && \ + dnf install -y --setopt=keepcache=0 \ + @development-tools \ + direnv \ + arm-none-eabi-gcc-cs \ + arm-none-eabi-gcc-c++ \ + arm-none-eabi-newlib \ + cmake \ + git \ + make \ + clang \ + libusb1-devel \ + 'dnf-command(copr)' && \ + dnf copr enable -y rleh/arm-none-eabi-gdb && \ + dnf install -y --setopt=keepcache=0 arm-none-eabi-gdb && \ + dnf clean all && \ + ln -sf /usr/bin/clang /usr/bin/cc && \ + ln -sf /usr/bin/clang++ /usr/bin/c++ + +RUN git clone --single-branch --depth 1 -b "develop" https://github.com/stlink-org/stlink.git /tmp/stlink && \ + cd /tmp/stlink && \ + make -j release && \ + make install && \ + ldconfig && \ + rm -rf /tmp/stlink + +# Fix for Fedora not finding libstlink.so.1 +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64 + +# Set Rust environment variables +ENV RUSTUP_HOME=/usr/local/rustup +ENV CARGO_HOME=/usr/local/cargo +ENV PATH="/usr/local/cargo/bin:${PATH}" + +# Create directories with world-writable permissions before switching to non-root user +RUN mkdir -p ${RUSTUP_HOME} ${CARGO_HOME} && \ + chmod 1777 ${RUSTUP_HOME} ${CARGO_HOME} + +# The container now runs with a non-root user to avoid file permission issues +ARG USERNAME=vscode +RUN useradd -m -s /bin/bash ${USERNAME} && \ + echo "${USERNAME} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers + +WORKDIR /home/${USERNAME} +USER ${USERNAME} + +RUN umask 0002 && \ + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ + | sh -s -- -y --no-modify-path && \ + rustup update stable && \ + rustup component add rust-src llvm-tools-preview && \ + cargo install cargo-binutils && \ + rustup target add thumbv7em-none-eabihf thumbv7em-none-eabi + +COPY --from=qemu-builder /usr/local/ /usr/local/ + +ENTRYPOINT ["/bin/bash"] diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..2ea96a9 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,33 @@ +// For format details, see https://aka.ms/devcontainer.json. +{ + "name": "Osiris Dev Container", + "build": { + "dockerfile": "Dockerfile", + "context": ".." + }, + "remoteUser": "vscode", + "privileged": false, + "capAdd": [ + // Permissions for accessing host USB devices + "SYS_RAWIO", "CAP_MKNOD" + ], + "customizations": { + "vscode": { + "extensions": [ + "rust-lang.rust-analyzer", + "vadimcn.vscode-lldb", + "ms-vscode.cmake-tools", + "llvm-vs-code-extensions.vscode-clangd" + ] + } + }, + "runArgs": [ + // Mount USB devices under Linux + "--device", + "/dev/bus/usb:/dev/bus/usb" + ], + "mounts": [ + // Make ssh keys available + "source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind,consistency=cached" + ] +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..2f79d5a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,104 @@ +on: + push: + branches-ignore: + - "gh-readonly-queue/**" + pull_request: + merge_group: + workflow_dispatch: + +name: Osiris CI + +env: + CARGO_TERM_COLOR: always + TERM: xterm-256color + + +jobs: + container: + name: Build Container + runs-on: ubuntu-latest + permissions: + packages: write + outputs: + container_name: ${{ steps.set_output.outputs.container_name }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set container name as output + id: set_output + run: | + BRANCH=$(echo "${GITHUB_REF}" | sed 's|refs/heads/||' | tr '[:upper:]' '[:lower:]') + REPO=$(echo "${GITHUB_REPOSITORY}" | tr '[:upper:]' '[:lower:]') + CONTAINER_NAME="ghcr.io/${REPO}/devcontainer:${BRANCH//\//-}" + echo "container_name=$CONTAINER_NAME" >> $GITHUB_OUTPUT + + - name: Build and push Docker image + uses: docker/build-push-action@v2 + with: + context: .devcontainer + file: .devcontainer/Dockerfile + push: true + tags: ${{ steps.set_output.outputs.container_name }} + cache-from: type=registry,ref=${{ steps.set_output.outputs.container_name }}-cache + cache-to: type=registry,ref=${{ steps.set_output.outputs.container_name }}-cache,mode=max + + fmt: + name: Check formatting + needs: [container] + runs-on: ubuntu-latest + container: + image: ${{ needs.container.outputs.container_name }} + options: --user root + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + + # This step is required to generate some Cargo.toml files + - name: Run CMake + run: cmake -B build + + - name: Check formatting for all Cargo manifests + run: | + manifests=$(find . \( -path './build*' -o -path '*dep*' -o -path '*verus*' -o -path './target' \) -prune -false -o -name Cargo.toml) + failed=0 + for manifest in $manifests; do + echo "::group::Checking formatting for $manifest" + cargo fmt --manifest-path="$manifest" -- --check || failed=1 + echo "::endgroup::" + done + if [ $failed -ne 0 ]; then + echo "Formatting check failed for one or more manifests" + exit 1 + fi + + build-stm32l4r5zi: + name: Build for the STM32L4R5ZI + needs: [container] + runs-on: ubuntu-latest + container: + image: ${{ needs.container.outputs.container_name }} + options: --user root + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Run CMake + run: cmake -DBOARD=stm32-nucleo-l4r5zi -DCPU=cortex-m4 -B build + + - name: Build + run: cmake --build build --parallel $(nproc) diff --git a/.gitignore b/.gitignore index 467fd94..2988fc8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -build/ +build*/ .vscode/ qemu/ .venv/