Makefile大型项目编译时候 (Argument list too long)后缀参数太长问题解决

在用Makefile编译大型项目文件时出现了如下错误,提示参数列表过长,gcc 命令后缀是不能超过8000多个字节猜测。

通过查资料gcc 的后缀列表可以放到一个文件中,通过gcc @file 的方式来解决 Argument list too long ,

参考依据:Overall Options (Using the GNU Compiler Collection (GCC))

@file
  Read command-line options from file. The options read are inserted in place of the original @file option. If file does not exist, or cannot be read, then the option will be treated literally, and not removed.
  Options in file are separated by whitespace. A whitespace character may be included in an option by surrounding the entire option in either single or double quotes. Any character (including a backslash) may be included by prefixing
  the character to be included with a backslash. The file may itself contain additional @file options; any such options will be processed recursively.

修改Makfile,将头文件位置重定向到特定的文件中,再gcc @file 去编译:

#-----------------------------------------wl-------------------------add--------------
current_root_dir_temp1 = $(shell pwd)
current_root_dir_cover1 = $(subst \,/,$(current_root_dir_temp1))
current_root_dir1 = $(subst /cygdrive/c,C:,$(current_root_dir_cover1))
$(info "----------------------$(current_root_dir1)") 
current_root_dir2 = "$(current_root_dir1)/iROMXX.ccompincludelist"
$(info "----------------------$(current_root_dir2)") 

#add file path
#VCU APP
A =  -I\"$(current_root_dir)/Source/App/SWC_VCU/AccPed  \"
C := $(shell echo $A >> $(current_root_dir2))
A = -I\"$(current_root_dir)/Source/App/SWC_VCU/AccPedDev \"
C := $(shell echo $A >> $(current_root_dir2))
A = -I\"$(current_root_dir)/Source/App/SWC_VCU/ACCtl_TqDem \"
C := $(shell echo $A >> $(current_root_dir2))
A = -I\"$(current_root_dir)/Source/App/SWC_VCU/ActvDynWhlLd \"
C := $(shell echo $A >> $(current_root_dir2))
A = -I\"$(current_root_dir)/Source/App/SWC_VCU/AntiRollBack \"
C := $(shell echo $A >> $(current_root_dir2))
A = -I\"$(current_root_dir)/Source/App/SWC_VCU/AxleTqPreZrCrsng \"
C := $(shell echo $A >> $(current_root_dir2))

编译文件的位置:

#$(info "------wl------$(ATECH_USER_LINKFLAGS)")
$(info $(LDFLAGS));
.SECONDEXPANSION:
ifneq ($(LINK_LIBRARIES),1)
$(TARGET): $$(OBJS) $(LD_DEPENDENCIES) $(LINKER_COMMAND_FILE) \
           $(ADDITIONAL_OBJECTS_U) $(ADDITIONAL_LIBRARIES_U) \
           $(TARGET_LIBRARY) $(TARGET_RESPONSE_FILE) \
           $(wildcard Makefile.project.part.defines) \
           $(dir $(TARGET))/.dirstamp
    @$(ECHO) "LD         $@"
    $(Q)$(CC_ENV) $(LD) $(LDFLAGS) $(LINKER_OBJS_ARG)       \
                                   $(ADDITIONAL_OBJECTS_U)   \
                                   $(ADDITIONAL_LIBRARIES_U) \
                                   $(SYSLIBS)                \
                                   $(LD_REDIRECT_OUTPUT) \
                                   @$(current_root_dir2) \
                                   $(ATECH_USER_LINKFLAGS) 

这样虽然能解决问题,但是只是将.h的路径放到文件中了,.o文件路径没增加到文件中,且这样写法过于啰嗦,如是有了以下修改,利用Makefile中的foreach函数切割对应的环境变量后,重定向到文件中:

#-----------------------------------------wl-------------------------add--------------
current_root_dir_temp1 = $(shell pwd)
current_root_dir_cover1 = $(subst \,/,$(current_root_dir_temp1))
current_root_dir1 = $(subst /cygdrive/c,C:,$(current_root_dir_cover1))
$(info "----------------------$(current_root_dir1)") 
current_root_dir2 = "$(current_root_dir1)/iROMXX.ccompincludelist"
$(info "----------------------$(current_root_dir2)") 

#add file path
#VCU APP
ATECH_INCLUDES := $(foreach dir1,$(ATECH_INCLUDE),$(shell echo $(dir1) >> $(current_root_dir2)))

#$(info "$(B)") 
#-----------------------------------------wl-------------------------end--------------


current_root_dir3 = "$(current_root_dir1)/iROMXX.ccompincludelist2"
#C := $(shell echo $(LINKER_OBJS_ARG) >> $(current_root_dir3))
#WLLL := $(shell for var in echo ${LINKER_OBJS_ARG};do echo var >> $(current_root_dir3);done)
ATECH_OBJECTS := $(foreach dir,$(LINKER_OBJS_ARG),$(shell echo $(dir) >> $(current_root_dir3)))

.SECONDEXPANSION:
ifneq ($(LINK_LIBRARIES),1)
$(TARGET): $$(OBJS) $(LD_DEPENDENCIES) $(LINKER_COMMAND_FILE) \
           $(ADDITIONAL_OBJECTS_U) $(ADDITIONAL_LIBRARIES_U) \
           $(TARGET_LIBRARY) $(TARGET_RESPONSE_FILE) \
           $(wildcard Makefile.project.part.defines) \
           $(dir $(TARGET))/.dirstamp
    @$(ECHO) "LD         $@"
    $(Q)$(CC_ENV) $(LD) $(LDFLAGS) @$(current_root_dir3)     \
                                   $(ADDITIONAL_OBJECTS_U)   \
                                   $(ADDITIONAL_LIBRARIES_U) \
                                   $(SYSLIBS)                \
                                   $(LD_REDIRECT_OUTPUT) \
                                   @$(current_root_dir2) \
                                   $(ATECH_USER_LINKFLAGS) 

