【发布时间】:2019-06-10 23:27:07
【问题描述】:
我正在使用裸机 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。在运行生成的 makefile 时查看命令行,我看到所有源文件都按指定的顺序排列,但 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 中是明确的,这也是我想更改的。
所以我对此有几个问题:
为什么 cmake 不对两个外部对象文件使用顺序,而是对编译后的文件使用它?
如何告诉 cmake 将这些对象与来自我的源的对象一样对待?
如何获得我在 Makefile 中的设置的完整克隆(在我的目标文件之间包含库标志)
我也检查了 CMAKE_C_LINK_EXECUTABLE,但它似乎没有足够的粒度/对链接器参数的控制来实现这一点。
我在 ubuntu 上使用 cmake 3.10.2。
还有一个关于 cmake 的(题外话)问题:
它不会将 .S 视为标准程序集文件扩展名。我尝试使用LIST(APPEND CMAKE_ASM-ATT_SOURCE_FILE_EXTENSIONS S) 添加它,它确实添加它就好了,但是除非我将其更改为.s,否则文件仍然没有被编译。有其他人遇到过这个问题吗?
谢谢!
【问题讨论】:
-
至于附加问题,
.S扩展是指需要预处理的汇编代码。一些 C 编译器能够预处理该代码并编译它。但并非所有 ASM 编译器都能够预处理代码。在CMake wiki 中查看更多信息。请在问题帖子中提出一个单个问题 - 这就是 Stack Overflow 的工作原理。 -
至于“主要”问题,在源文件/目标文件的具体顺序上有点意思。 libraries 应该按顺序排列。 CMake 有一个用于链接库的特殊命令 -
target_link_libraries。传递给该命令的所有选项都将在命令行中 带有保证的目标文件之后出现。 -
1.你是对的,题外话不属于这里。它不会再发生了。 2. 我知道 .S 文件是用来预处理的,但 cmake 不处理它们似乎很奇怪。感谢您的链接,我在搜索 .S 问题时没有遇到此页面。
标签: cmake