Files
ksOS/Kernel/CMakeLists.txt
T

150 lines
4.9 KiB
CMake

cmake_minimum_required(VERSION 3.20)
project(ksOSKernel LANGUAGES ASM C)
set(KERNEL_MODULE_NAME "Kernel")
# --- Locate Swift toolchain with Embedded Swift stdlib ---
# Priority: cmake var > env var > auto-detect
if(NOT SWIFT_TOOLCHAIN AND DEFINED ENV{SWIFT_TOOLCHAIN})
set(SWIFT_TOOLCHAIN "$ENV{SWIFT_TOOLCHAIN}")
endif()
if(SWIFT_TOOLCHAIN)
set(SWIFTC "${SWIFT_TOOLCHAIN}/usr/bin/swiftc")
set(SWIFT_RESOURCE_DIR "${SWIFT_TOOLCHAIN}/usr/lib/swift")
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
# Scan for a swift.org toolchain that ships the embedded stdlib.
# APPLE is false here (target is Generic), so we check the HOST OS.
file(GLOB _tc_candidates
"$ENV{HOME}/Library/Developer/Toolchains/*.xctoolchain"
"/Library/Developer/Toolchains/*.xctoolchain"
)
foreach(_tc ${_tc_candidates})
if(EXISTS "${_tc}/usr/lib/swift/embedded")
set(SWIFTC "${_tc}/usr/bin/swiftc")
set(SWIFT_RESOURCE_DIR "${_tc}/usr/lib/swift")
break()
endif()
endforeach()
else()
# Linux: find swiftc in PATH
find_program(_SWIFTC_EXE swiftc)
if(_SWIFTC_EXE)
get_filename_component(_SWIFTC_BIN "${_SWIFTC_EXE}" DIRECTORY)
get_filename_component(_SWIFTC_USR "${_SWIFTC_BIN}" DIRECTORY)
if(EXISTS "${_SWIFTC_USR}/lib/swift/embedded")
set(SWIFTC "${_SWIFTC_EXE}")
set(SWIFT_RESOURCE_DIR "${_SWIFTC_USR}/lib/swift")
elseif(EXISTS "${_SWIFTC_USR}/lib/swift/lib/swift/embedded")
set(SWIFTC "${_SWIFTC_EXE}")
set(SWIFT_RESOURCE_DIR "${_SWIFTC_USR}/lib/swift/lib/swift")
endif()
endif()
endif()
if(NOT SWIFTC OR NOT EXISTS "${SWIFT_RESOURCE_DIR}/embedded")
message(FATAL_ERROR
"Swift toolchain with Embedded Swift not found.\n"
"Install a swift.org toolchain and pass -DSWIFT_TOOLCHAIN=<root> "
"or set the SWIFT_TOOLCHAIN env var.")
endif()
message(STATUS "Swift: ${SWIFTC}")
message(STATUS "Swift resource dir: ${SWIFT_RESOURCE_DIR}")
# --- Build ---
add_compile_options(-ffreestanding -nostdlib -O0 -g)
set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld)
add_link_options(
-fuse-ld=lld
-nostdlib
-static
-Wl,-T,${LINKER_SCRIPT}
)
set(SWIFT_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/Source/kernel.swift
${CMAKE_CURRENT_SOURCE_DIR}/Source/Arch/dtb.swift
${CMAKE_CURRENT_SOURCE_DIR}/Source/IO/uart.swift
)
set(SWIFT_OBJ ${CMAKE_CURRENT_BINARY_DIR}/kernel_swift.o)
add_custom_command(
OUTPUT ${SWIFT_OBJ}
COMMAND ${SWIFTC}
-target aarch64-none-none-elf
-enable-experimental-feature Embedded
-parse-as-library
-wmo
-O
-Xcc -fno-stack-protector
-Xcc -I${CMAKE_CURRENT_SOURCE_DIR}/../Common
-import-bridging-header ${CMAKE_CURRENT_SOURCE_DIR}/Source/Support/BridgingHeader.h
-resource-dir ${SWIFT_RESOURCE_DIR}
-c ${SWIFT_SOURCES}
-o ${SWIFT_OBJ}
COMMAND ${LLVM_OBJCOPY} --remove-section=.swift_modhash ${SWIFT_OBJ}
DEPENDS ${SWIFT_SOURCES}
COMMENT "Compiling Swift kernel"
)
set_source_files_properties(${SWIFT_OBJ} PROPERTIES
EXTERNAL_OBJECT TRUE
GENERATED TRUE
)
add_executable(kernel.elf Source/Arch/entry.S Source/Support/stubs.c ${SWIFT_OBJ})
add_custom_command(TARGET kernel.elf POST_BUILD
COMMAND ${LLVM_OBJCOPY} -O binary kernel.elf kernel.bin
)
# --- SourceKit-LSP: generate compile_commands.json for Swift (Dynamic) ---
set(_BRIDGING_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/Source/Support/BridgingHeader.h")
set(SWIFT_ARGS
"\"${SWIFTC}\""
"\"-target\"" "\"aarch64-none-none-elf\""
"\"-enable-experimental-feature\"" "\"Embedded\""
"\"-module-name\"" "\"${KERNEL_MODULE_NAME}\""
"\"-parse-as-library\""
"\"-import-bridging-header\"" "\"${_BRIDGING_HEADER}\""
"\"-Xcc\"" "\"-I${CMAKE_CURRENT_SOURCE_DIR}/../Common\""
"\"-resource-dir\"" "\"${SWIFT_RESOURCE_DIR}\""
)
foreach(_src IN LISTS SWIFT_SOURCES)
list(APPEND SWIFT_ARGS "\"${_src}\"")
endforeach()
string(JOIN ", " SWIFT_ARGS_JSON ${SWIFT_ARGS})
set(COMPDB_ENTRIES "")
list(LENGTH SWIFT_SOURCES _src_count)
math(EXPR _last_idx "${_src_count} - 1")
set(_idx 0)
foreach(_src IN LISTS SWIFT_SOURCES)
set(_entry " {\n \"file\": \"${_src}\",\n \"directory\": \"${CMAKE_CURRENT_BINARY_DIR}\",\n \"arguments\": [${SWIFT_ARGS_JSON}]\n }")
if(_idx LESS _last_idx)
string(APPEND _entry ",\n")
else()
string(APPEND _entry "\n")
endif()
string(APPEND COMPDB_ENTRIES "${_entry}")
math(EXPR _idx "${_idx} + 1")
endforeach()
if(DEFINED ENV{TEMP_DIR})
set(COMPDB_OUTPUT_DIR "$ENV{TEMP_DIR}/Kernel")
elseif(DEFINED ENV{BUILD_DIR})
set(COMPDB_OUTPUT_DIR "$ENV{BUILD_DIR}/temp/Kernel")
else()
set(COMPDB_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
endif()
file(GENERATE OUTPUT "${COMPDB_OUTPUT_DIR}/compile_commands.json"
CONTENT "[\n${COMPDB_ENTRIES}]\n"
)