Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Makefile not doing what I want – Compiling same thing twice

CXX         := g++
CXX_FLAGS   := -std=c++17

SRC_DIR     := ./src
LIB_DIR     := $(SRC_DIR)/lib
OBJ_DIR     := $(SRC_DIR)/obj
BIN_DIR     := $(SRC_DIR)/bin

BIN_DEBUG   := $(BIN_DIR)/Test-debug
BIN_RELEASE := $(BIN_DIR)/Test

SRC_FILES   := $(wildcard $(SRC_DIR)/*.cpp)
LIB_FILES   := $(wildcard $(LIB_DIR)/*.cpp)
OBJ_FILES   := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES)) $(patsubst $(LIB_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(LIB_FILES))

$(BIN_RELEASE): $(OBJ_FILES)
    $(CXX) $(CXX_FLAGS) -o $@ $^

$(OBJ_FILES): $(SRC_FILES) $(LIB_FILES)
    $(CXX) $(CXX_FLAGS) -c -o $@ $<

clean:
    rm ./src/obj/*.o
    rm ./bin/*
    
run:
    $(BIN_RELEASE)

This is my Makefile and it is doing the same g++ -c command in a row and then failing in the linking because it tries to link the a file to it self. Or can someone say how you debug a Makefile.

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

This is wrong:

$(OBJ_FILES): $(SRC_FILES) $(LIB_FILES)
        $(CXX) $(CXX_FLAGS) -c -o $@ $<

Say you have src/foo.cpp and src/bar.cpp in SRC_FILES. Now OBJ_FILES is src/obj/foo.o and src/obj/bar.o. Now the above rule expands like this:

src/obj/foo.o src/obj/bar.o: src/foo.cpp src/bar.cpp
        $(CXX) $(CXX_FLAGS) -c -o $@ $<

It’s not the case that make will intuit what you want to do here and match up each object file with the source file, or something like that. The above means exactly the same thing as if you’d written these rules:

src/obj/foo.o: src/foo.cpp src/bar.cpp
        $(CXX) $(CXX_FLAGS) -c -o $@ $<

src/obj/bar.o: src/foo.cpp src/bar.cpp
        $(CXX) $(CXX_FLAGS) -c -o $@ $<

Now you can see why every compile line compiles the same source file: the $< variable expands to the first prerequisite, and for every object file the first prerequisite is always the same (here, src/foo.cpp).

You need to use a pattern rule here, telling make how to build one single file. And since you’re building things in two different ways, you actually need two pattern rules.

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
        $(CXX) $(CXX_FLAGS) -c -o $@ $<

$(OBJ_DIR)/%.o: $(LIB_DIR)/%.cpp
        $(CXX) $(CXX_FLAGS) -c -o $@ $<
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading