Basic Makefile with two .cpp files and a header file - c++

I wanted to learn how to create a basic Makefile for my program containing 3 files: a.cpp, b.cpp, and b.h. I include b.h in a.cpp and call a function that is declared there and defined in b.cpp. I went through several Makefile tutorials and came up with a Makefile like this:
CC=g++
CFLAGS= -std=c++11 -Wall -pedantic -g
SOURCES= a.cpp b.cpp
DEPS= b.h
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=exec
all: $(EXECUTABLE)
#echo Make has finished.
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o $(EXECUTABLE)
%.o: %.cpp $(DEPS)
$(CC) $(CFLAGS) -c -o $# $<
clean:
$(RM) *.o *~ $(EXECUTABLE)
However, when I make and run exec it doesn't work as intended. The compiler gives no warnings or errors, but the function call in a.cpp is skipped over as if it's not there. Instead if I run the simple
g++ -std=c++11 -Wall -pedantic -g a.cpp b.cpp -o exec
my program runs as intended. Obviously I'm not doing something right in my Makefile, but I cannot figure out what.

CC=g++
CFLAGS= -std=c++11 -Wall -pedantic -g
SOURCES= a.cpp b.cpp
DEPS= b.h
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=exec
all: $(EXECUTABLE)
#echo Make has finished.
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) -c $*.cpp
clean:
$(RM) *.o *~ $(EXECUTABLE)

When reading your Makefile example, it's useful to read it as a computer would, replacing fields as you walk through the file. The lines that popped out to me were:
SOURCES= a.cpp b.cpp
...
OBJECTS=$(SOURCES:.cpp=.o)
...
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o $(EXECUTABLE)
...
%.o: %.cpp $(DEPS)
$(CC) $(CFLAGS) -c -o $# $<
The first line defines the source files. The second defines the object files (extension .o) that the Makefile says can be built from the .cpp files. The third and fourth define a rule to produce the final executable, which requires that your two object files, a.o and b.o be successfully generated. The last two lines define a rule for generation of the object files, which specifies that they require their same-name .cpp files and the $(DEPS) == b.h files.
In the end, this Makefile calls the following lines:
g++ -std=c++11 -Wall -pedantic -g -c -o a.o a.cpp b.h
g++ -std=c++11 -Wall -pedantic -g -c -o b.o b.cpp b.h
g++ -std=c++11 -Wall -pedantic -g a.o b.o -o exec
So it appears that the breakage in your code is in the mixed-up flags passed to the compiler the first two times.

Related

C++ makefile not linking

EXENAME = prog1
OBJS = link.o main.o
CXX = clang++
CXXFLAGS = -Wall -Wextra
LD = clang++
all : $(EXENAME)
$(EXENAME) : $(OBJS)
$(LD) $(OBJS) -o $(EXENAME)
main.o : link.h main.cpp
$(CXX) $(CXXFLAGS) main.cpp
link.o : link.h link.cpp
$(CXX) $(CXXFLAGS) link.cpp
clean :
-rm -f *.o $(EXENAME)
This is the make file I got but all the function in link can't be called in main. I tried many different ways doesn't work. This works
prog1: main.cpp link.h link.cpp
clang++ -Wall -Wextra -o prog1 main.cpp link.cpp
But I suppose is not the right way to do this?
It would help if you provided at least some of the errors you got (probably the first few).
Your compiler invocation for building object files is wrong. Without any other flags specified, the compiler will try to take all the input files and create an executable out of them. So this rule:
main.o : link.h main.cpp
$(CXX) $(CXXFLAGS) main.cpp
expands to this compilation line:
clang++ -Wall -Wextra main.cpp
The compiler will attempt to compile and link the main.cpp file (only, because that's all that's listed here) into an executable named a.out (by default).
You need to add the -c option to your compile lines if you want to build an object file rather than link a program:
main.o : link.h main.cpp
$(CXX) $(CXXFLAGS) -c main.cpp
Ditto for building link.o.
Even better would be to simply use make's built-in rules for compiling object files rather than writing your own; in that case your entire makefile could just be:
EXENAME = prog1
OBJS = link.o main.o
CXX = clang++
CXXFLAGS = -Wall -Wextra
all : $(EXENAME)
$(EXENAME) : $(OBJS)
$(CXX) $(CXXFLAGS) $(OBJS) -o $(EXENAME)
main.o : link.h
link.o : link.h
clean :
-rm -f *.o $(EXENAME)

