Build Debug and Release Separately using CMAKE - makefile

I am trying to build a CMake file that replicates a Makefile that I have always used. My professor gave us a working CMakeLists.txt that I have been able to use but I was trying to customize it so it would act the same as my Makefile since I use different flags for each build.
Here is my Makefile:
OBJS = Assign1.cpp
CC = g++
DEBUG_FLAGS = -O0 -g3 -fsanitize=address
RELEASE_FLAGS = -O3 -g0
FLAGS = -std=c++14 -Wall -Wextra
release: $(OBJS)
$(CC) $(RELEASE_FLAGS) $(FLAGS) $(OBJS) -o Assign1
debug: $(OBJS)
$(CC) $(DEBUG_FLAGS) $(FLAGS) $(OBJS) -o debug && cgdb ./debug
In the command line, I simply type make and it automatically defaults to release. If I type make debug it will make the debug and run cgdb on the executable.
I have tried doing the same with my CMake File but I do not know how to set up/run different executables if that is the correct terminology. This is my Cmake File:
cmake_minimum_required(VERSION 3.5)
project(Assignment2)
set(RELEASE "-O3 -g0")
set(DEBUG "-O0 -g3 -fsanitize=address")
set(CMAKE_CXX_FLAGS "-std=c++14 -Wall -Wextra")
set(SOURCE_FILES main.cpp compute-e.hpp compute-e.cpp compute-fib.cpp compute-fib.hpp compute-pi.cpp compute-pi.hpp)
add_executable(Assign2 ${RELEASE} ${CMAKE_CXX_FLAGS} ${SOURCE_FILES})
add_executable(debug ${DEBUG} ${CMAKE_CXX_FLAGS} ${SOURCE_FILES} && cgdb ./debug)
What do I need to do to get this to work? I understand Makefiles better than I do CMake files.

Related

How I change my Makefile so it has a specific DEBUG option?

Currently I have a very simple Makefile. When I run it, it compiles my code with some specific options so I can debug it later on. I would like to be able to execute it with a normal "make" without option that creates my code withouth debug option, and one more complex, that add such as debuging. Currently my makefile only compiles with the debug options avaiable, see here the makefile:
main: main.o comandos.o utils.o
main.o:
gcc -Wall -gstabs -DDEBUG -c src/main.c
comandos.o:
gcc -Wall -gstabs -DDEBUG -c src/comandos.c
utils.o:
gcc -Wall -gstabs -DDEBUG -c src/utils.c
clean:
rm main \
*.o
Any advise on how to customize it for both debugging and not debugging options? I was thinking to add a CFLAGS variable at the start, and supressing the variables at gcc lines, but not sure on how I can run on easy way differents values for CFLAGS, one for debuging, with -gstabs -DDEBUG, and only for normal, with only -Wall.
EDIT I: I am aware I can do different targets, and do a specific TARGET called Debug, but the issue I see there is that when I am generating a commands.o, for example, that will be used later on in target main, I already have commands.o precompiled with some specific flags. I am looking for away to have 2 differents targets generatings the same "commands.o", one with debbuging flags other with normal,
and have the main target being able to use the correct one.
I think I found the solution, my main problem was to define two different $FLAGS depending on the target, so I can have a default FLAGS when doing a "normal" release and different flags when I had a debug. I did it this way:
CFLAGS = -Wall
CC = gcc
main: main.o comandos.o utils.o
debug: CFLAGS = -Wall -gstabs -DDEBUG
debug: main
main.o:
$(CC) $(CFLAGS) -c src/main.c
comandos.o:
$(CC) $(CFLAGS) -c src/comandos.c
utils.o:
$(CC) $(CFLAGS) -c src/utils.c
clean:
rm main \
*.o
Not sure if this is the correct way to do it, but seems is working. Thks to #tripple to redirect me to How can I configure my makefile for debug and release builds?.

compiler error gcc-8: error: unrecognized command line option '-no-pie'

