Problems with CMake for OS Project

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Ovid
Posts: 22
Joined: Mon Jun 28, 2021 12:48 pm

Problems with CMake for OS Project

Post by Ovid »

Hi, I create an OS kernel project using cmake.
Here is my 'CMakeLists.txt':

Code: Select all

cmake_minimum_required(VERSION 3.16.3)

# Set the active output directories:
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY build/x86_64/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY build/x86_64/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY build/x86_64/bin)

project(kernel)

set(PROJECT_VERSION_MAJOR 0)
set(PROJECT_VERSION_MINOR 1)

set(CMAKE_CXX_STANDAED 17)

set(KERNEL_BIN "x86_64-kernel.bin")

set(LINKER_SCRIPT targets/x86_64/linker.ld)
set(GRUB_CFG targets/x86_64/iso/boot/grub/grub.cfg)

set(CMAKE_ASM_NASM_OBJECT_FORMAT "elf64")

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-red-zone -mcmodel=large -mno-sse -ffreestanding -nostdlib -fno-pie -fno-pic -no-pie")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mno-red-zone -mcmodel=large -mno-sse -ffreestanding -nostdlib -fno-pie -fno-pic -no-pie")
set(CMAKE_ASM_FLAGS "{CMAKE_ASM_FLAGS} -felf64")

set(CMAKE_CXX_COMPILER "/usr/bin/gcc")
set(CMAKE_C_COMPILER "/usr/bin/g++")
set(CMAKE_LINKER "/usr/bin/ld")

enable_language(ASM_NASM)

