diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..5034de96 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,13 @@ +Dockerfile +!server/go.mod +server/go.sum +server/NanoKVM-Server +web + +support/sg2002/kvm_system/build +support/sg2002/kvm_system/dist +support/sg2002/kvm_system/CMakeLists.txt + +support/sg2002/kvm_vision_test/build +support/sg2002/kvm_vision_test/dist +support/sg2002/kvm_vision_test/CMakeLists.txt \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..591d64b4 --- /dev/null +++ b/Makefile @@ -0,0 +1,97 @@ +# Makefile for NanoKVM Project + +# Configuration +IMAGE_NAME := nanokvm-builder +UID := $(shell id -u) +GID := $(shell id -g) +PWD := $(shell pwd) + +# Docker run common parameters +DOCKER_RUN_BASE := docker run -e UID=$(UID) -e GID=$(GID) -v $(PWD):/home/build/NanoKVM --rm + +# Build commands +GO_BUILD_CMD := cd /home/build/NanoKVM/server && go mod tidy && CGO_ENABLED=1 GOOS=linux GOARCH=riscv64 CC=riscv64-unknown-linux-musl-gcc CGO_CFLAGS="-mcpu=c906fdv -march=rv64imafdcv0p7xthead -mcmodel=medany -mabi=lp64d" go build +SUPPORT_BUILD_CMD := . ./home/build/MaixCDK/bin/activate && cd /home/build/NanoKVM/support/sg2002 && ./build kvm_system && ./build kvm_system add_to_kvmapp + +.PHONY: help check-root builder-image rebuild-image check-image shell app support all clean + +# Default target +all: app support + +# Help target +help: + @echo "NanoKVM Build System" + @echo "" + @echo "Available targets:" + @echo " help - Show this help message" + @echo " check-image - Check builder Docker image and show versions" + @echo " builder-image - Build Docker image if not exists" + @echo " rebuild-image - Force rebuild Docker image" + @echo " shell - Enter interactive builder environment" + @echo " app - Build Go application server" + @echo " support - Build hardware support libraries" + @echo " all - Build both app and support (default)" + @echo " clean - Clean build artifacts" + @echo "" + @echo "Prerequisites:" + @echo " - Docker must be installed and running" + @echo " - Must not run as root user" + +# Security check - prevent running as root +check-root: + @if [ "$$(id -u)" -eq 0 ]; then \ + echo "Can't run as root"; \ + exit 1; \ + fi + +# Check if builder image exists and show versions +check-image: check-root + @echo "Checking builder image..." + @echo "Golang version: " && \ + docker run --rm -i $(IMAGE_NAME) go version && \ + echo "" && \ + echo "Host-tools version:" && \ + docker run --rm -i $(IMAGE_NAME) riscv64-unknown-linux-musl-gcc -v && \ + echo "" + +# Build Docker image if it doesn't exist +builder-image: check-root + @if ! docker image inspect $(IMAGE_NAME) >/dev/null 2>&1; then \ + echo "Building Docker image..."; \ + docker build -t $(IMAGE_NAME) -f docker/Dockerfile ./; \ + else \ + echo "Docker image $(IMAGE_NAME) already exists."; \ + fi + +# Force rebuild Docker image +rebuild-image: check-root + @echo "Force rebuilding Docker image..." + @docker build --no-cache -t $(IMAGE_NAME) -f docker/Dockerfile ./ + +# Enter interactive shell (equivalent to build.sh with no arguments) +shell: check-root builder-image + @echo "Switching into builder..." + @$(DOCKER_RUN_BASE) -it $(IMAGE_NAME) /bin/bash -c ". ./home/build/MaixCDK/bin/activate && cd /home/build/NanoKVM ; exec bash" + +# Build Go application +app: check-root builder-image + @echo "Building app..." + @$(DOCKER_RUN_BASE) -it $(IMAGE_NAME) /bin/bash -c '$(GO_BUILD_CMD)' + +# Build hardware support libraries +support: check-root builder-image + @echo "Building support..." + @$(DOCKER_RUN_BASE) -it $(IMAGE_NAME) /bin/bash -c '$(SUPPORT_BUILD_CMD)' + +# Clean build artifacts +clean: + @echo "Cleaning build artifacts..." + @if [ -f server/NanoKVM-Server ]; then \ + rm -f server/NanoKVM-Server; \ + echo "Removed server/NanoKVM-Server"; \ + fi + @if [ -d support/sg2002/build ]; then \ + rm -rf support/sg2002/build; \ + echo "Removed support/sg2002/build"; \ + fi + @echo "Clean completed." \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 00000000..2519e56e --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,79 @@ +FROM ubuntu:24.04 AS base_apt + +# RUN echo 'Acquire::http::Proxy "http://cache.lan:3142";' > /etc/apt/apt.conf.d/00cacher +RUN userdel -r ubuntu +RUN apt update \ + && apt install wget git cmake build-essential python3 python3-venv python3-pip autoconf automake libtool gosu -y + +ARG DOCKER_USER=build +RUN useradd -m "$DOCKER_USER" +USER $DOCKER_USER + +FROM base_apt AS host_tools + +USER root +RUN wget -O /tmp/host-tools.tar.gz https://sophon-file.sophon.cn/sophon-prod-s3/drive/23/03/07/16/host-tools.tar.gz \ + && tar -C /usr/local -zxvf /tmp/host-tools.tar.gz \ + && rm -f /tmp/host-tools.tar.gz \ + && export PATH=$PATH:/usr/local/host-tools/gcc/riscv64-linux-musl-x86_64/bin \ + && echo "Installed host-tools gcc" && riscv64-unknown-linux-musl-gcc -v + +FROM base_apt AS golang + +USER root +RUN bash -c 'wget -O /tmp/go.tar.gz https://go.dev/dl/go1.25.0.linux-$([ `uname -m` == "x86_64" ] && echo "amd64" || uname -m).tar.gz' \ + && tar -C /usr/local -zxvf /tmp/go.tar.gz \ + && export PATH=$PATH:/usr/local/go/bin \ + && echo "Installed golang" && go version + +COPY server /tmp/go_cache + +ENV PATH="$PATH:/usr/local/go/bin" + +RUN cd /tmp/go_cache \ + && echo "Caching go dep" \ + && go mod download \ + && go mod tidy \ + && cd / \ + && rm -rf /tmp/go_cache + +FROM base_apt AS sdk + +RUN cd ~ \ + && git clone https://github.com/Sipeed/MaixCDK \ + && cd MaixCDK \ + && python3 -m venv . \ + && . ./bin/activate \ + && pip install -U -r requirements.txt + +COPY --chown=$DOCKER_USER . /home/$DOCKER_USER/NanoKVM + +RUN cd ~/MaixCDK \ + && . ./bin/activate \ + && cd ~/NanoKVM/support/sg2002 \ + && ./build kvm_system + +FROM base_apt + +# Install golang +COPY --from=golang /usr/local/go /usr/local/go +COPY --chown=$DOCKER_USER --from=golang /root/go /home/$DOCKER_USER/go +ENV PATH="$PATH:/usr/local/go/bin" + +# Install host tools +COPY --from=host_tools /usr/local/host-tools /usr/local/host-tools +ENV PATH="$PATH:/usr/local/host-tools/gcc/riscv64-linux-musl-x86_64/bin" + +# Install SDK +COPY --from=sdk /home/$DOCKER_USER/MaixCDK /home/$DOCKER_USER/MaixCDK +COPY --chmod=+x docker/entrypoint /entrypoint + +RUN echo "Verify build tools" \ + && echo "Installed host-tools gcc" && riscv64-unknown-linux-musl-gcc -v \ + && echo "Installed golang" && go version + +USER root +RUN chmod 0755 /entrypoint \ + && sed "s/\$DOCKER_USER/$DOCKER_USER/g" -i /entrypoint + +ENTRYPOINT ["/entrypoint"] \ No newline at end of file diff --git a/docker/entrypoint b/docker/entrypoint new file mode 100644 index 00000000..a0e48aa5 --- /dev/null +++ b/docker/entrypoint @@ -0,0 +1,22 @@ +#!/bin/sh + +set -e +set -u + +: "${UID:=0}" +: "${GID:=${UID}}" + +if [ "$#" = 0 ] +then set -- "$(command -v bash 2>/dev/null || command -v sh)" -l +fi + +if [ "$UID" != 0 ] +then + usermod -u "$UID" "$DOCKER_USER" 2>/dev/null && { + groupmod -g "$GID" "$DOCKER_USER" 2>/dev/null || + usermod -a -G "$GID" "$DOCKER_USER" + } + set -- gosu "${UID}:${GID}" "${@}" +fi + +exec "$@" \ No newline at end of file