How to update the __cplusplus value - c++

in my project I would like to use the header on a raspberry pi zero. However, inside the header, this statement evaluates to false:
#if __cplusplus >= 201703L
I checked the value and it is indeed just at 201402L
g++ --version returns g++ (Raspbian 10.2.1-6+rpi1) 10.2.1 20210110
and in my Makefile I specified:
CXXFLAGS := -std=c++17 -Wall.
g++ -x c++ -std=c++17 -dM -E - </dev/null | less lists the value for #define __cplusplus 201703L
So I quite don't understand, why the __cplusplus value is still at the value for c++14.
Is there a way to update/change/set this macro?
Edit: My Makefile
SOURCES := $(shell find ./src -name '*.cpp')
CXXFLAGS := -std=c++17 -Wall
default:
$(CXX) $(CXXFLAGS) -O3 -pthread -o main $(SOURCES) -lpigpio -lrt
.PHONY: clean
clean:
rm main
Output, when I run make
g++ -std=c++17 -Wall -O3 -pthread -o main <all the cpp files here> -lpigpio -lrt

Related

How to correctly setup a make file for a project?

Vulkan SDK hosts a C++ header-only C-wrapped library. Problem is, it is really a heavy header, so it wastes a lot of compilation time.
So I looked into using a make file for my Vulkan project, which I never did before. I decided to programatically generate all the dependencies. Probably I messed up this part as well, making it too difficult to understand.
It does kind of work, probably there is an easier way to do the same thing(s).
Here comes the part I can't really work out with:
I generated all the .o (object) files for my project along with the .gch (precompiled headers)
Then I did the same for the vulkan.hpp and the glfw3.h. (Remember, that's where most of my compilation time is going into).
... And here is where I have several problems about this procedure:
Can I, somehow, force the g++ compiler to use .gch files? The combination of -I, -include doesn't seem to work at all and I cannot even debug what is going on with -H/-M/-MM because i have no output whatsoever from this commands.
I am using MSYS2 MINGW_64 release, if it makes a difference.
I'd be glad if someone could give me a tip or two about make files and, in particular, if there is something I completely misunderstood about the compilation process.
# Methods
define uniq =
$(eval seen :=)
$(foreach _,$1,$(if $(filter $_,${seen}),,$(eval seen += $_)))
${seen}
endef
# Compilation flags
_COMPILER := g++ -std=c++17
_FLAGS_WARNING := -Wall -Wextra -Wshadow
_FLAGS_COMPILE := -g -O0
_FLAGS_VULKAN := -lglfw3 -lvulkan
# Custom Flags
_FLAGS_DEBUG := -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0
# Output
_OUTPUT_NAME := test
# Directories
_TMP_DIR := _tmp
_O_DIR := ${_TMP_DIR}\.o
_GCH_DIR := ${_TMP_DIR}\.gch
_SOURCE_DIR := src
_BUILD_DIR := build
_DEBUG_DIR := ${_BUILD_DIR}\debug
_RELEASE_DIR := ${_BUILD_DIR}\release
# Files
_VULKAN_HPP := C:/VulkanSDK/1.2.148.1/Include/vulkan/vulkan.hpp
_GLFW_HPP := C:/msys64/mingw64/include/GLFW/glfw3.h
# Grouping Files
# .cpp & .o
_CPP_LIST := ${wildcard ${_SOURCE_DIR}/*.cpp ${_SOURCE_DIR}/*/*.cpp}
_CPP_LIST_NAME := ${notdir ${_CPP_LIST}}
_O_LIST := ${addprefix ${_O_DIR}/, ${patsubst %.cpp, %.o, ${_CPP_LIST_NAME}}}
# .hpp & .gch
_HPP_LIST := ${wildcard ${_SOURCE_DIR}/*.hpp ${_SOURCE_DIR}/*/*.hpp} ${_VULKAN_HPP}
_HPP_LIST_NAME := ${notdir ${_HPP_LIST}}
_GCH_LIST := ${addprefix ${_GCH_DIR}/, ${patsubst %.hpp, %.gch, ${_HPP_LIST_NAME}}}
# .h & .gch
_H_LIST := ${_GLFW_HPP}
_H_LIST_NAME := ${notdir ${_H_LIST}}
_C_GCH_LIST := ${addprefix ${_GCH_DIR}/, ${patsubst %.h, %.gch, ${_H_LIST_NAME}}}
_COMPILATION_BUNDLE_CPP = ${_FLAGS_WARNING} ${_FLAGS_COMPILE} ${_FLAGS_VULKAN} ${_FLAGS_DEBUG} -I ${_GCH_DIR}
_COMPILATION_BUNDLE_HPP = ${_FLAGS_COMPILE} -x c++-header ${_FLAGS_DEBUG} -I ${_GCH_DIR}
${_DEBUG_DIR}/${_OUTPUT_NAME}: ${_GCH_LIST} ${_C_GCH_LIST} ${_O_LIST}
${_COMPILER} ${_COMPILATION_BUNDLE_CPP} ${_O_LIST} ${addprefix -include , ${_GCH_LIST}} ${addprefix -include , ${_C_GCH_LIST}} -o $#
vpath %.cpp $(call uniq, ${dir ${_CPP_LIST}})
${_O_DIR}/%.o: %.cpp
${_COMPILER} ${_COMPILATION_BUNDLE_CPP} -c $< -o $#
vpath %.hpp $(call uniq, ${dir ${_HPP_LIST}})
${_GCH_DIR}/%.gch: %.hpp
${_COMPILER} ${_COMPILATION_BUNDLE_HPP} $< -o $#
vpath %.h $(call uniq, ${dir ${_H_LIST}})
${_GCH_DIR}/%.gch: %.h
${_COMPILER} ${_COMPILATION_BUNDLE_HPP} $< -o $#
The execution on a clean project (thus easier to follow along):
g++ -std=c++17 -g -O0 -x c++-header -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch src/helper/helper.hpp -o _tmp\.gch/helper.gch
g++ -std=c++17 -g -O0 -x c++-header -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch src/renderer/renderer.hpp -o _tmp\.gch/renderer.gch
g++ -std=c++17 -g -O0 -x c++-header -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch C:/VulkanSDK/1.2.148.1/Include/vulkan/vulkan.hpp -o _tmp\.gch/vulkan.gch
g++ -std=c++17 -g -O0 -x c++-header -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch C:/msys64/mingw64/include/GLFW/glfw3.h -o _tmp\.gch/glfw3.gch
g++ -std=c++17 -Wall -Wextra -Wshadow -g -O0 -lglfw3 -lvulkan -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch -c src/main.cpp -o _tmp\.o/main.o
g++ -std=c++17 -Wall -Wextra -Wshadow -g -O0 -lglfw3 -lvulkan -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch -c src/helper/helper.cpp -o _tmp\.o/helper.o
g++ -std=c++17 -Wall -Wextra -Wshadow -g -O0 -lglfw3 -lvulkan -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch -c src/renderer/renderer.cpp -o _tmp\.o/renderer.o
g++ -std=c++17 -Wall -Wextra -Wshadow -g -O0 -lglfw3 -lvulkan -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch _tmp\.o/main.o _tmp\.o/helper.o _tmp\.o/renderer.o -include _tmp\.gch/helper.gch -include _tmp\.gch/renderer.gch -include _tmp\.gch/vulkan.gch -include _tmp\.gch/glfw3.gch -o build\debug/test
Using pre-compiled headers is actually fairly straight forward. It might be easiest to break it down into manual steps. You can even retro fit to an existing project pretty easily. The steps could be:
Create a PCH file including a bunch of std libs or other headers you want to pre-compile. Note: Compile your PCH with the same flags as your other c++ code is compiled with, otherwise it may not work.
Add the include flags for the PCH in your makefile... and that is basically it.
So lets try a practical example:
Start with a source file, src1.cpp and compile it: g++ -I. <other flags> src1.cpp -o src1.o
Create your pch file, call it pch.hpp (or whatever)
Compile your PCH file: g++ -I. <other flags> pch.hpp (same flags as the previous compile). This generates the pch.hpp.gch file.
Now you can use your PCH file in your original compile line: g++ -I. <other flags> src1.cpp -o src1.o -Winvalid-pch -include pch.hpp
Couple of things to note:
If you use -Winvalid-pch warning flag this usually gives you enough information to figure out why the pch is not used (like its missing, bad path, bad options etc...).
Use -include pch.hpp not -include pch.hpp.gch since g++ will figure that out. You can see that retro fitting it is easy - since you just append the include flags to your compiler lines.
If your .gch file is not generated then the code should still compile using the pch.hpp header directly...

Error while compiling a project which includes CPLEX tool

I am working on the project which has to include the CPLEX tool at some point.
More in detail, I have the following classes implemented
(i.e. the corresponding files): Random.cpp, Instance.cpp, Timer.cpp. Solution.cpp which are included into Hybrid_ea.cpp which also have to include cplex library.
Finally, the project has been executed by running Algorithm.cpp (the main() function defined here).
I want to run the project on Linux platform, creating Makefile which looks like:
TARGET = Algorithm
CXXFLAGS = -ansi -O3
GENOBJS = Random.o
#CPLOBJS = Timer.o Random.o Instance.o Hybrid_ea.o
GREOBJS = Timer.o Random.o Instance.o Solution.o Hybrid_ea.o
SYSTEM = x86-64_linux
LIBFORMAT = static_pic
CPLEXDIR = /home/root/Desktop/projects/software/cplex-12.5/cplex
CONCERTDIR = /home/root/Desktop/projects/software/cplex-12.5/concert
CCC = g++
CCOPT = -m64 -O -fPIC -fexceptions -DNDEBUG -DIL_STD -std=c++11 -fpermissive -w
CPLEXBINDIR = $(CPLEXDIR)/bin/$(BINDIST)
CPLEXLIBDIR = $(CPLEXDIR)/lib/$(SYSTEM)/$(LIBFORMAT)
CONCERTLIBDIR = $(CONCERTDIR)/lib/$(SYSTEM)/$(LIBFORMAT)
CCLNFLAGS = -L$(CPLEXLIBDIR) -lilocplex -lcplex -L$(CONCERTLIBDIR) -lconcert -lm -pthread
CLNFLAGS = -L$(CPLEXLIBDIR) -lcplex -lm -pthread
CONCERTINCDIR = $(CONCERTDIR)/include
CPLEXINCDIR = $(CPLEXDIR)/include
CCFLAGS = $(CCOPT) -I$(CPLEXINCDIR) -I$(CONCERTINCDIR)
all: ${TARGET}
Algorithm: Algorithm.o $(GREOBJS)
$(CCC) $(CCFLAGS) Algorithm.o $(GREOBJS) -o Algorithm $(CCLNFLAGS)
Algorithm.o: Algorithm.cpp
$(CCC) -c $(CCFLAGS) Algorithm.cpp -o Algorithm.o
clean:
#rm -f *~ *.o ${TARGET} core
The linking process is somehow wrong. I checked, my CPLEX version is the right one since the others, simpler projects can be executed;
The full output given when trying to compile the project:
g++ -c -m64 -O -fPIC -fexceptions -DNDEBUG -DIL_STD -std=c++11 -fpermissive -w -I/home/root/Desktop/projects/LCAPS_software/cplex-12.5/cplex/include -I/home/root/Desktop/projects/LCAPS_software/cplex-12.5/concert/include Algorithm.cpp -o Algorithm.o
g++ -ansi -O3 -c -o Timer.o Timer.cc
g++ -ansi -O3 -c -o Random.o Random.cc
g++ -ansi -O3 -c -o Instance.o Instance.cpp
g++ -ansi -O3 -c -o Solution.o Solution.cpp
g++ -ansi -O3 -c -o hybrid_ea.o hybrid_ea.cpp
In file included from hybrid_ea.cpp:22:0:
hybrid_ea.h:39:10: fatal error: ilcplex/ilocplex.h: No such file or directory
#include <ilcplex/ilocplex.h>
^~~~~~~~~~~~~~~~~~~~
compilation terminated.
<builtin>: recipe for target 'hybrid_ea.o' failed
make: *** [hybrid_ea.o] Error 1
Any help would be appreciated.
Only the file Algorithm.cpp is compiled with appropriate options for finding the CPLEX include files:
-I/home/root/Desktop/projects/LCAPS_software/cplex-12.5/cplex/include
-I/home/root/Desktop/projects/LCAPS_software/cplex-12.5/concert/include
As hybrid_ea.h also tries to include some CPLEX header files, the compilation of hybrid_ea.cpp should also have the options above.
If the makefile that you posted in your question is complete, then I suspect that the issue is the following: you didn't define a specific command to compile any .cc or .cpp file, except for Algorithm.cpp. Therefore, all other files are compiled using a default command g++ -ansi -O3 -c -o [file].o [file].cpp. And this default command doesn't have the include directives for the location of the CPLEX libraries.
As explained in ftp://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_10.html, these files are compiled using make's implicit rules. The implicit rule for C++ files is to use $(CXX) -c $(CPPFLAGS) $(CXXFLAGS). Notice how this rule uses CPPFLAGS and CXXFLAGS rather than the variable CCFLAGS that you defined at the end of your makefile to include the proper include directives.
So changing the end of your makefile to the following should work:
CPPFLAGS = $(CCOPT) -I$(CPLEXINCDIR) -I$(CONCERTINCDIR)
all: ${TARGET}
Algorithm: Algorithm.o $(GREOBJS)
$(CCC) $(CCFLAGS) Algorithm.o $(GREOBJS) -o Algorithm $(CCLNFLAGS)
clean:
#rm -f *~ *.o ${TARGET} core
Once you define the variable CPPFLAGS, it will be used automatically to compile any .cpp file that you have in your project.

Precompiled headers not used by GCC when building with a makefile

I'm trying to use precompiled headers with GCC to speed up the compilation process. If I launch the compilation directly from the command line the precompiled headers are used, but if I try to organize the compilation using a makefile they are not.
More specifically, I try to compile with GCC 8.1.0 a file main.cpp using a precompiled header lib.hpp.gch for the file lib.hpp included as first token in main.cpp.
lib.hpp is precompiled with
$ g++ -O2 -H -Wall -std=c++17 -c lib.hpp
main.cpp is then compiled with
$ g++ -O2 -H -Wall -std=c++17 -c main.cpp -o main.o
! lib.hpp.gch
...
and I can see from the "!" that the precompiled lib.hpp.gch is actually used.
If I write a makefile for this
CXX = g++
CXXFLAGS = -O2 -H -Wall -std=c++17
main.o: \
main.cpp \
main.hpp \
lib.hpp
$(CXX) $(CXXFLAGS) \
-c main.cpp \
-o main.o
and then use make, I would expect the same usage of the precompiled header
but instead it fails, as can be seen from the "x":
$ make
g++ -O2 -H -Wall -std=c++17 \
-c main.cpp \
-o main.o
x lib.hpp.gch
...
This is very strange, because the command issued by make seems exactly the same as the one that I used manually before.
I've also made measurement of timings and can confirm that the compilation via make is definitely slower than the manual one, confirming that the precompiled header is not used.
What's wrong in the makefile?
You're not including the PCH anywhere in your make command. Try this:
CXX = g++
CXXFLAGS = -O2 -H -Wall -std=c++17
OBJ = main.o #more objects here eventually I would think!
PCH_SRC = lib.hpp
PCH_HEADERS = headersthataregoinginyourpch.hpp andanother.hpp
PCH_OUT = lib.hpp.gch
main: $(OBJ)
$(CXX) $(CXXFLAGS) -o $# $^
# Compiles your PCH
$(PCH_OUT): $(PCH_SRC) $(PCH_HEADERS)
$(CXX) $(CXXFLAGS) -o $# $<
# the -include flag instructs the compiler to act as if lib.hpp
# were the first header in every source file
%.o: %.cpp $(PCH_OUT)
$(CXX) $(CXXFLAGS) -include $(PCH_SRC) -c -o $# $<
First the PCH gets compiled. Then all cpp commands get compiled with -include lib.hpp this guarantees that lib.hpp.gch will always be searched first before lib.hpp

Error while compiling with a makefile and c++11

I currently have a problem with a C++ project I have. I need some tools provided with C++11 but when I want to compile with a Makefile, I have the 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.
Here is my Makefile :
.PHONY: clean, mrproper
# var
CXX = g++
EXEC = tablut
LDFLAGS =
CXXFLAGS = -std=c++11 -Wall -Wextra
SRC= partie.cpp pawn.cpp playground.cpp
OBJ= $(SRC:.c=.o)
# commands
all: $(EXEC)
tablut: $(OBJ)
$(CXX) -o tablut $(OBJ) $(LDFLAGS)
%.o: %.cpp
$(CXX) -o $# -c $< $(CXXFLAGS)
clean:
rm -rf *.o
mrproper: clean
rm -rf tablut
The funny thing is that my code compile if I enter the command g++ -c std=c++11 ...
What did I do wrong ?
NB : I tried with the flags -std=c++11, -std=c++0x and -std=gnu++11
You have the rule:
OBJ= $(SRC:.c=.o)
Which means that $(OBJ) ends up being:
OBJ= partie.cpp pawn.cpp playground.cpp
Because none of them match .c. You probably mean to write:
OBJ= $(SRC:.cpp=.o)
With that fix, running make produces:
$ make
g++ -o partie.o -c partie.cpp -std=c++11 -Wall -Wextra
g++ -o pawn.o -c pawn.cpp -std=c++11 -Wall -Wextra
g++ -o playground.o -c playground.cpp -std=c++11 -Wall -Wextra
g++ -o tablut partie.o pawn.o playground.o
Which is probably what you wanted.

How to add compile flag -g to a make file?

I got a C++ program for which someone else made a make file. I want to compile the program with flag -g, but I don't know where to add it. Below is the make file.
CC = g++
LOADLIBES = -lm
CFLAGS = -Wall -O2
SRC1 = Agent.cpp Breeder.cpp CandidateSolution.cpp \
Cupid.cpp FateAgent.cpp Grid.cpp Reaper.cpp \
fitness.cpp
SRC2 = main.cpp
SRC = $(SRC1) $(SRC2)
OBJS = $(SRC1:.cpp = .o)
AUX = $(SRC1:.c = .h)
main: $(OBJS)
# $(CC) $(CFLAGS) -o $(SRC) $(AUX)
.PHONY: clean
clean:
rm -f *.o main
Where should I add that I want to use -g?
$(CC) is used for compiling C programs. $(CXX) is used for compiling C++ programs. Similarly $(CFLAGS) is used for C programs, $(CXXFLAGS) is used for compiling C++.
Change the first few lines to this:
#CC = g++
LOADLIBES = -lm
CXXFLAGS = -Wall -O2 -g
(But see others' notes about incompatibilities between -O2 and -g.)
Get rid of the spaces inside the parentheses in this line:
OBJS = $(SRC1:.cpp=.o)
Change the main lines to this:
main: $(OBJS) $(SRC2)
# Built by implicit rules
The resulting makefile should look like this:
#CC = g++
LOADLIBES = -lm
CXXFLAGS = -Wall -O2 -g
SRC1 = Agent.cpp Breeder.cpp CandidateSolution.cpp \
Cupid.cpp FateAgent.cpp Grid.cpp Reaper.cpp \
fitness.cpp
SRC2 = main.cpp
SRC = $(SRC1) $(SRC2)
OBJS = $(SRC1:.cpp=.o)
AUX = $(SRC1:.c=.h)
main: $(OBJS) $(SRC2)
# Built by implicit rules
.PHONY: clean
clean:
rm -f *.o main
and the output should look like this:
$ make
g++ -Wall -O2 -g -c -o Agent.o Agent.cpp
g++ -Wall -O2 -g -c -o Breeder.o Breeder.cpp
g++ -Wall -O2 -g -c -o CandidateSolution.o CandidateSolution.cpp
g++ -Wall -O2 -g -c -o Cupid.o Cupid.cpp
g++ -Wall -O2 -g -c -o FateAgent.o FateAgent.cpp
g++ -Wall -O2 -g -c -o Grid.o Grid.cpp
g++ -Wall -O2 -g -c -o Reaper.o Reaper.cpp
g++ -Wall -O2 -g -c -o fitness.o fitness.cpp
g++ -Wall -O2 -g main.cpp Agent.o Breeder.o CandidateSolution.o Cupid.o FateAgent.o Grid.o Reaper.o fitness.o -lm -o main
For completeness, this is the version of make I am using on Ubuntu 10.04:
$ make -v
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for i486-pc-linux-gnu
You need to uncomment the line:
# $(CC) $(CFLAGS) -o $(SRC) $(AUX)
(remove the hash sigh):
$(CC) $(CFLAGS) -o $(SRC) $(AUX)
And change
CFLAGS = -Wall -O2
to
CFLAGS = -Wall -O2 -g
But you may find debugging easier if you disable optimization by removing -O2:
CFLAGS = -Wall -g