cmake:外部(生成的)和已编译对象以及库的链接顺序

时间:2019-06-10 23:27:07

标签: cmake

我正在玩裸机x86,并且遇到了将我的构建从直接makefile移植到cmake的麻烦。

在我的makefile中,我的对象是这样定义的:

LINK_LIST=\
$(LDFLAGS) \
$(ARCHDIR)/crti.o \
$(ARCHDIR)/crtbegin.o \
$(KERNEL_OBJS) \
$(LIBS) \
$(ARCHDIR)/crtend.o \
$(ARCHDIR)/crtn.o \

crtbegin.o和crtend.o是“生成的”,即由我的交叉编译器提供(-print-file-name标志)。 $(LIBS)是-l标志,例如-lgcc等。由于此标志直接传递给链接器,因此顺序是指定的。

我的cmake目标定义如下:

ADD_EXECUTABLE(loader 
    "${INIT_SRC}"
    "${INIT_OBJ}"
    "${PLATFORM_SRCS}"
    "${ISA_SRCS}"
    "${GENERIC_SRCS}"
    "${FINI_OBJ}"
    "${FINI_SRC}")

INIT_OBJ和FINI_OBJ在源文件属性中将EXTERNAL_OBJECT和GENERATED设置为true。在运行生成的生成文件时查看命令行,我看到所有源文件都按指定的顺序执行,但是init和fini对象位于列表的最后。

这是结果命令行(为简洁起见进行了编辑):

i686-elf-gcc -nostdlib -ffreestanding -nostdinc -T linker.ld -lgcc crti.s.obj boot.s.obj loader.c.obj crtn.s.obj crtbegin.o crtend.o -o loader

-lgcc标志在我的LINK_FLAGS中是显式的,这也是我要更改的地方。

所以我对此有一些疑问:

  1. 为什么cmake不使用两个外部对象文件的顺序,而是将其用于编译后的外部文件?

  2. 我如何告诉cmake将这些对象与我的来源中的对象一样对待?

  3. 我如何获得我在Makefile中拥有的设置的完整副本(目标文件之间带有库标志)

我也确实检查了CMAKE_C_LINK_EXECUTABLE,但是似乎没有足够的粒度/对链接程序参数的控制来实现这一目标。

我正在Ubuntu上使用cmake 3.10.2。

另一个关于cmake的问题(题外):

它不会将.S视为标准程序集文件扩展名。我尝试用LIST(APPEND CMAKE_ASM-ATT_SOURCE_FILE_EXTENSIONS S)添加它,并且确实添加得很好,但是除非将其更改为.s,否则文件仍不会得到编译。还有其他人遇到过这个问题吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

对链接命令中的位置有特定要求的

对象crtbegin.ocrtend.o可被视为工具链的一部分。如果您决定这样做,则可以设置变量CMAKE_C_LINK_EXECUTABLE来反映这一特定要求:

SET(ARCHDIR "<...>")
# Object 'crtbegin.o' will be linked before all other objects and libraries.
# Object 'crtend.o' will be linked after all other objects and libraries.
SET(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> 
    <LINK_FLAGS>
    ${ARCHDIR}/crtbegin.o
    <OBJECTS> -o <TARGET> <LINK_LIBRARIES>
    ${ARCHDIR}/crtend.o")

此设置应在工具链文件中完成,该文件通过选项cmake传递到-DCMAKE_TOOLCHAIN=<path/to/toolchain/file>

使用这种工具链,您可以在CMakeLists.txt中简单地编写

ADD_EXECUTABLE(loader ${PLATFORM_SRCS} ${ISA_SRCS} ${GENERIC_SRCS})

使用CMAKE_C_LINK_EXECUTABLE变量,您还可以放置诸如

之类的选项。
-nostdlib -ffreestanding -nostdinc -T linker.ld -lgcc

与工具链也非常相关。

另请参阅此邮件:https://cmake.org/pipermail/cmake/2010-June/037641.html

相关问题