CLKS拆分:第一步

This commit is contained in:
2026-04-23 19:30:12 +08:00
parent 5573ea1948
commit 3ed3f6acfe
8 changed files with 421 additions and 145 deletions

View File

@@ -27,6 +27,20 @@ set(READELF_FOR_TARGET "llvm-readelf" CACHE STRING "readelf tool for limine conf
set(QEMU_X86_64 "qemu-system-x86_64" CACHE STRING "QEMU executable") set(QEMU_X86_64 "qemu-system-x86_64" CACHE STRING "QEMU executable")
set(CLEONOS_SOURCE_DIR "${CMAKE_SOURCE_DIR}/cleonos")
if(EXISTS "${CLEONOS_SOURCE_DIR}/CMakeLists.txt")
set(_cleonos_enable_default ON)
else()
set(_cleonos_enable_default OFF)
endif()
set(CLEONOS_ENABLE ${_cleonos_enable_default} CACHE BOOL "Enable CLeonOS userland/ramdisk/iso integration")
if(CLEONOS_ENABLE AND NOT EXISTS "${CLEONOS_SOURCE_DIR}/CMakeLists.txt")
cl_log_error("CLEONOS_ENABLE=ON but missing ${CLEONOS_SOURCE_DIR}/CMakeLists.txt")
endif()
if(NOT CLEONOS_ENABLE)
cl_log_warn("CLEONOS_ENABLE=OFF, running in CLKS-only build mode")
endif()
set(LIMINE_DIR "limine" CACHE STRING "Limine source directory") set(LIMINE_DIR "limine" CACHE STRING "Limine source directory")
set(LIMINE_REPO "https://gh-proxy.com/https://github.com/limine-bootloader/limine.git" CACHE STRING "Limine git repository") set(LIMINE_REPO "https://gh-proxy.com/https://github.com/limine-bootloader/limine.git" CACHE STRING "Limine git repository")
set(LIMINE_REF "" CACHE STRING "Optional Limine branch or tag") set(LIMINE_REF "" CACHE STRING "Optional Limine branch or tag")
@@ -108,8 +122,10 @@ set(KERNEL_RUST_LIB "${BUILD_ROOT}/libclks_kernel_rust.a")
resolve_tool_with_fallback(CC gcc cc clang) resolve_tool_with_fallback(CC gcc cc clang)
resolve_tool_with_fallback(KERNEL_CXX g++ clang++ x86_64-elf-g++) resolve_tool_with_fallback(KERNEL_CXX g++ clang++ x86_64-elf-g++)
resolve_tool_with_fallback(LD ld.lld ld) resolve_tool_with_fallback(LD ld.lld ld)
resolve_tool_with_fallback(USER_CC cc gcc clang) if(CLEONOS_ENABLE)
resolve_tool_with_fallback(USER_LD ld.lld ld) resolve_tool_with_fallback(USER_CC cc gcc clang)
resolve_tool_with_fallback(USER_LD ld.lld ld)
endif()
resolve_tool_with_fallback(NM llvm-nm x86_64-elf-nm nm) resolve_tool_with_fallback(NM llvm-nm x86_64-elf-nm nm)
resolve_tool_with_fallback(ADDR2LINE llvm-addr2line x86_64-elf-addr2line addr2line) resolve_tool_with_fallback(ADDR2LINE llvm-addr2line x86_64-elf-addr2line addr2line)
resolve_tool_with_fallback(OBJCOPY_FOR_TARGET llvm-objcopy x86_64-linux-gnu-objcopy objcopy) resolve_tool_with_fallback(OBJCOPY_FOR_TARGET llvm-objcopy x86_64-linux-gnu-objcopy objcopy)
@@ -211,6 +227,13 @@ cl_set_bool_cache(CLEONOS_CLKS_ENABLE_SCHED_TASK_COUNT_LOG ON "Print scheduler t
cl_set_bool_cache(CLEONOS_CLKS_ENABLE_INTERRUPT_READY_LOG ON "Print interrupt ready log after IDT/PIC init") cl_set_bool_cache(CLEONOS_CLKS_ENABLE_INTERRUPT_READY_LOG ON "Print interrupt ready log after IDT/PIC init")
cl_set_bool_cache(CLEONOS_CLKS_ENABLE_SHELL_MODE_LOG ON "Print default shell mode log during boot") cl_set_bool_cache(CLEONOS_CLKS_ENABLE_SHELL_MODE_LOG ON "Print default shell mode log during boot")
if(NOT CLEONOS_ENABLE)
set(CLEONOS_CLKS_ENABLE_KELF OFF CACHE BOOL "Enable KELF app dispatcher" FORCE)
set(CLEONOS_CLKS_ENABLE_USERLAND_AUTO_EXEC OFF CACHE BOOL "Auto exec /shell/shell.elf on boot" FORCE)
set(CLEONOS_CLKS_ENABLE_USER_INIT_SCRIPT_PROBE OFF CACHE BOOL "Probe /shell/init.cmd during userland init" FORCE)
set(CLEONOS_CLKS_ENABLE_USER_SYSTEM_APP_PROBE OFF CACHE BOOL "Probe /system apps (elfrunner/memc) during userland init" FORCE)
endif()
cl_bool_to_int(CLEONOS_CLKS_ENABLE_AUDIO CLKS_CFG_AUDIO_INT) cl_bool_to_int(CLEONOS_CLKS_ENABLE_AUDIO CLKS_CFG_AUDIO_INT)
cl_bool_to_int(CLEONOS_CLKS_ENABLE_MOUSE CLKS_CFG_MOUSE_INT) cl_bool_to_int(CLEONOS_CLKS_ENABLE_MOUSE CLKS_CFG_MOUSE_INT)
cl_bool_to_int(CLEONOS_CLKS_ENABLE_DESKTOP CLKS_CFG_DESKTOP_INT) cl_bool_to_int(CLEONOS_CLKS_ENABLE_DESKTOP CLKS_CFG_DESKTOP_INT)
@@ -267,7 +290,6 @@ set(CFLAGS_COMMON
-Wextra -Wextra
-Werror -Werror
"-I${CMAKE_SOURCE_DIR}/clks/include" "-I${CMAKE_SOURCE_DIR}/clks/include"
"-I${CMAKE_SOURCE_DIR}/common/include"
) )
set(CXXFLAGS_COMMON set(CXXFLAGS_COMMON
@@ -284,7 +306,6 @@ set(CXXFLAGS_COMMON
-Wextra -Wextra
-Werror -Werror
"-I${CMAKE_SOURCE_DIR}/clks/include" "-I${CMAKE_SOURCE_DIR}/clks/include"
"-I${CMAKE_SOURCE_DIR}/common/include"
) )
set(ARCH_CFLAGS set(ARCH_CFLAGS
@@ -361,7 +382,6 @@ set(USER_CFLAGS
-Wextra -Wextra
-Werror -Werror
"-I${CMAKE_SOURCE_DIR}/cleonos/c/include" "-I${CMAKE_SOURCE_DIR}/cleonos/c/include"
"-I${CMAKE_SOURCE_DIR}/common/include"
) )
set(USER_CFLAGS_DOOM set(USER_CFLAGS_DOOM
@@ -377,7 +397,6 @@ set(USER_CFLAGS_DOOM
-Wno-sign-compare -Wno-sign-compare
-D_DEFAULT_SOURCE -D_DEFAULT_SOURCE
-D_POSIX_C_SOURCE=200809L -D_POSIX_C_SOURCE=200809L
"-I${CMAKE_SOURCE_DIR}/common/include"
"-I${CMAKE_SOURCE_DIR}/cleonos/third-party/doomgeneric/doomgeneric" "-I${CMAKE_SOURCE_DIR}/cleonos/third-party/doomgeneric/doomgeneric"
"-include" "-include"
"${CMAKE_SOURCE_DIR}/cleonos/c/apps/doom/doom_shim.h" "${CMAKE_SOURCE_DIR}/cleonos/c/apps/doom/doom_shim.h"
@@ -404,10 +423,13 @@ if(NOT CLKS_ARCH STREQUAL "x86_64")
endif() endif()
include("${CMAKE_SOURCE_DIR}/clks/CMakeLists.txt") include("${CMAKE_SOURCE_DIR}/clks/CMakeLists.txt")
include("${CMAKE_SOURCE_DIR}/cleonos/CMakeLists.txt") if(CLEONOS_ENABLE)
include("${CMAKE_SOURCE_DIR}/cleonos/CMakeLists.txt")
endif()
add_custom_target(setup-tools add_custom_target(setup-tools
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
"-DCLEONOS_ENABLE=${CLEONOS_ENABLE}"
"-DGIT_TOOL=${GIT_TOOL}" "-DGIT_TOOL=${GIT_TOOL}"
"-DTAR_TOOL=${TAR}" "-DTAR_TOOL=${TAR}"
"-DXORRISO_TOOL=${XORRISO}" "-DXORRISO_TOOL=${XORRISO}"
@@ -459,16 +481,17 @@ add_custom_command(
-P "${CL_LOG_EMIT_SCRIPT}" -P "${CL_LOG_EMIT_SCRIPT}"
) )
add_custom_target(disk-image if(CLEONOS_ENABLE)
add_custom_target(disk-image
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
"-DDISK_IMAGE=${DISK_IMAGE}" "-DDISK_IMAGE=${DISK_IMAGE}"
"-DDISK_MB=${CLEONOS_DISK_IMAGE_MB}" "-DDISK_MB=${CLEONOS_DISK_IMAGE_MB}"
-P "${CMAKE_SOURCE_DIR}/cmake/ensure_disk_image.cmake" -P "${CMAKE_SOURCE_DIR}/cmake/ensure_disk_image.cmake"
BYPRODUCTS "${DISK_IMAGE}" BYPRODUCTS "${DISK_IMAGE}"
VERBATIM VERBATIM
) )
add_custom_command( add_custom_command(
OUTPUT "${ISO_IMAGE}" OUTPUT "${ISO_IMAGE}"
COMMAND ${CMAKE_COMMAND} -E rm -rf "${ISO_ROOT}" COMMAND ${CMAKE_COMMAND} -E rm -rf "${ISO_ROOT}"
COMMAND ${CMAKE_COMMAND} -E make_directory "${ISO_ROOT}/boot/limine" "${ISO_ROOT}/EFI/BOOT" COMMAND ${CMAKE_COMMAND} -E make_directory "${ISO_ROOT}/boot/limine" "${ISO_ROOT}/EFI/BOOT"
@@ -511,12 +534,12 @@ add_custom_command(
-P "${CL_LOG_EMIT_SCRIPT}" -P "${CL_LOG_EMIT_SCRIPT}"
DEPENDS "${KERNEL_ELF}" "${RAMDISK_IMAGE}" "${CMAKE_SOURCE_DIR}/configs/limine.conf" DEPENDS "${KERNEL_ELF}" "${RAMDISK_IMAGE}" "${CMAKE_SOURCE_DIR}/configs/limine.conf"
VERBATIM VERBATIM
) )
add_custom_target(iso ALL DEPENDS "${ISO_IMAGE}") add_custom_target(iso ALL DEPENDS "${ISO_IMAGE}")
add_dependencies(iso setup-tools setup-limine kernel ramdisk) add_dependencies(iso setup-tools setup-limine kernel ramdisk)
add_custom_target(run add_custom_target(run
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
"-DNO_COLOR=${NO_COLOR}" "-DNO_COLOR=${NO_COLOR}"
"-DLOG_LEVEL=STEP" "-DLOG_LEVEL=STEP"
@@ -525,9 +548,9 @@ add_custom_target(run
COMMAND ${QEMU_X86_64} -M pc -m 1024M -boot order=d -cdrom "${ISO_IMAGE}" -drive "file=${DISK_IMAGE},format=raw,if=ide,index=0,media=disk" -serial stdio COMMAND ${QEMU_X86_64} -M pc -m 1024M -boot order=d -cdrom "${ISO_IMAGE}" -drive "file=${DISK_IMAGE},format=raw,if=ide,index=0,media=disk" -serial stdio
DEPENDS iso disk-image DEPENDS iso disk-image
USES_TERMINAL USES_TERMINAL
) )
add_custom_target(debug add_custom_target(debug
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
"-DNO_COLOR=${NO_COLOR}" "-DNO_COLOR=${NO_COLOR}"
"-DLOG_LEVEL=STEP" "-DLOG_LEVEL=STEP"
@@ -536,7 +559,10 @@ add_custom_target(debug
COMMAND ${QEMU_X86_64} -M pc -m 1024M -boot order=d -cdrom "${ISO_IMAGE}" -drive "file=${DISK_IMAGE},format=raw,if=ide,index=0,media=disk" -serial stdio -s -S COMMAND ${QEMU_X86_64} -M pc -m 1024M -boot order=d -cdrom "${ISO_IMAGE}" -drive "file=${DISK_IMAGE},format=raw,if=ide,index=0,media=disk" -serial stdio -s -S
DEPENDS iso disk-image DEPENDS iso disk-image
USES_TERMINAL USES_TERMINAL
) )
else()
add_custom_target(clks-default ALL DEPENDS kernel)
endif()
add_custom_target(clean-x86 add_custom_target(clean-x86
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
@@ -568,6 +594,7 @@ add_custom_target(clean-all
find_package(Python3 COMPONENTS Interpreter QUIET) find_package(Python3 COMPONENTS Interpreter QUIET)
if(Python3_Interpreter_FOUND) if(Python3_Interpreter_FOUND)
if(CLEONOS_ENABLE)
add_custom_target(menuconfig add_custom_target(menuconfig
COMMAND ${Python3_EXECUTABLE} "${CMAKE_SOURCE_DIR}/scripts/menuconfig.py" COMMAND ${Python3_EXECUTABLE} "${CMAKE_SOURCE_DIR}/scripts/menuconfig.py"
USES_TERMINAL USES_TERMINAL
@@ -576,6 +603,24 @@ if(Python3_Interpreter_FOUND)
COMMAND ${Python3_EXECUTABLE} "${CMAKE_SOURCE_DIR}/scripts/menuconfig.py" --gui COMMAND ${Python3_EXECUTABLE} "${CMAKE_SOURCE_DIR}/scripts/menuconfig.py" --gui
USES_TERMINAL USES_TERMINAL
) )
else()
add_custom_target(menuconfig
COMMAND ${Python3_EXECUTABLE} "${CMAKE_SOURCE_DIR}/scripts/menuconfig.py" --clks-only
USES_TERMINAL
)
add_custom_target(menuconfig-gui
COMMAND ${Python3_EXECUTABLE} "${CMAKE_SOURCE_DIR}/scripts/menuconfig.py" --gui --clks-only
USES_TERMINAL
)
endif()
add_custom_target(menuconfig-clks
COMMAND ${Python3_EXECUTABLE} "${CMAKE_SOURCE_DIR}/scripts/menuconfig.py" --clks-only
USES_TERMINAL
)
add_custom_target(menuconfig-gui-clks
COMMAND ${Python3_EXECUTABLE} "${CMAKE_SOURCE_DIR}/scripts/menuconfig.py" --gui --clks-only
USES_TERMINAL
)
else() else()
add_custom_target(menuconfig add_custom_target(menuconfig
COMMAND ${CMAKE_COMMAND} -E echo "python3 not found; run scripts/menuconfig.py manually" COMMAND ${CMAKE_COMMAND} -E echo "python3 not found; run scripts/menuconfig.py manually"
@@ -585,18 +630,45 @@ else()
COMMAND ${CMAKE_COMMAND} -E echo "python3 not found; run scripts/menuconfig.py --gui manually" COMMAND ${CMAKE_COMMAND} -E echo "python3 not found; run scripts/menuconfig.py --gui manually"
USES_TERMINAL USES_TERMINAL
) )
add_custom_target(menuconfig-clks
COMMAND ${CMAKE_COMMAND} -E echo "python3 not found; run scripts/menuconfig.py --clks-only manually"
USES_TERMINAL
)
add_custom_target(menuconfig-gui-clks
COMMAND ${CMAKE_COMMAND} -E echo "python3 not found; run scripts/menuconfig.py --gui --clks-only manually"
USES_TERMINAL
)
endif() endif()
add_custom_target(cleonos-help if(CLEONOS_ENABLE)
add_custom_target(cleonos-help
COMMAND ${CMAKE_COMMAND} -E echo "CLeonOS CMake build system (x86_64 only)" COMMAND ${CMAKE_COMMAND} -E echo "CLeonOS CMake build system (x86_64 only)"
COMMAND ${CMAKE_COMMAND} -E echo " CLEONOS_ENABLE=${CLEONOS_ENABLE}"
COMMAND ${CMAKE_COMMAND} -E echo " cmake -S . -B build-cmake" COMMAND ${CMAKE_COMMAND} -E echo " cmake -S . -B build-cmake"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target menuconfig" COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target menuconfig"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target menuconfig-gui" COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target menuconfig-gui"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target menuconfig-clks"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target menuconfig-gui-clks"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target setup" COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target setup"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target kernel"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target userapps" COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target userapps"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target iso" COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target iso"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target run" COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target run"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target debug" COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target debug"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target disk-image" COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target disk-image"
) )
else()
add_custom_target(cleonos-help
COMMAND ${CMAKE_COMMAND} -E echo "CLeonOS CMake build system (x86_64 only)"
COMMAND ${CMAKE_COMMAND} -E echo " CLEONOS_ENABLE=${CLEONOS_ENABLE}"
COMMAND ${CMAKE_COMMAND} -E echo " cmake -S . -B build-cmake"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target menuconfig"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target menuconfig-gui"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target menuconfig-clks"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target menuconfig-gui-clks"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target setup"
COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target kernel"
COMMAND ${CMAKE_COMMAND} -E echo " (CLKS-only mode: userapps/iso/run/debug/disk-image are disabled)"
)
endif()

View File

@@ -19,6 +19,7 @@ PYTHON ?= python3
MENUCONFIG_ARGS ?= MENUCONFIG_ARGS ?=
MENUCONFIG_PRESET ?= MENUCONFIG_PRESET ?=
DISK_IMAGE_MB ?= DISK_IMAGE_MB ?=
CLEONOS_ENABLE ?= auto
ifeq ($(strip $(CMAKE_GENERATOR)),) ifeq ($(strip $(CMAKE_GENERATOR)),)
GEN_ARG := GEN_ARG :=
@@ -28,6 +29,32 @@ endif
CMAKE_PASSTHROUGH_ARGS := CMAKE_PASSTHROUGH_ARGS :=
MENUCONFIG_PRESET_ARG := $(if $(strip $(MENUCONFIG_PRESET)),--preset $(MENUCONFIG_PRESET),) MENUCONFIG_PRESET_ARG := $(if $(strip $(MENUCONFIG_PRESET)),--preset $(MENUCONFIG_PRESET),)
CLEONOS_SOURCE_PRESENT := $(if $(wildcard cleonos/CMakeLists.txt),1,0)
ifeq ($(strip $(CLEONOS_ENABLE)),auto)
ifeq ($(CLEONOS_SOURCE_PRESENT),1)
CLEONOS_ENABLE_EFFECTIVE := ON
else
CLEONOS_ENABLE_EFFECTIVE := OFF
endif
else
CLEONOS_ENABLE_EFFECTIVE := $(CLEONOS_ENABLE)
endif
ifneq ($(filter 1 ON on TRUE true YES yes Y y,$(CLEONOS_ENABLE_EFFECTIVE)),)
CLEONOS_ENABLED_BOOL := 1
CLEONOS_MODE_LABEL := full
else
CLEONOS_ENABLED_BOOL := 0
CLEONOS_MODE_LABEL := clks-only
endif
MENUCONFIG_SCOPE_ARG :=
ifeq ($(CLEONOS_ENABLED_BOOL),0)
MENUCONFIG_SCOPE_ARG += --clks-only
endif
CMAKE_PASSTHROUGH_ARGS += -DCLEONOS_ENABLE=$(CLEONOS_ENABLE_EFFECTIVE)
ifneq ($(strip $(LIMINE_SKIP_CONFIGURE)),) ifneq ($(strip $(LIMINE_SKIP_CONFIGURE)),)
CMAKE_PASSTHROUGH_ARGS += -DLIMINE_SKIP_CONFIGURE=$(LIMINE_SKIP_CONFIGURE) CMAKE_PASSTHROUGH_ARGS += -DLIMINE_SKIP_CONFIGURE=$(LIMINE_SKIP_CONFIGURE)
@@ -57,38 +84,64 @@ ifneq ($(strip $(DISK_IMAGE_MB)),)
CMAKE_PASSTHROUGH_ARGS += -DCLEONOS_DISK_IMAGE_MB=$(DISK_IMAGE_MB) CMAKE_PASSTHROUGH_ARGS += -DCLEONOS_DISK_IMAGE_MB=$(DISK_IMAGE_MB)
endif endif
.PHONY: all configure reconfigure menuconfig menuconfig-gui setup setup-tools setup-limine kernel userapps ramdisk-root ramdisk disk-image iso run debug clean clean-all help .PHONY: all configure reconfigure menuconfig menuconfig-gui menuconfig-clks menuconfig-gui-clks setup setup-tools setup-limine kernel userapps ramdisk-root ramdisk disk-image iso run debug clean clean-all help
ifeq ($(CLEONOS_ENABLED_BOOL),1)
all: iso all: iso
else
all: kernel
endif
configure: configure:
> @$(CMAKE) -S . -B $(CMAKE_BUILD_DIR) $(GEN_ARG) -DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) -DNO_COLOR=$(NO_COLOR) $(CMAKE_EXTRA_ARGS) $(CMAKE_PASSTHROUGH_ARGS) > @$(CMAKE) -S . -B $(CMAKE_BUILD_DIR) $(GEN_ARG) -DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) -DNO_COLOR=$(NO_COLOR) $(CMAKE_EXTRA_ARGS) $(CMAKE_PASSTHROUGH_ARGS)
reconfigure: reconfigure:
> @rm -rf $(CMAKE_BUILD_DIR) > @rm -rf $(CMAKE_BUILD_DIR)
> @$(MAKE) configure CMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) CMAKE_GENERATOR="$(CMAKE_GENERATOR)" CMAKE_EXTRA_ARGS="$(CMAKE_EXTRA_ARGS)" NO_COLOR="$(NO_COLOR)" LIMINE_SKIP_CONFIGURE="$(LIMINE_SKIP_CONFIGURE)" LIMINE_REF="$(LIMINE_REF)" LIMINE_REPO="$(LIMINE_REPO)" LIMINE_DIR="$(LIMINE_DIR)" LIMINE_BIN_DIR="$(LIMINE_BIN_DIR)" OBJCOPY_FOR_TARGET="$(OBJCOPY_FOR_TARGET)" OBJDUMP_FOR_TARGET="$(OBJDUMP_FOR_TARGET)" READELF_FOR_TARGET="$(READELF_FOR_TARGET)" > @$(MAKE) configure CMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) CMAKE_GENERATOR="$(CMAKE_GENERATOR)" CMAKE_EXTRA_ARGS="$(CMAKE_EXTRA_ARGS)" NO_COLOR="$(NO_COLOR)" LIMINE_SKIP_CONFIGURE="$(LIMINE_SKIP_CONFIGURE)" LIMINE_REF="$(LIMINE_REF)" LIMINE_REPO="$(LIMINE_REPO)" LIMINE_DIR="$(LIMINE_DIR)" LIMINE_BIN_DIR="$(LIMINE_BIN_DIR)" OBJCOPY_FOR_TARGET="$(OBJCOPY_FOR_TARGET)" OBJDUMP_FOR_TARGET="$(OBJDUMP_FOR_TARGET)" READELF_FOR_TARGET="$(READELF_FOR_TARGET)" CLEONOS_ENABLE="$(CLEONOS_ENABLE)"
menuconfig: menuconfig:
> @if command -v $(PYTHON) >/dev/null 2>&1; then \ > @if command -v $(PYTHON) >/dev/null 2>&1; then \
> $(PYTHON) scripts/menuconfig.py $(MENUCONFIG_PRESET_ARG) $(MENUCONFIG_ARGS); \ > $(PYTHON) scripts/menuconfig.py $(MENUCONFIG_SCOPE_ARG) $(MENUCONFIG_PRESET_ARG) $(MENUCONFIG_ARGS); \
> elif command -v python >/dev/null 2>&1; then \ > elif command -v python >/dev/null 2>&1; then \
> python scripts/menuconfig.py $(MENUCONFIG_PRESET_ARG) $(MENUCONFIG_ARGS); \ > python scripts/menuconfig.py $(MENUCONFIG_SCOPE_ARG) $(MENUCONFIG_PRESET_ARG) $(MENUCONFIG_ARGS); \
> else \ > else \
> echo "python3/python not found"; \ > echo "python3/python not found"; \
> exit 1; \ > exit 1; \
> fi > fi
> @$(MAKE) configure CMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) CMAKE_GENERATOR="$(CMAKE_GENERATOR)" CMAKE_EXTRA_ARGS="$(CMAKE_EXTRA_ARGS)" NO_COLOR="$(NO_COLOR)" LIMINE_SKIP_CONFIGURE="$(LIMINE_SKIP_CONFIGURE)" LIMINE_REF="$(LIMINE_REF)" LIMINE_REPO="$(LIMINE_REPO)" LIMINE_DIR="$(LIMINE_DIR)" LIMINE_BIN_DIR="$(LIMINE_BIN_DIR)" OBJCOPY_FOR_TARGET="$(OBJCOPY_FOR_TARGET)" OBJDUMP_FOR_TARGET="$(OBJDUMP_FOR_TARGET)" READELF_FOR_TARGET="$(READELF_FOR_TARGET)" > @$(MAKE) configure CMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) CMAKE_GENERATOR="$(CMAKE_GENERATOR)" CMAKE_EXTRA_ARGS="$(CMAKE_EXTRA_ARGS)" NO_COLOR="$(NO_COLOR)" LIMINE_SKIP_CONFIGURE="$(LIMINE_SKIP_CONFIGURE)" LIMINE_REF="$(LIMINE_REF)" LIMINE_REPO="$(LIMINE_REPO)" LIMINE_DIR="$(LIMINE_DIR)" LIMINE_BIN_DIR="$(LIMINE_BIN_DIR)" OBJCOPY_FOR_TARGET="$(OBJCOPY_FOR_TARGET)" OBJDUMP_FOR_TARGET="$(OBJDUMP_FOR_TARGET)" READELF_FOR_TARGET="$(READELF_FOR_TARGET)" CLEONOS_ENABLE="$(CLEONOS_ENABLE)"
menuconfig-gui: menuconfig-gui:
> @if command -v $(PYTHON) >/dev/null 2>&1; then \ > @if command -v $(PYTHON) >/dev/null 2>&1; then \
> $(PYTHON) scripts/menuconfig.py --gui $(MENUCONFIG_PRESET_ARG) $(MENUCONFIG_ARGS); \ > $(PYTHON) scripts/menuconfig.py --gui $(MENUCONFIG_SCOPE_ARG) $(MENUCONFIG_PRESET_ARG) $(MENUCONFIG_ARGS); \
> elif command -v python >/dev/null 2>&1; then \ > elif command -v python >/dev/null 2>&1; then \
> python scripts/menuconfig.py --gui $(MENUCONFIG_PRESET_ARG) $(MENUCONFIG_ARGS); \ > python scripts/menuconfig.py --gui $(MENUCONFIG_SCOPE_ARG) $(MENUCONFIG_PRESET_ARG) $(MENUCONFIG_ARGS); \
> else \ > else \
> echo "python3/python not found"; \ > echo "python3/python not found"; \
> exit 1; \ > exit 1; \
> fi > fi
> @$(MAKE) configure CMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) CMAKE_GENERATOR="$(CMAKE_GENERATOR)" CMAKE_EXTRA_ARGS="$(CMAKE_EXTRA_ARGS)" NO_COLOR="$(NO_COLOR)" LIMINE_SKIP_CONFIGURE="$(LIMINE_SKIP_CONFIGURE)" LIMINE_REF="$(LIMINE_REF)" LIMINE_REPO="$(LIMINE_REPO)" LIMINE_DIR="$(LIMINE_DIR)" LIMINE_BIN_DIR="$(LIMINE_BIN_DIR)" OBJCOPY_FOR_TARGET="$(OBJCOPY_FOR_TARGET)" OBJDUMP_FOR_TARGET="$(OBJDUMP_FOR_TARGET)" READELF_FOR_TARGET="$(READELF_FOR_TARGET)" > @$(MAKE) configure CMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) CMAKE_GENERATOR="$(CMAKE_GENERATOR)" CMAKE_EXTRA_ARGS="$(CMAKE_EXTRA_ARGS)" NO_COLOR="$(NO_COLOR)" LIMINE_SKIP_CONFIGURE="$(LIMINE_SKIP_CONFIGURE)" LIMINE_REF="$(LIMINE_REF)" LIMINE_REPO="$(LIMINE_REPO)" LIMINE_DIR="$(LIMINE_DIR)" LIMINE_BIN_DIR="$(LIMINE_BIN_DIR)" OBJCOPY_FOR_TARGET="$(OBJCOPY_FOR_TARGET)" OBJDUMP_FOR_TARGET="$(OBJDUMP_FOR_TARGET)" READELF_FOR_TARGET="$(READELF_FOR_TARGET)" CLEONOS_ENABLE="$(CLEONOS_ENABLE)"
menuconfig-clks:
> @if command -v $(PYTHON) >/dev/null 2>&1; then \
> $(PYTHON) scripts/menuconfig.py --clks-only $(MENUCONFIG_PRESET_ARG) $(MENUCONFIG_ARGS); \
> elif command -v python >/dev/null 2>&1; then \
> python scripts/menuconfig.py --clks-only $(MENUCONFIG_PRESET_ARG) $(MENUCONFIG_ARGS); \
> else \
> echo "python3/python not found"; \
> exit 1; \
> fi
> @$(MAKE) configure CMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) CMAKE_GENERATOR="$(CMAKE_GENERATOR)" CMAKE_EXTRA_ARGS="$(CMAKE_EXTRA_ARGS)" NO_COLOR="$(NO_COLOR)" LIMINE_SKIP_CONFIGURE="$(LIMINE_SKIP_CONFIGURE)" LIMINE_REF="$(LIMINE_REF)" LIMINE_REPO="$(LIMINE_REPO)" LIMINE_DIR="$(LIMINE_DIR)" LIMINE_BIN_DIR="$(LIMINE_BIN_DIR)" OBJCOPY_FOR_TARGET="$(OBJCOPY_FOR_TARGET)" OBJDUMP_FOR_TARGET="$(OBJDUMP_FOR_TARGET)" READELF_FOR_TARGET="$(READELF_FOR_TARGET)" CLEONOS_ENABLE="$(CLEONOS_ENABLE)"
menuconfig-gui-clks:
> @if command -v $(PYTHON) >/dev/null 2>&1; then \
> $(PYTHON) scripts/menuconfig.py --gui --clks-only $(MENUCONFIG_PRESET_ARG) $(MENUCONFIG_ARGS); \
> elif command -v python >/dev/null 2>&1; then \
> python scripts/menuconfig.py --gui --clks-only $(MENUCONFIG_PRESET_ARG) $(MENUCONFIG_ARGS); \
> else \
> echo "python3/python not found"; \
> exit 1; \
> fi
> @$(MAKE) configure CMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) CMAKE_GENERATOR="$(CMAKE_GENERATOR)" CMAKE_EXTRA_ARGS="$(CMAKE_EXTRA_ARGS)" NO_COLOR="$(NO_COLOR)" LIMINE_SKIP_CONFIGURE="$(LIMINE_SKIP_CONFIGURE)" LIMINE_REF="$(LIMINE_REF)" LIMINE_REPO="$(LIMINE_REPO)" LIMINE_DIR="$(LIMINE_DIR)" LIMINE_BIN_DIR="$(LIMINE_BIN_DIR)" OBJCOPY_FOR_TARGET="$(OBJCOPY_FOR_TARGET)" OBJDUMP_FOR_TARGET="$(OBJDUMP_FOR_TARGET)" READELF_FOR_TARGET="$(READELF_FOR_TARGET)" CLEONOS_ENABLE="$(CLEONOS_ENABLE)"
setup: configure setup: configure
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target setup > @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target setup
@@ -102,6 +155,7 @@ setup-limine: configure
kernel: configure kernel: configure
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target kernel > @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target kernel
ifeq ($(CLEONOS_ENABLED_BOOL),1)
userapps: configure userapps: configure
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target userapps > @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target userapps
@@ -122,6 +176,11 @@ run: configure
debug: configure debug: configure
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target debug > @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target debug
else
userapps ramdisk-root ramdisk disk-image iso run debug:
> @echo "target '$@' requires CLEONOS_ENABLE=ON and cleonos sources present"
> @exit 1
endif
clean: clean:
> @if [ -d "$(CMAKE_BUILD_DIR)" ]; then \ > @if [ -d "$(CMAKE_BUILD_DIR)" ]; then \
@@ -139,9 +198,12 @@ clean-all:
help: help:
> @echo "CLeonOS (CMake-backed wrapper)" > @echo "CLeonOS (CMake-backed wrapper)"
> @echo "Mode: CLEONOS_ENABLE=$(CLEONOS_ENABLE_EFFECTIVE) ($(CLEONOS_MODE_LABEL))"
> @echo " make configure" > @echo " make configure"
> @echo " make menuconfig" > @echo " make menuconfig"
> @echo " make menuconfig-gui" > @echo " make menuconfig-gui"
> @echo " make menuconfig-clks"
> @echo " make menuconfig-gui-clks"
> @echo " make setup" > @echo " make setup"
> @echo " make userapps" > @echo " make userapps"
> @echo " make disk-image" > @echo " make disk-image"
@@ -155,6 +217,9 @@ help:
> @echo " make configure CMAKE_EXTRA_ARGS='-DLIMINE_SKIP_CONFIGURE=1 -DOBJCOPY_FOR_TARGET=objcopy'" > @echo " make configure CMAKE_EXTRA_ARGS='-DLIMINE_SKIP_CONFIGURE=1 -DOBJCOPY_FOR_TARGET=objcopy'"
> @echo "Direct passthrough is also supported:" > @echo "Direct passthrough is also supported:"
> @echo " make run LIMINE_SKIP_CONFIGURE=1" > @echo " make run LIMINE_SKIP_CONFIGURE=1"
> @echo "Kernel-only mode:"
> @echo " make kernel CLEONOS_ENABLE=OFF"
> @echo " make -C clks kernel"
> @echo "Disk image size example:" > @echo "Disk image size example:"
> @echo " make run DISK_IMAGE_MB=128" > @echo " make run DISK_IMAGE_MB=128"
> @echo "Preset examples:" > @echo "Preset examples:"

View File

@@ -1,7 +1,6 @@
#ifndef CLEONOS_VERSION_H #ifndef CLEONOS_VERSION_H
#define CLEONOS_VERSION_H #define CLEONOS_VERSION_H
#define CLKS_VERSION_STRING "1.0.0-alpha"
#define CLEONOS_VERSION_STRING "1.0.0-alpha" #define CLEONOS_VERSION_STRING "1.0.0-alpha"
#endif #endif

47
clks/Makefile Normal file
View File

@@ -0,0 +1,47 @@
.RECIPEPREFIX := >
MAKEFLAGS += --no-print-directory
ROOT_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))/..)
.PHONY: all configure reconfigure kernel menuconfig menuconfig-gui setup setup-tools setup-limine clean clean-all help
all: kernel
configure:
> @$(MAKE) -C "$(ROOT_DIR)" CLEONOS_ENABLE=OFF configure
reconfigure:
> @$(MAKE) -C "$(ROOT_DIR)" CLEONOS_ENABLE=OFF reconfigure
kernel:
> @$(MAKE) -C "$(ROOT_DIR)" CLEONOS_ENABLE=OFF kernel
menuconfig:
> @$(MAKE) -C "$(ROOT_DIR)" CLEONOS_ENABLE=OFF menuconfig-clks
menuconfig-gui:
> @$(MAKE) -C "$(ROOT_DIR)" CLEONOS_ENABLE=OFF menuconfig-gui-clks
setup:
> @$(MAKE) -C "$(ROOT_DIR)" CLEONOS_ENABLE=OFF setup
setup-tools:
> @$(MAKE) -C "$(ROOT_DIR)" CLEONOS_ENABLE=OFF setup-tools
setup-limine:
> @$(MAKE) -C "$(ROOT_DIR)" CLEONOS_ENABLE=OFF setup-limine
clean:
> @$(MAKE) -C "$(ROOT_DIR)" CLEONOS_ENABLE=OFF clean
clean-all:
> @$(MAKE) -C "$(ROOT_DIR)" CLEONOS_ENABLE=OFF clean-all
help:
> @echo "CLKS standalone wrapper"
> @echo " make -C clks kernel"
> @echo " make -C clks menuconfig"
> @echo " make -C clks menuconfig-gui"
> @echo " make -C clks configure"
> @echo " make -C clks clean"
> @echo " make -C clks clean-all"

