いくつかのC++ファイルをコンパイルしたいので、すべてのオブジェクトファイルを別のビルドディレクトリに配置する必要がありますが、完全にフラットに保存されます。つまり、サブディレクトリはありません。私はVPATHを使用した一般的な解決策を知っています。これは次のようになります。
SOURCES = foo/one.cpp \
foo/bar/two.cpp \
foo/bar/sub/three.cpp
OBJDIR = obj
VPATH=$(dir $(SOURCES))
OBJECTS = $(addprefix $(OBJDIR)/, $(notdir $(SOURCES:%.cpp=%.o)))
$(OBJDIR)/%.o : %.cpp
@echo Should compile: $(filter %/$*.cpp, $(SOURCES))
@echo Compiling $<
all: $(OBJECTS)
この例はほとんど機能します。「obj」サブディレクトリに3つのオブジェクトファイルone.o、two.o、three.oがあります(存在しているとみなすことができます)。
VPATHを使用する場合の注意点は次のとおりです。ファイル「foo/three.cpp」がある場合、これはSOURCES変数で指定されている「foo / bar / sub/three.cpp」の代わりにコンパイルされます。いいえ、どちらのファイルの名前も変更できません。この名前の衝突は単に存在し、私はそれについて何もできません。
だから私の質問は: SOURCES変数に表示される「.cpp」ファイルのみを使用するようにMakeに指示するにはどうすればよいですか?最善の解決策は、ターゲットの前提条件でその「filter」ステートメントを使用することだと思います。これは二次拡張を使用して可能になるはずですが、「%」をどうすればよいかわかりません。たとえば、私は試しました
.SECONDEXPANSION:
$(OBJDIR)/%.o : $$(filter %/$$*.cpp, $(SOURCES))
しかし、それは機能しません。
更新:tripleeの助けを借りて、私はこれを次のように機能させることができました:
define make-deps
$(OBJDIR)/$(notdir $(1:%.cpp=%.o)): $1
endef
$(foreach d, $(SOURCES), $(eval $(call make-deps,$d)))
%.o :
@echo Should compile $^ into $@
@echo Compiling $^