Makefile: How to build with debug symbols? - c++

Project structure:
Makefile
/src
/include
I have the following Makefile for a C++ project. It builds fine but I can't seem to be able to build the debug files with the -g flag.
Here's the Makefile:
NAME := MySuperProgram
BDIR := bin
ODIR := obj
SRC := $(wildcard src/*.cpp)
OBJ := $(SRC:src/%.cpp=$(ODIR)/%.o)
CXXFLAGS := -W -Wall -Werror
.PHONY: all debug clean fclean re
all: $(NAME)
debug: CXXFLAGS += -DDEBUG -g
debug:all
$(NAME): $(OBJ) | $(BDIR)
$(CXX) $(CXXFLAGS) $^ -o $(BDIR)/$#
$(ODIR)/%.o: src/%.cpp | $(ODIR)
$(CXX) $(CXXFLAGS) -c -o $# $<
$(ODIR) $(BDIR):
#mkdir -p $#
clean:
$(RM) -r $(ODIR)
fclean: clean
$(RM) -r $(BDIR)
re: fclean all
Environment:
Debian 8
GCC 4.9.2
I have read How can I configure my makefile for debug and release builds? but it's not helping on this particular case.
How to make it build with debug symbols in the $(BDIR) ?

Related

Copying all the cpp files in a Makefile using VSCode Terminal does not work

I'm trying to create a Makefile in VS Code but I don't want to lose time writing all of the .cpp files that I have .
A solution for that , which works on Unix is
echo *.cpp > Makefile
However when I try this command line in the terminal of VS code, it doesn't work . I get *.cpp in my Makefile
Make file exemple:
NAME = my_project
IDIR = include/
IDIR_MY = ./include
CC = g++
CFLAGS += -I $(IDIR) -I $(IDIR_MY)
CFLAGS += -W -Wall -Wextra
SRCS_DIR = src/
SRCS_FILES = *.cpp
SRCS = $(addprefix $(SRCS_DIR), $(SRCS_FILES))
OBJS = $(SRCS:.cpp=.o)
RM = rm -f
all: $(NAME)
$(NAME): $(OBJS)
$(CC) -o $(NAME) $(OBJS)
gdb: $(OBJS)
$(CC) -g -o debug ./*.cpp -I $(IDIR)
clean:
$(RM) $(OBJS)
fclean: clean
$(RM) $(NAME)
re: fclean all
and for lunch this say just "make" in your term

Makefile for building C++ Google Protocol Buffers Project

I Just started fooling around using Google Protocol Buffers and I am trying to incorporate the C++ output files from the protocol buffer compiler into my project. I have Been using a simple makefile for my projects so far and it does the trick for building source files all sharing the same extension. I use ".cpp" for my source files but Google Protocol Buffers outputs its source as ".pb.cc" files. I need to be able to compile and link both types of source files into one executable.
I have been searching and fiddling around with my makefile for a few hours now and have had no success.
My Current Makefile:
PROGRAM_NAME=aserv
CC=gcc
CXX=g++
RM=rm -f
CPPFLAGS=-g --std=c++14 -O3 -I/usr/local/include/
LDFLAGS=-g -L/usr/local/lib -L/usr/local/lib/boost
LDLIBS= -lrtaudio -pthread -lboost_system -lprotobuf
INSTALL_DIR = /usr/local/bin/
SRCS=$(wildcard *.cpp)
OBJS=$(subst .cpp,.o,$(SRCS))
all: $(PROGRAM_NAME)
$(PROGRAM_NAME): $(OBJS)
$(CXX) $(LDFLAGS) -o $(PROGRAM_NAME) $(OBJS) $(LDLIBS)
depend: .depend
.depend: $(SRCS)
rm -f ./.depend
$(CXX) $(CPPFLAGS) -MM $^>>./.depend;
clean:
$(RM) $(OBJS) $(PROGRAM_NAME) .depend
install:
cp $(PROGRAM_NAME) $(INSTALL_DIR)$(PROGRAM_NAME)
uninstall:
$(RM) $(INSTALL_DIR)$(PROGRAM_NAME)
dist-clean: clean
$(RM) *~ .depend
include .depend
I am not too well versed in writing makefiles yet, so I just don't quite know what to do to make this work.
If it helps i have GNU make 4.1 and gcc 5.3.1 on Ubuntu 16.04 beta
I couldnt get your original Makefile to work so I changed a few things but I think the tricky part with this is the implicit rules that make generates to build your .o files. I think for the .pb.cc files you need to generate .pb.o objects so that the implicit rules can match them.
Try this:
PROGRAM_NAME = aserv
CC = gcc
CXX = g++
RM = rm -f
CXXFLAGS = --std=c++14 -pthread -g -O3 -MMD -MP
CPPFLAGS = -I/usr/local/include/
LDFLAGS = -L/usr/local/lib -L/usr/local/lib/boost
LDLIBS = -lrtaudio -lboost_system -lprotobuf
INSTALL_DIR = /usr/local/bin
SRCS = $(wildcard *.cpp) $(wildcard *.pb.cc)
OBJS = $(subst .pb.cc,.pb.o,$(subst .cpp,.o,$(SRCS)))
DEPS = $(subst .pb.cc,.pb.d,$(subst .cpp,.d,$(SRCS)))
all: $(PROGRAM_NAME)
$(PROGRAM_NAME): $(OBJS)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $# $^ $(LDFLAGS) $(LDLIBS)
-include $(DEPS)
clean:
$(RM) $(OBJS) $(PROGRAM_NAME)
install:
cp $(PROGRAM_NAME) $(INSTALL_DIR)
uninstall:
$(RM) $(INSTALL_DIR)/$(PROGRAM_NAME)
dist-clean: clean
$(RM) *~ $(DEPS)
If you wanto to only strictly rely on Make, and not the surrounding shell you can add another set of SRC and OBJ variables, which will serve as a second set of dependencies.
Add these right below the first set:
SRC1=$(wildcard *.pb.cc)
OBJ1=$(subst .pb.cc,.o,$(SRC1))
And change the .depend and $(PROGRAM_NAME) rule:
.depend: $(SRCS) $(SRC1)
$(PROGRAM_NAME): $(OBJS) $(OBJ1)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
%.o: %.c
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) -c -o $# $<

Linker command fail with a bunch of undefined reference

I try to compile a project using clang and libc++. Here is my makefile :
EXEC = ModularMadness
SRCDIR = src/
INC =-I$(SRCDIR)
SOURCES := $(wildcard $(SRCDIR)*.cpp) $(wildcard $(SRCDIR)*/*.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
CXX = clang++
CXX_FLAGS = -std=c++1y -stdlib=libc++ $(INC)
all: $(EXEC)
$(EXEC): $(OBJECTS)
$(CXX) $(OBJECTS) -o $(EXEC)
%.o: %.cpp
$(CXX) -c $(CXX_FLAGS) $< -o $#
.PHONY: all clean
clean:
#echo Cleaning...
#rm -f $(EXEC) $(OBJECTS)
#echo done
The .o files creation works fine, but I ran in multiple error like
In function 'std::__1::weak_ptr<module::Module>::lock() const': undefined reference to 'std::__1::__shared_weak_count::lock()' during linker command.
Could someone help me understanding what's the problem here ?
Note
This makefile run perfectly on OS X.
I missed the linker flag -lc++... Thank you perencia.
Here is the working makefile :
EXEC = ModularMadness
SRCDIR = src/
INC =-I$(SRCDIR)
SOURCES := $(wildcard $(SRCDIR)*.cpp) $(wildcard $(SRCDIR)*/*.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
CXX = clang++
CXX_FLAGS = -std=c++1y -stdlib=libc++ $(INC)
all: $(EXEC)
$(EXEC): $(OBJECTS)
$(CXX) $(OBJECTS) -o $(EXEC) -lc++ # Here
%.o: %.cpp
$(CXX) -c $(CXX_FLAGS) $< -o $#
.PHONY: all clean
clean:
#echo Cleaning...
#rm -f $(EXEC) $(OBJECTS)
#echo done

C++ Makefile missing separator in .dep

On OS X Mavericks i am trying to build a project using the following Makefile:
CC=g++
EXECUTABLE=minigi
SRC_DIR=src
INTERM_DIR=obj
INCLUDES=-I $(SRC_DIR) -I /usr/local/Cg/examples/OpenGL/glew/include/
LIBS=-L/usr/local/lang/NVIDIA_GPU_Computing_SDK/sdk/C/common/lib/linux/ -lpng -stdc++ -lGL -lGLU -lGLEW -lSDLmain -lSDL -lgomp
CFLAGS_COMMON=$(INCLUDES)
CFLAGS=$(CFLAGS_COMMON) -O3 -DNDEBUG -fopenmp
#CFLAGS=$(CFLAGS_COMMON) -g -O0 -D_DEBUG
SOURCE_FILES=$(shell find $(SRC_DIR) -iname '*.cpp')
DEP_FILES=$(SOURCE_FILES:$(SRC_DIR)/%.cpp=./$(INTERM_DIR)/%.dep)
OBJ_FILES=$(SOURCE_FILES:$(SRC_DIR)/%.cpp=./$(INTERM_DIR)/%.o)
all: $(EXECUTABLE)
clean:
rm -rf obj $(EXECUTABLE)
.PHONY: clean all
.SUFFIXES:
.SUFFIXES:.o .dep .cpp .h
$(INTERM_DIR)/%.dep: $(SRC_DIR)/%.cpp
mkdir -p `dirname $#`
printf `dirname $#`/ > $#
$(CC) $(CFLAGS_COMMON) $< -MM | sed -r -e 's,^(.*)\.o\s*\:,\1.o $# :,g' >> $#
ifneq ($(MAKECMDGOALS),clean)
-include $(DEP_FILES)
endif
$(INTERM_DIR)/%.o: $(SRC_DIR)/%.cpp
mkdir -p $(INTERM_DIR)
$(CC) $(CFLAGS) -c $< -o $#
$(EXECUTABLE): $(OBJ_FILES)
$(CC) $^ $(LIBS) -o $#
However, when I type make I get the following error:
obj/app/sdl_gl_appliacation.dep:1: *** missing separator. Stop.
The file obj/app/sdl_gl_application.dep looks as follows:
-n obj/app/
As I know very little about makefiles (and did not write the posted one) every help would be appreciated.
P.S.
I modified the line printf dirname $#/ > $# . In the original file there was an echo -n but that is not working on OS X.
Well, let's clean this up a little bit.
The way the dependencies are handled really is ugly, GCC can do it for you automatically.
EXECUTABLE := minigi
SRC_DIR := src
OBJ_DIR := obj
SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp)
OBJ_FILES := $(SRC_FILES:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
DEP_FILES := $(OBJ_FILES:.o=.d)
LDLIBS := -lpng -lstdc++ -lGL -lGLU -lGLEW -lSDLmain -lSDL -lgomp
LDFLAGS := -L/usr/local/lang/NVIDIA_GPU_Computing_SDK/sdk/C/common/lib/linux/
CPPFLAGS := -MMD -MP -DNDEBUG -fopenmp -I $(SRC_DIR) -I /usr/local/Cg/examples/OpenGL/glew/include/
CXXFLAGS := -O3
.PHONY: all clean
all: $(EXECUTABLE)
clean:
$(RM) -r $(OBJ_DIR) $(EXECUTABLE)
$(EXECUTABLE): $(OBJ_FILES)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
$(OBJ_DIR):
mkdir $#
ifeq "$(MAKECMDGOALS)" ""
-include $(DEP_FILES)
endif
Some quick notes :
You're using C++, so you should use $(CXX) instead of $(CC) which is used for C code.
Along with this, you should use $(CXXFLAGS) instead of $(CFLAGS).
$(CPPFLAGS) is meant for preprocessor flags (-I, -D, or -fopenmp which is a compile-time flag).
-MMD -MP preprocessor flags will auto-generate dependency files when compiling. Learn more.
$(LDFLAGS) is meant for linker flags such as -L flags.
$(LDLIBS) is meant for linker libs such as -l flags
Avoid using the $(shell ) function since it will be executed every time the variable is expanded when assigned with the = operator instead of the := operator. $(wildcard ) is more suited for the job of listing files.

Makefile for fftw3?

So I can compile my code (fftw_ex.c) directly with:
login$ gcc -o -g fftw_ex fftw_ex.c -I$TACC_FFTW3_INC -L$TACC_FFTW3_LIB -lfftw3
However, my professor prefers that we use a Makefile. I am just learning how to use Makefile and make, and I'm having trouble creating the Makefile. So far, this is what I have:
# RULES
EXEC := fftw_ex
SRC := $(wildcard *.c)
OBJ := $(patsubst %.c,%.o,%(SRC))
# OPERATIONS
CC := gcc
CFLAGS := -O3 -I$TACC_FFTW3_INC
LDFLAGS := -L$TACC_FFTW3_LIB
LDLIBS := -lfftw3
$(EXEC): $(OBJ)
$(CC) $(LDFLAGS) $(LDLIBS) -o -g $# $^
%.o: %.c
$(CC) $(CFLAGS) -c $<
# PHONY TARGETS
.PHONY: clean
clean:
#echo Cleaning...;rm -rf *.o fftw_ex
I know there's a problem with the SRC line, as i'm getting the error message:
make: *** No rule to make target `%(SRC)', needed by `fftw_ex'. Stop.
Any help to get this to work would be appreciated.
1)To resolve:
No rule to make target `%(SRC)'
replace %(SRC) in
OBJ := $(patsubst %.c,%.o,%(SRC))
with $(SRC)
2)In line:
$(CC) $(LDFLAGS) $(LDLIBS) -o -g $# $^
you have mistake: -o -g, should be -g -o