diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..4bda5e9d --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,69 @@ +#!/usr/bin/env groovy + +pipeline { + agent { + docker { + image 'yeanwang/x-kernel-builder:v1.0' + args '-v /var/run/docker.sock:/var/run/docker.sock --privileged -u root:root' } + } + + environment { + CI = 'true' + TEST_HARNESS_REPO = 'https://gitee.com/openkylin/starry-test-harness' + TEST_HARNESS_BRANCH = 'master' + } + + stages { + stage('Parallel Architecture Verification') { + failFast true + parallel { + stage('Architecture: aarch64') { + steps { + script { executeBuildAndTest('aarch64') } + } + } + stage('Architecture: x86_64') { + steps { + script { executeBuildAndTest('x86_64') } + } + } + } + } + } + + post { + always { + archiveArtifacts artifacts: '**/artifacts/**/*', allowEmptyArchive: true + archiveArtifacts artifacts: '**/logs/**/*', allowEmptyArchive: true + cleanWs() + } + success { + updateGiteeCommitStatus state: 'success', context: 'ci/jenkins' + } + unsuccessful { + updateGiteeCommitStatus state: 'failed', context: 'ci/jenkins' + } + } +} + +def executeBuildAndTest(arch) { + ws("${WORKSPACE}/${arch}") { + echo "Verifying architecture: ${arch}" + + checkout scm + sh "git config --global --add safe.directory ${pwd()}" + dir('test-harness') { + git branch: "${env.TEST_HARNESS_BRANCH}", + url: "${env.TEST_HARNESS_REPO}", + credentialsId: 'gitee-my-token' + + sh "git config --global --add safe.directory ${pwd()}" + } + + dir('test-harness') { + withEnv(["XKERNEL_ROOT=${pwd()}/..", "ARCH=${arch}"]) { + sh "make ci-test run" + } + } + } +} diff --git a/Makefile b/Makefile index c7f2943f..0cc11aa3 100644 --- a/Makefile +++ b/Makefile @@ -94,6 +94,9 @@ GDB ?= gdb OUT_DIR ?= $(PWD) LD_SCRIPT ?= $(abspath $(TARGET_DIR)/$(TARGET)/$(MODE)/linker_$(PLAT_NAME).lds) +# Generate Rust const definitions from .config +CONFIG_RS := $(TARGET_DIR)/kbuild/config.rs + APP_NAME := xkernel OUT_ELF := $(OUT_DIR)/$(APP_NAME)_$(PLAT_NAME).elf OUT_BIN := $(patsubst %.elf,%.bin,$(OUT_ELF)) @@ -156,13 +159,18 @@ oldconfig: fi @xconf oldconfig -c .config -k Kconfig -s . -# Generate const definitions before build -gen-const: .config + +# 只在 .config 更新时才生成 +$(CONFIG_RS): .config @echo "📝 Generating Rust const definitions from .config..." @xconf gen-const @echo "✅ Generated config.rs" -build: gen-const $(OUT_DIR) $(FINAL_IMG) + +# Generate const definitions before build +gen-const: $(CONFIG_RS) + +build: $(CONFIG_RS) $(OUT_DIR) $(FINAL_IMG) disasm: $(OBJDUMP) $(OUT_ELF) | less @@ -180,7 +188,7 @@ debug: build -ex 'continue' \ -ex 'disp /16i $$pc' -clippy: gen-const +clippy: $(CONFIG_RS) ifeq ($(origin ARCH), command line) $(call cargo_clippy,--target $(TARGET)) else @@ -221,6 +229,8 @@ distclean: clean clean_c:: rm -rf $(app-objs) +# Note: gen-const is kept as PHONY to allow manual invocation, +# but the actual dependency is on $(CONFIG_RS) which is file-based .PHONY: all defconfig oldconfig menuconfig saveconfig gen-const \ build disasm run justrun debug \ clippy doc doc_check_missing fmt fmt_c unittest unittest_no_fail_fast \ diff --git a/scripts/make/deps.mk b/scripts/make/deps.mk index 5cadd336..2747b44d 100644 --- a/scripts/make/deps.mk +++ b/scripts/make/deps.mk @@ -1,10 +1,29 @@ # Necessary dependencies for the build system # Tool to generate xconfig -ifeq ($(shell xconfig --version 2>/dev/null),) - $(info Installing xconfig...) - $(shell cargo install --path xtask/xconfig) -endif +#ifeq ($(shell xconfig --version 2>/dev/null),) +# $(info Installing xconfig...) +# $(shell cargo install --path xtask/xconfig) +#endif + + +# xconf tool (the correct binary name is xconf, not xconfig) +XCONF_BIN := $(shell command -v xconf 2>/dev/null) +XCONF_SRC := $(shell find xtask/xconfig/src -type f -name '*.rs' 2>/dev/null) +XCONF_CARGO := xtask/xconfig/Cargo.toml + +# Only rebuild xconf if: +# 1. It doesn't exist, OR +# 2. Source files are newer than the binary +.PHONY: check-xconf +check-xconf: + @if [ -z "$(XCONF_BIN)" ]; then \ + echo "🔧 Installing xconf..."; \ + cargo install --path xtask/xconfig --force; \ + elif [ "$(XCONF_SRC)" -nt "$(XCONF_BIN)" ] || [ "$(XCONF_CARGO)" -nt "$(XCONF_BIN)" ]; then \ + echo "🔄 Updating xconf (source changed)..."; \ + cargo install --path xtask/xconfig --force; \ + fi # Cargo binutils ifeq ($(shell cargo install --list | grep cargo-binutils),)