file(GLOB KERNEL_C_MODULES src/impl/kernel/*.c)
file(GLOB X86_64_C_MODULES src/impl/x86_64/*.c)
file(GLOB BOOT_ASM_MODULES src/impl/x86_64/boot/*.asm)

add_executable(
    ${KERNEL_BIN}
    
    ${KERNEL_C_MODULES}
    ${X86_64_C_MODULES}
    ${BOOT_ASM_MODULES}
    )

set(CMAKE_LINKER "/usr/bin/ld")
set(CMAKE_LINKER_FLAGS "-n -o -T ${LINKER_SCRIPT}")
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_LINKER> ${CMAKE_LINKER_FLAGS} <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")

include_directories(src/intf)
target_include_directories(${KERNEL_BIN} PUBLIC src/intf)

set_target_properties(${KERNEL_BIN} PROPERTIES LINK_FLAGS "-n -T ${LINKER_SCRIPT}")

add_custom_command(TARGET ${KERNEL_BIN} POST_BUILD
    COMMAND mkdir -p build/x86_64/boot/grub
    COMMAND cp ${KERNEL_BIN} build/x86_64/boot/${KERNEL_BIN}
    COMMAND cp ${GRUB_CFG} build/x86_64/boot/grub
    COMMAND grub-mkrescue -o kernel.iso build/x86_64/
    COMMAND rm -r build/
    )
When I try to compile the 'Makefile' that was generated, I get these results:
/usr/bin/cmake -S/home/odedbe/Desktop/GitHub/LearnOS/LearnOS -B/home/odedbe/Desktop/GitHub/LearnOS/LearnOS --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/odedbe/Desktop/GitHub/LearnOS/LearnOS/CMakeFiles /home/odedbe/Desktop/GitHub/LearnOS/LearnOS/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/odedbe/Desktop/GitHub/LearnOS/LearnOS'
make -f CMakeFiles/x86_64-kernel.bin.dir/build.make CMakeFiles/x86_64-kernel.bin.dir/depend
make[2]: Entering directory '/home/odedbe/Desktop/GitHub/LearnOS/LearnOS'
cd /home/odedbe/Desktop/GitHub/LearnOS/LearnOS && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/odedbe/Desktop/GitHub/LearnOS/LearnOS /home/odedbe/Desktop/GitHub/LearnOS/LearnOS /home/odedbe/Desktop/GitHub/LearnOS/LearnOS /home/odedbe/Desktop/GitHub/LearnOS/LearnOS /home/odedbe/Desktop/GitHub/LearnOS/LearnOS/CMakeFiles/x86_64-kernel.bin.dir/DependInfo.cmake --color=
Dependee "/home/odedbe/Desktop/GitHub/LearnOS/LearnOS/CMakeFiles/x86_64-kernel.bin.dir/DependInfo.cmake" is newer than depender "/home/odedbe/Desktop/GitHub/LearnOS/LearnOS/CMakeFiles/x86_64-kernel.bin.dir/depend.internal".
Dependee "/home/odedbe/Desktop/GitHub/LearnOS/LearnOS/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/odedbe/Desktop/GitHub/LearnOS/LearnOS/CMakeFiles/x86_64-kernel.bin.dir/depend.internal".
Scanning dependencies of target x86_64-kernel.bin
make[2]: Leaving directory '/home/odedbe/Desktop/GitHub/LearnOS/LearnOS'
make -f CMakeFiles/x86_64-kernel.bin.dir/build.make CMakeFiles/x86_64-kernel.bin.dir/build
make[2]: Entering directory '/home/odedbe/Desktop/GitHub/LearnOS/LearnOS'
[ 14%] Building C object CMakeFiles/x86_64-kernel.bin.dir/src/impl/kernel/main.c.o
/usr/bin/g++ -I/home/odedbe/Desktop/GitHub/LearnOS/LearnOS/src/intf -mno-red-zone -mcmodel=large -mno-sse -ffreestanding -nostdlib -fno-pie -fno-pic -no-pie -o CMakeFiles/x86_64-kernel.bin.dir/src/impl/kernel/main.c.o -c /home/odedbe/Desktop/GitHub/LearnOS/LearnOS/src/impl/kernel/main.c
[ 28%] Building C object CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/print.c.o
/usr/bin/g++ -I/home/odedbe/Desktop/GitHub/LearnOS/LearnOS/src/intf -mno-red-zone -mcmodel=large -mno-sse -ffreestanding -nostdlib -fno-pie -fno-pic -no-pie -o CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/print.c.o -c /home/odedbe/Desktop/GitHub/LearnOS/LearnOS/src/impl/x86_64/print.c
[ 42%] Building C object CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/terminal.c.o
/usr/bin/g++ -I/home/odedbe/Desktop/GitHub/LearnOS/LearnOS/src/intf -mno-red-zone -mcmodel=large -mno-sse -ffreestanding -nostdlib -fno-pie -fno-pic -no-pie -o CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/terminal.c.o -c /home/odedbe/Desktop/GitHub/LearnOS/LearnOS/src/impl/x86_64/terminal.c
[ 57%] Building ASM_NASM object CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/boot/header.asm.o
/usr/local/bin/nasm -I/home/odedbe/Desktop/GitHub/LearnOS/LearnOS/src/intf -f elf64 -o CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/boot/header.asm.o /home/odedbe/Desktop/GitHub/LearnOS/LearnOS/src/impl/x86_64/boot/header.asm
[ 71%] Building ASM_NASM object CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/boot/main.asm.o
/usr/local/bin/nasm -I/home/odedbe/Desktop/GitHub/LearnOS/LearnOS/src/intf -f elf64 -o CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/boot/main.asm.o /home/odedbe/Desktop/GitHub/LearnOS/LearnOS/src/impl/x86_64/boot/main.asm
[ 85%] Building ASM_NASM object CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/boot/main64.asm.o
/usr/local/bin/nasm -I/home/odedbe/Desktop/GitHub/LearnOS/LearnOS/src/intf -f elf64 -o CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/boot/main64.asm.o /home/odedbe/Desktop/GitHub/LearnOS/LearnOS/src/impl/x86_64/boot/main64.asm
[100%] Linking C executable build/x86_64/bin/x86_64-kernel.bin
/usr/bin/cmake -E cmake_link_script CMakeFiles/x86_64-kernel.bin.dir/link.txt --verbose=1
/usr/bin/g++ -mno-red-zone -mcmodel=large -mno-sse -ffreestanding -nostdlib -fno-pie -fno-pic -no-pie -n -T targets/x86_64/linker.ld CMakeFiles/x86_64-kernel.bin.dir/src/impl/kernel/main.c.o CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/print.c.o CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/terminal.c.o CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/boot/header.asm.o CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/boot/main.asm.o CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/boot/main64.asm.o -o build/x86_64/bin/x86_64-kernel.bin
/usr/bin/ld: CMakeFiles/x86_64-kernel.bin.dir/src/impl/x86_64/boot/main64.asm.o: in function `long_mode_start':
/home/odedbe/Desktop/GitHub/LearnOS/LearnOS/src/impl/x86_64/boot/main64.asm:(.text+0xf): undefined reference to `kernel_main'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/x86_64-kernel.bin.dir/build.make:135: build/x86_64/bin/x86_64-kernel.bin] Error 1
make[2]: Leaving directory '/home/odedbe/Desktop/GitHub/LearnOS/LearnOS'
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/x86_64-kernel.bin.dir/all] Error 2
make[1]: Leaving directory '/home/odedbe/Desktop/GitHub/LearnOS/LearnOS'
make: *** [Makefile:84: all] Error 2
I did define the kernel_main in my 'main.c' file, but for some reason 'ld' doesn't recognize that.
What could be the reason for that?
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: Problems with CMake for OS Project

Post by nullplan »

You are compiling with G++. That is because you are assigning CMAKE_C_COMPILER and CMAKE_CXX_COMPILER the wrong way round. g++ will compile all your files in C++ mode. However, C++ functions get name mangled. You could add 'extern "C"' to the declaration, but that would really only be treating the symptom. Get CMake to compile your C files with GCC. And get yourself a cross compiler! Using the host compiler is discouraged for a variety of reasons, not least of which being that libgcc depends on your host OS.
Carpe diem!
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Problems with CMake for OS Project

Post by Solar »

Code: Select all

cmake_minimum_required(VERSION 3.16.3)
My answer to Which CMake version as the minimum? would be relevant here. Pick your minimum_required for a good reason...

Code: Select all

set(CMAKE_CXX_STANDAED 17)
The typo aside, I don't see your setup actually using any C++, so why are you bothering with these settings in the first place? For a kernel, pick one language and stick to it. Mixing C and C++ in kernel space seems quite ill-advised. Despite their common heritage and quite large intersection of features, these to languages don't mix too well when you get to the fine print (as you are bound to do in kernel space).
Every good solution is obvious once you've found it.
Ovid
Posts: 22
Joined: Mon Jun 28, 2021 12:48 pm

Re: Problems with CMake for OS Project

Post by Ovid »

nullplan wrote:You are compiling with G++. That is because you are assigning CMAKE_C_COMPILER and CMAKE_CXX_COMPILER the wrong way round. g++ will compile all your files in C++ mode. However, C++ functions get name mangled. You could add 'extern "C"' to the declaration, but that would really only be treating the symptom. Get CMake to compile your C files with GCC. And get yourself a cross compiler! Using the host compiler is discouraged for a variety of reasons, not least of which being that libgcc depends on your host OS.
Alright, I'll try to compile the files using a cross compiler.
Thanks for helping!
Ovid
Posts: 22
Joined: Mon Jun 28, 2021 12:48 pm

Re: Problems with CMake for OS Project

Post by Ovid »

Solar wrote:

Code: Select all

cmake_minimum_required(VERSION 3.16.3)
My answer to Which CMake version as the minimum? would be relevant here. Pick your minimum_required for a good reason...

Code: Select all

set(CMAKE_CXX_STANDAED 17)
The typo aside, I don't see your setup actually using any C++, so why are you bothering with these settings in the first place? For a kernel, pick one language and stick to it. Mixing C and C++ in kernel space seems quite ill-advised. Despite their common heritage and quite large intersection of features, these to languages don't mix too well when you get to the fine print (as you are bound to do in kernel space).
Thanks!
Korona
Member
Member
Posts: 1000
Joined: Thu May 17, 2007 1:27 pm
Contact:

Re: Problems with CMake for OS Project

Post by Korona »

Solar wrote:The typo aside, I don't see your setup actually using any C++, so why are you bothering with these settings in the first place? For a kernel, pick one language and stick to it. Mixing C and C++ in kernel space seems quite ill-advised. Despite their common heritage and quite large intersection of features, these to languages don't mix too well when you get to the fine print (as you are bound to do in kernel space).
Well, using libraries written in C (with a well defined C ABI interface) is certainly possible even if you write C++. For example, this can make sense for LAI or ACPICA, or crypto libs.
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
Post Reply