GNU Make 在使用来自另一个目录的源处理子目录下的目标时报告没有规则

GNU Make reports no rule when dealing with a target under subdirectory with source from another directory

我的项目目录是通过 NFS 挂载的。从它安装的目录中,我调用 make -f msh/Makefile cd=msh。 (msh 是我的挂载。) cd 是 Makefile 中的一个变量,它被添加到源文件中。这适用于直接位于 cd 下的源文件。但是,如果源文件位于 cd 中的子目录下,Make 会失败,表示没有规则可以创建该目标。如果我从我的坐骑中调用 Make,它不会失败。

这是我的 Makefile。

CC?=gcc
CFLAGS:=-Wall -Werror -D_POSIX_C_SOURCE=200112L $(CFLAGS)

cd?=.

objects_nix=if/tty.o
objects:=sub.o if.o $(objects_nix)

ifdef SO
CFLAGS+=-fPIC

bin=libmsh.so
else
bin=libmsh.a
endif

.PHONY : clean

$(bin) :


libmsh.a : $(objects)
    $(AR) -r -c -s $@ $(objects)

libmsh.so : $(objects)
    @echo
    @echo If you have resumed compilation after not having used the SO flag,
    @echo you should run make clean.
    @echo
    $(LD) $(LDFLAGS) -shared -o $@ $(objects)

test : $(cd)/test.c $(bin)
ifdef SO
    $(CC) $(CFLAGS) -I$(cd) $(LDFLAGS) -L. -lmsh -Wl,-rpath,. -o $@ $(cd)/test.c
else
    $(CC) $(CFLAGS) -I$(cd) $(LDFLAGS) -o $@ $(cd)/test.c $(bin)
endif

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

clean :
    rm -f libmsh.so libmsh.a
    rm -f $(objects)
    rm -f test.o test

我已经尝试为子目录创建另一个规则,并且成功了。但我希望它只适用于一个规则。

您已经告诉 Make 如何从 $(cd) 中的 .c 文件制作 .o 文件。如果 .c 文件在其他目录中,它不知道如何创建 .o 文件。您可以通过多种方式解决此问题,例如:

  • 为所有目录添加显式规则。你已经做到了。
  • 使用VPATH.
  • 为每个目录创建一个 Makefile。