Ваш метод сценария сборки
Если вы хотите придерживаться "метода сборки bash", то вам, вероятно, лучше всего "прикоснуться" к файлу ( touch lastbuild
), когда скрипт сборки запускается и завершает сборку. Кроме того, сценарий сборки может затем искать файл, сгенерированный касанием (если он не существует, предположить, что сборка необходима), или, если он существует, использовать, find
чтобы увидеть, существуют ли какие-либо более новые файлы:
find . -name "*.[ch]" -newer lastbuild
и затем построить, если этот вывод составляет 1 или более строк (можно проверить с помощью чего-то вроде wc -l
).
Вместо этого используйте Make
Для этого лучше всего использовать что-то вроде Makefile (специально используется для такого рода проверки зависимостей).
default: all
all: dependency1.o dependency2.o
dependency1.o: dependency1.c
./make_common_lib.bsh build
dependency2.o: dependency2.c
./make_common_lib.bsh build
install:
./make_common_lib.bsh install
Создание фиктивного сценария сборки
$ cat make_common_lib.bsh
#! /bin/sh
echo "Build $1"
Теперь мы можем запустить make:
$ make
./make_common_lib.bsh build
Build build
./make_common_lib.bsh build
Build build
Вы также можете заменить ./make_common_lib.bsh build
команду, ./make_common_lib.bsh build
которая выдаст команду build dependency1.o
:
dependency1.o: dependency1.c
gcc -c dependency1.c
Makefiles также допускают подстановку символов, поэтому вы можете объявить флаги complier и compiler ранее в Makefile:
CC=/usr/bin/gcc
CFLAGS=-O2 -Wall
а затем сделайте ссылки на них в ваших правилах:
dependency1.o: dependency1.c
$(CC) $(CFLAGS) -c dependency1.c
Обратите внимание, что строка с отступом после объявления зависимости должна начинаться с табуляции, а не с пробелов.
Сокращение списка правил зависимости
ОП спросила, можно ли сделать более короткие способы объявления всех зависимостей. Это возможно с помощью нескольких трюков с использованием GNU make (обратите внимание, что не все они будут работать с vanilla make).
Вы можете сделать замену переменных. Учитывая декларацию:
SRCS=dependency1.c dependency2.c dependency3.c
Затем вы можете создать правило объектов, используя подстановку переменных:
OBJS=$(SRCS:.c=.o)
это заменит все .c
с .o
's. По сути, дает строку вида:
OBJS=dependency1.o dependency2.o dependency3.o
Затем вы можете дополнительно укоротить «команду компиляции», используя специальные переменные $<
и $@
:
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
$<
представляет предпосылку в GNU make parlance (или зависимость, как я ее назвал) и $@
цель, и в результате она выдаст:
/usr/bin/gcc -Wall -O2 -c dependency1.c -o dependency1.o
/usr/bin/gcc -Wall -O2 -c dependency2.c -o dependency2.o
.
.
.
Собрав все это вместе, с опциями связывания и командой для связывания и компиляции исполняемого файла $(TARGET)
:
# Globals
CC=/usr/bin/gcc
CFLAGS=-Wall -O2
LDFLAGS=-L/usr/local/lib
LIBS=-ldependencylib
# declare all the sources
SRCS=dependency1.c dependency2.c
# declare the objects files using variable substitution (find .c and replace with .o)
OBJS=$(SRCS:.c=.o)
# Target executable name:
TARGET=myexefile
default: all
all: $(TARGET)
@echo Target has been built
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LDFLAGS) $(LIBS)
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
install:
./make_common_lib.bsh install
Обратите внимание, что есть много вещей, которые вы можете сделать с GNU make, и это хорошо задокументировано здесь GNU Make Manual .
make
? Он явно разработан для удовлетворения этого требования.