60 lines
2.6 KiB
CMake
60 lines
2.6 KiB
CMake
# Cross-compilation toolchain for i386-elf using Clang + LLD.
|
|
#
|
|
# This targets a bare-metal i386 (80386) environment with no host OS
|
|
# libraries. lld is used as the linker because the macOS system ld does
|
|
# not support the ELF32 output format required for a GRUB-bootable kernel.
|
|
|
|
set(CMAKE_SYSTEM_NAME Generic)
|
|
set(CMAKE_SYSTEM_PROCESSOR i386)
|
|
|
|
# Use Clang for both C and assembly.
|
|
set(CMAKE_C_COMPILER clang)
|
|
set(CMAKE_ASM_COMPILER clang)
|
|
|
|
# Prevent CMake from trying to run the cross-compiled test binaries.
|
|
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
|
|
|
# Target triple and architecture flags shared by all compilation steps.
|
|
set(CROSS_TARGET "i386-elf")
|
|
set(CROSS_ARCH_FLAGS "-target ${CROSS_TARGET} -m32 -march=i386 -mtune=i386")
|
|
|
|
# C compiler flags:
|
|
# - ffreestanding : no hosted C runtime assumptions
|
|
# - fno-stack-protector : no __stack_chk_fail dependency
|
|
# - fno-builtin : avoid implicit replacements of standard functions
|
|
set(CMAKE_C_FLAGS_INIT
|
|
"${CROSS_ARCH_FLAGS} -ffreestanding -fno-stack-protector -fno-builtin -Wall -Wextra"
|
|
)
|
|
|
|
# Assembler flags: only the flags the assembler front-end actually accepts.
|
|
# C-only flags like -ffreestanding, -fno-stack-protector, etc. must NOT be
|
|
# passed here — clang treats them as unused and errors out with -Werror.
|
|
# -Wno-unused-command-line-argument suppresses CMake's auto-added -MD/-MT/-MF
|
|
# dependency-tracking flags that clang ignores in pure assembler mode.
|
|
set(CMAKE_ASM_FLAGS_INIT
|
|
"-target ${CROSS_TARGET} -m32 -march=i386 -Wno-unused-command-line-argument"
|
|
)
|
|
|
|
# Linking:
|
|
# On aarch64 Alpine the clang driver delegates link steps to the host gcc,
|
|
# which does not support -m32 and therefore fails. Bypass the driver entirely
|
|
# and call ld.lld directly. The CMake rule variables below replace the normal
|
|
# "compile-with-compiler-driver" link invocation.
|
|
#
|
|
# Rule variables use these placeholders:
|
|
# <TARGET> — output binary path
|
|
# <OBJECTS> — all compiled object files
|
|
# <LINK_FLAGS> — extra flags from target_link_options / CMAKE_EXE_LINKER_FLAGS
|
|
# <LINK_LIBRARIES> — libraries to link (empty for a freestanding kernel)
|
|
set(CMAKE_LINKER "ld.lld")
|
|
set(CMAKE_C_LINK_EXECUTABLE
|
|
"ld.lld -m elf_i386 <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
|
set(CMAKE_ASM_LINK_EXECUTABLE
|
|
"ld.lld -m elf_i386 <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
|
|
|
# Keep CMake from accidentally picking up host system headers/libraries.
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|