オブジェクトファイルを別のサブディレクトリに配置する方法 質問する

オブジェクトファイルを別のサブディレクトリに配置する方法 質問する

おそらく非常に基本的なテクニックですが、make を使用してオブジェクト ファイルを別のサブディレクトリに配置するのに問題があります。このページの情報を使用しようとしました。http://www.gnu.org/software/hello/manual/make/Prerequisite-Types.html#Prerequisite-Types

make から次の出力が得られます。

make: *** No rule to make target `ku.h', needed by `obj/kumain.o'.  Stop.

ただし、ku.h は依存関係であり、ターゲットではありません (ただし、c ソース ファイル内に #include されていることは明らかです)。オブジェクト ファイルにサブディレクトリを使用しない (つまり、OBJDIR 部分を省略する) と、正常に動作します。なぜ make は ku.h をターゲットとみなすのでしょうか?

私のメイクファイルは次のとおりです: (スタイルはさまざまな情報源を読んだ後のものです)

.SUFFIXES:
.SUFFIXES: .c .o

CC=gcc 
CPPFLAGS=-Wall
LDLIBS=-lhpdf
VPATH=%.c src
VPATH=%.h src
VPATH=%.o obj
OBJDIR=obj

objects= $(addprefix $(OBJDIR)/, kumain.o kudlx.o kusolvesk.o kugetpuz.o kuutils.o \
  kurand.o kuASCboard.o kuPDFs.o kupuzstrings.o kugensud.o \
  kushapes.o )

ku : $(objects)
  $(CC) $(CPPFLAGS) -o ku $(objects) $(LDLIBS)

$(objects) : ku.h kudefines.h kuglobals.h kufns.h | $(OBJDIR)

$(OBJDIR):
  mkdir $(OBJDIR)

.PHONY: clean
clean :
  rm $(objects)

編集: vpath ディレクティブを使用するように変更を適用しました。私のバージョンでは、VPATH=xxx と vpath %.c xxx が混在していました。しかし、今度は別の問題が発生しました (これは、間違った vpath を追加する前の元の問題でした)。出力は次のようになります。

    gcc  -o ku -lhpdf obj/kumain.o obj/kudlx.o obj/kusolvesk.o ..etc
    gcc: obj/kumain.o: No such file or directory
    gcc: obj/kudlx.o: No such file or directory
    gcc: obj/kusolvesk.o: No such file or directory
    gcc: obj/kugetpuz.o: No such file or directory
    gcc: obj/kuutils.o: No such file or directory
    gcc: obj/kurand.o: No such file or directory
    gcc: obj/kuASCboard.o: No such file or directory
    gcc: obj/kuPDFs.o: No such file or directory
    gcc: obj/kupuzstrings.o: No such file or directory
    gcc: obj/kugensud.o: No such file or directory
    gcc: obj/kushapes.o: No such file or directory
    make: *** [ku] Error 1

マニュアルには「暗黙のルールは、慣習的な手法の使用方法を make に指示するため、使用したいときに詳細を指定する必要はありません。たとえば、C コンパイルには暗黙のルールがあります。ファイル名によって、どの暗黙のルールが実行されるかが決まります。たとえば、C コンパイルでは通常、.c ファイルを取得して .o ファイルを作成します。したがって、make は、このファイル名の末尾の組み合わせを検出すると、C コンパイルに暗黙のルールを適用します。」と記載されています。また、「暗黙のルールの検討中に、VPATH または vpath で指定されたディレクトリの検索も行われます (暗黙のルールの使用を参照)。」とも記載されています。

ここでも、「たとえば、ファイル foo.o に明示的なルールがない場合、make は、ファイルが存在する場合に foo.c をコンパイルする組み込みルールなどの暗黙のルールを考慮します。現在のディレクトリにそのようなファイルがない場合、適切なディレクトリが検索されます。いずれかのディレクトリに foo.c が存在する場合 (または makefile に記載されている場合)、C コンパイルの暗黙のルールが適用されます。」

暗黙のルールを私のメイクファイルに機能させるための支援があれば、大変助かります。

編集 2: 暗黙のルールを使用しても何もできなかったため、Jack Kelly のおかげで、.c ファイルをコンパイルするための明示的なルールを作成しました。また、vpath 情報については al_miro にも感謝します。

動作する makfile は次のとおりです:

.SUFFIXES:
.SUFFIXES: .c .o

CC=gcc 
CPPFLAGS=-Wall
LDLIBS=-lhpdf
OBJDIR=obj
vpath %.c src
vpath %.h src

objects = $(addprefix $(OBJDIR)/, kumain.o kudlx.o kusolvesk.o kugetpuz.o kuutils.o \
  kurand.o kuASCboard.o kuPDFs.o kupuzstrings.o kugensud.o \
  kushapes.o )

ku : $(objects)
  $(CC) $(CPPFLAGS) -o ku $(objects) $(LDLIBS)

$(OBJDIR) obj/%.o : %.c ku.h kudefines.h kuglobals.h kufns.h 
  $(CC) -c $(CPPFLAGS) $< -o $@

.PHONY : clean
clean :
  rm $(objects)

ベストアンサー1

GNUmake を使用しているため、オブジェクト ファイルをコンパイルするためのパターン ルールを使用します。

$(OBJDIR)/%.o: %.c
    $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<

おすすめ記事