how do I set compilingflags in a makefile?

I'm used to program in IDEs, but switched to vim and plugins recently. Now I try to write a makefile for a c++ project, but somehow if I run make I always get the error
g++ -c -o *.o createOutput.cpp
In file included from /usr/include/c++/4.8/thread:35:0,
from createOutput.cpp:5:
/usr/include/c++/4.8/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support for the \
^
This is my makefile:
CC = clang++
# compiler flags
CFLAGS = -O3 -Wall -Werror -std=c++11
CFLAGS_SFML = -lsfml-graphics -lsfml-window -lsfml-system
all: program.exe clean
program.exe: *.o
$(CC) -o program.exe *.o $(CFLAGS) $(CFLAGS_SFML)
getInput.o: getInput.cpp
$(CC) -c getInput.cpp $(CFLAGS)
createOutput.o: createOutput.cpp
$(CC) -c createOutput.cpp $(CFLAGS)
main.o: main.cpp
$(CC) -c main.cpp $(CFLAGS)
.PHONY: clean
clean:
rm *.o
#echo clean done
Where is my error? Why is it using g++ instead of clang? And why isn't it using the -std=c++11 parameter? Sorry for the beginner questions, I unfortunately can't find a solution with google.
You want to set CXXFLAGS, that gets picked up automatically by make (and sent to your compiler (eg g++, clang++, etc).
make tried to make target '*.o'.
So, instead of that, you can specify sources list explicitly:
CC = clang++
#compiler flags
CFLAGS = -O3 -Wall -Werror -std=c++11
CFLAGS_SFML = -lsfml-graphics -lsfml-window -lsfml-system
SRCS = getInput.cpp createOutput.cpp main.cpp
OBJS = $(SRCS:.cpp=.o)
all: program.exe
program.exe: $(OBJS)
$(CC) -o program.exe *.o $(CFLAGS) $(CFLAGS_SFML)
getInput.o: getInput.cpp
$(CC) -c getInput.cpp $(CFLAGS)
createOutput.o: createOutput.cpp
$(CC) -c createOutput.cpp $(CFLAGS)
main.o: main.cpp
$(CC) -c main.cpp $(CFLAGS)
.PHONY : clean
clean:
rm *.o
#echo clean done
Note definition of variables OBJS and SRCS.

Makefile - wildcard, how to do that properly?

FLAGS:= -Wall -Wvla -g -lm
OBJECT := Nominated.h UniversityNominated.h AliceGraduate.h BobGraduate.h CollegeNominated.h ColinGraduate.h DannyGraduate.h NominatedList.h Parser.h Parser.cpp
all: Hire
Nominated.o: Nominated.h Nominated.cpp
g++ -c $(FLAGS) Nominated.cpp -o Nominated.o
NominatedList.o: Nominated.h NominatedList.h NominatedList.cpp
g++ -c $(FLAGS) NominatedList.cpp -o NominatedList.o
UniversityNominated.o: Nominated.h UniversityNominated.h UniversityNominated.cpp
g++ -c $(FLAGS) UniversityNominated.cpp -o UniversityNominated.o
AliceGraduate.o: Nominated.h UniversityNominated.h AliceGraduate.h AliceGraduate.cpp
g++ -c $(FLAGS) AliceGraduate.cpp -o AliceGraduate.o
BobGraduate.o: Nominated.h UniversityNominated.h BobGraduate.h BobGraduate.cpp
g++ -c $(FLAGS) BobGraduate.cpp -o BobGraduate.o
CollegeNominated.o: Nominated.h CollegeNominated.h CollegeNominated.cpp
g++ -c $(FLAGS) CollegeNominated.cpp -o CollegeNominated.o
ColinGraduate.o: Nominated.h CollegeNominated.h ColinGraduate.h ColinGraduate.cpp
g++ -c $(FLAGS) ColinGraduate.cpp -o ColinGraduate.o
DannyGraduate.o: Nominated.h CollegeNominated.h DannyGraduate.h DannyGraduate.cpp
g++ -c $(FLAGS) DannyGraduate.cpp -o DannyGraduate.o
Parser.o: $(OBJECT)
g++ -c $(FLAGS) Parser.cpp -o Parser.o
Parser: Nominated.o UniversityNominated.o AliceGraduate.o BobGraduate.o CollegeNominated.o ColinGraduate.o DannyGraduate.o NominatedList.o Parser.o
ar rcu libParser.a Nominated.o UniversityNominated.o AliceGraduate.o BobGraduate.o CollegeNominated.o ColinGraduate.o DannyGraduate.o NominatedList.o Parser.o
ranlib libParser.a
Hire: Hire.cpp Parser
g++ Hire.cpp libParser.a -o Hire
clean:
rm -f Hire *.a *.o *~
.PHONY: clean all
so this is my Makefile.
How can I make less ugly ?
I am always read about that but I can not get the idea
How ?
I mean I understand I need to use the wildcard tool but as you I probably used it wrong
Here's an example of how to use wildcard and pattern substitution:
SOURCES := $(wildcard *.cpp)
OBJECTS := $(patsubst %.cpp,%.o,$(SOURCES))
CXX := g++ -Wall -Wvla -g
.cpp.o:
${CXX} -c $<
This will build all the .cpp files into their object files.
There's many things you can do, but one of the best is a pattern rule for specific types. All of your objects seem to be built the same way.
%.o: %.cpp
${CXX} -c $(FLAGS) -o $# $<
You'll notice that this doesn't include any header files as dependencies. Manually maintaining the header dependencies in a Makefile is a bad idea because it's bound to get out of date as you modify your program. Sometimes your compiler can generate make-friendly dependencies for you automatically. Assuming you have a list of objects such as this:
OBJS := $(SOURCES:%.c=%.o)
You can include this at the very end of your Makefile (with no blank line afterward)
-include $(OBJS:.o=.d)
Then add, -MMD to your compiler flags. This will cause GCC to generate .d files that contain the header dependencies for each of your objects as a Make rule, and the above include line will include those rules and use them to resolve the dependencies of your objects. This will mean that any header change will cause all files that include it (directly or indirectly) to be rebuilt.
Try this:
FLAGS = -Wall -Wextra
SRC = $(wildcard *.cpp)
OBJ = $(patsubst %.cpp,%.o,$(SRC))
DEP = $(patsubst %.cpp,%.d,$(SRC))
PARSER = $(filter-out Hire.o,$(OBJ))
all: $(DEP) build
build:
make Hire
%.d:
g++ -MM $*.cpp > $*.d
%.o: %.cpp
g++ $(FLAGS) -c $*.cpp
libParser.a: $(PARSER)
ar rcu libParser.a $(PARSER)
ranlib libParser.a
Hire: Hire.cpp libParser.a
g++ Hire.cpp libParser.a -o Hire
clean:
rm -f Hire *.a *.o *.d *~
.PHONY: clean all
#
# This line includes all the dependencies.
# There is one for each file.
# Check the *.d files after you run make
-include $(DEP)

Writing a makefile to use -D_GLIBCXX_DEBUG in debug build

I have a makefile that can be reduced to this:
OBJS = obj1.o obj2.o
FLAGS = -Wall -Wextra -Werror -pedantic-errors -fno-rtti -std=c++0x
DEBUG_FLAGS = -ggdb -O0 -fstack-protector-all -D_GLIBCXX_DEBUG
RELEASE_FLAGS = -O3
release: $(OBJS)
g++ $(FLAGS) $(RELEASE_FLAGS) $(OBJS)
debug: $(OBJS)
g++ $(FLAGS) $(DEBUG_FLAGS) $(OBJS)
obj1.o: obj1.cpp
g++ -c $(FLAGS) obj1.cpp
obj2.o: obj2.cpp
g++ -c $(FLAGS) obj2.cpp
The problem is that all or none of the files must be built with the -D_GLIBCXX_DEBUG flag. I don't know how to do this without writing two entries for every compilation unit, like
obj1_release.o: obj1.cpp
g++ -c $(FLAGS) $(RELEASE_FLAGS) obj1.cpp
obj1_debug.o: obj1.cpp
g++ -c $(FLAGS) $(DEBUG_FLAGS) obj1.cpp
How can I make the -D_GLIBCXX_DEBUG flag (and the other debug flags) take effect for all compilation units only when the user types make debug without writing two entries for every CU? (And vice versa; the release flags need to take effect on all CUs when the user types make release.)
I apologise if this is the basics of writing Makefiles, I don't know much about them.
You are looking for pattern rules: something like this should do what you want. Note that this cannot be made to work correctly unless the debug and release versions of the program are given different names.
OBJS := obj1 obj2 obj3
R_OBJS := $(OBJS:=_r.o)
D_OBJS := $(OBJS:=_d.o)
all: prog_r prog_d
release: prog_r
debug: prog_d
prog_r: $(R_OBJS)
$(CXX) $(CXXFLAGS) $(RELEASE_FLAGS) $(LDFLAGS) $^ $(LIBS) -o $#
prog_d: $(D_OBJS)
$(CXX) $(CXXFLAGS) $(DEBUG_FLAGS) $(LDFLAGS) $^ $(LIBS) -o $#
%_r.o: %.cc
$(CXX) $(CXXFLAGS) $(RELEASE_FLAGS) -c $< -o $#
%_d.o: %.cc
$(CXX) $(CXXFLAGS) $(DEBUG_FLAGS) -c $< -o $#
# header files
obj1_d.o obj1_r.o: foo.h bar.h
obj2_d.o obj2_r.o: quux.h
# ... etc ...
There is a pretty straightforward way to select compilation flags based on the type of the build in Makefiles.
In addition to that you may like to ensure that debug build only links debug object files and same for release (i.e. no mixing debug and release object files). To achieve that compile object into different directories depending on the build type.
This might help : http://sunsite.ualberta.ca/Documentation/Gnu/make-3.79/html_chapter/make_7.html
You could check the first argument (debug/release) and set the CFLAGS accordingly.
HTH.

Creating two separate executables from a makefile (g++)

Currently, I have my makefile set up to compile and make a fairly large project. I have written a second cpp file with main function for running tests. I want these to run separately, but build together and they use the same files. How is this accomplished?
edit: As reference, here is my current makefile. I'm not sure how to adjust it.
CC=g++
CFLAGS=-c -Wall -DDEBUG -g
LDFLAGS=
SOURCES=main.cpp Foo.cpp Bar.cpp Test.cpp A.cpp B.cpp C.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=myprogram
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
Normally you would just have multiple targets and do something like this:
.PHONY: all target tests
all: target tests
target: ...
...
tests: ...
...
Then you can just make (defaults to make all), or just make target or make tests as needed.
So for your makefile example above you might want to have something like this:
CC = g++
CFLAGS = -c -Wall -DDEBUG -g
LDFLAGS =
COMMON_SOURCES = Foo.cpp Bar.cpp A.cpp B.cpp C.cpp
TARGET_SOURCES = main.cpp
TEST_SOURCES = test_main.cpp
COMMON_OBJECTS = $(COMMON_SOURCES:.cpp=.o)
TARGET_OBJECTS = $(TARGET_SOURCES:.cpp=.o)
TEST_OBJECTS = $(TEST_SOURCES:.cpp=.o)
EXECUTABLE = myprogram
TEST_EXECUTABLE = mytestprogram
.PHONY: all target tests
all: target tests
target: $(EXECUTABLE)
tests: $(TEST_EXECUTABLE)
$(EXECUTABLE): $(COMMON_OBJECTS) $(TARGET_OBJECTS)
$(CC) $(LDFLAGS) $^ -o $#
$(TEST_EXECUTABLE): $(COMMON_OBJECTS) $(TEST_OBJECTS)
$(CC) $(LDFLAGS) $^ -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
Here's one way to do it:
CXXFLAGS += -std=c++11 -Wall -O3
all: myprog mytest
myprog.cpp: main.cpp
cp -vf $< $#
myprog: myprog.o Foo.o Bar.o Test.o A.o B.o C.o
mytest.cpp: main.cpp
cp -vf $< $#
mytest.o: CPPFLAGS += -DDEBUG
mytest.o: CXXFLAGS += -O0 -g
mytest: mytest.o Foo.o Bar.o Test.o A.o B.o C.o
This works because built-in rules exist for compiling objects from c++ source (%.o: %.cpp) and linking main programs (%: %.o).
Also note the use of target-specific values for the variables CPPFLAGS and CXXFLAGS.