Why are there no dependencies in the makefiles?

I recently learned how to use Make files and I found out that GCC / g ++ generates dependencies for you:

$ g++ -MM file.cpp
file.o: file.cpp file.h

      

Then I thought it would be obvious to use this to create dependencies directly in a file without creating a dependency file:

CXX = g++

SRCS = $(wildcard src/*.cpp)
OBJS = $(SRCS:.cpp=.o)
OCT = $(CXX -MM $(SRCS))
OBJDIR = obj
CPPFLAGS = -Wall -I/usr/local/include -L/usr/local/lib -lGLEW -lglfw -lGL

.PHONY: all
all: $(OBJS)
    $(CXX) $(CPPFLAGS) $(OBJS) -o output

$(OCT)

.PHONY: clean
clean:
    rm -f obj/*

      

For some reason, I have never seen anyone else do this; they always create a dependency file. Is there something wrong with this system? In my case, yes - objects do not go to OBJDIR, they go to the location of the source file. I'm sure this can be fixed. If anyone knows how I can fix this and why dependency files are usually generated, please let me know.

+3


source to share


1 answer


Well, the first reason people don't do it is because it can't be done: if you try to propose in real life, you'll see it. For example, your example does nothing. It:

OCT = $(CXX -MM $(SRCS))

      

(I assume you mean $($(CXX) -MM $(SRCS))

, but that doesn't matter anyway) puts a reference to a make variable named literally CXX -MM $(SRCS)

in a variable OCT

: you probably think it uses shell command invoke syntax $(...)

, but this is a makefile, and not a shell script. So when you write:

$(OCT)

      

which is trying to find what makes a variable that obviously doesn't exist and so it expands to an empty string and nothing happens at all. If you are actually trying to test your makefile by clicking on the header, etc., you will see that nothing has been restored.

How can you do this? You cannot do this. You can change the assignment of a variable like this:



OCT = $(shell $(CXX) -MM $(SRCS))

      

and this will actually run the compiler which moves you in the right direction, but the results of the shell function change all newlines to spaces, so this:

$(OCT)

      

will expand to all the output of the compiler command on one line, and since it contains multiple colons, you will get a syntax error.

All you can do is redirect the compiler's output to a file and use make's include

ability to include that file. But now you basically go back to the script suggested in the GNU make manual , except that your version is less efficient because, as pointed out in the comments above, you are restoring all headers for all source files every time you run make, not only restore the header information for files that have actually changed.

There are better ways to generate headers, such as the one used by most GNU packages .

+1


source







All Articles