Seu método de criação de scripts
Se você quiser manter o "método de compilação bash", provavelmente será melhor "tocar" em um arquivo ( touch lastbuild
) quando o script de compilação for executado e concluir a compilação. Além disso, o script de construção poderia procurar pelo arquivo gerado pelo touch (se ele não existir, suponha que uma compilação é necessária) ou, se existir, use find
para ver se existem arquivos mais recentes:
find . -name "*.[ch]" -newer lastbuild
e, em seguida, construa se essa saída for 1 ou mais linhas (pode ser verificada com algo como wc -l
).
Usando o Make
Isso é melhor gerenciado por algo como um Makefile (usado especificamente para esse tipo de verificação de dependência).
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
Criando um script "build" fictício:
$ cat make_common_lib.bsh
#! /bin/sh
echo "Build $1"
Agora podemos executar o make:
$ make
./make_common_lib.bsh build
Build build
./make_common_lib.bsh build
Build build
Você também pode substituir o ./make_common_lib.bsh build
pelo comando que o ./make_common_lib.bsh build
emitirá para criar dependency1.o
etc:
dependency1.o: dependency1.c
gcc -c dependency1.c
Makefiles também permitem a substituição de símbolos, então você pode declarar o complier e o compilador sinalizar antes no Makefile:
CC=/usr/bin/gcc
CFLAGS=-O2 -Wall
e, em seguida, faça referências a eles em suas regras:
dependency1.o: dependency1.c
$(CC) $(CFLAGS) -c dependency1.c
Observe que a linha que é recuada após uma declaração de dependência deve começar com uma tabulação e não com espaços.
Encurtando a lista de regras de dependência
O OP perguntou se é possível fazer maneiras mais curtas de declarar todas as dependências. É possível com alguns truques usando o make do GNU (note que nem todos eles funcionarão com o make vanilla).
Você pode fazer uma substituição variável. Dada a declaração:
SRCS=dependency1.c dependency2.c dependency3.c
Você pode então criar uma regra de objetos usando a substituição de variáveis:
OBJS=$(SRCS:.c=.o)
isso substituirá todos os .c
com .o
. Com efeito, dando uma linha do formulário:
OBJS=dependency1.o dependency2.o dependency3.o
Você pode, além disso, reduzir o "comando de compilação" usando as variáveis especiais $<
e $@
:
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
$<
representa o pré-requisito no GNU make language (ou dependência como eu o chamei) e $@
o destino, e assim ele acabará lançando:
/usr/bin/gcc -Wall -O2 -c dependency1.c -o dependency1.o
/usr/bin/gcc -Wall -O2 -c dependency2.c -o dependency2.o
.
.
.
Colocando tudo isso junto, com opções de vinculação e um comando para vincular e compilar o executável $(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
Note que há muitas coisas que você pode fazer com o GNU make, e está bem documentado aqui GNU Make Manual .