在 cmake 中编译链接器脚本 - 找不到目标文件(嵌入式项目)

Compile linker script in cmake - cannot find object file (embedded project)

我的问题是我想从这个项目的普通 makefile 中创建一个 cmake 文件: https://github.com/brianwiddas/pi-baremetal

我创建了 CMakeLists 文件,但在链接项目时遇到问题。在 make 命令之后我有这样的错误:

Linking C executable rpi-0.1.elf
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld: cannot find start.o
collect2: error: ld returned 1 exit status
make[2]: *** [rpi-0.1.elf] Błąd 1
make[1]: *** [CMakeFiles/rpi.dir/all] Błąd 2

链接器代码片段:

MEMORY
{
    initsys : org = 0x8000, len = 1M
    kernel : org = 0xf0000000, len = 1M
    data : org = 0xc0000000, len = 1M
}
SECTIONS
{
    /* Initial section, loads/runs at 0x8000 */
    .init : {
        start.o(.text* .data* .bss* .rodata*)
        initsys.o (.text* .data* .bss* .rodata*)
    } >initsys

    //the rest of code in SECTION

}

我意识到 cmake 创建带有“.c.obj/.s.obj”扩展名的目标文件,与这个带有“.o”扩展名的 makefile 相比,我在链接器代码中更改了它,但是现在错误是:

cannot find start.s.obj

现在不知道怎么了。可能是因为在 makefile 项目中,源代码文件和目标文件位于同一文件夹中。 Cmake 在另一个文件夹中创建目标文件,在我的例子中:

source files folder - ../Projekt/code
object files folder - ../Projekt/build/CMakeFiles/rpi.dir/code

也许链接描述文件看不到目标文件,因为它们在另一个文件夹中。 build文件夹由cmake自动创建。

这是我的CMakeLists.txt文件:

## Minimal cmake version
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

## Project name
project(rpi C CXX ASM)

## Project version
set(${PROJECT_NAME}_version "0.1")

## Project options
option(DISABLE_NEWLIB_SUPPLIED_SYSCALLS "Disables pre-defined libraries for ARM" ON)

## Compilation options
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O6 -nostdinc -ffreestanding -marm -mcpu=arm1176jzf-s")

## Creation of the necessary definitions
if (DISABLE_NEWLIB_SUPPLIED_SYSCALLS)
    add_definitions(-DDISABLE_NEWLIB_SUPPLIED_SYSCALLS)
endif (DISABLE_NEWLIB_SUPPLIED_SYSCALLS)

## Assembler source code
set(ASM_SOURCE_FILES ${PROJECT_SOURCE_DIR}/code/start.s)

## C source code
set(C_SOURCE_FILES ${PROJECT_SOURCE_DIR}/code/atags.c
           ${PROJECT_SOURCE_DIR}/code/atags.h
           ${PROJECT_SOURCE_DIR}/code/barrier.h
           ${PROJECT_SOURCE_DIR}/code/divby0.c
           ${PROJECT_SOURCE_DIR}/code/framebuffer.c
           ${PROJECT_SOURCE_DIR}/code/framebuffer.h
           ${PROJECT_SOURCE_DIR}/code/interrupts.c
           ${PROJECT_SOURCE_DIR}/code/interrupts.h
           ${PROJECT_SOURCE_DIR}/code/led.c
           ${PROJECT_SOURCE_DIR}/code/led.h
           ${PROJECT_SOURCE_DIR}/code/initsys.c
           ${PROJECT_SOURCE_DIR}/code/mailbox.c
           ${PROJECT_SOURCE_DIR}/code/mailbox.h
           ${PROJECT_SOURCE_DIR}/code/main.c
           ${PROJECT_SOURCE_DIR}/code/memory.c
           ${PROJECT_SOURCE_DIR}/code/memory.h
           ${PROJECT_SOURCE_DIR}/code/memutils.c
           ${PROJECT_SOURCE_DIR}/code/memutils.h
           ${PROJECT_SOURCE_DIR}/code/teletext.h
           ${PROJECT_SOURCE_DIR}/code/textutils.c
           ${PROJECT_SOURCE_DIR}/code/textutils.h)

## Additional files
set(OTHER_FILES ${PROJECT_SOURCE_DIR}/code/linker.ld)

## Create an executable binary files
add_executable(${PROJECT_NAME} ${ASM_SOURCE_FILES} ${C_SOURCE_FILES})

## Settings resulting executable file
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}-${${PROJECT_NAME}_version}.elf")
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-Wl,-Map,${CMAKE_BINARY_DIR}/${PROJECT_NAME}-${${PROJECT_NAME}_version}.map -T ${PROJECT_SOURCE_DIR}/code/linker.ld -nostdlib -nostartfiles -gc-sections")

## Creates a kernel image
add_custom_command(TARGET ${PROJECT_NAME} COMMAND ${CROSS_COMPILER_PREFIX}objcopy ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-${${PROJECT_NAME}_version}.elf -O binary ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-${${PROJECT_NAME}_version}.img)

toolchain-raspberry-pi.cmake文件:

## Determination of the operating system on which the program is designed
set(CMAKE_SYSTEM_NAME Generic)

## The term architecture on which the program is established
set(${PROJECT_NAME}_architecture raspberry-pi)

## Prefix tools used for cross-compiling
set(CROSS_COMPILER_PREFIX arm-none-eabi-)

## Compilers that will be used.
include (CMakeForceCompiler)
cmake_force_c_compiler(${CROSS_COMPILER_PREFIX}gcc GNU)
cmake_force_cxx_compiler(${CROSS_COMPILER_PREFIX}g++ GNU)

如何修复此错误以及为什么 cmake 不在与源代码相同的文件夹中创建扩展名为“.o”的目标文件? 请帮忙。

解法:

在链接描述文件中,我在 start.s.obj/initsys.c.obj 之前添加 *,如下所示:

*start.s.obj (.text* .data* .bss* .rodata*)
*initsys.c.obj (.text* .data* .bss* .rodata*)

你能在链接器文件中尝试 *start*.o(.text* .data* .bss* .rodata*) 吗?

PS: 我无法编译你的项目。我猜您正在使用 arm-none-eabi-* 工具链进行交叉编译。您如何覆盖默认编译器?