我有一个关于我的Makefile的问题。Makefile打算使用Cosmic编译器编译包含STM8μC代码的C文件。问题是,每当我调用构建目标时,所有可用的源文件都将重新编译而不做任何更改。我在makefile领域是个新手,我不知道如何修复它。
第二个问题与两个目标“%.o:src/%.c”和“%.o:src/stm8/%.c”有关。它们的作用完全相同,我希望使用一个能够处理src文件夹中所有子目录的通用问题。使用此解决方案时,需要为src文件夹的每个子文件夹添加一个附加规则

#***************PROJECT INFORMATIONS****************
PROJECT_NAME = stm8template
MODULES = stm8

#****************SET BUILD MODE*********************
ifeq ($(MODE), )
  MODE=Debug
endif

#***************DIRECTORY INFORMATION***************
SRCDIR = src
INCLUDES = includes
OUTPUT_DIR = bin/$(MODE)

#**************HELPER FUNCTIONS*********************
rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))

#***************FILE SPECIFICATIONS***************
SOURCE_FILES = $(foreach d, $(call rwildcard,$(SRCDIR),*.c), $(notdir $d))
OBJECT_FILES = $(patsubst %.c, %.o, $(SOURCE_FILES))
HEADER_FILES = $(wildcard $(INCLUDES)/*.h) $(wildcard $(INCLUDES)/**/*.h)
INCLUDE_DIRS_PARAM=$(foreach d, $(MODULES), -iincludes/$d) -iincludes -iC:\Hstm8

#***************COMPILER INFORMATIONS***************
CC = cxstm8
LIBS = -l +mods0
ifeq ("$(MODE)","Debug")
CFLAGS = $(INCLUDE_DIRS_PARAM) -cl$(OUTPUT_DIR) -co$(OUTPUT_DIR) -pxp -no -pp +debug
else
CFLAGS = $(INCLUDE_DIRS_PARAM) -cl$(OUTPUT_DIR) -co$(OUTPUT_DIR) -pxp -no -pp
endif

#***************LINKER INFORMATIONS***************
LINKFILE=$(OUTPUT_DIR)\$(PROJECT_NAME).lkf
OUTFILE=$(PROJECT_NAME)
LFLAGS = -lC:\Lib

#*************FLASHER CONFIGURATIONS***************
FLASHER_PATH="C:\Program Files (x86)\STMicroelectronics\st_toolset\stvp\STVP_CmdLine.exe"
DEVICE=STM8S105x6
PORT=USB
PROG_MODE=SWIM
BOARD_NAME=ST-LINK
FLASHER_PARAM = -no_loop

#***************BUILT TARGETS***************
all: build run

%.o: src/%.c
  $(info ********** Compile $< ***********)
  $(CC) $(CFLAGS) $(LIBS) $<

%.o: src/stm8/%.c
  $(info ********** Compile $< ***********)
  $(CC) $(CFLAGS) $(LIBS) $<

build: $(OBJECT_FILES)
  $(info ********** Build the Application ***********)
  clnk -m $(OUTPUT_DIR)\$(OUTFILE).map -o $(OUTPUT_DIR)\$(OUTFILE).sm8 $(LINKFILE)
  cvdwarf $(OUTPUT_DIR)\$(OUTFILE).sm8
  chex -o $(OUTPUT_DIR)\$(OUTFILE).s19 $(OUTPUT_DIR)\$(OUTFILE).sm8

run:
  $(info ********** Flashing the Application ***********)
  $(FLASHER_PATH) -BoardName=$(BOARD_NAME) -Device=$(DEVICE) -Port=$(PORT) -ProgMode=$(PROG_MODE) -FileProg="$(OUTPUT_DIR)\$(OUTFILE).s19" $(FLASHER_PARAM)

最佳答案

build目标永远不会被创建,因此每次运行make(或make allmake build)时都会执行它之后的命令,因此每次都会链接程序。
更改build目标,使其为假的:

.PHONY: build clean

因此它取决于程序,而不是对象文件:
build: $(OUTPUT_DIR)\$(OUTFILE).sm8

如果对象文件是最新的,则有一个规则(配方)生成程序:
$(OUTPUT_DIR)\$(OUTFILE).sm8: $(OBJECT_FILES)
    $(info ********** Build the Application ***********)
    clnk -m $(OUTPUT_DIR)\$(OUTFILE).map -o $(OUTPUT_DIR)\$(OUTFILE).sm8 $(LINKFILE)
    cvdwarf $(OUTPUT_DIR)\$(OUTFILE).sm8
    chex -o $(OUTPUT_DIR)\$(OUTFILE).s19 $(OUTPUT_DIR)\$(OUTFILE).sm8

我不是百分之百清楚我为程序选择了正确的后缀。我还会创建一系列宏以避免重复出现:
OUTFILE.sm8 = $(OUTPUT_DIR)\$(OUTFILE).sm8
OUTFILE.s19 = $(OUTPUT_DIR)\$(OUTFILE).s19
OUTFILE.map = $(OUTPUT_DIR)\$(OUTFILE).map

build: $(OUTFILE.sm8)

$(OUTFILE.sm8): $(OBJECT_FILES)
    $(info ********** Build the Application ***********)
    clnk -m $(OUTFILE.map) -o $(OUTFILE.sm8) $(LINKFILE)
    cvdwarf $(OUTFILE.sm8)
    chex -o $(OUTFILE.s19) $(OUTFILE.sm8)

另外,由于我主要在Unix上工作,所以我会使用/而不是\,但这只是一个小细节。

关于c - 调整Makefile以仅在文件已更改时重新编译文件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54270001/

10-11 23:07
查看更多