James R.
James R.

Reputation: 143

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

My project's directory is mounted via NFS. From the directory under which it is mounted, I call make -f msh/Makefile cd=msh. (msh is my mount.) cd is a variable in the Makefile that is prepended to source files. This works fine with source files directly under cd. However, if the source files are under a subdirectory within cd, Make fails, saying that there is no rule to make that target. It does not fail if I call Make from within my mount.

This is my 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

I have tried creating another rule for the subdirectory, and this works. But I'd like it to work with only the one rule.

Upvotes: 0

Views: 46

Answers (1)

rveerd
rveerd

Reputation: 4006

You have told Make how to make a .o file from .c file in $(cd). It does not know how to make a .o file if the .c file in some other directory. You can solve this in various ways, such as:

  • Add an explicit rule for all directories. You have already done that.
  • Use VPATH.
  • Create a Makefile for each directory.

Upvotes: 1

Related Questions