Home > Back-end >  Why don't I need to use the -MT option for dependency generation when I save my object files to
Why don't I need to use the -MT option for dependency generation when I save my object files to

Time:11-21

I have a (GNU)Makefile that gives the .o files a name that puts them in a separate directory. If I'm reading the GCC documentation on preprocessor options correctly, then all directory components and the file extension of the source file are stripped, .o is appended, and that's the name of the target. However, it seems to also prepend the path to where I store my object files automatically, without me manually specifying what to name the target with the -MT option. What am I misunderstanding?

I tried to attach a minimal working example (MWE) project for your convenience, but I cannot figure out how to do this on stackoverflow.

I have tried with and without -MT $@ in the CPPFLAGS. It doesn't seem to change a thing.

Makefile:

# Name directories
SRC_DIR := src
BUILD_DIR := build
OBJ_DIR := ${BUILD_DIR}/obj
DEP_DIR := ${BUILD_DIR}/dep
BUILD_DIRS := ${BUILD_DIR} ${OBJ_DIR} ${DEP_DIR}

# Name executable
BIN := ${BUILD_DIR}/howdy

# List directories where header files are found
_INCLUDE := include
INCLUDE := ${_INCLUDE:%=-I%}

# Make obj and dep files per source file
SRC := $(wildcard ${SRC_DIR}/*.cc)  # Sneaky trick to get all .cc in a directory
OBJ := ${SRC:${SRC_DIR}/%.cc=${OBJ_DIR}/%.o}
DEP := ${OBJ:${OBJ_DIR}/%.o=${DEP_DIR}/%.d}

# Compiler and preprocessor setup
CXX := g  
CPPFLAGS = -MP -MMD -MF ${DEP_DIR}/$*.d

.PHONY: all  # Output info and build if "make" or "make all" is invoked
all: ${BIN}

${BIN}: ${OBJ}  # Link the object files to build the executable
    ${CXX} ${LDFLAGS} $^ -o $@

# Compile the source files into object files
${OBJ}: ${OBJ_DIR}/%.o: ${SRC_DIR}/%.cc | ${BUILD_DIRS}
    ${CXX} ${CXXFLAGS} ${CPPFLAGS} ${INCLUDE} -c $< -o $@

${BUILD_DIRS}:  # Create directories as needed
    mkdir -p $@

.PHONY: clean  # Delete all object files, all dep files, and the executable
clean:
    rm -rf ${BUILD_DIR}/*

-include ${DEP}  # The dash makes make not fail if .d file not found

main.d:

build/obj/main.o: src/main.cc include/howdy.hh
include/howdy.hh:

CodePudding user response:

This question doesn't have anything to do with make or makefiles. It's purely about how the GCC compiler's dependency generation works.

I agree with you that the behavior generated doesn't seem to match the documentation, unless we're misinterpreting what it says. Here's a test case, that doesn't need all the complexity of the makefile you provided:

$ touch /tmp/foo.c

$ gcc -MP -MMD -MF /tmp/foo.d -c -o /tmp/blahlbah.o /tmp/foo.c

$ cat /tmp/foo.d
/tmp/blahblah.o: /tmp/foo.c

It appears that, regardless of what the docs appear to say, the output target name by default (with no -MT) is the name provided with -o.

Perhaps what the docs mean is that if you don't provide -o and you don't provide -MT, then the result will be as documented. But, I think this is not a very successful way to document this.

In any event, I don't think StackOverflow is the right place to pursue this; you should contact the GCC folks for example at [email protected]

  • Related