I am trying to compile using this makefile but got this error. I can compile using school's linux computer with gcc 6.3. I tried using my MacOS mojave using a few different version of gcc from homebrew (gcc-8, gcc-4.9, gcc-6) but I get this error consistently.
CC = gcc-8
OPT = -O3 -g
LIBS = -lz -lcvp -lz
FLAGS = -std=c++11 -L. $(LIBS) $(OPT) -no-pie
OBJ = myprogram.o
DEPS = cvp.h myprogram.h
all: cvp
cvp: $(OBJ)
$(CC) $(FLAGS) -o $# $^
%.o: %.cc $(DEPS)
$(CC) $(FLAGS) -c -o $# $<
.PHONY: clean
clean:
rm -f *.o cvp
Going off information found here: https://github.com/xd009642/tarpaulin/issues/7#issuecomment-317180523
The problem may very well be related to how gcc is built: "Builds of gcc that don't have the --enable-default-pie flag set at compile time because they are too old or have the --disable-default-pie flag just don't have the -no-pie linker flag"
You might need to update or recompile gcc for that environment to be able to use that flag if important to you.

Simplifying a makefile

I have written a scary-looking Makefile by copy/pasting suggestions from Stack Overflow. However, I have read that it might not be necessary to provide explicit compiler invocations so many times (for example, the -O3 flag is everywhere). How can I simplify this Makefile?
CFLAGS = -Weverything -Wno-padded -Wno-unused-parameter -Wno-unused-variable -Wno-sign-conversion
all: fianchetto.o util.o ttable.o movegen.o
clang -O3 $(CFLAGS) -D NDEBUG $^ -o fianchetto
debugf: fianchetto.o ttable.o movegen.o
clang -O3 $(CFLAGS) -g3 $^ -o fianchetto
clean:
rm *.o && rm *.gch & rm fianchetto && rm -rf fianchetto.dSYM
%.o: %.c
clang -O3 -c $(CFLAGS) $< -o $#
fianchetto.o: fianchetto.c
ttable.o: ttable.h ttable.c
movegen.o: movegen.h movegen.c
util.o: util.h util.c
I am mystified by a lot of the syntax, and would appreciate links or explanations of why simplifications work!
CFLAGS and defines (which should be in CPPFLAGS anyway) are useless when linking
You're reinventing make's built-in rules, make will automatically link a target if one of its dependencies is "target.o" (in this case fianchetto: fianchetto.o). Make also knows how to compile C source files (as long as the source and object path match), so your pattern rule is superfluous too.
The object prerequisites aren't necessary as both clang and GCC can generate dependencies for you with the -M set of flags.
Compiling release and debug builds in the same dir makes for a more simple makefile, although you will need to remember to clean the object files when switching.
By default make assigns cc to CC, and cc should be a link to your system's default compiler, so you might not even need the first line below
CC := clang
CPPFLAGS := -MMD -MP
CFLAGS := -Weverything -Wno-padded -Wno-unused-parameter -Wno-unused-variable -Wno-sign-conversion -O3
objs := fianchetto.o util.o ttable.o movegen.o
deps := $(objs:.o=.d)
.PHONY: all debugf clean
all: CPPFLAGS += -DNDEBUG
debugf: CFLAGS += -g3
all debugf: fianchetto
fianchetto: $(objs)
clean: ; $(RM) $(objs) $(deps) fianchetto fianchetto.dSYM
-include $(deps)

gcc, makefile does not link correctly

I have this makefile:
CC=gcc
CFLAGS= -c -Wall -std=c99 -ggdb
all: plan
plan: plan.o graph.o
$(CC) $(CFLAGS) plan.o graph.o -o plan
plan.o: plan.c graph.h
$(CC) $(CFLAGS) plan.c
graph.o: graph.c graph.h
$(CC) $(CFLAGS) graph.c
run: all
./plan
when I run make, gcc give me the message "linker input file unused because linking not done", what does it mean by that?
The -c option means:
Compile or assemble the source files, but do not link. The linking stage simply is not done. The ultimate output is in the form of an object file for each source file.
You should not use that option when building.
See gcc man
Update
For the plan target, do not use the CFLAGS:
plan: plan.o graph.o
$(CC) -Wall -std=c99 -ggdb plan.o graph.o -o plan

