CMake-按正确顺序将项目与C运行时对象文件链接
CMake - Link project with C runtime object files in correct order
有C运行时/启动文件:crt0.o
、crti.o
、crtbegin.o
…crtend.o
、crtn.o
。
crtbegin.o
和crtend.o
由工具链(GCC(提供crt0.o
、crti.o
和crtn.o
是我自己在项目范围
该项目是关于在没有操作系统的i686裸机上运行可执行文件。
问题在于最终可执行文件的链接-项目对象文件与上述所有C运行时文件的链接顺序很重要
我的构建系统是CMake,其中我使用target_sources
命令来定义可执行文件使用的源文件(编译后链接在一起(:
set( BARE_METAL app.bin )
add_executable( ${BARE_METAL} "" )
target_sources( ${BARE_METAL}
PRIVATE
boot.s # contains symbols analogical to crt0.s
crti.s
crtn.s
a.cpp
b.cpp
# … other files go here
)
target_link_options( ${BARE_METAL}
PUBLIC
-t linker.ld
-nostdlib
-nostartfiles
)
target_link_libraries( ${BARE_METAL}
PUBLIC
support
)
问题是GCC没有与crtbegin.o
和crtend.o
链接,尽管它可以在我的工具链中找到:
toolchain/i686-elf/lib/gcc/i686-elf/10.0.1/crtbegin.o
toolchain/i686-elf/lib/gcc/i686-elf/10.0.1/crtend.o
你能告诉我如何从CMake中以正确的顺序调用带有所有必需参数的链接器吗?我希望有一个类似的链接命令
./i686-elf-ld -t linker.ld -nostdlib -nostartfiles boot.o crti.o crtbegin.o a.o b.o -libsupport.a crtend.o crtn.o
请注意C运行时文件的顺序。我已经简化了所有文件的目录结构,但关键的一点应该在这里强调
非常感谢任何愿意帮助我的人…Martin
更新:
我试图在等待任何建议的同时进行更多的研究,而有希望的方法似乎是使用CMAKE_CXX_LINK_EXECUTABLE
来定义用于链接的特定于项目的构建规则。
我的项目使用在root/main project((语句之前设置的工具链文件。在子项目中,我设置了CMAKE_CXX_LINK_EXECUTABLE
,它似乎对其他子项目没有影响。这就是为什么我称之为承诺,尽管整个事情还没有奏效。
我的计划是用三个特定于项目的C运行时文件crt0.o
、crti.o
和crtn.o
创建一个对象库,将它们从<OBJECTS>
中删除,使项目依赖于这个对象库,但在链接构建规则中手动管理运行时文件。
你认为这种方式会成功结束吗一旦我有了结果,我就会发布。。。
感谢@KamilCuk,我成功地让它运行起来。以下是我制作的解决方案(供任何试图解决相同问题的人使用(
project( Bare_Metal LANGUAGES CXX C ASM )
set( BARE_METAL app.bin )
set( BARE_METAL_CRTS app-crts )
add_library( ${BARE_METAL_CRTS} OBJECT
boot.s # contains symbols analogical to crt0.s
crti.s
crtn.s
)
add_executable( ${BARE_METAL} "" )
target_sources( ${BARE_METAL}
PRIVATE
a.cpp
b.cpp
# … other files go here
)
target_link_options( ${BARE_METAL}
PUBLIC
-t linker.ld
-nostdlib
-nostartfiles
)
target_link_libraries( ${BARE_METAL}
PUBLIC
support
)
# This ensures the boot.o crti.o, crtn.o to be build prior to BARE_METAL target
add_dependencies( ${BARE_METAL} ${BARE_METAL_CRTS} )
# Ask GCC to get the full path name of crtbegin. and crtend.o
execute_process( COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=crtbegin.o OUTPUT_VARIABLE CRTBEGIN_O OUTPUT_STRIP_TRAILING_WHITESPACE )
execute_process( COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=crtend.o OUTPUT_VARIABLE CRTEND_O OUTPUT_STRIP_TRAILING_WHITESPACE)
# Set linker executable to be used - navigate to the toolchain used (might be setup in toolchain file)
set( BARE_METAL_LINKER ${BARE_METAL_TOOLCHAIN_ROOT}/bin/${CMAKE_TARGET_PROCESSOR}-elf-ld )
set( CMAKE_CXX_LINK_EXECUTABLE "${BARE_METAL_LINKER} <CMAKE_C_LINK_FLAGS> <FLAGS> <LINK_FLAGS> boot.obj crti.obj ${REVOLTA_CRTBEGIN} <OBJECTS> -o <TARGET> <LINK_LIBRARIES> ${REVOLTA_CRTEND} crtn.obj" )
请记住,上面的代码不是复制粘贴解决方案,而是完整的,可以作为指导/灵感来做这样的事情:(
- CMake-按正确顺序将项目与C运行时对象文件链接
- 通过switch和static_cast访问多态对象的运行时类型
- "main"函数堆栈中的对象在第一个任务运行时被覆盖 (FreeRTOS)
- cout 新创建的对象引发运行时错误
- C++,如何根据运行时条件构造引用不同 istream 对象的对象?
- 创建 QtChart 对象会在运行时创建EXC_BAD_ACCESS错误
- 如何在运行时在对象数组中动态追加新对象C++并打印它们
- 如何在运行时创建和命名对象?
- C++ 在运行时选择一个随机对象
- 在运行时 c++ 更改用类对象填充的数组的大小
- C++ 在运行时获取具有 ID 的对象
- 如何在运行时从 c++ 中的 DLL 文件创建对象?
- 为什么 Z3 BitVec 对象没有运行时大小信息?
- 未知大小的数组作为类成员,用于在运行时(对象创建时间)创建数组的对象
- 是否有任何可能的方法将事件(自定义)附加到在运行时创建的对象?[C 构建器]
- 在C 中运行时从指针访问对象实例
- 如何在运行时指定对象类型
- 根据用户的输入在运行时创建对象
- 使用数据库模型(键)来引用运行时对象,是好是坏
- Visual C++运行时对象销毁顺序