× К оглавлению На главную Об авторе

Дата и время публикации:

Использование в простых проектах


1.Что такое GNU Make?

Утилита GNU Make является средством, позволяющим управлять генерацией исполняемых и иных файлов программы из исходных текстов (англ.source code).

Она, трактует как собирать одну и оболее программ с помощью правил, перечисленных в файле Makefile. Поэтому в директории проекта должен быть находится собственноручно написанный этот файл, что несомненно является затруднительным в больших проектах, но упрощает жизнь в простых, таких как uncurses .

Сборка проекта uncurses (версии 0.2), пропущенного через сито GNU Make, проиллюстрированна на рисунке 1.1

Рисунок 1.1

На котором изображены файлы на входе и выходе утилиты GNU Make и цели Makefile, которые позволяют генерировать в конечном итоге исполняемые файлы w.select и m.echo, а так же файл дистрибьюции uncurses-0.2.tar.gz и его контрольную сумму.

2. Использование Makefile

В листинге 2.1 приведен Makefile проекта uncurses.

Листинг 2.1

001 
002 CC := $(if $(CC),$(CC),/usr/bin/gcc)
003 RM := $(if $(CC),$(CC),/bin/rm)
004 
005 CFLAGS=-g -Werror
006 
007 DEPS = ucurses.h ucurses_modes.h ukeys.h 
008 
009 MECHO_OBJ = mecho.o
010 WSELECT_OBJ = wtypeselect.o
011 
012 %.o: %.c $(DEPS)
013 	  $(CC) -c -o $@ $< $(CFLAGS)
014 
015 all: m.echo w.select
016 
017 .PHONY: clean dist m.echo w.select
018 
019 m.echo: $(MECHO_OBJ)
020 	$(CC) -o $@ $(MECHO_OBJ) $(CFLAGS) -lncurses
021 
022 w.select: $(WSELECT_OBJ)
023 	$(CC) -o $@ $(WSELECT_OBJ) $(CFLAGS) -lncurses
024 
025 clean:
026 	rm *.o m.echo w.select
027 
028 ## Name of package
029 PACKAGE_NAME = uncurses
030 ## Define to the version of this package. */
031 PACKAGE_VERSION = 0.2
032 TAR := $(if $(TAR),$(TAR),/bin/tar czvf )
033 DISTDIR = $(PACKAGE_NAME)-$(PACKAGE_VERSION)
034 DISTFILES = CHANGELOG Makefile $(DEPS) mecho.c wtypeselect.c
035 REMOVE_DISTDIR = \
036   if test -d "$(DISTDIR)"; then \
037     find "$(DISTDIR)" -type d ! -perm -200 -exec chmod u+w {} ';' \
038       && rm -rf "$(DISTDIR)" \
039       || { sleep 5 && rm -rf "$(DISTDIR)"; }; \
040  fi
041 COPIED_FILES = `for FILE in $$DISTFILES; do cp $$ $(DISTDIR); done` 
042 
043 dist: $(DISTFILES)
044 	$(REMOVE_DISTDIR)
045 	test -d "$(DISTDIR)" || mkdir "$(DISTDIR)"
046 	for file in $(DISTFILES); do \
047 		echo -n "Copy " $$file ;\
048 		cp -fpR $$file $(DISTDIR) || exit 1;\
049 		echo "  Ok"; \
050 	done  
051 $(TAR) $(PACKAGE_NAME)-$(PACKAGE_VERSION).tar.gz $(DISTDIR) >/dev/null 2>&1;  
052 	if test -f "$(PACKAGE_NAME)-$(PACKAGE_VERSION).tar.gz"; then \
053 	  sha1sum $(PACKAGE_NAME)-$(PACKAGE_VERSION).tar.gz < $(PACKAGE_NAME)-054 $(PACKAGE_VERSION).tar.gz.sha1; \
055 	  echo "$(PACKAGE_NAME)-$(PACKAGE_VERSION).tar.gz created!"; \
056 	  rm -rf $(DISTDIR) ;	\
057 	fi
058 

В строке 1,2 и 32 определяем переменные, в т.ч. определенные по умолчанию, такие как $(CC),$(RM). Переменая $(TAR) к такой относится, но не исключая того, что в будущем может ей стать, применяем условное выражение $(if) в формате, показанном в листинге 2.2

Листинг 2.2

TEST := $(if $(TEST),$(TEST),$(нечто другое))

В котором проверяется переменная $(TEST) на предмет присвоения ей значения – в результате чего make повторно переназначит $(TEST) или $(нечто другое), если установлено, что её значение отсутсвует.

В строках 5 и 7 определяем флаги компилятору GCC(1) и зависимости в виде заголовочных файлов, показанные ранее на рисунке 1.1

В строке 12 и 13 опредяляется общее правило сборки для каждого объектного файла (все файлы с расширением .o) компилируется из файла исходного кода (все файлы с расширением , имеющие зависимость от заголовочных файлов, перечисленных ранее в переменной $(DEPS), строке 7 листинга 2.1

В строке 19,20 и 22,23 определены правила для сборки целей m.echo и w.select, которые являются финальной стадией компоновки ранее собранных объектных файлов в соответсвующие исполняемые бинарные модули, описываемые $@, и их линковку с библиотекой ncurses.

В строке 17, в .PHONY перечисляем цели, которые желательно сделать абстрактными для того, чтобы не был нарушен последовательный порядок их вызыва для цели all, которая определена в строке 15 листинга 2.1

В строках 28,...,56 демонстрируется возможность использования SHELL для создания файла дистрибутива uncurses-0.2.tar.gz, показанный на рисунке 1.1

 

3.1 GNU Make

3.2 GNU Make:Conditional Syntax

3.3 Makefile set if variable is empty

3.3 GNU Make:Variables Used by Implicit Rules

3.4 A Simple Makefile Tutorial

3.5 Эффективное использование GNU Make