mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 10:40:00 +00:00
转为CMakeList
This commit is contained in:
10
.gitignore
vendored
10
.gitignore
vendored
@@ -1,4 +1,14 @@
|
||||
build/
|
||||
build-cmake*/
|
||||
*.iso
|
||||
*.tar
|
||||
limine/
|
||||
|
||||
# CMake generated files
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
cmake_install.cmake
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
Testing/
|
||||
.cmake/
|
||||
|
||||
573
CMakeLists.txt
Normal file
573
CMakeLists.txt
Normal file
@@ -0,0 +1,573 @@
|
||||
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_STEP_PREFIX "[STEP]")
|
||||
set(BUILD_LOG_INFO_PREFIX "[INFO]")
|
||||
else()
|
||||
string(ASCII 27 BUILD_LOG_ESC)
|
||||
set(BUILD_LOG_STEP_PREFIX "${BUILD_LOG_ESC}[1;35m[STEP]${BUILD_LOG_ESC}[0m")
|
||||
set(BUILD_LOG_INFO_PREFIX "${BUILD_LOG_ESC}[1;36m[INFO]${BUILD_LOG_ESC}[0m")
|
||||
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 ${CMAKE_COMMAND} -E echo "${BUILD_LOG_STEP_PREFIX} assembling ${SRC}"
|
||||
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 ${CMAKE_COMMAND} -E echo "${BUILD_LOG_STEP_PREFIX} building rust user lib"
|
||||
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 echo "${BUILD_LOG_INFO_PREFIX} 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 echo "${BUILD_LOG_STEP_PREFIX} staging ramdisk root -> ${RAMDISK_ROOT}"
|
||||
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 ${CMAKE_COMMAND} -E echo "${BUILD_LOG_STEP_PREFIX} packing ramdisk -> ${RAMDISK_IMAGE}"
|
||||
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 echo "${BUILD_LOG_INFO_PREFIX} environment ready")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${ISO_IMAGE}"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "${BUILD_LOG_STEP_PREFIX} assembling iso root"
|
||||
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 echo "${BUILD_LOG_STEP_PREFIX} 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 echo "${BUILD_LOG_STEP_PREFIX} installing limine boot sectors"
|
||||
COMMAND "${LIMINE_BIN_DIR_ABS}/limine" bios-install "${ISO_IMAGE}"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "${BUILD_LOG_INFO_PREFIX} 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 echo "${BUILD_LOG_STEP_PREFIX} 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 echo "${BUILD_LOG_STEP_PREFIX} 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 echo "${BUILD_LOG_STEP_PREFIX} cleaning ${BUILD_ROOT}"
|
||||
COMMAND ${CMAKE_COMMAND} -E rm -rf "${BUILD_ROOT}"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "${BUILD_LOG_INFO_PREFIX} clean done"
|
||||
)
|
||||
|
||||
add_custom_target(clean-all
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "${BUILD_LOG_STEP_PREFIX} cleaning build"
|
||||
COMMAND ${CMAKE_COMMAND} -E rm -rf "${CMAKE_SOURCE_DIR}/build"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "${BUILD_LOG_INFO_PREFIX} 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"
|
||||
)
|
||||
383
Makefile
383
Makefile
@@ -1,332 +1,121 @@
|
||||
.RECIPEPREFIX := >
|
||||
MAKEFLAGS += --no-print-directory
|
||||
|
||||
CMAKE ?= cmake
|
||||
CMAKE_BUILD_DIR ?= build-cmake
|
||||
CMAKE_BUILD_TYPE ?= Release
|
||||
CMAKE_GENERATOR ?=
|
||||
CMAKE_EXTRA_ARGS ?=
|
||||
NO_COLOR ?= 0
|
||||
|
||||
BUILD_ROOT := build/x86_64
|
||||
OBJ_ROOT := $(BUILD_ROOT)/obj
|
||||
ISO_ROOT := $(BUILD_ROOT)/iso_root
|
||||
RAMDISK_ROOT := $(BUILD_ROOT)/ramdisk_root
|
||||
KERNEL_ELF := $(BUILD_ROOT)/clks_kernel.elf
|
||||
RAMDISK_IMAGE := $(BUILD_ROOT)/cleonos_ramdisk.tar
|
||||
ISO_IMAGE := build/CLeonOS-x86_64.iso
|
||||
|
||||
USER_BUILD_ROOT := $(BUILD_ROOT)/user
|
||||
USER_OBJ_ROOT := $(USER_BUILD_ROOT)/obj
|
||||
USER_APP_DIR := $(USER_BUILD_ROOT)/apps
|
||||
USER_LIB_DIR := $(USER_BUILD_ROOT)/lib
|
||||
|
||||
LIMINE_DIR ?= limine
|
||||
LIMINE_REPO ?= https://gh-proxy.com/https://github.com/limine-bootloader/limine.git
|
||||
LIMINE_SKIP_CONFIGURE ?=
|
||||
LIMINE_REF ?=
|
||||
LIMINE_BIN_DIR ?= $(LIMINE_DIR)/bin
|
||||
LIMINE_SETUP_STAMP := $(LIMINE_DIR)/.cleonos-limine-setup.stamp
|
||||
LIMINE_BUILD_STAMP := $(LIMINE_DIR)/.cleonos-limine-build.stamp
|
||||
LIMINE_CONFIGURE_FLAGS ?= --enable-bios-cd --enable-uefi-cd --enable-uefi-x86-64
|
||||
LIMINE_SKIP_CONFIGURE ?= 0
|
||||
OBJCOPY_FOR_TARGET ?= llvm-objcopy
|
||||
OBJDUMP_FOR_TARGET ?= llvm-objdump
|
||||
READELF_FOR_TARGET ?= llvm-readelf
|
||||
LIMINE_REPO ?=
|
||||
LIMINE_DIR ?=
|
||||
LIMINE_BIN_DIR ?=
|
||||
OBJCOPY_FOR_TARGET ?=
|
||||
OBJDUMP_FOR_TARGET ?=
|
||||
READELF_FOR_TARGET ?=
|
||||
|
||||
XORRISO ?= xorriso
|
||||
TAR ?= tar
|
||||
|
||||
QEMU_X86_64 ?= qemu-system-x86_64
|
||||
|
||||
CC ?= x86_64-elf-gcc
|
||||
LD ?= x86_64-elf-ld
|
||||
ARCH_CFLAGS := -DCLKS_ARCH_X86_64=1 -m64 -mno-red-zone -mcmodel=kernel -fno-pic -fno-pie
|
||||
LINKER_SCRIPT := clks/arch/x86_64/linker.ld
|
||||
RUN_COMMAND := $(QEMU_X86_64) -M q35 -m 1024M -cdrom $(ISO_IMAGE) -serial stdio
|
||||
DEBUG_COMMAND := $(QEMU_X86_64) -M q35 -m 1024M -cdrom $(ISO_IMAGE) -serial stdio -s -S
|
||||
|
||||
USER_CC ?= cc
|
||||
USER_LD ?= ld
|
||||
RUSTC ?= rustc
|
||||
USER_LINKER_SCRIPT := cleonos/c/user.ld
|
||||
KELF_LINKER_SCRIPT := cleonos/c/kelf.ld
|
||||
USER_CFLAGS := -std=c11 -ffreestanding -fno-stack-protector -fno-builtin -Wall -Wextra -Werror -Icleonos/c/include
|
||||
USER_LDFLAGS := -nostdlib -z max-page-size=0x1000 -T $(USER_LINKER_SCRIPT)
|
||||
KELF_LDFLAGS := -nostdlib -z max-page-size=0x1000 -T $(KELF_LINKER_SCRIPT)
|
||||
|
||||
ifeq ($(NO_COLOR),1)
|
||||
COLOR_RESET :=
|
||||
COLOR_INFO :=
|
||||
COLOR_WARN :=
|
||||
COLOR_ERROR :=
|
||||
COLOR_STEP :=
|
||||
ifeq ($(strip $(CMAKE_GENERATOR)),)
|
||||
GEN_ARG :=
|
||||
else
|
||||
COLOR_RESET := \033[0m
|
||||
COLOR_INFO := \033[1;36m
|
||||
COLOR_WARN := \033[1;33m
|
||||
COLOR_ERROR := \033[1;31m
|
||||
COLOR_STEP := \033[1;35m
|
||||
GEN_ARG := -G "$(CMAKE_GENERATOR)"
|
||||
endif
|
||||
|
||||
define log_info
|
||||
@printf '%b\n' "$(COLOR_INFO)[INFO]$(COLOR_RESET) $(1)"
|
||||
endef
|
||||
CMAKE_PASSTHROUGH_ARGS :=
|
||||
|
||||
define log_warn
|
||||
@printf '%b\n' "$(COLOR_WARN)[WARN]$(COLOR_RESET) $(1)"
|
||||
endef
|
||||
ifneq ($(strip $(LIMINE_SKIP_CONFIGURE)),)
|
||||
CMAKE_PASSTHROUGH_ARGS += -DLIMINE_SKIP_CONFIGURE=$(LIMINE_SKIP_CONFIGURE)
|
||||
endif
|
||||
ifneq ($(strip $(LIMINE_REF)),)
|
||||
CMAKE_PASSTHROUGH_ARGS += -DLIMINE_REF=$(LIMINE_REF)
|
||||
endif
|
||||
ifneq ($(strip $(LIMINE_REPO)),)
|
||||
CMAKE_PASSTHROUGH_ARGS += -DLIMINE_REPO=$(LIMINE_REPO)
|
||||
endif
|
||||
ifneq ($(strip $(LIMINE_DIR)),)
|
||||
CMAKE_PASSTHROUGH_ARGS += -DLIMINE_DIR=$(LIMINE_DIR)
|
||||
endif
|
||||
ifneq ($(strip $(LIMINE_BIN_DIR)),)
|
||||
CMAKE_PASSTHROUGH_ARGS += -DLIMINE_BIN_DIR=$(LIMINE_BIN_DIR)
|
||||
endif
|
||||
ifneq ($(strip $(OBJCOPY_FOR_TARGET)),)
|
||||
CMAKE_PASSTHROUGH_ARGS += -DOBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET)
|
||||
endif
|
||||
ifneq ($(strip $(OBJDUMP_FOR_TARGET)),)
|
||||
CMAKE_PASSTHROUGH_ARGS += -DOBJDUMP_FOR_TARGET=$(OBJDUMP_FOR_TARGET)
|
||||
endif
|
||||
ifneq ($(strip $(READELF_FOR_TARGET)),)
|
||||
CMAKE_PASSTHROUGH_ARGS += -DREADELF_FOR_TARGET=$(READELF_FOR_TARGET)
|
||||
endif
|
||||
|
||||
define log_error
|
||||
@printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) $(1)"
|
||||
endef
|
||||
|
||||
define log_step
|
||||
@printf '%b\n' "$(COLOR_STEP)[STEP]$(COLOR_RESET) $(1)"
|
||||
endef
|
||||
|
||||
C_SOURCES := \
|
||||
clks/kernel/kmain.c \
|
||||
clks/kernel/log.c \
|
||||
clks/kernel/limine_requests.c \
|
||||
clks/kernel/tty.c \
|
||||
clks/kernel/pmm.c \
|
||||
clks/kernel/heap.c \
|
||||
clks/kernel/keyboard.c \
|
||||
clks/kernel/interrupts.c \
|
||||
clks/kernel/scheduler.c \
|
||||
clks/kernel/elf64.c \
|
||||
clks/kernel/elfrunner.c \
|
||||
clks/kernel/syscall.c \
|
||||
clks/kernel/ramdisk.c \
|
||||
clks/kernel/fs.c \
|
||||
clks/kernel/userland.c \
|
||||
clks/kernel/driver.c \
|
||||
clks/kernel/service.c \
|
||||
clks/kernel/kelf.c \
|
||||
clks/kernel/exec.c \
|
||||
clks/lib/string.c \
|
||||
clks/drivers/serial/serial.c \
|
||||
clks/drivers/video/framebuffer.c \
|
||||
clks/drivers/video/font8x8.c \
|
||||
clks/arch/x86_64/boot.c
|
||||
|
||||
ASM_SOURCES := \
|
||||
clks/arch/x86_64/interrupt_stubs.S
|
||||
|
||||
C_OBJECTS := $(patsubst %.c,$(OBJ_ROOT)/%.o,$(C_SOURCES))
|
||||
ASM_OBJECTS := $(patsubst %.S,$(OBJ_ROOT)/%.o,$(ASM_SOURCES))
|
||||
OBJECTS := $(C_OBJECTS) $(ASM_OBJECTS)
|
||||
|
||||
USER_COMMON_SOURCES := \
|
||||
cleonos/c/src/runtime.c \
|
||||
cleonos/c/src/syscall.c
|
||||
|
||||
USER_COMMON_OBJECTS := $(patsubst %.c,$(USER_OBJ_ROOT)/%.o,$(USER_COMMON_SOURCES))
|
||||
USER_SHELL_OBJECT := $(USER_OBJ_ROOT)/cleonos/c/apps/shell_main.o
|
||||
USER_TTYDRV_OBJECT := $(USER_OBJ_ROOT)/cleonos/c/apps/ttydrv_main.o
|
||||
USER_ELFRUNNER_KOBJ := $(USER_OBJ_ROOT)/cleonos/c/apps/elfrunner_kmain.o
|
||||
USER_MEMC_KOBJ := $(USER_OBJ_ROOT)/cleonos/c/apps/memc_kmain.o
|
||||
USER_RUST_LIB := $(USER_LIB_DIR)/libcleonos_user_rust.a
|
||||
|
||||
APP_SHELL := $(USER_APP_DIR)/shell.elf
|
||||
APP_TTYDRV := $(USER_APP_DIR)/ttydrv.elf
|
||||
APP_ELFRUNNER := $(USER_APP_DIR)/elfrunner.elf
|
||||
APP_MEMC := $(USER_APP_DIR)/memc.elf
|
||||
USER_APPS := $(APP_SHELL) $(APP_TTYDRV) $(APP_ELFRUNNER) $(APP_MEMC)
|
||||
|
||||
CFLAGS_COMMON := -std=c11 -ffreestanding -fno-stack-protector -fno-builtin -Wall -Wextra -Werror -Iclks/include
|
||||
ASFLAGS_COMMON := -ffreestanding -Iclks/include
|
||||
LDFLAGS_COMMON := -nostdlib -z max-page-size=0x1000
|
||||
|
||||
.PHONY: all setup setup-tools setup-limine kernel userapps ramdisk-root ramdisk iso run debug clean clean-all help
|
||||
.PHONY: all configure reconfigure setup setup-tools setup-limine kernel userapps ramdisk-root ramdisk iso run debug clean clean-all help
|
||||
|
||||
all: iso
|
||||
|
||||
setup: setup-tools setup-limine
|
||||
> $(call log_info,environment ready)
|
||||
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)
|
||||
|
||||
setup-tools:
|
||||
> $(call log_step,checking host tools)
|
||||
> @command -v git >/dev/null 2>&1 || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) missing tool: git" && exit 1)
|
||||
> @command -v $(TAR) >/dev/null 2>&1 || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) missing tool: $(TAR)" && exit 1)
|
||||
> @command -v $(XORRISO) >/dev/null 2>&1 || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) missing tool: $(XORRISO)" && exit 1)
|
||||
> @command -v clang >/dev/null 2>&1 || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) missing tool: clang" && exit 1)
|
||||
> @command -v ld.lld >/dev/null 2>&1 || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) missing tool: ld.lld" && exit 1)
|
||||
> @command -v $(OBJCOPY_FOR_TARGET) >/dev/null 2>&1 || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) missing tool: $(OBJCOPY_FOR_TARGET)" && exit 1)
|
||||
> @command -v $(OBJDUMP_FOR_TARGET) >/dev/null 2>&1 || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) missing tool: $(OBJDUMP_FOR_TARGET)" && exit 1)
|
||||
> @command -v $(READELF_FOR_TARGET) >/dev/null 2>&1 || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) missing tool: $(READELF_FOR_TARGET)" && exit 1)
|
||||
> @command -v $(USER_CC) >/dev/null 2>&1 || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) missing tool: $(USER_CC)" && exit 1)
|
||||
> @command -v $(USER_LD) >/dev/null 2>&1 || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) missing tool: $(USER_LD)" && exit 1)
|
||||
> @command -v $(RUSTC) >/dev/null 2>&1 || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) missing tool: $(RUSTC)" && exit 1)
|
||||
> $(call log_info,required tools are available)
|
||||
reconfigure:
|
||||
> @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)"
|
||||
|
||||
setup-limine:
|
||||
> $(call log_step,preparing limine)
|
||||
> @if [ ! -d "$(LIMINE_DIR)" ]; then \
|
||||
> if [ -n "$(LIMINE_REF)" ]; then \
|
||||
> printf '%b\n' "$(COLOR_INFO)[INFO]$(COLOR_RESET) cloning limine ($(LIMINE_REF)) into $(LIMINE_DIR)"; \
|
||||
> git clone --branch "$(LIMINE_REF)" --depth 1 "$(LIMINE_REPO)" "$(LIMINE_DIR)"; \
|
||||
> else \
|
||||
> printf '%b\n' "$(COLOR_INFO)[INFO]$(COLOR_RESET) cloning limine (default branch) into $(LIMINE_DIR)"; \
|
||||
> git clone --depth 1 "$(LIMINE_REPO)" "$(LIMINE_DIR)"; \
|
||||
> fi; \
|
||||
> fi
|
||||
> @if [ "$(LIMINE_SKIP_CONFIGURE)" = "1" ]; then \
|
||||
> test -f "$(LIMINE_DIR)/Makefile" || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) LIMINE_SKIP_CONFIGURE=1 but $(LIMINE_DIR)/Makefile is missing" && exit 1); \
|
||||
> printf '%b\n' "$(COLOR_WARN)[WARN]$(COLOR_RESET) skipping limine Makefile generation (LIMINE_SKIP_CONFIGURE=1)"; \
|
||||
> else \
|
||||
> cfg_fingerprint="FLAGS=$(LIMINE_CONFIGURE_FLAGS);OBJCOPY=$(OBJCOPY_FOR_TARGET);OBJDUMP=$(OBJDUMP_FOR_TARGET);READELF=$(READELF_FOR_TARGET)"; \
|
||||
> need_configure=0; \
|
||||
> if [ ! -f "$(LIMINE_DIR)/Makefile" ]; then need_configure=1; fi; \
|
||||
> if [ ! -f "$(LIMINE_SETUP_STAMP)" ]; then need_configure=1; fi; \
|
||||
> if [ -f "$(LIMINE_SETUP_STAMP)" ] && ! grep -qx "$$cfg_fingerprint" "$(LIMINE_SETUP_STAMP)"; then need_configure=1; fi; \
|
||||
> if [ "$$need_configure" -eq 1 ]; then \
|
||||
> printf '%b\n' "$(COLOR_STEP)[STEP]$(COLOR_RESET) generating/reconfiguring limine Makefile"; \
|
||||
> if [ -x "$(LIMINE_DIR)/bootstrap" ]; then \
|
||||
> (cd "$(LIMINE_DIR)" && ./bootstrap); \
|
||||
> fi; \
|
||||
> test -x "$(LIMINE_DIR)/configure" || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) limine configure script missing" && exit 1); \
|
||||
> (cd "$(LIMINE_DIR)" && OBJCOPY_FOR_TARGET="$(OBJCOPY_FOR_TARGET)" OBJDUMP_FOR_TARGET="$(OBJDUMP_FOR_TARGET)" READELF_FOR_TARGET="$(READELF_FOR_TARGET)" ./configure $(LIMINE_CONFIGURE_FLAGS)); \
|
||||
> printf '%s\n' "$$cfg_fingerprint" > "$(LIMINE_SETUP_STAMP)"; \
|
||||
> rm -f "$(LIMINE_BUILD_STAMP)"; \
|
||||
> else \
|
||||
> printf '%b\n' "$(COLOR_INFO)[INFO]$(COLOR_RESET) limine configure state unchanged"; \
|
||||
> fi; \
|
||||
> fi
|
||||
> @need_build=0; \
|
||||
> if [ ! -f "$(LIMINE_BUILD_STAMP)" ]; then need_build=1; fi; \
|
||||
> for f in limine limine-bios.sys limine-bios-cd.bin limine-uefi-cd.bin; do \
|
||||
> if [ ! -f "$(LIMINE_BIN_DIR)/$$f" ]; then need_build=1; fi; \
|
||||
> done; \
|
||||
> if [ "$$need_build" -eq 1 ]; then \
|
||||
> printf '%b\n' "$(COLOR_INFO)[INFO]$(COLOR_RESET) building limine"; \
|
||||
> $(MAKE) -C "$(LIMINE_DIR)"; \
|
||||
> touch "$(LIMINE_BUILD_STAMP)"; \
|
||||
> else \
|
||||
> printf '%b\n' "$(COLOR_INFO)[INFO]$(COLOR_RESET) limine already built, skipping compile"; \
|
||||
> fi
|
||||
> @test -f "$(LIMINE_BIN_DIR)/limine" || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) limine build failed" && exit 1)
|
||||
> @test -f "$(LIMINE_BIN_DIR)/limine-bios.sys" || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) limine-bios.sys missing" && exit 1)
|
||||
> @test -f "$(LIMINE_BIN_DIR)/limine-bios-cd.bin" || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) limine-bios-cd.bin missing" && exit 1)
|
||||
> @test -f "$(LIMINE_BIN_DIR)/limine-uefi-cd.bin" || (printf '%b\n' "$(COLOR_ERROR)[ERROR]$(COLOR_RESET) limine-uefi-cd.bin missing" && exit 1)
|
||||
> $(call log_info,limine artifacts ready)
|
||||
setup: configure
|
||||
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target setup
|
||||
|
||||
kernel: $(KERNEL_ELF)
|
||||
setup-tools: configure
|
||||
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target setup-tools
|
||||
|
||||
userapps: $(USER_APPS)
|
||||
> $(call log_info,user elf apps ready)
|
||||
setup-limine: configure
|
||||
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target setup-limine
|
||||
|
||||
ramdisk-root: userapps
|
||||
> $(call log_step,staging ramdisk root -> $(RAMDISK_ROOT))
|
||||
> @rm -rf $(RAMDISK_ROOT)
|
||||
> @mkdir -p $(RAMDISK_ROOT)
|
||||
> @cp -a ramdisk/. $(RAMDISK_ROOT)/
|
||||
> @mkdir -p $(RAMDISK_ROOT)/system $(RAMDISK_ROOT)/shell $(RAMDISK_ROOT)/driver
|
||||
> @cp $(APP_SHELL) $(RAMDISK_ROOT)/shell/shell.elf
|
||||
> @cp $(APP_ELFRUNNER) $(RAMDISK_ROOT)/system/elfrunner.elf
|
||||
> @cp $(APP_MEMC) $(RAMDISK_ROOT)/system/memc.elf
|
||||
> @cp $(APP_TTYDRV) $(RAMDISK_ROOT)/driver/ttydrv.elf
|
||||
kernel: configure
|
||||
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target kernel
|
||||
|
||||
ramdisk: $(RAMDISK_IMAGE)
|
||||
userapps: configure
|
||||
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target userapps
|
||||
|
||||
$(KERNEL_ELF): $(OBJECTS) $(LINKER_SCRIPT) Makefile
|
||||
> $(call log_step,linking kernel -> $(KERNEL_ELF))
|
||||
> @mkdir -p $(dir $@)
|
||||
> @$(LD) $(LDFLAGS_COMMON) -T $(LINKER_SCRIPT) -o $@ $(OBJECTS)
|
||||
ramdisk-root: configure
|
||||
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target ramdisk-root
|
||||
|
||||
$(OBJ_ROOT)/%.o: %.c Makefile
|
||||
> $(call log_step,compiling $<)
|
||||
> @mkdir -p $(dir $@)
|
||||
> @$(CC) $(CFLAGS_COMMON) $(ARCH_CFLAGS) -c $< -o $@
|
||||
ramdisk: configure
|
||||
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target ramdisk
|
||||
|
||||
$(OBJ_ROOT)/%.o: %.S Makefile
|
||||
> $(call log_step,assembling $<)
|
||||
> @mkdir -p $(dir $@)
|
||||
> @$(CC) $(ASFLAGS_COMMON) $(ARCH_CFLAGS) -c $< -o $@
|
||||
iso: configure
|
||||
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target iso
|
||||
|
||||
$(USER_OBJ_ROOT)/%.o: %.c Makefile
|
||||
> $(call log_step,compiling user $<)
|
||||
> @mkdir -p $(dir $@)
|
||||
> @$(USER_CC) $(USER_CFLAGS) -c $< -o $@
|
||||
run: configure
|
||||
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target run
|
||||
|
||||
$(USER_RUST_LIB): cleonos/rust/src/lib.rs Makefile
|
||||
> $(call log_step,building rust user lib)
|
||||
> @mkdir -p $(dir $@)
|
||||
> @$(RUSTC) --crate-type staticlib -C panic=abort -O $< -o $@
|
||||
|
||||
$(APP_SHELL): $(USER_COMMON_OBJECTS) $(USER_SHELL_OBJECT) $(USER_RUST_LIB) $(USER_LINKER_SCRIPT)
|
||||
> $(call log_step,linking user shell.elf)
|
||||
> @mkdir -p $(dir $@)
|
||||
> @$(USER_LD) $(USER_LDFLAGS) -o $@ $(USER_COMMON_OBJECTS) $(USER_SHELL_OBJECT) $(USER_RUST_LIB)
|
||||
|
||||
$(APP_TTYDRV): $(USER_COMMON_OBJECTS) $(USER_TTYDRV_OBJECT) $(USER_LINKER_SCRIPT)
|
||||
> $(call log_step,linking user ttydrv.elf)
|
||||
> @mkdir -p $(dir $@)
|
||||
> @$(USER_LD) $(USER_LDFLAGS) -o $@ $(USER_COMMON_OBJECTS) $(USER_TTYDRV_OBJECT)
|
||||
|
||||
$(APP_ELFRUNNER): $(USER_ELFRUNNER_KOBJ) $(KELF_LINKER_SCRIPT)
|
||||
> $(call log_step,linking kernel-elf elfrunner.elf)
|
||||
> @mkdir -p $(dir $@)
|
||||
> @$(USER_LD) $(KELF_LDFLAGS) -o $@ $(USER_ELFRUNNER_KOBJ)
|
||||
|
||||
$(APP_MEMC): $(USER_MEMC_KOBJ) $(KELF_LINKER_SCRIPT)
|
||||
> $(call log_step,linking kernel-elf memc.elf)
|
||||
> @mkdir -p $(dir $@)
|
||||
> @$(USER_LD) $(KELF_LDFLAGS) -o $@ $(USER_MEMC_KOBJ)
|
||||
|
||||
$(RAMDISK_IMAGE): ramdisk-root Makefile
|
||||
> $(call log_step,packing ramdisk -> $(RAMDISK_IMAGE))
|
||||
> @mkdir -p $(dir $@)
|
||||
> @$(TAR) -C $(RAMDISK_ROOT) -cf $@ .
|
||||
|
||||
iso: setup-tools setup-limine $(KERNEL_ELF) $(RAMDISK_IMAGE) configs/limine.conf
|
||||
> $(call log_step,assembling iso root)
|
||||
> @rm -rf $(ISO_ROOT)
|
||||
> @mkdir -p $(ISO_ROOT)/boot/limine
|
||||
> @cp $(KERNEL_ELF) $(ISO_ROOT)/boot/clks_kernel.elf
|
||||
> @cp $(RAMDISK_IMAGE) $(ISO_ROOT)/boot/cleonos_ramdisk.tar
|
||||
> @cp configs/limine.conf $(ISO_ROOT)/boot/limine/limine.conf
|
||||
> @cp $(LIMINE_BIN_DIR)/limine-bios.sys $(ISO_ROOT)/boot/limine/
|
||||
> @cp $(LIMINE_BIN_DIR)/limine-bios-cd.bin $(ISO_ROOT)/boot/limine/
|
||||
> @cp $(LIMINE_BIN_DIR)/limine-uefi-cd.bin $(ISO_ROOT)/boot/limine/
|
||||
> @mkdir -p $(dir $(ISO_IMAGE))
|
||||
> $(call log_step,building iso -> $(ISO_IMAGE))
|
||||
> @$(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)
|
||||
> $(call log_step,installing limine boot sectors)
|
||||
> @$(LIMINE_BIN_DIR)/limine bios-install $(ISO_IMAGE)
|
||||
> $(call log_info,iso ready: $(ISO_IMAGE))
|
||||
|
||||
run: iso
|
||||
> $(call log_step,launching qemu run)
|
||||
> @$(RUN_COMMAND)
|
||||
|
||||
debug: iso
|
||||
> $(call log_step,launching qemu debug (-s -S))
|
||||
> @$(DEBUG_COMMAND)
|
||||
debug: configure
|
||||
> @$(CMAKE) --build $(CMAKE_BUILD_DIR) --target debug
|
||||
|
||||
clean:
|
||||
> $(call log_step,cleaning $(BUILD_ROOT))
|
||||
> @rm -rf $(BUILD_ROOT)
|
||||
> $(call log_info,clean done)
|
||||
> @if [ -d "$(CMAKE_BUILD_DIR)" ]; then \
|
||||
> $(CMAKE) --build $(CMAKE_BUILD_DIR) --target clean-x86; \
|
||||
> else \
|
||||
> rm -rf build/x86_64; \
|
||||
> fi
|
||||
|
||||
clean-all:
|
||||
> $(call log_step,cleaning build)
|
||||
> @rm -rf build
|
||||
> $(call log_info,clean-all done)
|
||||
> @if [ -d "$(CMAKE_BUILD_DIR)" ]; then \
|
||||
> $(CMAKE) --build $(CMAKE_BUILD_DIR) --target clean-all; \
|
||||
> else \
|
||||
> rm -rf build build-cmake; \
|
||||
> fi
|
||||
|
||||
help:
|
||||
> @echo "CLeonOS build system (x86_64 only)"
|
||||
> @echo "CLeonOS (CMake-backed wrapper)"
|
||||
> @echo " make configure"
|
||||
> @echo " make setup"
|
||||
> @echo " make setup LIMINE_REF=<branch-or-tag>"
|
||||
> @echo " make setup LIMINE_SKIP_CONFIGURE=1"
|
||||
> @echo " make setup LIMINE_CONFIGURE_FLAGS='--enable-bios-cd --enable-uefi-cd --enable-uefi-x86-64'"
|
||||
> @echo " make setup OBJCOPY_FOR_TARGET=llvm-objcopy OBJDUMP_FOR_TARGET=llvm-objdump READELF_FOR_TARGET=llvm-readelf"
|
||||
> @echo " make userapps"
|
||||
> @echo " make iso"
|
||||
> @echo " make run"
|
||||
> @echo " make debug"
|
||||
> @echo " make NO_COLOR=1 <target>"
|
||||
> @echo " make clean"
|
||||
> @echo " make clean-all"
|
||||
> @echo ""
|
||||
> @echo "Pass custom CMake cache args via:"
|
||||
> @echo " make configure CMAKE_EXTRA_ARGS='-DLIMINE_SKIP_CONFIGURE=1 -DOBJCOPY_FOR_TARGET=objcopy'"
|
||||
> @echo "Direct passthrough is also supported:"
|
||||
> @echo " make run LIMINE_SKIP_CONFIGURE=1"
|
||||
|
||||
38
cmake/check_tools.cmake
Normal file
38
cmake/check_tools.cmake
Normal file
@@ -0,0 +1,38 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/log.cmake")
|
||||
|
||||
function(require_tool TOOL_VALUE)
|
||||
if("${TOOL_VALUE}" STREQUAL "")
|
||||
cl_log_error("missing tool name")
|
||||
endif()
|
||||
|
||||
if(IS_ABSOLUTE "${TOOL_VALUE}")
|
||||
if(NOT EXISTS "${TOOL_VALUE}")
|
||||
cl_log_error("missing tool: ${TOOL_VALUE}")
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_program(_tool_path NAMES "${TOOL_VALUE}")
|
||||
if(NOT _tool_path)
|
||||
cl_log_error("missing tool: ${TOOL_VALUE}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
cl_log_step("checking host tools")
|
||||
|
||||
require_tool("${GIT_TOOL}")
|
||||
require_tool("${TAR_TOOL}")
|
||||
require_tool("${XORRISO_TOOL}")
|
||||
require_tool("${CC_TOOL}")
|
||||
require_tool("${LD_TOOL}")
|
||||
require_tool("${OBJCOPY_TOOL}")
|
||||
require_tool("${OBJDUMP_TOOL}")
|
||||
require_tool("${READELF_TOOL}")
|
||||
require_tool("${USER_CC_TOOL}")
|
||||
require_tool("${USER_LD_TOOL}")
|
||||
require_tool("${RUSTC_TOOL}")
|
||||
require_tool("${MAKE_TOOL}")
|
||||
require_tool("${SH_TOOL}")
|
||||
|
||||
cl_log_info("required tools are available")
|
||||
36
cmake/log.cmake
Normal file
36
cmake/log.cmake
Normal file
@@ -0,0 +1,36 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
if(NOT DEFINED NO_COLOR)
|
||||
set(NO_COLOR 0)
|
||||
endif()
|
||||
|
||||
if(NO_COLOR)
|
||||
set(CL_LOG_RESET "")
|
||||
set(CL_LOG_INFO "")
|
||||
set(CL_LOG_WARN "")
|
||||
set(CL_LOG_ERROR "")
|
||||
set(CL_LOG_STEP "")
|
||||
else()
|
||||
string(ASCII 27 CL_LOG_ESC)
|
||||
set(CL_LOG_RESET "${CL_LOG_ESC}[0m")
|
||||
set(CL_LOG_INFO "${CL_LOG_ESC}[1;36m")
|
||||
set(CL_LOG_WARN "${CL_LOG_ESC}[1;33m")
|
||||
set(CL_LOG_ERROR "${CL_LOG_ESC}[1;31m")
|
||||
set(CL_LOG_STEP "${CL_LOG_ESC}[1;35m")
|
||||
endif()
|
||||
|
||||
function(cl_log_step TEXT)
|
||||
message(NOTICE "${CL_LOG_STEP}[STEP]${CL_LOG_RESET} ${TEXT}")
|
||||
endfunction()
|
||||
|
||||
function(cl_log_info TEXT)
|
||||
message(NOTICE "${CL_LOG_INFO}[INFO]${CL_LOG_RESET} ${TEXT}")
|
||||
endfunction()
|
||||
|
||||
function(cl_log_warn TEXT)
|
||||
message(NOTICE "${CL_LOG_WARN}[WARN]${CL_LOG_RESET} ${TEXT}")
|
||||
endfunction()
|
||||
|
||||
function(cl_log_error TEXT)
|
||||
message(FATAL_ERROR "${CL_LOG_ERROR}[ERROR]${CL_LOG_RESET} ${TEXT}")
|
||||
endfunction()
|
||||
118
cmake/setup_limine.cmake
Normal file
118
cmake/setup_limine.cmake
Normal file
@@ -0,0 +1,118 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/log.cmake")
|
||||
|
||||
function(run_cmd)
|
||||
set(options)
|
||||
set(oneValueArgs WORKING_DIRECTORY)
|
||||
set(multiValueArgs COMMAND)
|
||||
cmake_parse_arguments(RUN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if("${RUN_WORKING_DIRECTORY}" STREQUAL "")
|
||||
execute_process(COMMAND ${RUN_COMMAND} RESULT_VARIABLE _rv)
|
||||
else()
|
||||
execute_process(COMMAND ${RUN_COMMAND} WORKING_DIRECTORY "${RUN_WORKING_DIRECTORY}" RESULT_VARIABLE _rv)
|
||||
endif()
|
||||
|
||||
if(NOT _rv EQUAL 0)
|
||||
string(REPLACE ";" " " _cmd "${RUN_COMMAND}")
|
||||
cl_log_error("command failed (${_rv}): ${_cmd}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
cl_log_step("preparing limine")
|
||||
set(_limine_makefile_missing FALSE)
|
||||
|
||||
if(NOT EXISTS "${LIMINE_DIR}")
|
||||
if("${LIMINE_REF}" STREQUAL "")
|
||||
cl_log_info("cloning limine (default branch) into ${LIMINE_DIR}")
|
||||
run_cmd(COMMAND "${GIT_TOOL}" clone --depth 1 "${LIMINE_REPO}" "${LIMINE_DIR}")
|
||||
else()
|
||||
cl_log_info("cloning limine (${LIMINE_REF}) into ${LIMINE_DIR}")
|
||||
run_cmd(COMMAND "${GIT_TOOL}" clone --branch "${LIMINE_REF}" --depth 1 "${LIMINE_REPO}" "${LIMINE_DIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(LIMINE_SKIP_CONFIGURE)
|
||||
if(NOT EXISTS "${LIMINE_DIR}/Makefile")
|
||||
set(_limine_makefile_missing TRUE)
|
||||
cl_log_warn("LIMINE_SKIP_CONFIGURE=1 but ${LIMINE_DIR}/Makefile is missing; continue with existing limine binaries")
|
||||
endif()
|
||||
cl_log_warn("skipping limine Makefile generation (LIMINE_SKIP_CONFIGURE=1)")
|
||||
else()
|
||||
set(cfg_fingerprint "FLAGS=${LIMINE_CONFIGURE_FLAGS};OBJCOPY=${OBJCOPY_FOR_TARGET};OBJDUMP=${OBJDUMP_FOR_TARGET};READELF=${READELF_FOR_TARGET}")
|
||||
|
||||
set(need_configure FALSE)
|
||||
if(NOT EXISTS "${LIMINE_DIR}/Makefile")
|
||||
set(need_configure TRUE)
|
||||
endif()
|
||||
if(NOT EXISTS "${LIMINE_SETUP_STAMP}")
|
||||
set(need_configure TRUE)
|
||||
endif()
|
||||
|
||||
if(EXISTS "${LIMINE_SETUP_STAMP}")
|
||||
file(READ "${LIMINE_SETUP_STAMP}" _stamp_content)
|
||||
string(STRIP "${_stamp_content}" _stamp_content)
|
||||
if(NOT _stamp_content STREQUAL cfg_fingerprint)
|
||||
set(need_configure TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(need_configure)
|
||||
cl_log_step("generating/reconfiguring limine Makefile")
|
||||
|
||||
if(EXISTS "${LIMINE_DIR}/bootstrap")
|
||||
run_cmd(COMMAND "${SH_TOOL}" "./bootstrap" WORKING_DIRECTORY "${LIMINE_DIR}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${LIMINE_DIR}/configure")
|
||||
cl_log_error("limine configure script missing")
|
||||
endif()
|
||||
|
||||
separate_arguments(_cfg_flags UNIX_COMMAND "${LIMINE_CONFIGURE_FLAGS}")
|
||||
run_cmd(
|
||||
COMMAND
|
||||
"${CMAKE_COMMAND}" -E env
|
||||
"OBJCOPY_FOR_TARGET=${OBJCOPY_FOR_TARGET}"
|
||||
"OBJDUMP_FOR_TARGET=${OBJDUMP_FOR_TARGET}"
|
||||
"READELF_FOR_TARGET=${READELF_FOR_TARGET}"
|
||||
"${SH_TOOL}" "./configure" ${_cfg_flags}
|
||||
WORKING_DIRECTORY "${LIMINE_DIR}"
|
||||
)
|
||||
|
||||
file(WRITE "${LIMINE_SETUP_STAMP}" "${cfg_fingerprint}\n")
|
||||
file(REMOVE "${LIMINE_BUILD_STAMP}")
|
||||
else()
|
||||
cl_log_info("limine configure state unchanged")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(need_build FALSE)
|
||||
if(NOT EXISTS "${LIMINE_BUILD_STAMP}")
|
||||
set(need_build TRUE)
|
||||
endif()
|
||||
|
||||
foreach(_bin limine limine-bios.sys limine-bios-cd.bin limine-uefi-cd.bin)
|
||||
if(NOT EXISTS "${LIMINE_BIN_DIR}/${_bin}")
|
||||
set(need_build TRUE)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(need_build)
|
||||
if(_limine_makefile_missing)
|
||||
cl_log_warn("limine Makefile missing, skip limine build and use existing artifacts only")
|
||||
else()
|
||||
cl_log_info("building limine")
|
||||
run_cmd(COMMAND "${MAKE_TOOL}" -C "${LIMINE_DIR}")
|
||||
file(WRITE "${LIMINE_BUILD_STAMP}" "built\n")
|
||||
endif()
|
||||
else()
|
||||
cl_log_info("limine already built, skipping compile")
|
||||
endif()
|
||||
|
||||
foreach(_required limine limine-bios.sys limine-bios-cd.bin limine-uefi-cd.bin)
|
||||
if(NOT EXISTS "${LIMINE_BIN_DIR}/${_required}")
|
||||
cl_log_error("${_required} missing in ${LIMINE_BIN_DIR}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
cl_log_info("limine artifacts ready")
|
||||
Reference in New Issue
Block a user