Search code examples
c++build-processmakefile

Can I compile all .cpp files in src/ to .o's in obj/, then link to binary in ./?


My project directory looks like this:

/project
    Makefile
    main
    /src
        main.cpp
        foo.cpp
        foo.h
        bar.cpp
        bar.h
    /obj
        main.o
        foo.o
        bar.o

What I would like my makefile to do would be to compile all .cpp files in the /src folder to .o files in the /obj folder, then link all the .o files in /obj into the output binary in the top-level folder /project.

I have next to no experience with Makefiles, and am not really sure what to search for to accomplish this.

Also, is this a "good" way to do this, or is there a more standard approach to what I'm trying to do?


Solution

  • Makefile part of the question

    This is pretty easy, unless you don't need to generalize try something like the code below (but replace space indentation with tabs near g++)

    SRC_DIR := .../src
    OBJ_DIR := .../obj
    SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp)
    OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
    LDFLAGS := ...
    CPPFLAGS := ...
    CXXFLAGS := ...
    
    main.exe: $(OBJ_FILES)
       g++ $(LDFLAGS) -o $@ $^
    
    $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
       g++ $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
    

    Automatic dependency graph generation

    A "must" feature for most make systems. With GCC in can be done in a single pass as a side effect of the compilation by adding -MMD flag to CXXFLAGS and -include $(OBJ_FILES:.o=.d) to the end of the makefile body:

    CXXFLAGS += -MMD
    -include $(OBJ_FILES:.o=.d)
    

    And as guys mentioned already, always have GNU Make Manual around, it is very helpful.