次の構造を想像してください。
root/
|
+-- include/
+-- src/
+-- build/
+-- lib/
+-- tests/
|
+-- common
+-- test1
+-- test2
+-- test3
ではtests/
、フォルダーcommon/
には、データを生成したり、ログに記録されたファイルなどからデータを読み取ったりするいくつかのソース ファイルが含まれており、これらはすべてのテスト間で共有されます。したがって、各テストには 1 つのファイルしかありません。main.c
(現在)。各テストのMakefile
は次のようになります。
.SUFFIXES:
.SUFFIXES: .c .o
TARGET := test
# OS dependent stuff omitted for brevity
CFLAGS += -I../../include -I../common
LDFLAGS += -L../../lib -lname
VPATH = ../common
.phony: all clean
all: $(TARGET)
clean:
-$(RM) *.o $(TARGET)
# Other targets removed for brevity
OBJECTS := main.o io.o read_str.o
$(TARGET): $(OBJECTS) ../../lib/libname.a
$(LD) -o $@ $(OBJECTS) $(LDFLAGS)
%.o: %.c
$(CC) -c $(CFLAGS) -o $@ $<
main.o: main.c io.h $(wildcard ../../include/*.h)
最初common/
は各テストでファイルをコピーしましたが、すべて問題ありませんでしたが、それらを入れてcommon/
使用したVPATH
ので、問題に直面しています。
いくつかの行を説明しましょう:
main.o: main.c io.h $(wildcard ../../include/*.h)
^^^^
VPATH correctly finds this file in common/
$(TARGET): $(OBJECTS) ../../lib/libname.a
^^^^^^^^^^^^^^^^^^^
If the library is rebuilt, the tests need to re-link
$(LD) -o $@ $(OBJECTS) $(LDFLAGS)
^^^^^^^^^^
I can't use $^ because that also includes ../../lib/libname.a
ご想像のとおり、common/*.o
ファイルはこのフォルダーに$(LD)
ないため、 はそれらを見つけることができません。一方make
、与えられたVPATH = ../common
はそれらを見つけるのに問題はありません。を削除できれば../../lib/libname.a
、$^
オブジェクト ファイルへの正しいパスを指定できます。
ただし、lib ファイルへの依存関係を削除するとmake
、最上位にいるときに、lib 自体のみが更新されている場合、テストは更新されません。
したがって、私の質問は、別のファイル (lib ファイル) への依存関係があることをどのように確認できますか?make
VPATH
依存関係を削除することを考えました。Makefile
そのビルドlibname.a
では、ライブラリが作成された後に、Makefile
テストの s にそれらTARGET
の sを削除するように指示するコマンドを追加します。
lib/Makefile:
.SUFFIXES:
TARGET = libname.a
VPATH = ../build
.PHONY: all clean
all: $(TARGET)
clean:
-$(RM) $(TARGET)
$(TARGET): list.o of.o my.o library.o files.o
$(AR) $(TARGET) $^
@$(MAKE) --no-print-directory -C ../tests remove_targets
これにより$(LD)
、それらを再度作成する必要があります。Makefile
ただし、このソリューションは、関係を混乱させる傾向があります。Makefile
lib をビルドするのは、テストがあるかどうかとは無関係です。
私は多くのビルドとテストを行っています。そのため、依存関係を完全なものにしようとしています。これによりmake
、すべてを正しくビルドするために可能な限り最小限のアクションが必要になります。毎回クリーンアップして再構築するという解決策は選択肢ではありません。
また、この構文も認識しています。この構文は、.lib ファイル ディレクトリを に渡すgcc
代わりに、-Lpath/to/lib -lname
. ただし、それが良いアイデアかどうかはわかりません(つまり-L
、とのリンクを常に見ていましたが、ライブラリファイルを直接渡すときに不利な点があるかどうかはわかりません)
ところで、私がひどく間違ったことをしている場合、または自分でそれを難しくしている場合は、どうすれば正しく実行できるか教えてください.