再次编译后出现下面错误 :

gcc region `BMHDO‘ overflowed by xxx bytes

这个原因是固件大小超过了特定的大小,修改链接脚本,本人这里的链接脚本vLinkGen_Template.ld,,这里是通过特定的环境变量LDFLAGS打印出来的。

-T script 是指定ld链接脚本

修改链接脚本,增大BMHDO section 的大小

MEMORY
{
  DSPR_Core5 : ORIGIN = 0x10000000 , LENGTH = 0x00018000 /* 96 KiB */
  DSPR_Core4 : ORIGIN = 0x30000000 , LENGTH = 0x00018000 /* 96 KiB */
  DSPR_Core3 : ORIGIN = 0x40000000 , LENGTH = 0x00018000 /* 96 KiB */
  DSPR_Core2 : ORIGIN = 0x50000000 , LENGTH = 0x00018000 /* 96 KiB */
  DSPR_Core1 : ORIGIN = 0x60000000 , LENGTH = 0x0003C000 /* 240 KiB */
  DSPR_Core0 : ORIGIN = 0x70000000 , LENGTH = 0x00032FF0 /* 204 KiB */
  Variables_Shared : ORIGIN = 0x70032FF0 , LENGTH = 0x00000080 /* 16 Byte */
  StartupStack_Shared : ORIGIN = 0x70033000 , LENGTH = 0x00009000 /* 36 KiB */
  PFlash0_Boot_reserved : ORIGIN = 0x80000000 , LENGTH = 0x00060000 /* 384 KiB */
  StartupCode_FirstExecInst : ORIGIN = 0x80060000 , LENGTH = 0x00000500 /* 1 KiB */
  CoreExceptions_FirstExecInst : ORIGIN = 0x80060500 , LENGTH = 0x00000600 /* 512 Byte */
  PFlash0_Cached : ORIGIN = 0x80060700 , LENGTH = 0x0029F900 /* 3 MiB */
  PFlash1_Cached : ORIGIN = 0x80300000 , LENGTH = 0x002FFF00 /* 3 MiB */
  PFlash1_Info_reserved : ORIGIN = 0x805FFF00 , LENGTH = 0x00000300 /* 256 Byte */
  BMHD0 : ORIGIN = 0xAF400000 , LENGTH = 0x00000600 /* 512 Byte */
}

至此,完成对整个Makefile大型工程的修改。

参考文档:C Dialect Options (Using the GNU Compiler Collection (GCC))

Option Summary (Using the GNU Compiler Collection (GCC))

(37条消息) gcc @Commandfile解决命令过长问题_EarnForLive的博客-CSDN博客

(37条消息) PX4固件编译问题region `flash‘ overflowed by 4253 bytes_gcc-arm-none-eabi-7.3.1_彩云的笔记的博客-CSDN博客

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
在 C/C++ 程序中,通常会将程序分为多个源文件,每个源文件实现不同的功能模块。当编译这些源文件时,我们需要使用 makefile 来管理这些源文件的编译和链接过程。 makefile 中需要解决的一个重要问题就是跨文件问题。在一个源文件中使用了另一个源文件中定义的函数或变量时,编译器会提示未定义的引用错误。为了解决这个问题,我们需要在 makefile 中指定编译器搜索头文件和库文件的路径,并将需要链接的目标文件或库文件添加到链接命令中。 具体来说,我们可以在 makefile 中定义变量来保存源文件、头文件和库文件的路径等信息,然后在编译和链接命令中使用这些变量。例如: ```makefile # 定义变量 SRC_DIR := src INC_DIR := include LIB_DIR := lib OBJ_DIR := obj # 指定编译器和编译选项 CC := gcc CFLAGS := -Wall -Werror -I$(INC_DIR) # 指定链接器和链接选项 LD := gcc LDFLAGS := -L$(LIB_DIR) -lmylib # 指定目标文件和依赖关系 TARGET := myapp OBJS := $(addprefix $(OBJ_DIR)/, main.o utils.o) DEPS := $(wildcard $(INC_DIR)/*.h) # 编译规则 all: $(TARGET) $(TARGET): $(OBJS) $(LD) $(LDFLAGS) $^ -o $@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(DEPS) $(CC) $(CFLAGS) -c $< -o $@ # 清理规则 clean: rm -rf $(OBJ_DIR)/*.o $(TARGET) ``` 在上面的 makefile 中,我们定义了四个变量:`SRC_DIR` 表示源文件目录,`INC_DIR` 表示头文件目录,`LIB_DIR` 表示库文件目录,`OBJ_DIR` 表示目标文件目录。我们还定义了编译器和链接器的变量,以及编译选项和链接选项的变量。 在编译规则中,我们定义了目标文件 `$(TARGET)` 和依赖关系 `$(DEPS)`,并使用 `$(addprefix)` 函数将源文件的路径和目标文件的路径拼接起来。在编译命令中,我们使用 `-I` 选项指定头文件的路径,并使用 `-c` 选项生成目标文件。 在链接规则中,我们使用 `$(LD)` 变量指定链接器,并使用 `-L` 选项指定库文件的路径,`-l` 选项指定需要链接的库文件。在链接命令中,我们使用 `$^` 变量表示所有的依赖文件,`-o` 选项指定生成的可执行文件的名称。 最后,我们还定义了一个清理规则,用于删除生成的目标文件和可执行文件。 通过使用 makefile,我们可以方便地管理多个源文件的编译和链接过程,解决跨文件问题,提高代码的可维护性和可重用性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水火汪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值