在 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-* 工具链进行交叉编译。您如何覆盖默认编译器?
我的问题是我想从这个项目的普通 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-* 工具链进行交叉编译。您如何覆盖默认编译器?