# The Moon kernel for Luna.

file(GLOB_RECURSE HEADERS src/*.h)

set(SOURCES 
    ${HEADERS}
    src/main.cpp
    src/Log.cpp
    src/Pledge.cpp
    src/cxxabi.cpp
    src/video/Framebuffer.cpp
    src/video/TextConsole.cpp
    src/memory/MemoryManager.cpp
    src/memory/Heap.cpp
    src/memory/KernelVM.cpp
    src/memory/AddressSpace.cpp
    src/memory/MemoryMap.cpp
    src/memory/SharedMemory.cpp
    src/boot/Init.cpp
    src/arch/Serial.cpp
    src/arch/Timer.cpp
    src/arch/PCI.cpp
    src/thread/Thread.cpp
    src/thread/ThreadImage.cpp
    src/thread/Scheduler.cpp
    src/sys/Syscall.cpp
    src/sys/exit.cpp
    src/sys/clock_gettime.cpp
    src/sys/mmap.cpp
    src/sys/usleep.cpp
    src/sys/open.cpp
    src/sys/exec.cpp
    src/sys/file.cpp
    src/sys/id.cpp
    src/sys/mkdir.cpp
    src/sys/pstat.cpp
    src/sys/waitpid.cpp
    src/sys/getdents.cpp
    src/sys/stat.cpp
    src/sys/chdir.cpp
    src/sys/link.cpp
    src/sys/uname.cpp
    src/sys/mount.cpp
    src/sys/resource.cpp
    src/sys/signal.cpp
    src/sys/socket.cpp
    src/sys/poll.cpp
    src/sys/alarm.cpp
    src/sys/pledge.cpp
    src/sys/memstat.cpp
    src/fs/VFS.cpp
    src/fs/Pipe.cpp
    src/fs/Mount.cpp
    src/fs/MBR.cpp
    src/fs/GPT.cpp
    src/fs/StorageCache.cpp
    src/net/UnixSocket.cpp
    src/fs/tmpfs/FileSystem.cpp
    src/fs/tmpfs/Inode.cpp
    src/fs/ext2/FileSystem.cpp
    src/fs/ext2/Inode.cpp
    src/fs/devices/DeviceRegistry.cpp
    src/fs/devices/BlockDevice.cpp
    src/fs/devices/NullDevice.cpp
    src/fs/devices/ZeroDevice.cpp
    src/fs/devices/FullDevice.cpp
    src/fs/devices/ConsoleDevice.cpp
    src/fs/devices/FramebufferDevice.cpp
    src/fs/devices/UARTDevice.cpp
    src/fs/devices/MouseDevice.cpp
    src/fs/devices/KeyboardDevice.cpp
    src/fs/InitRD.cpp
    src/binfmt/ELF.cpp
    src/binfmt/BinaryFormat.cpp
    src/binfmt/Script.cpp
)

if("${LUNA_ARCH}" MATCHES "x86_64")
    set(SOURCES
        ${SOURCES}
        src/arch/x86_64/IO.cpp
        src/arch/x86_64/Serial.cpp
        src/arch/x86_64/MMU.cpp
        src/arch/x86_64/CPU.cpp
        src/arch/x86_64/Timer.cpp
        src/arch/x86_64/Thread.cpp
        src/arch/x86_64/PCI.cpp
        src/arch/x86_64/Keyboard.cpp
        src/arch/x86_64/disk/ATA.cpp
        src/arch/x86_64/init/GDT.cpp
        src/arch/x86_64/init/IDT.cpp
        src/arch/x86_64/init/PIC.cpp
        src/arch/x86_64/PS2Mouse.cpp
    )
endif()

add_executable(moon ${SOURCES})

if("${LUNA_ARCH}" MATCHES "x86_64")
    set(ASM_SOURCES
        src/arch/x86_64/CPU.asm
        src/arch/x86_64/Entry.asm
    )
    add_library(moon-asm STATIC ${ASM_SOURCES})
    target_link_libraries(moon moon-asm)
endif()

target_link_libraries(moon luna-freestanding)

target_compile_definitions(moon PRIVATE IN_MOON)

target_compile_options(moon PRIVATE ${COMMON_FLAGS})
target_compile_options(moon PRIVATE -nostdlib -mcmodel=kernel -ffreestanding)

if("${LUNA_ARCH}" MATCHES "x86_64")
    target_compile_options(moon PRIVATE -mno-red-zone)
    target_compile_options(moon PRIVATE -mno-80387 -mno-mmx -mno-sse -mno-sse2)
    target_link_options(moon PRIVATE -mno-red-zone)
endif()

if(MOON_DEBUG)
    include(debug.cmake)
endif()

if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/config.cmake)
    message(STATUS "Using custom config.cmake file")
    include(config.cmake)
endif()

if(BUILD_TESTS)
target_compile_definitions(moon PRIVATE MOON_ENABLE_TESTING_FEATURES)
endif()

target_link_options(moon PRIVATE -lgcc -Wl,--build-id=none -z max-page-size=0x1000 -mcmodel=kernel)

set_target_properties(moon PROPERTIES CXX_STANDARD 20)

target_include_directories(moon PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src)
target_include_directories(moon PRIVATE ${LUNA_BASE}/usr/include)

configure_file(src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/gen/config.h @ONLY)

target_include_directories(moon PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/gen)

target_link_options(moon PRIVATE LINKER:-T ${CMAKE_CURRENT_LIST_DIR}/moon.ld -nostdlib -nodefaultlibs)

install(FILES "${CMAKE_CURRENT_BINARY_DIR}/moon" DESTINATION ${LUNA_ROOT}/initrd/boot)