2015-10-05 7 views
2

Это работает на FreeBSD, который использует PMake вместо GMake.My Makefile всегда создает все файлы

Это мой первый файл Makefile. Я использовал Google много, чтобы помочь создать это, а также источники, такие как «PMake - A Tutorial». Единственная проблема, которую я не могу решить, заключается в том, что каждый раз, когда я запускаю Makefile, он скомпилирует каждый файл, даже если никаких изменений не будет.

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

Что я делаю, это сканирование исходной папки и создание списка файлов для использования как для источника, так и для объекта, а также для заголовков. Обычно я запускаю «отлаживать» для отладки и «делать myservice» в противном случае.

Если я запустил «make clean», «make debug» и «make debug», он очистит мои папки, создаст все файлы, а затем переделает все файлы вместо того, чтобы ничего не делать.

Основываясь на моем поиске, я склоняюсь к правилу $ (OBJ), являющегося проблемой, но я не совсем понимаю это. Чтобы мои правила назначения и отладки были созданы, им нужно знать, как создавать объекты.

CC = clang 

BINDIR = $(.CURDIR)/bin 
OBJDIR = $(.CURDIR)/obj 
SRCDIR = $(.CURDIR)/src 
INCDIR = $(.CURDIR)/include 

CFLAGS = -Wall -I/usr/local/include -I$(INCDIR) 
LFLAGS = -lm -lpq -lpthread 
LIBDIR = -L/usr/local/lib 

_SRC != ls $(SRCDIR)/*.c 
SRC = ${_SRC:T} 
INC != ls $(INCDIR)/*.h 
OBJ = ${SRC:S/src/obj/g:.c=.o} 

TARGET = myservice 

$(TARGET): $(OBJ) 
    $(CC) -o $(BINDIR)/[email protected] $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS) 

debug: $(OBJ) 
    $(CC) -g -O0 -o $(BINDIR)/$(TARGET) $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS) 

$(OBJ) : $(SRCDIR)/$(.PREFIX).c $(INCDIR)/$(.PREFIX).h 
    $(CC) -c $< $(CFLAGS) 

.PHONY: clean 
clean: 
    rm -rf $(OBJDIR)/*.o $(BINDIR)/$(TARGET) 

редактировать - Новый Makefile

Новый Makefile. Не перестраивается, если никаких изменений. Не имеет отладки, все еще выдает определение отладки.

CC  = clang 

BINDIR = $(.CURDIR)/bin 
OBJDIR = $(.CURDIR)/obj 
SRCDIR = $(.CURDIR)/src 
INCDIR = $(.CURDIR)/include 

CFLAGS = -Wall -I/usr/local/include -I$(INCDIR) 
LFLAGS = -lm -lpq -lpthread 
LIBDIR = -L/usr/local/lib 

TARGET = $(BINDIR)/myservice 

_SRC != ls $(SRCDIR)/*.c 
SRC  = ${_SRC:T} 
INC  != ls $(INCDIR)/*.h 
OBJ  = ${SRC:S/src/obj/g:.c=.o} 

$(TARGET): $(OBJ) 
     $(CC) -o $(TARGET) $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS) 

$(OBJ) : $(SRCDIR)/$(.PREFIX).c $(INCDIR)/$(.PREFIX).h 
     $(CC) $(CFLAGS) -c $< -o [email protected] 

.PHONY: clean 
clean: 
     rm -rf $(OBJDIR)/*.o $(TARGET) 

редактировать - Рабочая Makefile

Добавлено если условно для целей отладки.

CC = clang 

BINDIR = $(.CURDIR)/bin 
OBJDIR = $(.CURDIR)/obj 
SRCDIR = $(.CURDIR)/src 
INCDIR = $(.CURDIR)/include 

CFLAGS = -Wall -I/usr/local/include -I$(INCDIR) 
.if make(debug) 
CFLAGS += -g -O0 
.endif 
LFLAGS = -lm -lpq -lpthread 
LIBDIR = -L/usr/local/lib 

TARGET = $(BINDIR)/myservice 

_SRC != ls $(SRCDIR)/*.c 
SRC = ${_SRC:T} 
INC != ls $(INCDIR)/*.h 
OBJ = ${SRC:S/src/obj/g:.c=.o} 

all: $(TARGET) 

debug: $(TARGET) 

$(TARGET): $(OBJ) 
    $(CC) -o $(TARGET) $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS) 

$(OBJ): $(SRCDIR)/$(.PREFIX).c $(INCDIR)/$(.PREFIX).h 
    $(CC) $(CFLAGS) -c $< -o [email protected] 

.PHONY: clean 
clean: 
    rm -rf $(OBJDIR)/*.o $(TARGET) 
+0

Просто дружественный совет: CMake немного более высокий уровень и может обойти некоторые из этого. –

+0

@JohnZwinck Спасибо за отзыв. На данный момент я хотел бы продолжить работу с PMake, чтобы я мог понять, где я ошибаюсь, и учиться на нем. Я быстро просмотрел примеры CMake. Это определенно то, что я рассмотрю дальше, как только узнаю немного. – quickblueblur

ответ

1

Второй make debug не может ничего сделать, debug это фальшивое цель, а не фактический выходной файл, по крайней мере, фаза ссылка будет повторно запустить.

Кроме того, повторное использование фазы ссылки с -g -O0 не перекомпилирует исходные файлы с информацией об отладке и без оптимизации.

Кстати, правило $(TARGET) также является фальшивым правилом, оно производит $(BINDIR)/$(TARGET), а не $(TARGET).

Вы должны переписать свой файл с различными правилами для создания объектных и двоичных файлов вывода в разных каталогах для режимов отладки и выпуска. gmake шаблоны позволяют легко писать, я не знаю о pmake или cmake для этой цели.

+0

С вашей помощью обсуждая цели PHONY, в частности мое правило $ (TARGET) и мое правило $ (BINDIR)/$ (TARGET), я смог переписать мои правила и заставить их работать. Я немного узнал о цели PHONY, но этого недостаточно. По моему мнению, правило PHONY всегда будет работать, если будет сказано. Поэтому, создав правило отладки и вызывая «make debug», он будет всегда строить, потому что debug никогда не будет существовать.Можно ли создать правило, которое позволяет отлаживать, не перестраивая ненужные? Я редактировал свой основной пост с помощью нового Makefile. – quickblueblur

+0

Вы можете создать правило отладки, которое зависит от исполняемого файла отладки, и создать отдельное правило, чтобы сделать отладочный исполняемый файл из файлов объектов отладки и еще одним общим правилом для создания файлов объектов отладки из исходных файлов. Вы также должны перечислить Makefile как зависимый для всех этих правил, чтобы принудительно перекомпилировать, когда вы изменяете Makefile, так как вы, возможно, изменили команды и/или параметры компиляции. – chqrlie

+0

Я считаю, что нашел способ, не создавая новых повторяющихся правил, но условные выражения, похоже, не работают. [Условные обозначения - PMake] (https://www.freebsd.org/doc/en/books/pmake/book.html#condition). '#if defined (DEBUG) || make (debug) CFLAGS + = -g -O0 # endif' Используя этот код, независимо от того, что я запускаю с make, он добавляет флаги -g -O0. Я предположил, что DEBUG был определен каким-то образом, поэтому я удалил это, чтобы оставить только 'make (debug)'. Запуск 'make' по-прежнему добавляет флаги, хотя я не запускаю' make debug'. – quickblueblur

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