我可以在 .ld 文件中使用预处理器指令吗
Can I use Preprocessor Directives in .ld file
我可以在 .ld 文件中使用预处理器指令吗?
我需要使用两组 .ld 文件中的一组,并想让构建引擎使用宏来处理它,我可以这样做吗?
是的,你可以。您需要为您的链接描述文件手动 运行 预处理器,如下所示:
in="your_linker_script.ld"
out="generated_script.ld"
cflags=-Iinclude/
gcc -E -x c $cflags $in | grep -v '^#' >$out
标志:
-E
将 GCC 指定为仅 运行 预处理器
-x c
告诉 GCC 将您的链接描述文件视为 C 源文件(运行 GCC 需要使用您的 LD 脚本)
或者你可以简单地使用cpp
工具,它实际上是C预处理器。
在此之后,您将能够使用生成的链接描述文件来构建您的程序(例如,在 Makefile 中)。
例子
以下是我在项目中解决这个问题的方法:
Here 是我的链接描述文件使用预处理器(#include
指令和 CONFIG_TEXT_BASE
常量)。摘录:
#include <config.h>
. = CONFIG_TEXT_BASE;
Here 是生成预处理链接描述文件的脚本。摘录:
gcc -E -x c -Iinclude $cflags $in | grep -v '^#' >>$out
Here 是我的 Makefile
,它在 $(LDS_GEN)
目标(第 53 行)生成预处理的链接器脚本,并且生成的脚本用于构建结果二进制(第 42 行)。摘录:
$(LDS_GEN): $(LDS)
build/gen-lds.sh $(LDS) $(LDS_GEN) $(CFLAGS)
$(APP).bin: $(OBJS) $(LDS_GEN)
$(LD) $(OBJS) -T $(LDS_GEN) -o $(APP).elf
为了简化 Sam 的回答,我将以下内容添加到我的 makefile 中,然后我们开始:)
PRE_LD_FILE = $(PROG_NAME).ld
LD_FILE = $(PROG_NAME)_generated.ld
$(LD_FILE) : $(PRE_LD_FILE)
cpp $(PRE_LD_FILE) | grep -v '^#' >>$(LD_FILE)
久违的小更新。这种预处理方式一直有效,直到内存文件不包含欺骗预处理器的行。例如:
"KEEP(*path/*.o(.rodata .rodata*))"
路径后的“/*”被认为是注释开始(该行包含被认为是 C 多行注释开始而不是匹配模式)。
此行对链接器有效,但它被视为注释,C 预处理器的输出将删除所有内容,直到找到假定的结束注释:
"KEEP(*path"
生成的文件显然对链接器无效。我暂时没有解决办法。
我可以在 .ld 文件中使用预处理器指令吗? 我需要使用两组 .ld 文件中的一组,并想让构建引擎使用宏来处理它,我可以这样做吗?
是的,你可以。您需要为您的链接描述文件手动 运行 预处理器,如下所示:
in="your_linker_script.ld"
out="generated_script.ld"
cflags=-Iinclude/
gcc -E -x c $cflags $in | grep -v '^#' >$out
标志:
-E
将 GCC 指定为仅 运行 预处理器-x c
告诉 GCC 将您的链接描述文件视为 C 源文件(运行 GCC 需要使用您的 LD 脚本)
或者你可以简单地使用cpp
工具,它实际上是C预处理器。
在此之后,您将能够使用生成的链接描述文件来构建您的程序(例如,在 Makefile 中)。
例子
以下是我在项目中解决这个问题的方法:
Here 是我的链接描述文件使用预处理器(
#include
指令和CONFIG_TEXT_BASE
常量)。摘录:#include <config.h> . = CONFIG_TEXT_BASE;
Here 是生成预处理链接描述文件的脚本。摘录:
gcc -E -x c -Iinclude $cflags $in | grep -v '^#' >>$out
Here 是我的
Makefile
,它在$(LDS_GEN)
目标(第 53 行)生成预处理的链接器脚本,并且生成的脚本用于构建结果二进制(第 42 行)。摘录:$(LDS_GEN): $(LDS) build/gen-lds.sh $(LDS) $(LDS_GEN) $(CFLAGS) $(APP).bin: $(OBJS) $(LDS_GEN) $(LD) $(OBJS) -T $(LDS_GEN) -o $(APP).elf
为了简化 Sam 的回答,我将以下内容添加到我的 makefile 中,然后我们开始:)
PRE_LD_FILE = $(PROG_NAME).ld
LD_FILE = $(PROG_NAME)_generated.ld
$(LD_FILE) : $(PRE_LD_FILE)
cpp $(PRE_LD_FILE) | grep -v '^#' >>$(LD_FILE)
久违的小更新。这种预处理方式一直有效,直到内存文件不包含欺骗预处理器的行。例如:
"KEEP(*path/*.o(.rodata .rodata*))"
路径后的“/*”被认为是注释开始(该行包含被认为是 C 多行注释开始而不是匹配模式)。
此行对链接器有效,但它被视为注释,C 预处理器的输出将删除所有内容,直到找到假定的结束注释:
"KEEP(*path"
生成的文件显然对链接器无效。我暂时没有解决办法。