Как мне сказать Make игнорировать файлы, которые не были обновлены?

#c #makefile #gnu-make

#c #makefile #gnu-make

Вопрос:

Я новичок в использовании Make, и у меня возникли некоторые проблемы с пониманием синтаксиса. Я просмотрел несколько примеров и, по сути, объединил несколько из них, чтобы создать свой собственный файл. Я не уверен, как указать make игнорировать уже скомпилированные исходные или заголовочные файлы, которые не изменились. Как я могу заставить make компилировать только измененные файлы?

Я посмотрел на веб-сайте GNU: https://www.gnu.org/software/make/manual/html_node/Avoiding-Compilation.html

Я попробовал некоторые из этих флагов, но я все еще не получаю желаемых результатов.

 # specify compiler
CC=gcc
# set compiler flags
CFLAGS=-Igen/display -Igen/logic -Iman -Ilib/include -pipe -march=native
# set linker flags
LDFLAGS=-lglut32 -loglx -lopengl32 -Llib 
# include all sources
SOURCES=gen/display/*.c gen/logic/*.c man/*.c
# create objects from the source files
OBJECTS=$(SOURCES:.cpp=.o)
# specify the name and the output directory of executable
EXECUTABLE=win32/demo

all: $(SOURCES) $(EXECUTABLE)

# compile the target file from sources 
# $@ = placeholder for target name
$(EXECUTABLE): $(OBJECTS) 
    $(CC) $(CFLAGS) $(OBJECTS) $(LDFLAGS) -o $@

.c.o:
    $(CC) $(CFLAGS)

lt; -o $@


У меня есть несколько заголовочных и исходных файлов в разных каталогах, которые компилируются, но независимо от того, что я делаю, все перекомпилируется.

Комментарии:

1. Как насчет OBJECTS=$(SOURCES:.c=.o) ?

2. На несвязанном примечании вам не нужно делать all depend on $(SOURCES) .

3. make делает это автоматически.

4. Вероятно, вам было бы лучше использовать встроенное .c.o правило, чем предоставлять свое собственное. Однако, если вы предоставляете свои собственные, тогда поймите это правильно: чтобы скомпилировать в объектный файл, но избежать связывания (в то время) с программой, вам нужен -c флаг — $(CC) $(CFLAGS) -c -o $@ $< . Но опять же, make есть встроенное .c.o правило, которое будет делать правильные вещи здесь, и вы напрасно переопределяете его.


Ответ №1:

Хорошо, давайте сделаем это, как и должно быть сделано 😉

 # set up our variables
# note: you may also prefer := or ?= assignments,
#       however it's not that important here
CC=gcc
CFLAGS=-Igen/display -Igen/logic -Iman -Ilib/include -pipe -march=native
# linker's flags are different from compiler's
LDFLAGS=
# these are really libs, not flags
LDLIBS=-Llib -lglut32 -loglx -lopengl32

# 1) make is not your shell - it does not expand wildcards by default
# 2) use := to force immediate wildcard expansion;
#    otherwise make could perform it several times,
#    which is, at the least, very ineffective
SOURCES:=$(wildcard gen/display/*.c gen/logic/*.c man/*.c)

# use the right extensions here: .c -> .o
OBJECTS=$(SOURCES:.c=.o)

# note: it's okay to omit .exe extension if you're using "POSIX"-like make
# (e.g. cygwin/make or msys/make). However, if your make was built on Windows
# natively (such as mingw32-make), you'd better to add '.exe' here
EXECUTABLE=win32/demo

# don't forget to say to make that 'all' is not a real file
.PHONY: all
# *.c files are what you write, not make
# note: in fact, you don't need 'all' target at all;
#       this is rather a common convention
all: $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@

# note: 1) suffix rules are deprecated; use pattern rules instead
#       2) this doesn't add much to the built-in rule, so you can even omit it
#       3) .o files are created in the same directories where .c files reside;
#          most of the time this is not the best solution, although it's not
#          a mistake per se
%.o: %.c
    $(CC) $(CFLAGS) -c

lt; -o $@

Комментарии:

1. Спасибо, чувак! Я ценю, что вы нашли время, чтобы все объяснить и исправить мой код. Это отлично работает!!