Компилировать сразу несколько ** измененных ** исходных файлов в GNU make - PullRequest
8 голосов
/ 18 мая 2011

Я знаю, что было несколько вопросов с похожими названиями, но ни один из них, похоже, не дает ответа на то, что мне нужно (поправьте меня, если я ошибаюсь).

Рассмотрите этот make-файл:

SOURCES=file1.cpp file2.cpp file3.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=myprog

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
    $(CXX) -o $@ $(OBJECTS)

file1.o: file1.cpp file1.h
file2.o: file2.cpp file2.h file1.h
file3.o: file3.cpp

.cpp.o:
    $(CXX) $(CXXFLAGS) -c -o $@ $<

Если я изменю file1.h, запускается следующее:

g++ -c -o file1.o file1.cpp
g++ -c -o file2.o file2.cpp
g++ -o myprog file1.o file2.o file3.o 

Что я хотел бы получить:

g++ -c file1.cpp file2.cpp
g++ -o myprog file1.o file2.o file3.o 

(я знаю, что не могу указать объектвыходной каталог с GCC, но с этим я могу жить; должна быть возможность работать с некоторыми командами cd.

В nmake это делается с помощью правила вывода с двоеточием (так называемогоназывается " правило пакетного режима" ).По сути, он группирует правила вывода (например, «.obj.cpp:») для нескольких целей и вызывает компилятор для всех зависимостей, а не один раз для файла.Переменная $< получает список зависимостей вместо первой.

Сейчас мы используем параллельное построение (make -j), но у него есть свои проблемы, и компилятор VC ++ работает намного лучше врежим одного вызова, поэтому я бы предпочел использовать это.

Ответы [ 2 ]

1 голос
/ 19 мая 2011

Вы можете заставить GNUmake делать то, что вы хотите, собирая файлы, которые будут перестроены в правиле сборки, а затем фактически собирая их при ссылке:

SOURCES=file1.cpp file2.cpp file3.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=myprog

all: $(EXECUTABLE)

.PHONY: build_list

build_list:
        -rm -f build_list

$(OBJECTS): %.o: %.cpp | build_list
        echo $< >> build_list

$(EXECUTABLE): build_list $(OBJECTS)
        if [ -r build_list ]; then $(CXX) $(CXXFLAGS) -c `cat build_list`; fi
        $(CXX) -o $@ $(OBJECTS)

file1.o: file1.h
file2.o: file2.h file1.h
1 голос
/ 18 мая 2011

Я не понимаю, зачем вам этот эффект, но вот как его получить (в GNUMake):

SOURCES=file1.cpp file2.cpp file3.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=myprog

all: $(EXECUTABLE)

$(EXECUTABLE): $(SOURCES)
    $(CXX) $(CXXFLAGS) -c $?
    $(CXX) -o $@ $(OBJECTS)

РЕДАКТИРОВАТЬ:
Я удивлен, чтоэто решение работает - что-то не так с моим представлением о том, что делает Make - но я не думаю, что оно будет работать в вашем случае, с зависимостями заголовка, без следующего клуджа.(Есть один или два других подхода, которые могут работать, если это не сработает.)

SOURCES=file1.cpp file2.cpp file3.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=myprog

all: $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
    $(CXX) -o $@ $(OBJECTS)

file1.cpp: file1.h
file2.cpp: file2.h file1.h

$(SOURCES):
    @touch $@

$(OBJECTS): $(SOURCES)
    $(CXX) $(CXXFLAGS) -c $?
    @touch $(OBJECTS)
...