提问人:H.atyq 提问时间:10/26/2023 最后编辑:Peter CordesH.atyq 更新时间:10/27/2023 访问量:62
使用特殊的编译标志编译目录中的某些文件
compile certain files in a directory with special compilation flags
问:
我在项目目录中有几个文件,我想使用非常具体的编译选项编译某些文件,并使用标准编译选项编译其他文件,我想使用其他文件来处理文件。
我目前遇到的问题,程序在if语句上崩溃,你能帮我吗?
对于信息,我使用Windows cmd.exe
低于预期结果,非常感谢您的帮助
生成文件:
SPECIAL_FILES := Fee_PBcfg.obj Fee.obj Can_17_McmCan_PBcfg.obj Dio.obj
Dio_Lcfg.obj Mcu.obj Can_17_McmCan_Isr.obj Can_17_McmCan.obj
McalLib.obj Spi_PBcfg.obj Spi.obj EcuM_Callout_Stubs.obj EcuM_Cfg.obj
EcuM_Init_Cfg.obj
%.$(OBJ_EXT): %.c $(MCS_H)_mcs.h $(COMPILER_OPT_FILE)
if exist $(BUILD_PATH)\$*.obj del $(BUILD_PATH)\$*.obj
if exist $(BUILD_PATH)\$*.d del $(BUILD_PATH)\$*.d
if exist $(BUILD_PATH)\$*.i del $(BUILD_PATH)\$*.i
if exist $(BUILD_PATH)\$*.s del $(BUILD_PATH)\$*.s
if $(filter $*, $(SPECIAL_FILES))
$(DBGOUT)
echo Compile $* with $(COPT_ECHO_MCAL) option
$(CC) $(TARGET) $(CFLAGS_MCAL) $(INCLUDES_PATH) -o
$(BUILD_PATH)/$*.obj $< 2>$(BUILD_PATH)/$*.warn || type
$(BUILD_PATH)\$*.warn && $(FALSE)
else
$(DBGOUT)
echo Compile $* with $(COPT_ECHO) option
$(CC) $(TARGET) $(CFLAGS) $(INCLUDES_PATH) -o $(BUILD_PATH)/$*.obj
$< 2>$(BUILD_PATH)/$*.warn || type $(BUILD_PATH)\$*.warn && $(FALSE)
endif
答:
您不能使用 etc.,因为它们类似于预处理器语句:它们在读入 makefile 时被处理。但是,配方直到很久以后才构建,当 make 将构建目标时。ifeq
在 GNU Make 手册中,你会发现像这样的自动变量只在配方中有效;这里的“配方内部”是指配方脚本中,即由 TAB 字符缩进并传递给 shell 的规则部分。make 运算符,如 etc. 是(如上所述)进行预处理器语句,而不是配方的一部分。$*
ifeq
为了满足您的要求,您可以使用特定于目标的变量。像这样的东西:
$(SPECIAL_FILES) : CFLAGS := $(CFLAGS_MCAL)
%.$(OBJ_EXT): %.c $(MCS_H)_mcs.h $(COMPILER_OPT_FILE)
...
echo Compile $* with $(CFLAGS) option
$(CC) $(TARGET) $(CFLAGS) $(INCLUDES_PATH) -o $(BUILD_PATH)/$*.obj $< 2>$(BUILD_PATH)/$*.warn || type $(BUILD_PATH)\$*.warn && $(FALSE)
或者,如果您愿意,您可以保持大多数 CFLAGS 相同,只需为特殊目标添加一些额外的 CFLAG:
EXTRA_CFLAGS =
$(SPECIAL_FILES) : EXTRA_CFLAGS := $(MCAL_FLAGS)
%.$(OBJ_EXT): %.c $(MCS_H)_mcs.h $(COMPILER_OPT_FILE)
...
echo Compile $* with $(EXTRA_CFLAGS) option
$(CC) $(TARGET) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDES_PATH) -o $(BUILD_PATH)/$*.obj $< 2>$(BUILD_PATH)/$*.warn || type $(BUILD_PATH)\$*.warn && $(FALSE)
伊塔
请注意,配方的每一行都是在单独的 shell 中调用的。因此,您不能创建跨越多行的语句;例如:
if $(filter $*, $(SPECIAL_FILES))
$(DBGOUT)
echo Compile $* with $(COPT_ECHO_MCAL) option
$(CC) $(TARGET) $(CFLAGS_MCAL) $(INCLUDES_PATH) -o $(BUILD_PATH)/$*.obj $< 2>$(BUILD_PATH)/$*.warn || type $(BUILD_PATH)\$*.warn && $(FALSE)
是一个错误,因为只有第一行(语句)被传递给 shell,这是无效的语法。if
如果您使用的是 POSIX shell,它很好地支持在同一行上编写复杂的脚本(您在语句之间添加并且它具有常规语法),这是很有可能的。;
我的怀疑是,如果您使用巴洛克式的 Windows cmd shell 编写 makefile,那么以这种方式操作不会取得多大成功,因为如果不使用换行符,很难编写长批处理命令。但是,如果你想这样做,你需要问那些对 Windows 批处理文件的复杂性非常了解的人这个问题:这并不是一个真正的制造问题。
您可以尝试的一件事是添加 .ONESHELL:
makefile 的伪目标,它告诉 make 在单个 shell 中运行整个配方。也许这会有所帮助。
我的建议是避免所有这些,而是使用 GNU Make 功能将这些复杂性限制在您的 makefile 中,而不是尝试在进行调用的 shell 中运行它们。
评论