Makefile for a project - c++

I have a Makefile for a project using regex. Thus I need to use g++-4.9 and c++11.
BIN = bin
OBJ = src/main.o src/time2.o src/except.o src/except2.o src/struct.o src/index.o
FLAGS = -lncurses
CC = g++-4.9 -std=c++11 -Wall -pedantic -Wno-long-long -O0 -ggdb
all: compile
run: compile
./$(BIN)
clean:
rm -f $(BIN) $(OBJ)
compile: $(OBJ)
$(CC) -o $(BIN) $(OBJ) $(FLAGS)
but when I try to make compile:
g++ -c -o src/main.o src/main.cpp In file included from
/usr/include/c++/4.8/regex:35:0,
from src/time2.h:16,
from src/main.cpp:3: /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 \ ^ In file
included from src/main.cpp:5:0: src/struct.h:99:18: error: ‘regex’ has
not been declared bool isnamegood(regex x,const string& name);
^
so I don't understand what is wrong, may you help me please?

The problem is that your compile target already depends on the object files! But they aren't build yet, so make tries to find a rule to build them. Because you have not defined a custom rule, it uses the implicit rule:
Compiling C++ programs n.o is made automatically from n.cc, n.cpp, or
n.C with a recipe of the form ‘$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c’. We
encourage you to use the suffix ‘.cc’ for C++ source files instead of
‘.C’.
This rule will of course not use the flags you set in CC. This explains why the gcc command line printed by make does not match your CC. You can test this by running make with --no-builtin-rules, as this should disable all the implicit rules.
A good idea in such cases is to run make with -d or --debug, I think this should display rule evaluations.

Instead of using the c macros, use the c++ macros
CXX= g++-4.9
CXXFLAGS= -std=c++11 -Wall -pedantic -Wno-long-long -O0 -ggdb
Then the default rules should pick them up and you need to type less in your makefile.
Also see the complete list of variables (macros) used by Make

Related

CFLAGS for C++ (GNU compiler) not working

Im compiling a c++ file with the gnu compiler g++. For C I use CFLAGS but its not working for c++. What Im seeing the .cpp files using the -O2 flag but g++ -Wall *.o -o tp2 is compiling without the flags.
I added it manually to tp2 but now the flags are not being used compile. So my question is how do I fix this. Ive also tried with CXXFLAGS and CPPFLAGS. Thanks.
.PHONY: link clean
CFLAGS:= -O2 -Wall
Make: tp2
compile: coordonnees.o personne.o tp2.o
%.o: %.cpp %h
clean:
rm -rf tp2 *~ *.o
tp2: compile
g++ -Wall *.o -o tp2
CFLAGS and the like only apply to the implicit rules of make. Since you defined the command as g++ -Wall *.o -o tp2 instead of depending on an implicit rule, it runs exactly that command. If you want to add those flags you can put $(CFLAGS) on the line where you define the command.

How to write makefile for a target that includes a header file?

I have two files "create-exercise.cpp" and "exercise.hpp". I want to write a makefile to use gnu++17 and g++ to compile them. exercise.hpp is included in create-exercise.cpp. I only want to get a binary out of create-exercise.cpp. the command I would use is g++ -std=gnu++17 create-exercise.cpp -o create-exercise and it works well. I tried using the following in a make file.
CXXFLAGS=-Wall -std=gnu++17
create-exercise: create-exercise.cpp exercise.hpp
but that generated the following g++ -Wall -std=gnu++17 create-exercise.cpp exercise.hpp -o create-exercise I don't want exercise.hpp to be included in the compilation command. I also tried to use the following instead.
CXXFLAGS=-Wall -std=gnu++17
create-exercise.o: create-exercise.cpp exercise.hpp
That generated g++ -Wall -std=gnu++17 -c -o create-exercise.o create-exercise.cpp. I don't want the -c flag. because when I try to run create-exercise.o that results in permission denied error. I tried the following as well:
CXXFLAGS=-Wall -std=gnu++17
create-exercise.o: create-exercise.cpp exercise.hpp
$(CXX) $(CXXFLAGS) create-exercise.cpp -o create-exercise.o
but when I edit exercise.hpp make says 'create-exercise.o' is up to date. and doesn't recompile it. what should I do?
The rule to write in your makefile would be:
create-exercise.o: exercise.hpp
This is a rule without a recipe, and it simply adds one more prerequisite (exercise.hpp) to the target create-exercise.o, i.e., whenever exercise.hpp changes, create-exercise.o should be rebuilt.
However, the problem when providing that rule is that GNU Make assumes create-exercise.o is an object file generated from a C source file when building create-exercise. Therefore, it doesn't link the C++ library but the C library instead, that's why you are having the liking error of undefined reference to std::cout.
GNU Make has the following implicit rule for generating an executable from a C++ source file:
%: %.cpp
# commands to execute (built-in):
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $#
You can use that rule's recipe to build create-exercise from creating-exercise.o and still treat creating-exercise.o as an object file that was generated from a C++ source file:
create-exercise: create-exercise.o
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $#
The whole makefile would be then:
CXXFLAGS = -Wall -std=gnu++17
create-exercise: create-exercise.o
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $#
create-exercise.o: exercise.hpp
The target create-exercise also becomes the default goal because it's the first rule in the makefile. It's the target to build if you don't specify any to make.
You can do this:
CXXFLAGS = -Wall -std=gnu++17
create-exercise: create-exercise.o
$(LINK.cpp) $^ $(LDLIBS) -o $#
create-exercise.o: exercise.hpp
This says: build create-exercise from the object file create-exercise.o, if it's changed. And it says rebuild create-exercise.o if the header file exercise.hpp changes; it's not right to modify or rebuild a source file if a header changes. It's the object file that depends on the header.
Make has a number of built in rules. Among them are rules that know how to link a program but unfortunately that assumes your object files were built from C files, so if you're using C++ you have to create a specific recipe. But you can still use GNU make's default variables.
It also knows how to build a .o file from a .cpp file on its own: you don't need to write that recipe.
I am not sure, but maybe try to include the .hpp file instead of compiling it with the other file. You can do so by using g++ *.cpp -I *.hpp -o output
Try it out and let me know if it works for you.

