Makefile を使用して大きなプロジェクト ファイルをコンパイルすると、パラメーター リストが長すぎるため、gcc コマンドのサフィックスが 8000 バイトを超えることはできないことを示す次のエラーが発生しました。
データをチェックすることで、gcc の接尾辞リストをファイルに入れることができ、長すぎる引数リストは gcc @file によって解決できます。
参考依据: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 領域 `BMHDO' が xxx バイトでオーバーフローしました
この理由は、ファームウェアのサイズが特定のサイズを超えているためです。リンク スクリプトを変更します。ここでは、リンク スクリプト vLinkGen_Template.ld を、特定の環境変数 LDFLAGS を通じて出力します。
-T スクリプトは ld リンク スクリプトを指定します
リンカー スクリプトを変更して、BMHDO セクションのサイズを増やします。
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 方言オプション (GNU Compiler Collection (GCC) の使用)
オプションの概要 (GNU Compiler Collection (GCC) の使用)
(メッセージ 37 件) gcc @Commandfile が長すぎるコマンドの問題を解決_EarnForLive のブログ - CSDN ブログ