I made simple kernel for studying purposes. I cange MakeFile to CMakeLists.txt to automatically genreate my kernel form sources. But I encounter this relocation error.
/usr/bin/ld: CMakeFiles/x86_64-kernel.bin.dir/src/arch/x86_64/multiboot2_boot32.asm.o: relocation R_X86_64_32 against `.boot.32' can not be used when making a PIE object; recompile with -fPIE
To solve this I think I have to remove -fno-pie in linker flags. By checking log of gcc with make VERBOSE=1, I can found that there is CMAKE_CXX_FLAGS at my linker flags.
[100%] Linking CXX executable x86_64-kernel.bin
/usr/bin/cmake -E cmake_link_script CMakeFiles/x86_64-kernel.bin.dir/link.txt --verbose=1
/usr/bin/gcc -mno-red-zone -mcmodel=large -mno-sse -ffreestanding -nostdlib -fno-pie -fno-pic -rdynamic -n -T /home/ahn9807/study/AOS/src/arch/x86_64/linker.ld CMakeFiles/x86_64-kernel.bin.dir/src/arch/x86_64/kernel_entry.cpp.o CMakeFiles/x86_64-kernel.bin.dir/src/arch/x86_64/multiboot2_boot32.asm.o CMakeFiles/x86_64-kernel.bin.dir/src/arch/x86_64/multiboot2_boot64.asm.o CMakeFiles/x86_64-kernel.bin.dir/src/arch/x86_64/multiboot2_header.asm.o -o x86_64-kernel.bin
/usr/bin/ld: CMakeFiles/x86_64-kernel.bin.dir/src/arch/x86_64/multiboot2_boot32.asm.o: relocation R_X86_64_32 against `.boot.32' can not be used when making a PIE object; recompile with -fPIE
How can I remove this CMAKE_CXX_FLAGS in my LINKER_FLAGS? Why camke automatically insert this useless options for my MakeFile? Is there any other way to bypass this error messages? I hope your answers... And this is my CMakeLists.txt.
cmake_minimum_required(VERSION 2.17)
project(kernell)
set(PROJECT_VERSION_MAJOR 0)
set(PROJECT_VERSION_MINOR 1)
set(CMAKE_CXX_STANDAED 17)
set(KERNEL_BIN "x86_64-kernel.bin")
set(CMAKE_BINARY_DIR ${PROJECT_SOURCE_DIR}/build)
set(LINKER_SCRIPT ${PROJECT_SOURCE_DIR}/src/arch/x86_64/linker.ld)
set(GRUB_CFG ${PROJECT_SOURCE_DIR}/src/arch/x86_64/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")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mno-red-zone -mcmodel=large -mno-sse -ffreestanding -nostdlib -fno-pie -fno-pic")
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)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include/
)
add_executable(
${KERNEL_BIN}
# Header files
include/arch/x86_64/kernel_entry.h
include/arch/x86_64/vga_text.h
include/arch/x86_64/multiboot2.h
# Source files
src/arch/x86_64/kernel_entry.cpp
src/arch/x86_64/multiboot2_boot32.asm
src/arch/x86_64/multiboot2_boot64.asm
src/arch/x86_64/multiboot2_header.asm
)
set_target_properties(${KERNEL_BIN} PROPERTIES LINK_FLAGS "-n -T ${LINKER_SCRIPT}")
add_custom_command(TARGET ${KERNEL_BIN} POST_BUILD
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/build/isofiles/boot/grub
COMMAND cp ${KERNEL_BIN} ${CMAKE_BINARY_DIR}/build/isofiles/boot/${KERNEL_BIN}
COMMAND cp ${GRUB_CFG} ${CMAKE_BINARY_DIR}/build/isofiles/boot/grub
COMMAND grub-mkrescue -o kernel.iso ${CMAKE_BINARY_DIR}/build/isofiles
COMMAND rm -r ${CMAKE_BINARY_DIR}/build/
)
Finally I figure out how to remove useless linker argument from cmake. CMAKE uses compiler as an default linker. In my case, gcc is default linker because I build my source code with gcc. The important fact is that cmake also berings CMAKE_CXX_FLAGS with gcc in linking stage. So we have to use custom linker as like this to avoid cmake linking our oject files with default compiler linker.
set(CMAKE_LINKER "/usr/bin/ld")
set(CMAKE_LINKER_FLAGS "-n -T ${LINKER_SCRIPT}")
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_LINKER> ${CMAKE_LINKER_FLAGS} <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
In this way, we can automatically generate executable with custom linker.