【问题标题】:How can remove this gcc flags from linker flags in cmake?如何从 cmake 中的链接器标志中删除这个 gcc 标志?
【发布时间】:2021-07-20 10:12:40
【问题描述】:

我为学习目的制作了简单的内核。我将 MakeFile 转换为 CMakeLists.txt 以自动分类我的内核表单源。但是我遇到了这个重定位错误。

/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

为了解决这个问题,我想我必须删除链接器标志中的 -fno-pie。通过使用 make VERBOSE=1 检查 gcc 的日志,我可以发现我的链接器标志中有 CMAKE_CXX_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

如何在我的 LINKER_FLAGS 中删除此 CMAKE_CXX_FLAGS?为什么 camke 会自动为我的 MakeFile 插入这个无用的选项?有没有其他方法可以绕过此错误消息?我希望你的答案... 这是我的 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/
)

【问题讨论】:

  • 在 CMakeLists.txt 文件中搜索 -fno-pie 会发现什么?这样做不是很明显需要做什么吗?
  • 我把 -fno-pie 选项放到 CMAKE_CXX_FLAGS 和 CMAKE_C_FLAGS。我想从这些标志生成目标文件并仅使用 -n -T linker.ld 链接它们。但是 cmake 尝试将我的文件与 gcc 和 CMAKE_C*_FLAGS 链接。我不明白为什么以及如何修复 -f no-pie 在链接阶段产生的重定位错误。
  • 更具体地说,我无法理解为什么 cmake 会尝试将我的目标文件与 gcc 和 gcc 选项链接起来。尽管如此,我还是告诉 cmake 将 *.o 与 /usr/lib/ld 和 -n -T *.ld 链接起来。
  • 为什么需要-fno-pie
  • 因为我构建内核。在我的内核中,内核不需要 PIE 和 PIC。这个问题也源于链接器试图将我的内核与所有带有链接阶段的 CMAKE_CXX_FLAGS 链接......我认为至少......

标签: c++ c gcc cmake linker


【解决方案1】:

最后我想出了如何从 cmake 中删除无用的链接器参数。 CMAKE 使用编译器作为默认链接器。就我而言,gcc 是默认链接器,因为我使用 gcc 构建源代码。重要的事实是 cmake 在链接阶段也将 CMAKE_CXX_FLAGS 与 gcc 联系起来。所以我们必须像这样使用自定义链接器来避免 cmake 使用默认编译器链接器链接我们的 oject 文件。

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>")

这样,我们就可以自动生成带有自定义链接器的可执行文件了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-30
    • 2014-03-06
    • 2014-08-09
    • 2021-04-01
    • 2011-04-02
    • 1970-01-01
    • 2021-04-10
    • 2020-09-07
    相关资源
    最近更新 更多