2013-12-16 4 views
0

Я пытался создать свой собственный, но универсальный Makefile для моих университетских проектов. То, что мне удалось написать, - это текущий код. Проблема в том, что я должен запустить make all несколько раз, чтобы скомпилировать все исполняемые файлы. Файлы .o и соответствующие исполняемые файлы создаются инкрементально при каждом вызове make, а не сразу. Как это должно быть сделано правильно?Простой, универсальный Makefile

# Variables 
Project = Project_Name 
Src  = src 
Include = inc 
Lib  = lib 
Build = build 
Dist = dist 
Res  = resources 
LibSem = -L$(Lib) -lbib 
CC  = gcc $(CFLAGS) 

# Vpaths for implicite rules. 
vpath %.c $(Src) 
vpath %.h $(Include) 
vpath %.o $(Build) 
vpath %.d $(Build) 
# Src is set for explicite named files. 
CPPFLAGS += -I$(Src) -I$(Include) 

# Define Source variable with the list of .c files 
# File is updated by Vim by the call of "make update" 
include build/Sources.inc 

all: prog1 prog2 
    cp -fr $(Res)/* $(Dist) 

bib: libbib.o 
    ar -cvrs $(Lib)/libbib.a $^ 

prog1: prog1.o sem 
    $(CC) $(CFLAGS) $(CPPFLAGS) -o $(Dist)/[email protected] $< $(LibSem) 

prog2: prog2.o sem 
    $(CC) $(CFLAGS) $(CPPFLAGS) -o $(Dist)/[email protected] $< $(LibSem) 

update: 
    #---------------------------------------- 
    # Updating list of sources. 
    #---------------------------------------- 
    echo -n "Sources = " > $(Build)/Sources.inc 
    find src/ -type f -name '*.c' -printf "%f " >> $(Build)/Sources.inc 

clean: 
    #---------------------------------------- 
    # Cleaning files. 
    #---------------------------------------- 
    rm -rf $(Build)/* 
    rm -rf $(Dist)/* 
    rm -rf $(Lib)/* 
    touch $(Build)/Sources.inc 

dist: clean dep all 
    #---------------------------------------- 
    # Distribute archive. 
    #---------------------------------------- 
    tar -cvzf $(Project).tar.gz $(Include) $(Res) $(Src) Makefile 

# changed for output in Build directory 
%.o: %.c 
    $(COMPILE.c) -o $(Build)/[email protected] $< 

# autogenerated dependencies files 
-include $(subst .c,.d,$(Sources)) 

dep %.d: %.c 
    #---------------------------------------- 
    # Generating auto-dependencies 
    #---------------------------------------- 
    $(CC) -M $(CPPFLAGS) $< > $(Build)/[email protected]$$$$; \ 
    sed 's,\($*\)\.o[ :]*,\1.o [email protected] : ,g' < $(Build)/[email protected]$$$$ > $(Build)/[email protected]; \ 
    rm -f $(Build)/[email protected]$$$$ 
+0

см. Этот [проект] (https://github.com/deminets/unimake) – dsnk

ответ

0

Эти правила неправильны:

prog1: prog1.o sem 
     $(CC) $(CFLAGS) $(CPPFLAGS) -o $(Dist)/[email protected] $< $(LibSem) 

Каждый «нормальное» правило в сделать должны обновить цель вы сказали сделать это будет обновлять. Здесь ваше правило сообщает, что оно обновит файл prog1, но на самом деле ваше правило обновляет файл dist/prog1. Все они совершенно разные, и ваш make-файл не работает, потому что вы лгали.

В общем случае невозможно использовать vpath, чтобы описать, где поставить сгенерированные цели. Функция vpath действительна только при использовании для нахождения источника файлов.

Вы должны написать правила, как это:

$(Dist)/prog1: $(Build)/prog1.o sem 
     $(CC) $(CFLAGS) $(CPPFLAGS) -o [email protected] $< $(LibSem) 

Однако это только верхушка айсберга. Из-за этого вам нужно будет сделать больше изменений, чтобы получить то, что вам нужно.

Смежные вопросы