How can I configure my makefile for debug and release builds?

I have the following makefile for my project, and I'd like to configure it for release and debug builds. In my code, I have lots of #ifdef DEBUG macros in place, so it's simply a matter of setting this macro and adding the -g3 -gdwarf2 flags to the compilers. How can I do this?
$(CC) = g++ -g3 -gdwarf2
$(cc) = gcc -g3 -gdwarf2
all: executable
executable: CommandParser.tab.o CommandParser.yy.o Command.o
g++ -g -o output CommandParser.yy.o CommandParser.tab.o Command.o -lfl
CommandParser.yy.o: CommandParser.l
flex -o CommandParser.yy.c CommandParser.l
gcc -g -c CommandParser.yy.c
CommandParser.tab.o: CommandParser.y
bison -d CommandParser.y
g++ -g -c CommandParser.tab.c
Command.o: Command.cpp
g++ -g -c Command.cpp
clean:
rm -f CommandParser.tab.* CommandParser.yy.* output *.o
Just to clarify, when I say release/debug builds, I want to be able to just type make and get a release build or make debug and get a debug build, without manually commenting out things in the makefile.
You can use Target-specific Variable Values. Example:
CXXFLAGS = -g3 -gdwarf2
CCFLAGS = -g3 -gdwarf2
all: executable
debug: CXXFLAGS += -DDEBUG -g
debug: CCFLAGS += -DDEBUG -g
debug: executable
executable: CommandParser.tab.o CommandParser.yy.o Command.o
$(CXX) -o output CommandParser.yy.o CommandParser.tab.o Command.o -lfl
CommandParser.yy.o: CommandParser.l
flex -o CommandParser.yy.c CommandParser.l
$(CC) -c CommandParser.yy.c
Remember to use $(CXX) or $(CC) in all your compile commands.
Then, 'make debug' will have extra flags like -DDEBUG and -g where as 'make' will not.
On a side note, you can make your Makefile a lot more concise like other posts had suggested.
This question has appeared often when searching for a similar problem, so I feel a fully implemented solution is warranted. Especially since I (and I would assume others) have struggled piecing all the various answers together.
Below is a sample Makefile which supports multiple build types in separate directories. The example illustrated shows debug and release builds.
Supports ...
separate project directories for specific builds
easy selection of a default target build
silent prep target to create directories needed for building the project
build-specific compiler configuration flags
GNU Make's natural method of determining if project requires a rebuild
pattern rules rather than the obsolete suffix rules
#
# Compiler flags
#
CC = gcc
CFLAGS = -Wall -Werror -Wextra
#
# Project files
#
SRCS = file1.c file2.c file3.c file4.c
OBJS = $(SRCS:.c=.o)
EXE = exefile
#
# Debug build settings
#
DBGDIR = debug
DBGEXE = $(DBGDIR)/$(EXE)
DBGOBJS = $(addprefix $(DBGDIR)/, $(OBJS))
DBGCFLAGS = -g -O0 -DDEBUG
#
# Release build settings
#
RELDIR = release
RELEXE = $(RELDIR)/$(EXE)
RELOBJS = $(addprefix $(RELDIR)/, $(OBJS))
RELCFLAGS = -O3 -DNDEBUG
.PHONY: all clean debug prep release remake
# Default build
all: prep release
#
# Debug rules
#
debug: $(DBGEXE)
$(DBGEXE): $(DBGOBJS)
$(CC) $(CFLAGS) $(DBGCFLAGS) -o $(DBGEXE) $^
$(DBGDIR)/%.o: %.c
$(CC) -c $(CFLAGS) $(DBGCFLAGS) -o $# $<
#
# Release rules
#
release: $(RELEXE)
$(RELEXE): $(RELOBJS)
$(CC) $(CFLAGS) $(RELCFLAGS) -o $(RELEXE) $^
$(RELDIR)/%.o: %.c
$(CC) -c $(CFLAGS) $(RELCFLAGS) -o $# $<
#
# Other rules
#
prep:
#mkdir -p $(DBGDIR) $(RELDIR)
remake: clean all
clean:
rm -f $(RELEXE) $(RELOBJS) $(DBGEXE) $(DBGOBJS)
If by configure release/build, you mean you only need one config per makefile, then it is simply a matter and decoupling CC and CFLAGS:
CFLAGS=-DDEBUG
#CFLAGS=-O2 -DNDEBUG
CC=g++ -g3 -gdwarf2 $(CFLAGS)
Depending on whether you can use gnu makefile, you can use conditional to make this a bit fancier, and control it from the command line:
DEBUG ?= 1
ifeq ($(DEBUG), 1)
CFLAGS =-DDEBUG
else
CFLAGS=-DNDEBUG
endif
.o: .c
$(CC) -c $< -o $# $(CFLAGS)
and then use:
make DEBUG=0
make DEBUG=1
If you need to control both configurations at the same time, I think it is better to have build directories, and one build directory / config.
Note that you can also make your Makefile simpler, at the same time:
DEBUG ?= 1
ifeq (DEBUG, 1)
CFLAGS =-g3 -gdwarf2 -DDEBUG
else
CFLAGS=-DNDEBUG
endif
CXX = g++ $(CFLAGS)
CC = gcc $(CFLAGS)
EXECUTABLE = output
OBJECTS = CommandParser.tab.o CommandParser.yy.o Command.o
LIBRARIES = -lfl
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CXX) -o $# $^ $(LIBRARIES)
%.yy.o: %.l
flex -o $*.yy.c $<
$(CC) -c $*.yy.c
%.tab.o: %.y
bison -d $<
$(CXX) -c $*.tab.c
%.o: %.cpp
$(CXX) -c $<
clean:
rm -f $(EXECUTABLE) $(OBJECTS) *.yy.c *.tab.c
Now you don't have to repeat filenames all over the place. Any .l files will get passed through flex and gcc, any .y files will get passed through bison and g++, and any .cpp files through just g++.
Just list the .o files you expect to end up with, and Make will do the work of figuring out which rules can satisfy the needs...
for the record:
$# The name of the target file (the one before the colon)
$< The name of the first (or only) prerequisite file (the first one after the colon)
$^ The names of all the prerequisite files (space separated)
$* The stem (the bit which matches the % wildcard in the rule definition.
you can have a variable
DEBUG = 0
then you can use a conditional statement
ifeq ($(DEBUG),1)
else
endif
Completing the answers from earlier... You need to reference the variables you define info in your commands...
DEBUG ?= 1
ifeq (DEBUG, 1)
CFLAGS =-g3 -gdwarf2 -DDEBUG
else
CFLAGS=-DNDEBUG
endif
CXX = g++ $(CFLAGS)
CC = gcc $(CFLAGS)
all: executable
executable: CommandParser.tab.o CommandParser.yy.o Command.o
$(CXX) -o output CommandParser.yy.o CommandParser.tab.o Command.o -lfl
CommandParser.yy.o: CommandParser.l
flex -o CommandParser.yy.c CommandParser.l
$(CC) -c CommandParser.yy.c
CommandParser.tab.o: CommandParser.y
bison -d CommandParser.y
$(CXX) -c CommandParser.tab.c
Command.o: Command.cpp
$(CXX) -c Command.cpp
clean:
rm -f CommandParser.tab.* CommandParser.yy.* output *.o
You could also add something simple to your Makefile such as
ifeq ($(DEBUG),1)
OPTS = -g
endif
Then compile it for debugging
make DEBUG=1

Resources