cmake_minimum_required(VERSION 3.20) project(CLeonOS NONE) # User-configurable toolchain and tool variables (Makefile-compatible defaults). set(NO_COLOR 0 CACHE STRING "Disable colored log output when set to 1") include("${CMAKE_SOURCE_DIR}/cmake/log.cmake") if(NO_COLOR) set(BUILD_LOG_COLOR_OPT --no-color) else() set(BUILD_LOG_COLOR_OPT) endif() set(CC "x86_64-elf-gcc" CACHE STRING "Kernel C compiler") set(LD "x86_64-elf-ld" CACHE STRING "Kernel linker") set(USER_CC "cc" CACHE STRING "User-space C compiler") set(USER_LD "ld" CACHE STRING "User-space linker") set(RUSTC "rustc" CACHE STRING "Rust compiler") set(XORRISO "xorriso" CACHE STRING "xorriso executable") set(TAR "tar" CACHE STRING "tar executable") set(GIT_TOOL "git" CACHE STRING "git executable") set(MAKE_TOOL "make" CACHE STRING "make executable") set(SH_TOOL "sh" CACHE STRING "POSIX shell executable") set(OBJCOPY_FOR_TARGET "llvm-objcopy" CACHE STRING "objcopy tool for limine configure") set(OBJDUMP_FOR_TARGET "llvm-objdump" CACHE STRING "objdump tool for limine configure") set(READELF_FOR_TARGET "llvm-readelf" CACHE STRING "readelf tool for limine configure") set(QEMU_X86_64 "qemu-system-x86_64" CACHE STRING "QEMU executable") 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_REF "" CACHE STRING "Optional Limine branch or tag") set(LIMINE_BIN_DIR "${LIMINE_DIR}/bin" CACHE STRING "Limine bin directory") set(LIMINE_CONFIGURE_FLAGS "--enable-bios-cd --enable-uefi-cd --enable-uefi-x86-64" CACHE STRING "Limine configure flags") set(LIMINE_SKIP_CONFIGURE 0 CACHE BOOL "Skip Limine configure step") function(resolve_path INPUT_PATH OUTPUT_VAR) if(IS_ABSOLUTE "${INPUT_PATH}") set(${OUTPUT_VAR} "${INPUT_PATH}" PARENT_SCOPE) else() set(${OUTPUT_VAR} "${CMAKE_SOURCE_DIR}/${INPUT_PATH}" PARENT_SCOPE) endif() endfunction() function(resolve_tool_with_fallback VAR_NAME) set(_fallbacks ${ARGN}) set(_requested "${${VAR_NAME}}") if("${_requested}" STREQUAL "") message(FATAL_ERROR "[ERROR] empty tool variable: ${VAR_NAME}") endif() if(IS_ABSOLUTE "${_requested}") if(NOT EXISTS "${_requested}") message(FATAL_ERROR "[ERROR] ${VAR_NAME} not found: ${_requested}") endif() set(_resolved "${_requested}") else() find_program(_requested_path NAMES "${_requested}") if(_requested_path) set(_resolved "${_requested}") else() set(_resolved "") foreach(_cand IN LISTS _fallbacks) find_program(_cand_path NAMES "${_cand}") if(_cand_path) cl_log_warn("${VAR_NAME} '${_requested}' not found; fallback to '${_cand}'") set(_resolved "${_cand}") break() endif() endforeach() if("${_resolved}" STREQUAL "") message(FATAL_ERROR "[ERROR] ${VAR_NAME} tool not found: '${_requested}', fallbacks='${_fallbacks}'") endif() endif() endif() get_property(_help CACHE "${VAR_NAME}" PROPERTY HELPSTRING) if("${_help}" STREQUAL "") set(_help "tool path/name") endif() set(${VAR_NAME} "${_resolved}" CACHE STRING "${_help}" FORCE) set(${VAR_NAME} "${_resolved}" PARENT_SCOPE) endfunction() set(BUILD_ROOT "${CMAKE_SOURCE_DIR}/build/x86_64") set(OBJ_ROOT "${BUILD_ROOT}/obj") set(ISO_ROOT "${BUILD_ROOT}/iso_root") set(RAMDISK_ROOT "${BUILD_ROOT}/ramdisk_root") set(KERNEL_ELF "${BUILD_ROOT}/clks_kernel.elf") set(RAMDISK_IMAGE "${BUILD_ROOT}/cleonos_ramdisk.tar") set(ISO_IMAGE "${CMAKE_SOURCE_DIR}/build/CLeonOS-x86_64.iso") set(USER_BUILD_ROOT "${BUILD_ROOT}/user") set(USER_OBJ_ROOT "${USER_BUILD_ROOT}/obj") set(USER_APP_DIR "${USER_BUILD_ROOT}/apps") set(USER_LIB_DIR "${USER_BUILD_ROOT}/lib") set(USER_RUST_LIB "${USER_LIB_DIR}/libcleonos_user_rust.a") resolve_tool_with_fallback(CC gcc cc clang) resolve_tool_with_fallback(LD ld.lld ld) resolve_tool_with_fallback(USER_CC cc gcc clang) resolve_tool_with_fallback(USER_LD ld.lld ld) resolve_tool_with_fallback(OBJCOPY_FOR_TARGET llvm-objcopy x86_64-linux-gnu-objcopy objcopy) resolve_tool_with_fallback(OBJDUMP_FOR_TARGET llvm-objdump x86_64-linux-gnu-objdump objdump) resolve_tool_with_fallback(READELF_FOR_TARGET llvm-readelf x86_64-linux-gnu-readelf readelf) resolve_path("${LIMINE_DIR}" LIMINE_DIR_ABS) resolve_path("${LIMINE_BIN_DIR}" LIMINE_BIN_DIR_ABS) set(LIMINE_SETUP_STAMP "${LIMINE_DIR_ABS}/.cleonos-limine-setup.stamp") set(LIMINE_BUILD_STAMP "${LIMINE_DIR_ABS}/.cleonos-limine-build.stamp") set(CLKS_ARCH "x86_64" CACHE STRING "Target CLKS arch") set(LINKER_SCRIPT "${CMAKE_SOURCE_DIR}/clks/arch/${CLKS_ARCH}/linker.ld") set(USER_LINKER_SCRIPT "${CMAKE_SOURCE_DIR}/cleonos/c/user.ld") set(KELF_LINKER_SCRIPT "${CMAKE_SOURCE_DIR}/cleonos/c/kelf.ld") set(CFLAGS_COMMON -std=c11 -ffreestanding -fno-stack-protector -fno-builtin -Wall -Wextra -Werror "-I${CMAKE_SOURCE_DIR}/clks/include" ) set(ARCH_CFLAGS -DCLKS_ARCH_X86_64=1 -m64 -mno-red-zone -mcmodel=kernel -fno-pic -fno-pie ) set(ASFLAGS_COMMON -ffreestanding "-I${CMAKE_SOURCE_DIR}/clks/include" ) set(LDFLAGS_COMMON -nostdlib -z max-page-size=0x1000 ) set(USER_CFLAGS -std=c11 -ffreestanding -fno-stack-protector -fno-builtin -Wall -Wextra -Werror "-I${CMAKE_SOURCE_DIR}/cleonos/c/include" ) set(USER_LDFLAGS -nostdlib -z max-page-size=0x1000 -T "${USER_LINKER_SCRIPT}" ) set(KELF_LDFLAGS -nostdlib -z max-page-size=0x1000 -T "${KELF_LINKER_SCRIPT}" ) if(NOT CLKS_ARCH STREQUAL "x86_64") message(FATAL_ERROR "[ERROR] CLKS_ARCH=${CLKS_ARCH} is not supported by this CMake build yet; use x86_64") endif() set(KERNEL_SOURCE_DIRS "${CMAKE_SOURCE_DIR}/clks/kernel" "${CMAKE_SOURCE_DIR}/clks/lib" "${CMAKE_SOURCE_DIR}/clks/drivers" "${CMAKE_SOURCE_DIR}/clks/arch/${CLKS_ARCH}" ) set(C_SOURCES) set(ASM_SOURCES) foreach(_src_dir IN LISTS KERNEL_SOURCE_DIRS) if(EXISTS "${_src_dir}") file(GLOB_RECURSE _c_abs CONFIGURE_DEPENDS "${_src_dir}/*.c") file(GLOB_RECURSE _s_abs CONFIGURE_DEPENDS "${_src_dir}/*.S") foreach(_abs IN LISTS _c_abs) file(RELATIVE_PATH _rel "${CMAKE_SOURCE_DIR}" "${_abs}") list(APPEND C_SOURCES "${_rel}") endforeach() foreach(_abs IN LISTS _s_abs) file(RELATIVE_PATH _rel "${CMAKE_SOURCE_DIR}" "${_abs}") list(APPEND ASM_SOURCES "${_rel}") endforeach() endif() endforeach() list(REMOVE_DUPLICATES C_SOURCES) list(REMOVE_DUPLICATES ASM_SOURCES) list(SORT C_SOURCES) list(SORT ASM_SOURCES) if(NOT C_SOURCES) message(FATAL_ERROR "[ERROR] no kernel C sources found in clks/") endif() if(NOT EXISTS "${LINKER_SCRIPT}") message(FATAL_ERROR "[ERROR] missing linker script: ${LINKER_SCRIPT}") endif() file(GLOB_RECURSE USER_COMMON_SOURCES_ABS CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/cleonos/c/src/*.c") set(USER_COMMON_SOURCES) foreach(_abs IN LISTS USER_COMMON_SOURCES_ABS) file(RELATIVE_PATH _rel "${CMAKE_SOURCE_DIR}" "${_abs}") list(APPEND USER_COMMON_SOURCES "${_rel}") endforeach() list(SORT USER_COMMON_SOURCES) file(GLOB USER_APP_MAIN_SOURCES_ABS CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/cleonos/c/apps/*_main.c") file(GLOB USER_APP_KMAIN_SOURCES_ABS CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/cleonos/c/apps/*_kmain.c") set(USER_APP_MAIN_SOURCES) set(USER_APP_KMAIN_SOURCES) foreach(_abs IN LISTS USER_APP_MAIN_SOURCES_ABS) file(RELATIVE_PATH _rel "${CMAKE_SOURCE_DIR}" "${_abs}") list(APPEND USER_APP_MAIN_SOURCES "${_rel}") endforeach() foreach(_abs IN LISTS USER_APP_KMAIN_SOURCES_ABS) file(RELATIVE_PATH _rel "${CMAKE_SOURCE_DIR}" "${_abs}") list(APPEND USER_APP_KMAIN_SOURCES "${_rel}") endforeach() list(SORT USER_APP_MAIN_SOURCES) list(SORT USER_APP_KMAIN_SOURCES) if(NOT USER_COMMON_SOURCES) message(FATAL_ERROR "[ERROR] no user common sources found in cleonos/c/src/") endif() if(NOT USER_APP_MAIN_SOURCES) message(FATAL_ERROR "[ERROR] no user app *_main.c found in cleonos/c/apps/") endif() if(NOT USER_APP_KMAIN_SOURCES) message(FATAL_ERROR "[ERROR] no kernel app *_kmain.c found in cleonos/c/apps/") endif() function(add_kernel_c_object SRC OUTPUT_LIST_VAR) string(REGEX REPLACE "\\.c$" ".o" OBJ_REL "${SRC}") set(OBJ_PATH "${OBJ_ROOT}/${OBJ_REL}") get_filename_component(OBJ_DIR "${OBJ_PATH}" DIRECTORY) add_custom_command( OUTPUT "${OBJ_PATH}" COMMAND ${CMAKE_COMMAND} -E make_directory "${OBJ_DIR}" COMMAND ${CC} ${CFLAGS_COMMON} ${ARCH_CFLAGS} -c "${CMAKE_SOURCE_DIR}/${SRC}" -o "${OBJ_PATH}" DEPENDS "${CMAKE_SOURCE_DIR}/${SRC}" VERBATIM ) set(${OUTPUT_LIST_VAR} ${${OUTPUT_LIST_VAR}} "${OBJ_PATH}" PARENT_SCOPE) endfunction() function(add_kernel_asm_object SRC OUTPUT_LIST_VAR) string(REGEX REPLACE "\\.S$" ".o" OBJ_REL "${SRC}") set(OBJ_PATH "${OBJ_ROOT}/${OBJ_REL}") get_filename_component(OBJ_DIR "${OBJ_PATH}" DIRECTORY) add_custom_command( OUTPUT "${OBJ_PATH}" COMMAND ${CMAKE_COMMAND} -E make_directory "${OBJ_DIR}" COMMAND ${CC} ${ASFLAGS_COMMON} ${ARCH_CFLAGS} -c "${CMAKE_SOURCE_DIR}/${SRC}" -o "${OBJ_PATH}" DEPENDS "${CMAKE_SOURCE_DIR}/${SRC}" VERBATIM ) set(${OUTPUT_LIST_VAR} ${${OUTPUT_LIST_VAR}} "${OBJ_PATH}" PARENT_SCOPE) endfunction() function(add_user_c_object SRC OUTPUT_VAR) string(REGEX REPLACE "\\.c$" ".o" OBJ_REL "${SRC}") set(OBJ_PATH "${USER_OBJ_ROOT}/${OBJ_REL}") get_filename_component(OBJ_DIR "${OBJ_PATH}" DIRECTORY) add_custom_command( OUTPUT "${OBJ_PATH}" COMMAND ${CMAKE_COMMAND} -E make_directory "${OBJ_DIR}" COMMAND ${USER_CC} ${USER_CFLAGS} -c "${CMAKE_SOURCE_DIR}/${SRC}" -o "${OBJ_PATH}" DEPENDS "${CMAKE_SOURCE_DIR}/${SRC}" VERBATIM ) set(${OUTPUT_VAR} "${OBJ_PATH}" PARENT_SCOPE) endfunction() set(KERNEL_OBJECTS) foreach(SRC IN LISTS C_SOURCES) add_kernel_c_object("${SRC}" KERNEL_OBJECTS) endforeach() foreach(SRC IN LISTS ASM_SOURCES) add_kernel_asm_object("${SRC}" KERNEL_OBJECTS) endforeach() add_custom_command( OUTPUT "${KERNEL_ELF}" COMMAND ${CMAKE_COMMAND} -E make_directory "${BUILD_ROOT}" COMMAND ${LD} ${LDFLAGS_COMMON} -T "${LINKER_SCRIPT}" -o "${KERNEL_ELF}" ${KERNEL_OBJECTS} DEPENDS ${KERNEL_OBJECTS} "${LINKER_SCRIPT}" VERBATIM ) add_custom_target(kernel DEPENDS "${KERNEL_ELF}") set(USER_COMMON_OBJECTS) foreach(SRC IN LISTS USER_COMMON_SOURCES) add_user_c_object("${SRC}" OBJ_OUT) list(APPEND USER_COMMON_OBJECTS "${OBJ_OUT}") endforeach() add_custom_command( OUTPUT "${USER_RUST_LIB}" COMMAND ${CMAKE_COMMAND} -E make_directory "${USER_LIB_DIR}" COMMAND ${RUSTC} --crate-type staticlib -C panic=abort -O "${CMAKE_SOURCE_DIR}/cleonos/rust/src/lib.rs" -o "${USER_RUST_LIB}" DEPENDS "${CMAKE_SOURCE_DIR}/cleonos/rust/src/lib.rs" VERBATIM ) set(USER_KELF_APP_NAMES) foreach(SRC IN LISTS USER_APP_KMAIN_SOURCES) get_filename_component(_stem "${SRC}" NAME_WE) string(REGEX REPLACE "_kmain$" "" _app_name "${_stem}") list(APPEND USER_KELF_APP_NAMES "${_app_name}") endforeach() list(REMOVE_DUPLICATES USER_KELF_APP_NAMES) set(USER_APP_OUTPUTS) set(USER_APP_NAMES) set(RAMDISK_SHELL_APPS) set(RAMDISK_DRIVER_APPS) set(RAMDISK_SYSTEM_APPS) foreach(SRC IN LISTS USER_APP_MAIN_SOURCES) get_filename_component(_stem "${SRC}" NAME_WE) string(REGEX REPLACE "_main$" "" _app_name "${_stem}") list(FIND USER_KELF_APP_NAMES "${_app_name}" _shadowed_by_kmain) if(NOT _shadowed_by_kmain EQUAL -1) cl_log_info("skip ${SRC} because ${_app_name}_kmain.c exists") continue() endif() list(FIND USER_APP_NAMES "${_app_name}" _dup_name_idx) if(NOT _dup_name_idx EQUAL -1) message(FATAL_ERROR "[ERROR] duplicate user app name: ${_app_name}") endif() list(APPEND USER_APP_NAMES "${_app_name}") add_user_c_object("${SRC}" _user_obj) set(_app_out "${USER_APP_DIR}/${_app_name}.elf") add_custom_command( OUTPUT "${_app_out}" COMMAND ${CMAKE_COMMAND} -E make_directory "${USER_APP_DIR}" COMMAND ${USER_LD} ${USER_LDFLAGS} -o "${_app_out}" ${USER_COMMON_OBJECTS} "${_user_obj}" "${USER_RUST_LIB}" DEPENDS ${USER_COMMON_OBJECTS} "${_user_obj}" "${USER_RUST_LIB}" "${USER_LINKER_SCRIPT}" VERBATIM ) list(APPEND USER_APP_OUTPUTS "${_app_out}") if(_app_name MATCHES ".*drv$") list(APPEND RAMDISK_DRIVER_APPS "${_app_out}") else() list(APPEND RAMDISK_SHELL_APPS "${_app_out}") endif() endforeach() foreach(SRC IN LISTS USER_APP_KMAIN_SOURCES) get_filename_component(_stem "${SRC}" NAME_WE) string(REGEX REPLACE "_kmain$" "" _app_name "${_stem}") list(FIND USER_APP_NAMES "${_app_name}" _dup_name_idx) if(NOT _dup_name_idx EQUAL -1) message(FATAL_ERROR "[ERROR] duplicate user app name: ${_app_name}") endif() list(APPEND USER_APP_NAMES "${_app_name}") add_user_c_object("${SRC}" _kelf_obj) set(_app_out "${USER_APP_DIR}/${_app_name}.elf") add_custom_command( OUTPUT "${_app_out}" COMMAND ${CMAKE_COMMAND} -E make_directory "${USER_APP_DIR}" COMMAND ${USER_LD} ${KELF_LDFLAGS} -o "${_app_out}" "${_kelf_obj}" DEPENDS "${_kelf_obj}" "${KELF_LINKER_SCRIPT}" VERBATIM ) list(APPEND USER_APP_OUTPUTS "${_app_out}") list(APPEND RAMDISK_SYSTEM_APPS "${_app_out}") endforeach() if(NOT USER_APP_OUTPUTS) message(FATAL_ERROR "[ERROR] no user ELF apps were discovered") endif() add_custom_target(userapps DEPENDS ${USER_APP_OUTPUTS}) add_custom_command( TARGET userapps POST_BUILD COMMAND ${CMAKE_COMMAND} -E cmake_echo_color ${BUILD_LOG_COLOR_OPT} --cyan "[INFO] user elf apps ready" ) file(GLOB_RECURSE RAMDISK_FILES CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/ramdisk/*") set(RAMDISK_ROOT_STAMP "${BUILD_ROOT}/.ramdisk_root.stamp") set(RAMDISK_COPY_COMMANDS) foreach(_app IN LISTS RAMDISK_SHELL_APPS) get_filename_component(_app_file "${_app}" NAME) list(APPEND RAMDISK_COPY_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy "${_app}" "${RAMDISK_ROOT}/shell/${_app_file}") endforeach() foreach(_app IN LISTS RAMDISK_DRIVER_APPS) get_filename_component(_app_file "${_app}" NAME) list(APPEND RAMDISK_COPY_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy "${_app}" "${RAMDISK_ROOT}/driver/${_app_file}") endforeach() foreach(_app IN LISTS RAMDISK_SYSTEM_APPS) get_filename_component(_app_file "${_app}" NAME) list(APPEND RAMDISK_COPY_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy "${_app}" "${RAMDISK_ROOT}/system/${_app_file}") endforeach() add_custom_command( OUTPUT "${RAMDISK_ROOT_STAMP}" COMMAND ${CMAKE_COMMAND} -E rm -rf "${RAMDISK_ROOT}" COMMAND ${CMAKE_COMMAND} -E make_directory "${RAMDISK_ROOT}" COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/ramdisk" "${RAMDISK_ROOT}" COMMAND ${CMAKE_COMMAND} -E make_directory "${RAMDISK_ROOT}/system" "${RAMDISK_ROOT}/shell" "${RAMDISK_ROOT}/driver" ${RAMDISK_COPY_COMMANDS} COMMAND ${CMAKE_COMMAND} -E touch "${RAMDISK_ROOT_STAMP}" DEPENDS ${RAMDISK_FILES} ${USER_APP_OUTPUTS} VERBATIM ) add_custom_target(ramdisk-root DEPENDS "${RAMDISK_ROOT_STAMP}") add_dependencies(ramdisk-root userapps) add_custom_command( OUTPUT "${RAMDISK_IMAGE}" COMMAND ${CMAKE_COMMAND} -E make_directory "${BUILD_ROOT}" COMMAND ${TAR} -C "${RAMDISK_ROOT}" -cf "${RAMDISK_IMAGE}" . DEPENDS "${RAMDISK_ROOT_STAMP}" VERBATIM ) add_custom_target(ramdisk DEPENDS "${RAMDISK_IMAGE}") add_custom_target(setup-tools COMMAND ${CMAKE_COMMAND} "-DGIT_TOOL=${GIT_TOOL}" "-DTAR_TOOL=${TAR}" "-DXORRISO_TOOL=${XORRISO}" "-DNO_COLOR=${NO_COLOR}" "-DCC_TOOL=${CC}" "-DLD_TOOL=${LD}" "-DOBJCOPY_TOOL=${OBJCOPY_FOR_TARGET}" "-DOBJDUMP_TOOL=${OBJDUMP_FOR_TARGET}" "-DREADELF_TOOL=${READELF_FOR_TARGET}" "-DUSER_CC_TOOL=${USER_CC}" "-DUSER_LD_TOOL=${USER_LD}" "-DRUSTC_TOOL=${RUSTC}" "-DMAKE_TOOL=${MAKE_TOOL}" "-DSH_TOOL=${SH_TOOL}" -P "${CMAKE_SOURCE_DIR}/cmake/check_tools.cmake" ) add_custom_target(setup-limine COMMAND ${CMAKE_COMMAND} "-DGIT_TOOL=${GIT_TOOL}" "-DMAKE_TOOL=${MAKE_TOOL}" "-DSH_TOOL=${SH_TOOL}" "-DNO_COLOR=${NO_COLOR}" "-DLIMINE_DIR=${LIMINE_DIR_ABS}" "-DLIMINE_REPO=${LIMINE_REPO}" "-DLIMINE_REF=${LIMINE_REF}" "-DLIMINE_BIN_DIR=${LIMINE_BIN_DIR_ABS}" "-DLIMINE_SETUP_STAMP=${LIMINE_SETUP_STAMP}" "-DLIMINE_BUILD_STAMP=${LIMINE_BUILD_STAMP}" "-DLIMINE_CONFIGURE_FLAGS=${LIMINE_CONFIGURE_FLAGS}" "-DLIMINE_SKIP_CONFIGURE=${LIMINE_SKIP_CONFIGURE}" "-DOBJCOPY_FOR_TARGET=${OBJCOPY_FOR_TARGET}" "-DOBJDUMP_FOR_TARGET=${OBJDUMP_FOR_TARGET}" "-DREADELF_FOR_TARGET=${READELF_FOR_TARGET}" -P "${CMAKE_SOURCE_DIR}/cmake/setup_limine.cmake" ) add_dependencies(setup-limine setup-tools) add_custom_target(setup DEPENDS setup-tools setup-limine) add_custom_command(TARGET setup POST_BUILD COMMAND ${CMAKE_COMMAND} -E cmake_echo_color ${BUILD_LOG_COLOR_OPT} --cyan "[INFO] environment ready") add_custom_command( OUTPUT "${ISO_IMAGE}" COMMAND ${CMAKE_COMMAND} -E rm -rf "${ISO_ROOT}" COMMAND ${CMAKE_COMMAND} -E make_directory "${ISO_ROOT}/boot/limine" COMMAND ${CMAKE_COMMAND} -E copy "${KERNEL_ELF}" "${ISO_ROOT}/boot/clks_kernel.elf" COMMAND ${CMAKE_COMMAND} -E copy "${RAMDISK_IMAGE}" "${ISO_ROOT}/boot/cleonos_ramdisk.tar" COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/configs/limine.conf" "${ISO_ROOT}/boot/limine/limine.conf" COMMAND ${CMAKE_COMMAND} -E copy "${LIMINE_BIN_DIR_ABS}/limine-bios.sys" "${ISO_ROOT}/boot/limine/limine-bios.sys" COMMAND ${CMAKE_COMMAND} -E copy "${LIMINE_BIN_DIR_ABS}/limine-bios-cd.bin" "${ISO_ROOT}/boot/limine/limine-bios-cd.bin" COMMAND ${CMAKE_COMMAND} -E copy "${LIMINE_BIN_DIR_ABS}/limine-uefi-cd.bin" "${ISO_ROOT}/boot/limine/limine-uefi-cd.bin" COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_SOURCE_DIR}/build" COMMAND ${CMAKE_COMMAND} -E cmake_echo_color ${BUILD_LOG_COLOR_OPT} --magenta "[STEP] building iso -> ${ISO_IMAGE}" COMMAND ${XORRISO} -as mkisofs -b boot/limine/limine-bios-cd.bin -no-emul-boot -boot-load-size 4 -boot-info-table --efi-boot boot/limine/limine-uefi-cd.bin -efi-boot-part --efi-boot-image --protective-msdos-label "${ISO_ROOT}" -o "${ISO_IMAGE}" COMMAND ${CMAKE_COMMAND} -E cmake_echo_color ${BUILD_LOG_COLOR_OPT} --magenta "[STEP] installing limine boot sectors" COMMAND "${LIMINE_BIN_DIR_ABS}/limine" bios-install "${ISO_IMAGE}" COMMAND ${CMAKE_COMMAND} -E cmake_echo_color ${BUILD_LOG_COLOR_OPT} --cyan "[INFO] iso ready: ${ISO_IMAGE}" DEPENDS "${KERNEL_ELF}" "${RAMDISK_IMAGE}" "${CMAKE_SOURCE_DIR}/configs/limine.conf" VERBATIM ) add_custom_target(iso ALL DEPENDS "${ISO_IMAGE}") add_dependencies(iso setup-tools setup-limine kernel ramdisk) add_custom_target(run COMMAND ${CMAKE_COMMAND} -E cmake_echo_color ${BUILD_LOG_COLOR_OPT} --magenta "[STEP] launching qemu run" COMMAND ${QEMU_X86_64} -M q35 -m 1024M -cdrom "${ISO_IMAGE}" -serial stdio DEPENDS iso USES_TERMINAL ) add_custom_target(debug COMMAND ${CMAKE_COMMAND} -E cmake_echo_color ${BUILD_LOG_COLOR_OPT} --magenta "[STEP] launching qemu debug (-s -S)" COMMAND ${QEMU_X86_64} -M q35 -m 1024M -cdrom "${ISO_IMAGE}" -serial stdio -s -S DEPENDS iso USES_TERMINAL ) add_custom_target(clean-x86 COMMAND ${CMAKE_COMMAND} -E cmake_echo_color ${BUILD_LOG_COLOR_OPT} --magenta "[STEP] cleaning ${BUILD_ROOT}" COMMAND ${CMAKE_COMMAND} -E rm -rf "${BUILD_ROOT}" COMMAND ${CMAKE_COMMAND} -E cmake_echo_color ${BUILD_LOG_COLOR_OPT} --cyan "[INFO] clean done" ) add_custom_target(clean-all COMMAND ${CMAKE_COMMAND} -E cmake_echo_color ${BUILD_LOG_COLOR_OPT} --magenta "[STEP] cleaning build" COMMAND ${CMAKE_COMMAND} -E rm -rf "${CMAKE_SOURCE_DIR}/build" COMMAND ${CMAKE_COMMAND} -E cmake_echo_color ${BUILD_LOG_COLOR_OPT} --cyan "[INFO] clean-all done" ) add_custom_target(cleonos-help COMMAND ${CMAKE_COMMAND} -E echo "CLeonOS CMake build system (x86_64 only)" COMMAND ${CMAKE_COMMAND} -E echo " cmake -S . -B build-cmake" COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target setup" 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 run" COMMAND ${CMAKE_COMMAND} -E echo " cmake --build build-cmake --target debug" )