我正在尝试使用LD脚本中的STARTUP
指令将程序与我自己的启动文件链接:
...
ENTRY(_start)
STARTUP(my_crt1.o)
...
GCC驱动程序用于链接程序(不用担心libgcc等库路径):
gcc -T my_script.ld ...
不幸的是,它仅适用于为powerpc目标编译的GCC,而arm或i686目标则不包含但仍包含在collect2中的crt0.o。例如:
arm-eabi-g++ -v -T my_script.ld ...
给了我:
collect2 ... /opt/lib/gcc/arm-eabi/4.8.0/../../../../arm-eabi/lib/crt0.o ...
因此:
crt0.S:101: multiple definition of `_start'
似乎STARTUP
指令完全被忽略(powerpc目标也使用其默认的crt0,除非指定了STARTUP
指令)并且无法禁用默认的crt0。
是否有可移植的方式链接另一个启动文件?
我的启动文件使用libgcc
个函数(调用ctors和dtors),因此需要crtbegin.o
,crtend.o
等,所以我想避免{{1} }禁用-nostartfiles
的选项 - 我只需要停用crt*.o
。
谢谢
答案 0 :(得分:4)
我正在尝试将程序与我自己的启动文件链接...
GCC驱动程序用于链接程序...
在这种情况下,您必须还向GCC提供-nostartfiles
标志。
答案 1 :(得分:2)
此限制确实会强制您使用-nostartfiles
禁用默认启动文件(我更喜欢-nostdlib
)。然后,您需要自己构建运行时对象列表。 gcc有选项-print-file-name
来打印它编译的库的绝对路径(crtbegin.o,crtend.o,libgcc.a ...)。例如:arm-eabi-g++ <FLAGS> -print-file-name=crtbegin.o
这是我使用的GNU Make宏(提供gcc和cflags):
define m.in/toolchain/gnu/locate =
$(strip
$(shell $(m.in/toolchain/gnu/bin/gcc) $(m.in/toolchain/gnu/cflags) \
-print-file-name=$(m.in/argv/1))
)
endef
crtn := $(call m.in/toolchain/gnu/locate, crtn.o)