私がしたいのは、ソースコードが変更されたときにのみ特定のプログラムをコンパイルするために別のbashスクリプトを実行するbashスクリプトを作成することです。これまでJ2000時代以降、各ファイルのタイムスタンプ(秒単位)を取得する方法があります。
#get a list of the source timestamps
sourceTimes=$(stat -f "%Sm" -t "%s" *.f)
#get a list of the program timestamps
exeTimes=$(stat -f "%Sm" -t "%s")
そしてインストールスクリプト
./make_common_lib.bsh build
./make_common_lib.bsh install
if状態(半疑似コード)を生成する方法を見つけようとしています。
if [any of $sourceTimes>$exeTimes];
then #run make_common_lib.bsh script
else #Do nothing
fi
これまで私の推測では何とか使用しているようですが、read
両方の変数を同時にインデックス付けする方法がわかりません。
私は初めてbashスクリプトに触れたので、これを行うための本当に簡単な方法がある場合は申し訳ありません。しかし、これまでに検索した結果、実際に有用な情報を返したことはありません。
追加情報:
タイムスタンプ変数の形式は次のとおりです。
1432326068 1432326069 1432326069 1432326069 1432326069 1432326069 1432326069 1432326069 1432326069 1432326069 1432326069 1432326069 1432326068 1432326069 1432326069
答え1
ビルドスクリプト方法
「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
dependency1.o
dependency1.o: dependency1.c
gcc -c dependency1.c
Makefileはシンボルの置換も許可するので、Makefileの前半でコンパイラとコンパイラフラグを宣言できます。
CC=/usr/bin/gcc
CFLAGS=-O2 -Wall
次に、ルールでこれを参照してください。
dependency1.o: dependency1.c
$(CC) $(CFLAGS) -c dependency1.c
依存関係宣言の後のインデント行は、空白ではなくタブで始まる必要があります。
依存関係ルールリストの短縮
OPは、すべての依存関係を宣言するより短い方法があるかどうか尋ねました。 GNU makeを使用すると、いくつかのトリックが可能です(これらすべてがバニラmakeに適用されるわけではありません)。
変数置換を実行できます。与えられた文は次のようになります。
SRCS=dependency1.c dependency2.c dependency3.c
その後、変数置換を使用してオブジェクトルールを作成できます。
OBJS=$(SRCS:.c=.o)
これにより.c
' がすべて.o
' に置き換えられます。実際には、次の形式の行を提供します。
OBJS=dependency1.o dependency2.o dependency3.o
$<
その後、特殊変数を使用して「コンパイルコマンド」をさらに短縮できます$@
。
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
$<
前提条件(または私が呼ぶ依存関係)と$@
GNUのターゲットは用語を指定するので、最終的には次のものがエクスポートされます。
/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製作マニュアル。