1
votes

I am trying to a create a makefile architecture so I have one global makefile at the top which call another in a subdirectory.

Global makefile :

CC          = gcc
CFLAGS      = -W -Wall -pedantic
LDFLAGS     =

PROJECT     = proj

SOURCES     =

PATH        = $(PROJECT)
include $(PATH)/Makefile

all : $(PROJECT).exe

$(PROJECT).exe :
  $(CC) $(CFLAGS) $(LDFLAGS) $(DEFINES) $(INCLUDES) $(SOURCES) -o $@

clean :
  rm -rf *.exe

Subdirectory makefile :

CC          = gcc
CFLAGS      = -W -Wall -pedantic
LDFLAGS     = 

SOURCES     += $(PATH)/main.c

When I "make" in the top directory I have the following error :

gcc -W -Wall -pedantic     proj/main.c -o proj.exe
make: gcc: Command not found
make: *** [Makefile:17: FK16_jake.exe] Error 127

But when i type exactly the same command (gcc -W -Wall -pedantic proj/main.c -o proj.exe) in my terminal, it's building.

And if I remove the makefile include, he recognize gcc but don't build because no sources (normal behavior).

2

2 Answers

3
votes

You are overriding PATH, which is used to determine where to look for executables. Change this variable and it should work.

2
votes

In the UNIX shell, the environment variable PATH specifies the set of directories to search for executables when you run a command.

The GNU Make manual says:

When make runs a recipe, variables defined in the makefile are placed into the environment of each shell. This allows you to pass values to sub-make invocations (see Recursive Use of make). By default, only variables that came from the environment or the command line are passed to recursive invocations.

Because PATH is a shell variable and is defined in the environment of make, it is "came from the environment". That means when you modify the value with PATH = $(PROJECT) the updated value will be set in the environment of the shell that runs the recipe for $(PROJECT).exe. That means the shell runs with a bad value for the PATH and so cannot find gcc.

To avoid this confusion, do not use PATH as a makefile variable. Use another name which is not the same as an environment variable that the shell depends on. You could call it PROJECT_PATH instead, or just use $(PROJECT) instead of $(PATH).