adding c++11 in makefile to remove the error to_string is not declared in this scope

I suppose this question is asked in some other threads, I was getting the error while calling make: to_string is not declared in this scope. I found out I have to add c++11 in makefile. But I tried some options mentioned in several threads. Could you provide some solution here? Thanks
Adding -std=c++11 to CFLAGS will cause g++ to compile with the C++11 standard. Like this
CFLAGS=-std=c++11 -c -g -O3 -finline-functions -fstack-protector
However, as highlighted in comments the appropriate syntax for compiling C++ programs with a makefile is to use a rule like this
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c
where your C++ files use the suffix .cc [1]. Then you would add -std=c++11 to CXXFLAGS. The difference between CPPFLAGS and CXXFLAGS is [2]
CPPFLAGS is supposed to be for flags for the C PreProcessor; CXXFLAGS
is for flags for the C++ compiler.
This would require some rewrites within your makefile, namely
CXX=g++
LD=g++
CXXFLAGS=-c -g -O3 -fstack-protector -I./Eigen
and rules from
$(CC) $(INCLUDE) $(CFLAGS) -c
to
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c
as above.
The $(INCLUDE) can also be removed from your linking command ($(LD)) as it is only needed during compile time. Your linking command can also be simplified to
ParEGOIteration13: ParEGOIteration13.o Utilities.o WeightVector.o SearchSpace.o DACE.o GeneticAlgorithm.o Matrix.o
$(CXX) $? -o $#
by using the automatic variables [3]
$? expands to all of the prerequisites
$# expands to the name of the target
I'll let you work out how to use the automatic variables in your compilation rules.
Note: I've removed -finline-functions as -O3 (and -O2) turn it on by default with gcc.

Making -std=c++11 the default in mac terminal

When I want to compile, I need to specify -std=c++11 like this:
g++ -Wall -std=c++11 main.cpp -o main
and I wonder if there was a solution to set the -std=c++11 flag permanently so it will be possible to do:
g++ -Wall main.cpp -o main
without flags.
Create an alias: alias g++='g++ -std=c++11' should do the trick.
(However, the version of GCC that comes with OS X is so ancient that it doesn't support C++11, you'd be better off using clang and clang++.)
I know this already has an accepted but I feel like I have some advice to offer. For one you should be using a makefile for c++, this is the one I use for answering on SO.
CFLAGS=-std=c++11
CFLAGS+=-stdlib=libc++
CC=clang++
#flags for test.c
cc=clang
DEBUG=-g
#warnings
WARNINGS=-Weverything
#always have -Weverything on for SO lol
OPT= -O0 -O1 -O2 -O3 -O4
test: test.cpp
$(info set CC for compiler)
$(CC) $(CFLAGS) $< -o $# $(DEBUG)
stack: stack.cpp
$(CC) $(CFLAGS) stack.cpp -o $# $(DEBUG) $(WARNINGS)
testc: test.c
$(cc) $< -o $# $(DEBUG)
clean:
rm test
Now whenever I download someones crappy code from SO I have a makefile for c and c++ files where I can easily change the flags if I want to.
As for bash alias I would suggest you alias it like so alias clang++11='clang++ -std=c++11 this way you don't overwrite the clang++ if you don't want to use the c++11 standard. Lastly you can add the line I just showed you to your .bash_profile on a mac which is in your home or ~ folder, this will make the change permanent. Once you change it run source .bash_profile to put the changes into effect. On linux I think the file is called .bashrc. Hopefully these tips will help you out when ur c++ing, I would advise you to learn the mac command line, has differences from the linux one, it can be very useful to know some of the things it can do.

