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 1:
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.
Solution 2:
Wildcard works for me also, but I'd like to give a side note for those using directory variables. Always use slash for folder tree (not backslash), otherwise it will fail:
BASEDIR = ../..
SRCDIR = $(BASEDIR)/src
INSTALLDIR = $(BASEDIR)/lib
MODULES = $(wildcard $(SRCDIR)/*.cpp)
OBJS = $(wildcard *.o)