Настройте Makefile, чтобы перекомпилировать файлы, только если они изменились - PullRequest
0 голосов
/ 19 января 2019

У меня есть вопрос относительно моего Makefile. Makefile намеревается скомпилировать C-файлы, содержащие код для STM8 µC, используя компилятор Cosmic. Проблема в том, что каждый раз, когда я вызываю цель сборки, все доступные исходные файлы перекомпилируются без каких-либо изменений. Я действительно новичок в области Makefiles и понятия не имею, как это исправить.

Второй вопрос связан с двумя целями "% .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) 

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Обновление: Спасибо за вашу помощь. Я изменил Makefile, как показано ниже. Вторая проблема теперь исправлена, но первая проблема все еще остается.

Каждый раз, когда вызывается правило сборки, все .c файлы перекомпилируются. Я думал, что компиляция только измененных файлов является основной целью / преимуществом использования make. Так что что-то не так, но, к сожалению, я не нахожу ошибку.

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

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

#***************DIRECTORY INFORMATION***************
SRCDIR = src
INCLUDES = includes

#**************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, $(call rwildcard,$(SRCDIR),*.c))
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
LFLAGS = -LC:\Lib

#*******************OUTPUT FILES********************
OUTPUT_DIR = bin/$(MODE)
OUTFILE=$(PROJECT_NAME)
OUTFILE.sm8 = $(OUTPUT_DIR)\$(OUTFILE).sm8
OUTFILE.s19 = $(OUTPUT_DIR)\$(OUTFILE).s19
OUTFILE.map = $(OUTPUT_DIR)\$(OUTFILE).map
TARGET_FILE=$(OUTPUT_DIR)\$(PROJECT_NAME).elf

#*************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***************
.PHONY: all run build clean
all: build run

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

build: $(OUTPUT_DIR)\$(PROJECT_NAME).elf

$(TARGET_FILE): $(OBJECT_FILES)
  $(info ********** Build the Application ***********)
  clnk -m $(OUTFILE.map) -o $(OUTFILE.sm8) $(LINKFILE)
  cvdwarf $(OUTFILE.sm8) 
  chex -o $(OUTFILE.s19) $(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) 
0 голосов
/ 19 января 2019

Цель build никогда не создается, поэтому команды после нее выполняются при каждом запуске make (или make all или make 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

Мне не на 100% ясно, что я выбрал правильный суффикс для программы.Я бы также создал серию макросов, чтобы избежать повторения, которое я вижу:

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, я бы использовал / вместо \, но это незначительная деталь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...