Can someone explain this makefile to me?

I've been using c++ casually for a couple of months with a makefile I don't even remember where I got or if I did it myself (the actual structure it has. I know I've added some libraries and flags though):
SRC = filename.cpp
TARG = filename
CC = g++
CPPFLAGS = -g -Wall -Werror -Wextra -pipe -pedantic -Weffc++ -std=c++0x -O2 -Wno-unused-function `pkg-config --cflags opencv`
LDFLAGS = `pkg-config --libs opencv` -lboost_regex -lboost_filesystem
OBJ = $(SRC:.cpp=.o)
all: $(TARG)
clean:
rm -f *~ *.o $(TARG)
I wanted to use it to compile a class, but first I have to understand what is going on since I have to modify it a bit. Also, are there any bad practices in it?
If you want to compile a class instead of a program, you need to do a little surgery on the file. I'm assuming that you want an object file, not a library; the rules for libraries are more complex. But this should do the trick.
SRC = class.cpp
OBJ = $(SRC:.cpp=.o)
CC = g++
CPPFLAGS = -g -Wall -Werror -Wextra -pipe -pedantic -Weffc++ -std=c++0x -O2 \
-Wno-unused-function `pkg-config --cflags opencv`
LDFLAGS = `pkg-config --libs opencv` -lboost_regex -lboost_filesystem
DEBRIS = core a.out *~
all: $(OBJ)
class.o: class.h
clean:
rm -f $(DEBRIS) $(OBJ)
It is not immediately clear whether $(CPPFLAGS) will automatically appear in the compilation or linking commands.
If you end up wanting to build the program from two files, then you use a hybrid:
SRC = filename.cpp class.cpp
OBJ = $(SRC:.cpp=.o)
PROGRAM = program
CXX = g++
CXXFLAGS = -g -Wall -Werror -Wextra -pipe -pedantic -Weffc++ -std=c++0x -O2 \
-Wno-unused-function `pkg-config --cflags opencv`
LDFLAGS = `pkg-config --libs opencv` -lboost_regex -lboost_filesystem
DEBRIS = core a.out *~
all: $(PROGRAM)
$(PROGRAM): $(OBJ)
$(CXX) $(CXXFLAGS) -o $# $(OBJ) $(LDFLAGS)
class.o: class.h
filename.cpp: class.h
clean:
rm -f $(DEBRIS) $(OBJ) $(PROGRAM)
Note that I've changed the macro for the C++ compiler from CC to CXX. The standards are not clear on the name for the C++ compiler. POSIX doesn't mention C++ in its description of make. However, CC is clearly intended for compiling C rather than C++. That needn't stop your version of make from using CC for C++ compilation, but it would be a little unusual. (GNU Make 3.81 on MacOS X 10.6.8 uses CXX for the C++ compilation.) The link line now uses $(CXXFLAGS) (thanks to eriktous); it is still not clear whether the C++ source to object file compilation would do so. Ultimately, that's why you end up seeing makefiles with rules such as:
class.o: class.h
$(CXX) -c $(CXXFLAGS) $*.cpp
This guarantees that the compilation rule is what you see for this object file. You might write that as an old-fashioned but portable suffix rule (.cpp.o:) instead; the POSIX specification for make supports these. Or you might use the more modern but not necessarily quite as portable %.o : %.o notation instead (not required by POSIX). Either of these replaces any previous (built-in) definition of how to compile an object file from C++ source.
.cpp.o:
$(CXX) -c $(CXXFLAGS) $*.cpp
%.o : %.cpp
$(CXX) -c $(CXXFLAGS) $*.cpp
I assume you are using opencv (and some of Boost); if not, your compilation and linking flags include irrelevant options. The dependencies are guessed; make will infer the dependency of the object file on the C++ source code, so I only listed header dependencies. But you may have many more if you're using opencv and Boost.
(Makefiles not formally tested.)
when you type "make" with no args, it looks for the first recipe, something that starts in the first column with a colon after it. that would be all, which tells it to build TARG. TARG is filename. Make is already configured on many systems to know what to do with .cpp files, so there is no specific recipe in this Makefile to do that. The OBJ construct is unused here, so no need to explain that; but what it means is "replace .cpp in SRC with .o", so OBJ would be filename.o.
It already looks good. You defined the proper variables, the file is short and readable, what else do you want?
In the clean target, you could only remove $(OBJ) instead of *.o. And you should not remove your editor's backup files as part of the build process. I suggest this instead:
clean:
rm -f $(TARG) $(OBJ)
clean-all: clean
rm -f *~
# mark these targets as non-files.
.PHONY: all clean clean-all