1

I just got into Makefiles and I have a problem when turning the .cpp files in .o files. The list of files to be used are defined as the following:

# Directories
BIN_DIR = bin
SRC_DIR = src
ICD_DIR = include
OBJ_DIR = $(BIN_DIR)/obj
    
    
# Files
SOURCES := $(wildcard $(SRC_DIR)/*.cpp)
OBJECTS  := $(SOURCES:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
EXECUTABLE = main

If I @echo the files, I have what I want:

SOURCES
src/main.cpp src/random_graph.cpp src/word_graph.cpp

OBJECTS
bin/obj/main.o bin/obj/random_graph.o bin/obj/word_graph.o

To compile my program I have the following two functions:

# Make executables from objects
$(BIN_DIR)/$(EXECUTABLE): $(OBJECTS)
    $(CXX) $(CXXFLAGS) $^ -o $@
    @echo "Build successful!"

# Make objects
$(OBJECTS): $(SOURCES)
    mkdir -p $(@D)
    $(CXX) $(CXXFLAGS) -c $< -o $@

The problem is, when making the object files, I want to link src/main.cpp -> bin/obj/main.o, src/random_graph.cpp -> bin/obj/random_graph.o and src/word_graph.cpp -> bin/obj/word_graph.o, but it links src/main.cpp to each if the object files (making 3 copies).

Is there a way to link each .cpp file to the object .o file with the same name?

hellohelo
  • 13
  • 2

1 Answers1

1

I suggest that you create a pattern to build a single object file:

$(BIN_DIR)/$(EXECUTABLE): $(OBJECTS)
        $(CXX) $(CXXFLAGS) -o $@ $(OBJECTS)

bin/obj/%.o : src/%.cpp | $(OBJ_DIR)
        $(CXX) $(CXXFLAGS) -c $< -o $@

$(OBJ_DIR):
        mkdir -p $(OBJ_DIR)

Since $(BIN_DIR)/$(EXECUTABLE) requires all object files, they will all be built using the above bin/obj/%.o and each object file also depends on the corresponding source file, so any change you make to that source file will cause a rebuild of the object file.

You can also move out the creation of $(OBJ_DIR) like above. It's unnecessary to try to create it if it already exists.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108