View File

@@ -0,0 +1,6 @@
#ifndef CLKS_VERSION_H
#define CLKS_VERSION_H
#define CLKS_VERSION_STRING "1.0.0-alpha"
#endif

View File

@@ -17,7 +17,7 @@
#include <clks/tty.h> #include <clks/tty.h>
#include <clks/types.h> #include <clks/types.h>
#include <clks/userland.h> #include <clks/userland.h>
#include <cleonos_version.h> #include <clks/version.h>
/* Yes, this file is a syscall kitchen sink and nobody is pretending otherwise. */ /* Yes, this file is a syscall kitchen sink and nobody is pretending otherwise. */

View File

@@ -20,10 +20,11 @@ function(require_tool TOOL_VALUE)
endfunction() endfunction()
cl_log_step("checking host tools") cl_log_step("checking host tools")
if(NOT DEFINED CLEONOS_ENABLE)
set(CLEONOS_ENABLE ON)
endif()
require_tool("${GIT_TOOL}") require_tool("${GIT_TOOL}")
require_tool("${TAR_TOOL}")
require_tool("${XORRISO_TOOL}")
require_tool("${CC_TOOL}") require_tool("${CC_TOOL}")
require_tool("${LD_TOOL}") require_tool("${LD_TOOL}")
require_tool("${OBJCOPY_TOOL}") require_tool("${OBJCOPY_TOOL}")
@@ -31,10 +32,14 @@ require_tool("${OBJDUMP_TOOL}")
require_tool("${READELF_TOOL}") require_tool("${READELF_TOOL}")
require_tool("${NM_TOOL}") require_tool("${NM_TOOL}")
require_tool("${ADDR2LINE_TOOL}") require_tool("${ADDR2LINE_TOOL}")
require_tool("${USER_CC_TOOL}")
require_tool("${USER_LD_TOOL}")
require_tool("${RUSTC_TOOL}") require_tool("${RUSTC_TOOL}")
require_tool("${MAKE_TOOL}") require_tool("${MAKE_TOOL}")
require_tool("${SH_TOOL}") require_tool("${SH_TOOL}")
if(CLEONOS_ENABLE)
require_tool("${TAR_TOOL}")
require_tool("${XORRISO_TOOL}")
require_tool("${USER_CC_TOOL}")
require_tool("${USER_LD_TOOL}")
endif()
cl_log_info("required tools are available") cl_log_info("required tools are available")

View File

@@ -5,6 +5,10 @@ CLeonOS menuconfig
Interactive feature selector that writes: Interactive feature selector that writes:
- configs/menuconfig/.config.json - configs/menuconfig/.config.json
- configs/menuconfig/config.cmake - configs/menuconfig/config.cmake
- configs/menuconfig/.config.clks.json
- configs/menuconfig/config.clks.cmake
- configs/menuconfig/.config.cleonos.json
- configs/menuconfig/config.cleonos.cmake
Design: Design:
- CLKS options come from configs/menuconfig/clks_features.json - CLKS options come from configs/menuconfig/clks_features.json
@@ -44,6 +48,10 @@ MENUCONFIG_DIR = ROOT_DIR / "configs" / "menuconfig"
CLKS_FEATURES_PATH = MENUCONFIG_DIR / "clks_features.json" CLKS_FEATURES_PATH = MENUCONFIG_DIR / "clks_features.json"
CONFIG_JSON_PATH = MENUCONFIG_DIR / ".config.json" CONFIG_JSON_PATH = MENUCONFIG_DIR / ".config.json"
CONFIG_CMAKE_PATH = MENUCONFIG_DIR / "config.cmake" CONFIG_CMAKE_PATH = MENUCONFIG_DIR / "config.cmake"
CONFIG_CLKS_JSON_PATH = MENUCONFIG_DIR / ".config.clks.json"
CONFIG_CLEONOS_JSON_PATH = MENUCONFIG_DIR / ".config.cleonos.json"
CONFIG_CLKS_CMAKE_PATH = MENUCONFIG_DIR / "config.clks.cmake"
CONFIG_CLEONOS_CMAKE_PATH = MENUCONFIG_DIR / "config.cleonos.cmake"
@dataclass(frozen=True) @dataclass(frozen=True)
@@ -388,11 +396,11 @@ def discover_user_apps() -> List[OptionItem]:
return options return options
def load_previous_values() -> Dict[str, int]: def _load_values_from_json(path: Path) -> Dict[str, int]:
if not CONFIG_JSON_PATH.exists(): if not path.exists():
return {} return {}
try: try:
raw = json.loads(CONFIG_JSON_PATH.read_text(encoding="utf-8")) raw = json.loads(path.read_text(encoding="utf-8"))
except Exception: except Exception:
return {} return {}
@@ -407,6 +415,16 @@ def load_previous_values() -> Dict[str, int]:
return out return out
def load_previous_values(include_user: bool) -> Dict[str, int]:
out: Dict[str, int] = {}
# Merge order: legacy combined -> split CLKS -> split CLeonOS.
out.update(_load_values_from_json(CONFIG_JSON_PATH))
out.update(_load_values_from_json(CONFIG_CLKS_JSON_PATH))
if include_user:
out.update(_load_values_from_json(CONFIG_CLEONOS_JSON_PATH))
return out
def init_values(options: Iterable[OptionItem], previous: Dict[str, int], use_defaults: bool) -> Dict[str, int]: def init_values(options: Iterable[OptionItem], previous: Dict[str, int], use_defaults: bool) -> Dict[str, int]:
values: Dict[str, int] = {} values: Dict[str, int] = {}
for item in options: for item in options:
@@ -1368,12 +1386,15 @@ def _run_ncurses_main(stdscr, clks_options: List[OptionItem], user_options: List
total_items = len(clks_options) + len(user_options) total_items = len(clks_options) + len(user_options)
total_on = clks_on + user_on total_on = clks_on + user_on
items = [ menu_entries: List[Tuple[str, str]] = [
f"CLKS features ({clks_on}/{len(clks_options)} enabled)", ("clks", f"CLKS features ({clks_on}/{len(clks_options)} enabled)"),
f"User apps ({user_on}/{len(user_options)} enabled)",
"Save and Exit",
"Quit without Saving",
] ]
if user_options:
menu_entries.append(("user", f"User apps ({user_on}/{len(user_options)} enabled)"))
else:
menu_entries.append(("user-disabled", "User apps (CLKS-only mode)"))
menu_entries.append(("save", "Save and Exit"))
menu_entries.append(("quit", "Quit without Saving"))
if h < 12 or w < 58: if h < 12 or w < 58:
_safe_addnstr(stdscr, 0, 0, "Terminal too small for menuconfig (need >= 58x12).", theme["status_warn"]) _safe_addnstr(stdscr, 0, 0, "Terminal too small for menuconfig (need >= 58x12).", theme["status_warn"])
@@ -1387,7 +1408,7 @@ def _run_ncurses_main(stdscr, clks_options: List[OptionItem], user_options: List
_draw_box(stdscr, 2, 0, h - 5, w, "Main", theme["panel_border"], theme["panel_title"]) _draw_box(stdscr, 2, 0, h - 5, w, "Main", theme["panel_border"], theme["panel_title"])
base = 4 base = 4
for i, text in enumerate(items): for i, (_action, text) in enumerate(menu_entries):
prefix = ">" if i == selected else " " prefix = ">" if i == selected else " "
row_text = f"{prefix} {text}" row_text = f"{prefix} {text}"
attr = theme["selected"] if i == selected else theme["value_label"] attr = theme["selected"] if i == selected else theme["value_label"]
@@ -1406,7 +1427,10 @@ def _run_ncurses_main(stdscr, clks_options: List[OptionItem], user_options: List
) )
_safe_addnstr(stdscr, h - 2, 0, " Arrows/jk move Enter select s save q quit ", theme["help"]) _safe_addnstr(stdscr, h - 2, 0, " Arrows/jk move Enter select s save q quit ", theme["help"])
if user_options:
_safe_addnstr(stdscr, h - 1, 0, " Tip: open CLKS/USER section then use Space to toggle options. ", theme["help"]) _safe_addnstr(stdscr, h - 1, 0, " Tip: open CLKS/USER section then use Space to toggle options. ", theme["help"])
else:
_safe_addnstr(stdscr, h - 1, 0, " Tip: CLKS-only mode, open CLKS section then use Space to toggle options. ", theme["help"])
stdscr.refresh() stdscr.refresh()
key = stdscr.getch() key = stdscr.getch()
@@ -1416,20 +1440,23 @@ def _run_ncurses_main(stdscr, clks_options: List[OptionItem], user_options: List
if key in (ord("s"), ord("S")): if key in (ord("s"), ord("S")):
return True return True
if key in (curses.KEY_UP, ord("k"), ord("K")): if key in (curses.KEY_UP, ord("k"), ord("K")):
selected = (selected - 1) % len(items) selected = (selected - 1) % len(menu_entries)
continue continue
if key in (curses.KEY_DOWN, ord("j"), ord("J")): if key in (curses.KEY_DOWN, ord("j"), ord("J")):
selected = (selected + 1) % len(items) selected = (selected + 1) % len(menu_entries)
continue continue
if key in (curses.KEY_ENTER, 10, 13): if key in (curses.KEY_ENTER, 10, 13):
if selected == 0: action = menu_entries[selected][0]
if action == "clks":
_run_ncurses_grouped_section(stdscr, theme, "CLKS", clks_options, all_options, values) _run_ncurses_grouped_section(stdscr, theme, "CLKS", clks_options, all_options, values)
elif selected == 1: elif action == "user":
_run_ncurses_section(stdscr, theme, "USER", user_options, all_options, values) _run_ncurses_section(stdscr, theme, "USER", user_options, all_options, values)
elif selected == 2: elif action == "save":
return True return True
else: elif action == "quit":
return False return False
else:
continue
continue continue
@@ -1501,7 +1528,10 @@ def interactive_menu_gui(clks_options: List[OptionItem], user_options: List[Opti
header_title.setFont(header_font) header_title.setFont(header_font)
root_layout.addWidget(header_title) root_layout.addWidget(header_title)
if user_options:
root_layout.addWidget(QtWidgets.QLabel("Window mode (PySide): configure CLKS features and user apps, then save.")) root_layout.addWidget(QtWidgets.QLabel("Window mode (PySide): configure CLKS features and user apps, then save."))
else:
root_layout.addWidget(QtWidgets.QLabel("Window mode (PySide): CLKS-only mode (user app options unavailable)."))
summary_label = QtWidgets.QLabel("") summary_label = QtWidgets.QLabel("")
root_layout.addWidget(summary_label) root_layout.addWidget(summary_label)
@@ -1743,8 +1773,9 @@ def interactive_menu_gui(clks_options: List[OptionItem], user_options: List[Opti
for group_name, group_items in clks_groups: for group_name, group_items in clks_groups:
clks_tabs.addTab(_SectionPanel(f"CLKS Features / {group_name}", group_items), group_name) clks_tabs.addTab(_SectionPanel(f"CLKS Features / {group_name}", group_items), group_name)
user_panel = _SectionPanel("User Apps", user_options)
tabs.addTab(clks_panel, "CLKS") tabs.addTab(clks_panel, "CLKS")
if user_options:
user_panel = _SectionPanel("User Apps", user_options)
tabs.addTab(user_panel, "USER") tabs.addTab(user_panel, "USER")
update_summary() update_summary()
@@ -1777,31 +1808,31 @@ def interactive_menu_gui(clks_options: List[OptionItem], user_options: List[Opti
return result["save"] return result["save"]
def write_outputs(all_values: Dict[str, int], ordered_options: List[OptionItem]) -> None: def _write_json_config(path: Path, values: Dict[str, int], options: List[OptionItem]) -> None:
MENUCONFIG_DIR.mkdir(parents=True, exist_ok=True)
output_values: Dict[str, object] = {} output_values: Dict[str, object] = {}
for item in ordered_options: for item in options:
if item.key not in all_values: if item.key not in values:
continue continue
value = normalize_tri(all_values[item.key], item.default, item.kind) value = normalize_tri(values[item.key], item.default, item.kind)
if item.kind == "bool": if item.kind == "bool":
output_values[item.key] = value == TRI_Y output_values[item.key] = value == TRI_Y
else: else:
output_values[item.key] = tri_char(value) output_values[item.key] = tri_char(value)
CONFIG_JSON_PATH.write_text( path.write_text(
json.dumps(output_values, ensure_ascii=True, indent=2, sort_keys=True) + "\n", json.dumps(output_values, ensure_ascii=True, indent=2, sort_keys=True) + "\n",
encoding="utf-8", encoding="utf-8",
) )
def _write_cmake_config(path: Path, values: Dict[str, int], options: List[OptionItem], loaded_var: str) -> None:
lines = [ lines = [
"# Auto-generated by scripts/menuconfig.py", "# Auto-generated by scripts/menuconfig.py",
"# Do not edit manually unless you know what you are doing.", "# Do not edit manually unless you know what you are doing.",
'set(CLEONOS_MENUCONFIG_LOADED ON CACHE BOOL "CLeonOS menuconfig loaded" FORCE)', f'set({loaded_var} ON CACHE BOOL "CLeonOS menuconfig loaded" FORCE)',
] ]
for item in ordered_options: for item in options:
value = normalize_tri(all_values.get(item.key, item.default), item.default, item.kind) value = normalize_tri(values.get(item.key, item.default), item.default, item.kind)
if item.kind == "bool": if item.kind == "bool":
cmake_value = "ON" if value == TRI_Y else "OFF" cmake_value = "ON" if value == TRI_Y else "OFF"
lines.append(f'set({item.key} {cmake_value} CACHE BOOL "{item.title}" FORCE)') lines.append(f'set({item.key} {cmake_value} CACHE BOOL "{item.title}" FORCE)')
@@ -1813,6 +1844,39 @@ def write_outputs(all_values: Dict[str, int], ordered_options: List[OptionItem])
f'CACHE BOOL "{item.title} enabled(y|m)" FORCE)' f'CACHE BOOL "{item.title} enabled(y|m)" FORCE)'
) )
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
def write_outputs(all_values: Dict[str, int], clks_options: List[OptionItem], user_options: List[OptionItem]) -> None:
MENUCONFIG_DIR.mkdir(parents=True, exist_ok=True)
ordered_options = clks_options + user_options
_write_json_config(CONFIG_JSON_PATH, all_values, ordered_options)
_write_json_config(CONFIG_CLKS_JSON_PATH, all_values, clks_options)
_write_cmake_config(CONFIG_CLKS_CMAKE_PATH, all_values, clks_options, "CLEONOS_MENUCONFIG_CLKS_LOADED")
if user_options:
_write_json_config(CONFIG_CLEONOS_JSON_PATH, all_values, user_options)
_write_cmake_config(
CONFIG_CLEONOS_CMAKE_PATH,
all_values,
user_options,
"CLEONOS_MENUCONFIG_CLEONOS_LOADED",
)
else:
if CONFIG_CLEONOS_JSON_PATH.exists():
CONFIG_CLEONOS_JSON_PATH.unlink()
if CONFIG_CLEONOS_CMAKE_PATH.exists():
CONFIG_CLEONOS_CMAKE_PATH.unlink()
# Backward-compatible aggregator for existing CMake include path.
lines = [
"# Auto-generated by scripts/menuconfig.py",
"# Backward-compatible aggregate include.",
'set(CLEONOS_MENUCONFIG_LOADED ON CACHE BOOL "CLeonOS menuconfig loaded" FORCE)',
'include("${CMAKE_CURRENT_LIST_DIR}/config.clks.cmake" OPTIONAL)',
'include("${CMAKE_CURRENT_LIST_DIR}/config.cleonos.cmake" OPTIONAL)',
]
CONFIG_CMAKE_PATH.write_text("\n".join(lines) + "\n", encoding="utf-8") CONFIG_CMAKE_PATH.write_text("\n".join(lines) + "\n", encoding="utf-8")
@@ -1826,22 +1890,29 @@ def show_summary(clks_options: List[OptionItem], user_options: List[OptionItem],
print() print()
print("========== CLeonOS menuconfig ==========") print("========== CLeonOS menuconfig ==========")
print(f"1) CLKS features : on={clks_on} m={clks_m} total={len(clks_options)}") print(f"1) CLKS features : on={clks_on} m={clks_m} total={len(clks_options)}")
if user_options:
print(f"2) User features : on={user_on} m={user_m} total={len(user_options)}") print(f"2) User features : on={user_on} m={user_m} total={len(user_options)}")
else:
print("2) User features : unavailable (CLKS-only mode)")
print("s) Save and exit") print("s) Save and exit")
print("q) Quit without saving") print("q) Quit without saving")
def interactive_menu(clks_options: List[OptionItem], user_options: List[OptionItem], values: Dict[str, int]) -> bool: def interactive_menu(clks_options: List[OptionItem], user_options: List[OptionItem], values: Dict[str, int]) -> bool:
all_options = clks_options + user_options all_options = clks_options + user_options
has_user = len(user_options) > 0
while True: while True:
show_summary(clks_options, user_options, values) show_summary(clks_options, user_options, values)
choice = input("Select> ").strip().lower() choice = input("Select> ").strip().lower()
if choice == "1": if choice == "1":
grouped_section_loop("CLKS", clks_options, all_options, values) grouped_section_loop("CLKS", clks_options, all_options, values)
continue continue
if choice == "2": if choice == "2" and has_user:
section_loop("USER", user_options, all_options, values) section_loop("USER", user_options, all_options, values)
continue continue
if choice == "2" and not has_user:
print("user features unavailable in CLKS-only mode")
continue
if choice in {"s", "save"}: if choice in {"s", "save"}:
return True return True
if choice in {"q", "quit"}: if choice in {"q", "quit"}:
@@ -1870,6 +1941,7 @@ def parse_args() -> argparse.Namespace:
parser.add_argument("--non-interactive", action="store_true", help="save config without opening interactive menu") parser.add_argument("--non-interactive", action="store_true", help="save config without opening interactive menu")
parser.add_argument("--plain", action="store_true", help="use legacy plain-text menu instead of ncurses") parser.add_argument("--plain", action="store_true", help="use legacy plain-text menu instead of ncurses")
parser.add_argument("--gui", action="store_true", help="use GUI window mode (PySide)") parser.add_argument("--gui", action="store_true", help="use GUI window mode (PySide)")
parser.add_argument("--clks-only", action="store_true", help="only expose CLKS options and emit CLKS-only config")
parser.add_argument( parser.add_argument(
"--preset", "--preset",
choices=["full", "minimal", "dev"], choices=["full", "minimal", "dev"],
@@ -1892,10 +1964,13 @@ def main() -> int:
raise RuntimeError("--gui and --plain cannot be used together") raise RuntimeError("--gui and --plain cannot be used together")
clks_options = load_clks_options() clks_options = load_clks_options()
user_options = discover_user_apps() clks_only_mode = args.clks_only or not APPS_DIR.exists()
if clks_only_mode and not args.clks_only:
print(f"menuconfig: cleonos app directory not found, switching to CLKS-only mode ({APPS_DIR})")
user_options = [] if clks_only_mode else discover_user_apps()
all_options = clks_options + user_options all_options = clks_options + user_options
previous = load_previous_values() previous = load_previous_values(include_user=not clks_only_mode)
values = init_values(all_options, previous, use_defaults=args.defaults) values = init_values(all_options, previous, use_defaults=args.defaults)
if args.preset: if args.preset:
@@ -1921,9 +1996,16 @@ def main() -> int:
return 0 return 0
final_eval = evaluate_config(all_options, values) final_eval = evaluate_config(all_options, values)
write_outputs(final_eval.effective, all_options) write_outputs(final_eval.effective, clks_options, user_options)
print(f"menuconfig: wrote {CONFIG_JSON_PATH}") print(f"menuconfig: wrote {CONFIG_JSON_PATH}")
print(f"menuconfig: wrote {CONFIG_CMAKE_PATH}") print(f"menuconfig: wrote {CONFIG_CMAKE_PATH}")
print(f"menuconfig: wrote {CONFIG_CLKS_JSON_PATH}")
print(f"menuconfig: wrote {CONFIG_CLKS_CMAKE_PATH}")
if user_options:
print(f"menuconfig: wrote {CONFIG_CLEONOS_JSON_PATH}")
print(f"menuconfig: wrote {CONFIG_CLEONOS_CMAKE_PATH}")
else:
print("menuconfig: CLeonOS app config skipped (CLKS-only mode)")
return 0 return 0