0

I'm using a Makefile to compile and link my source files with sfml libraries. This works perfectly. The only problem: it generates .o files (and .exe) in the same directory as the source files (.cpp). I want my Makefile to generate those into a different one (/obj for example). How could I do that ?

Here is the Makefile :

CXX      = g++
INCL_DIR = src/include
LIB_DIR  = src/lib
SRC      = $(wildcard *.cpp)
OBJ      = $(SRC:.cpp=.o)

all: compile link

compile:
    $(CXX) -I $(INCL_DIR) -c $(SRC)

link:
    $(CXX) $(OBJ) -o main -L$(LIB_DIR) -lsfml-graphics -lsfml-window -lsfml-system
  • Consider using https://github.com/cppfw/prorab in order to simplify your `makefile` and put objects to a separate directory. – igagis Oct 26 '21 at 10:17

1 Answers1

0

Here's a cut and paste from one of my Makefiles:

# This defines subdirectories. I have sources in ./src.
SRCDIR := src
OBJDIR := obj
BINDIR := bin

# Just a bunch of -I commands to the compiler.
# You probably don't need these.    
INCLUDES += -I. -I./generated -I/usr/local/include -I/usr/local/include/antlr4-runtime

# This gives options to g++. -O3 is optimization.
# The includes are from above, but you probably could ignore.
# --std=c++17 means this is C++ 17 rather than something older.
CXXFLAGS = -O3 ${INCLUDES} --std=c++17 -g ${AUTO_ARGUMENT}

# You can probably skip this.
LDFLAGS += -L/usr/local/lib

# This defines the command for building. You can probably make
# this much shorter.    
COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

# This is a link command. You'll see I'm forcing a static link
# against a library, but of course, yo udon't need that.
${BINDIR}/wave: ${OBJECTS}
    ${CXX} ${OBJECTS} ${LDFLAGS} /usr/local/lib/libantlr4-runtime.a -o ${BINDIR}/wave

# Because sources can be in two different directories, I have
# two generic rules. This rule builds the generated source
# (output from antlr4) into obj/foo.o    
${OBJDIR}/%.o : generated/%.cpp
    $(COMPILE.cc) $(OUTPUT_OPTION) $<

# Same thing but the code i'm actually writing.
# Make already knows about $(OUTPUT_OPTION) and $< is
# the input.
${OBJDIR}/%.o : src/%.cpp
    $(COMPILE.cc) $(OUTPUT_OPTION) $<

I have my source in ./src and some generated files (from antlr4) in ./generated, so I have two rules for building those.

Thus, you make a rule (or in my case, 2 rules) to produce .o files in the ${OBJDIR} directory and then one rule to produce the binary in ${BINDIR}.

Joseph Larson
  • 8,530
  • 1
  • 19
  • 36
  • Hi Joseph. I'm sorry i'm struggling trying to understand your makefile. Is it normal there is some used but undefined variable like TARGET_ARCH ? Does it work anyway ? – Enigmo Thread Oct 24 '21 at 15:25
  • I did a little cleanup but not everything. As TARGET_ARCH is undefined, it turns into null and shouldn't hurt anything. Or you can edit it out. Let me edit my answer and I'll over inline comments. – Joseph Larson Oct 25 '21 at 16:12