I have this working Makefile and I would like to improve it:
CXX = g++
RM = rm -f
CXXFLAGS = -O2 -s -Wall -std=c++11
LDFLAGS = -Wl,-z,relro
SRCS = target1.cpp target2.cpp target3.cpp utils.cpp
OBJS = $(subst .cpp,.o,$(SRCS))
.PHONY: all target1 target2 target3 clean
all: target1 target2 target3
target1: target1.o utils.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $# $(LDLIBS)
target2: target2.o utils.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $# $(LDLIBS)
target3: target3.o utils.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $# $(LDLIBS)
clean:
$(RM) $(OBJS)
My questions are:
Every target needs utils.o. Is it possible to avoid writing 3 times the same lines for target1/target2/target3?
I would like to separate sources, objects and binaries (Makefile in ./, binaries in ./, sources in src/, objects in obj/). What is the best solution in order to avoid writing target1: obj/target1.o obj/utils.o and so on?
Thanks!
1) Yes, you can use a pattern rule:
target%: target%.o utils.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $# $(LDLIBS)
2) It really isn't that bad:
target%: obj/target%.o obj/utils.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $# $(LDLIBS)
You can avoid those two obj/ prefixes, but it really isn't worth the trouble.
Related
I have one Makefile to build an executable and a library. Executable consists of a lot of source files and library consists of one .cpp file. The difference between compilation of executable and library is -fPIC option.
There is a compilation rule:
%.o : %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $#
all: $(TARGET) $(TARGET_LIB)
$(TARGET): $(OBJS)
$(CXX) $(LDFLAGS) -o $# $^
$(TARGET_LIB): $(LIBOBJS)
$(CXX) $(LDFLAGS) -fPIC -shared -o $# $^
I tried to add compilation rule for library and got this:
lib.o : lib.cpp
$(CXX) -fPIC -c $(CXXFLAGS) $< -o $#
%.o : %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $#
all: $(TARGET) $(TARGET_LIB)
$(TARGET): $(OBJS)
$(CXX) $(LDFLAGS) -o $# $^
$(TARGET_LIB): $(LIBOBJS)
$(CXX) $(LDFLAGS) -fPIC -shared -o $# $^
Unfortunately, only lib is compiled in this case. Second rule is omitted.
How can I use a rule for one file and different rule for group of other files?
If you just run make without a target, the first target gets built. So just put all back at the top and it should work fine.
I recently got feedback that my Makefile doesn't call the required flags. This is a snippet of my Makefile.
CXX = g++
CXXFLAGS = -Wall
all: testFacility testCode testRunway testSiteNumber airport distance
testFacility: testFacility.cpp Facility.o gcdistance.o
$(CXX) -o $# $^
Does the flag "-Wall" get called when I type Make?
No, it needs to be referenced directly:
$(CXX) $(CXXFLAGS) -o $# $^
You probably want to define something to compile all those .cpp files too:
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $# $<
testFacility: testFacility.o Facility.o gcdistance.o
$(CXX) $(CXXFLAGS) -o $# $^
Using make, I need to produce two versions of an executable, which differ by the use of a precompiler flag DXYZ. The way I have this working so far is to produce the *.o objects for the vanilla program, and, another set *.o_xyz for the objects that make use of the -DXYZ flag.
So basically I have two two rules to produce the objects, ie: $(OBJ)/%.o: %.cpp and $(OBJ)/%.o_xyz: %.cpp.
I am wondering if this is this the best way to achieve this? Is it possible to reduce this to a single rule?
CXX=g++
OBJ=./obj
BIN=./bin
INC=-I./inc
CXXFLAGS=-std=c++11 -Wall -Wno-comment
LDFLAGS=-lpthread
CXX_SOURCES=$(wildcard *.cpp)
CXX_OBJECTS=$(patsubst %.cpp, $(OBJ)/%.o,$(notdir $(CXX_SOURCES)))
.PHONY: all
all : program_xyz program
program_xyz: $(addsuffix _xyz,$(CXX_OBJECTS))
#mkdir -p $(BIN)
$(CXX) -o $(BIN)/$# $^ $(LDFLAGS) $(INC) -DXYZ
program: $(CXX_OBJECTS)
#mkdir -p $(BIN)
$(CXX) -o $(BIN)/$# $^ $(LDFLAGS) $(INC)
##Vanilla Endpoints
$(OBJ)/%.o: %.cpp
#mkdir -p $(#D)
$(CXX) -c $< -o $# $(INC) $(CXXFLAGS)
##Endpoint with DXYZ flag
$(OBJ)/%.o_xyz: %.cpp
#mkdir -p $(#D)
$(CXX) -c $< -o $# $(INC) $(CXXFLAGS) -DXYZ
The file tree in my C++ project is like this:
project/
source/
main.cpp (with int main() function)
a.cpp
a.h
b.cpp
...
obj/
Makefile
But when I compile it, it throws an error: "In function _start': (.text+0x20): undefined reference to main'"
My makefile is:
EXECUTABLE = name_of_program
CXX = g++
CXXFLAGS = -Wall -Isource
LIBS =
SRC_DIR = source
OBJ_DIR = obj
SRC = $(wildcard $(SRC_DIR)/*.cpp)
OBJ = $(SRC:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
.PHONY: all clean
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJ)
$(CXX) -o $# $^ $(LIBS)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -o $# $<
$(CXX) $(CXXFLAGS) -o $# -c $<
clean:
rm $(OBJ)
Which things should I correct in order to make it compile correctly? I know it's a compiler error but I'm sure it's about Makefile.
I don't have enough of your source to reproduce the problem, but by inspection, it looks like you have an extra line here:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -o $# $<
$(CXX) $(CXXFLAGS) -o $# -c $<
Remove the first line so you don't try to link each object file independently.
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -o $# -c $<
I have the following makefile:
CC=g++
CCOPTS=-Wall -Wextra -g
OBJS = manager.o tcpcon.o
TARGETS = manager
.PHONY: all clean
$(TARGETS) : $(OBJS)
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
all: $(TARGETS) $(OBJS)
clean:
rm -f $(TARGETS) $(OBJS)
%: %.cpp
$(CC) $(CCOPTS) -o $# $<
Is there a way I can make my .o and bin files be built into a directory called build? I tried going through some tutorials, but I guess I just don't fully understand makefiles..
Don't feel too bad; I'm not sure anyone fully understands makefiles.
BUILD_DIR = build
OBJS = $(BUILD_DIR)/manager.o $(BUILD_DIR)/tcpcon.o
TARGETS = $(BUILD_DIR)/manager
...
$(BUILD_DIR)/%.o: %.cpp
$(CC) -c $(CCOPTS) -o $# $<