Ваш метод сценария сборки
Если вы хотите придерживаться "метода сборки 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? Он явно разработан для удовлетворения этого требования.