Page 1 of 1

Problems with CMake for OS Project

Posted: Mon Jun 28, 2021 12:59 pm
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?

Re: Problems with CMake for OS Project

Posted: Mon Jun 28, 2021 9:30 pm
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.

Re: Problems with CMake for OS Project

Posted: Mon Jun 28, 2021 9:57 pm
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).

Re: Problems with CMake for OS Project

Posted: Tue Jun 29, 2021 10:47 am
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!

Re: Problems with CMake for OS Project

Posted: Tue Jun 29, 2021 10:53 am
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!

Re: Problems with CMake for OS Project

Posted: Tue Jun 29, 2021 12:06 pm
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.