How to activate c++11 support on MinGW using CMake? - c++

I've installed latest version of MinGW/MSYS environment. Now I try to activat c++11 standard support. I've added to my cmake script:
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=gnu++0x")
If I try to build a simple test. I got the following compile failure:
error: 'shared_ptr' is not a member of 'std'
It seems to me that c++11 support is not set. If I remove the std::shared_ptr declaration from my code and try to compile some code of the chrono library it works. This confuses me.
Why some c++11 libraries are supported but core elements like shared_ptr fails?
Do I need to do something extra to enable smart pointers or they are just not there?

You can/should (also) use -std=c++0x so as to not enable g++ extension.
Make sure to #include <memory>.

Related

Inducing minimal C++ standard version in CMake

CMake has a nice framework for setting and defining an explicit value for the C++ standard, typically:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
However this does not clearly fit my needs, I'd rather states that I need at least c++11. I thought that I could just do instead:
$ cat CMakeLists.txt
cmake_minimum_required(VERSION 3.7)
project(p CXX)
set(CMAKE_CXX_EXTENSIONS OFF)
add_executable(foobar foobar.cxx)
target_compile_features(foobar PRIVATE cxx_nullptr)
where
$ cat foobar.cxx
int main()
{
char * p = nullptr;
}
However again in this case this forces me to use -std=c++11 eventhough by default g++ 6.3.0 default to -std=c++14 (technically -std=gnu++14):
$ c++ -dumpversion
6.3.0
leads to:
$ make VERBOSE=1
[...]
make[2]: Entering directory '/tmp/p'
[ 50%] Building CXX object CMakeFiles/foobar.dir/foobar.cxx.o
/usr/bin/c++ -std=c++11 -o CMakeFiles/foobar.dir/foobar.cxx.o -c /tmp/p/foobar.cxx
[100%] Linking CXX executable foobar
/usr/bin/cmake -E cmake_link_script CMakeFiles/foobar.dir/link.txt --verbose=1
Is there a way to say: "Build this project with at least C++11 Standard" in CMake ?
Typically for a project built using g++ 4.8.5 it would add -std=c++11 but for a project build with g++ 6.3.0 it would leave the default (implicit) -std=c++14
Update: The following is out of the scope for the question, but since I received a lengthy answer from #ComicSansMS, I feel I need to clarify the need for this.
I am working with my Debian Maintainer hat on, and I was convinced a couple of months back that setting an explicit C++ standard version in cmake within a project was the right way to do, hence my proposal:
Mandates explicit -std=c++XY for c++ projects
However there are two things that get mixed here:
Defining a c++ standard version for the interface of the library being built
Defining a c++ standard version for the implementation detail of the library being built.
From a Debian Maintainer perspective setting explicitly a C++ standard version makes it hard to rebuild a portion of the package archive when a library SONAME is being updated. Let's consider the case where GDCM is using the Poppler library. While the implementation details of GDCM are written using C++98, the fact that Poppler library has been build using the default (implicit) standard version of gcc-6 makes it suddenly a compilation failure for GDCM, since an explicit -std=c++98 is being passed.
So while for an implementation prospective, setting an explicit c++ standard version make sense (obviously!), it is a little less clear for an interface prospective. The vast majority of open-source projects do not define multiple c++ ABI (std::string[98] AND std::string[11]) and assume a single version will be used to ship the binary. In this case it makes it important for a c++ package to be build using the default (implicit) version of gcc (at least when uploaded as official Debian package).
You can always test for compilers support of the specific standard flags yourself.
First check for -std=c++14, and if it doesn't exist then check for -std=c++11, and if that doesn't work then error out.
Flags can easily be checked with the CheckCXXCompilerFlag module.
These days you should probably start with -std=c++17 though. You might also want to add checks for the pre-release standard versions like c++1z (for C++17) and c++1y (for C++14).
Start with the highest version, then work your way downward the minimum required version. Stop when it doesn't fail.
For newer versions of CMake you could use target_compile_features to specify features that the target compiler should be able to provide for.
This way, if (for example) your project uses auto type deduction you could tell CMake that the compiler need to suport the cxx_auto_type feature. Then CMake will make sure that the compiler can indeed support C++11 and the auto type deduction.
Is there a way to say: "Build this project with at least C++11 Standard" in CMake ?
No, and this is probably not a reasonable thing to request.
It does not make any sense to request a standards version that is newer than the code you are trying to build, as your code will not make any use of those features anyway.
The other big problem here is that newer standards are not strict supersets of older standards. In recent versions, the C++ standard has been quite keen on deprecating and even removing features that have outlived its usefulness.
What you have is a specific piece of code that expects a specific set of language features to be available. And that is exactly what you should tell the buildsystem. If your code expects the C++11 features to be available, set CMAKE_CXX_STANDARD to 11 and be done with it. It will guarantee that all of the required features are available and safeguard you (within reasonable bounds) against any future deprecations.
Now, there is one scenario where specifying an exact standard is not enough: You might have different implementations in your code and then want to switch between implementations depending on the available compiler capabilities. That is, your code might be C++14 aware and you want it to compile in C++14 mode if available, but still leave the C++11 mode as a fallback.
This is exactly the default behaviour of CMAKE_CXX_STANDARD:
This means that using:
set_property(TARGET tgt PROPERTY CXX_STANDARD 11)
with a compiler
which does not support -std=gnu++11 or an equivalent flag will not
result in an error or warning, but will instead add the -std=gnu++98
flag if supported. This “decay” behavior may be controlled with the
CXX_STANDARD_REQUIRED target property.
So in a nutshell, always specify the latest standard that your code is aware of, but not newer.

GNU C++: unique_ptr.h no such file or directory

I am cross compiling some code from Windows on Linux machine (Kubuntu 16.05),g++ 5.4.0 64bit. Using Code Lite IDE as a dev env.
I have got several lines of code where I init unique pointer with
std::make_unique
The compiler complains with the error:
error: 'make_unique' is not a member of 'std'
I tried to add <memory> as well as <unique_ptr.h> to the header. Then the compiler complains that it can't find <unique_ptr.h> file. Interestingly,when I click to open the file from within the editor it is found and opened. The file is located in /usr/include/c++/5/bits/unique_ptr.h
I made sure that the compiler version that builds the code is indeed 5.4, so I don't understand why it doesn't support unique_ptr out of the box.I make sure to enable C++11 and C++14 flags:
-g;-O0;-std=c++14;-std=c++11;-Wall
Also, in the includes I add /user/include
What am I missing here? Do I have to include in the project the /usr/include/c++/5/bits/ directory explicitly?
Try these flags:
-g -O0 -std=c++14 -Wall. Note that semicolon is not needed for separating flags.
Compiler will take the latest entry of -std so you are effectively compiling with C++11 but not C++14.
As you can see HERE enabling -std=c++11 after a newer standard disables the first declared standard. Enabling only C++14 is enough.
C++11 introduced std::unique_ptr, but there was no std::make_unique (this broke the "symmetry" of shared_ptr/make_shared).
They fixed that in C++14, adding std::make_unique.
So, if you compile your code in C++11 mode, you can't use std::make_unique.
As others already pointed out, you need to set the latest C++ standard with the -std compiler option; in this case, it's -std=c++14 to enable also std::make_unique.

Passing CXXFLAGS to make has no effect

I am trying to compile some software with make on Ubuntu 16.04. However, it fails with the error:
/usr/include/c++/5/bits/c++0x_warning.h:32:2: error: #error This file
requires compiler and library support for the ISO C++ 2011 standard. This
support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
A quick websearch shows that compiler options can be passed to make either by
export CXXFLAGS="-std=c++11"
or
make CXXFLAGS="-std=c++11"
None of those options have worked. I have also tried with deleting everything in the build folder and starting from scratch. The error still persists.
How can I pass CXXFLAGS to make ?

how to define -std=c++11 as default in g++

I'm using some features in my C++ programs that I need -std=c++11 option set in g++
Is it possible set this option as a default and don't be necessary use this all time I compile it?
Or how to set this in Makefile.
Yes, you typically set this in a Makefile:
CXXFLAGS=-std=c++11
One layer above you can also detect a suitable compiler via autoconf, cmake or whichever other meta-buildtool you might deploy.
You of course play games as define g++11 as g++ -std=c++11 but such set-ups are not portable.
g++-6.* will default to c++14 so at some this switch will be implicit. But it might take a really long time for all those RHEL and CentOS boxen with g++-4.4.* to disappear. Those may not even handle your current project...
Yes, upgrade to GCC 6.1:
The C++ frontend now defaults to C++14 standard instead of C++98
From https://gcc.gnu.org/ml/gcc/2016-04/msg00244.html
You can have a makefile do this as follows (this is a simple version with no variables).
out: source.cpp
g++ -std=c++11 source.cpp -o out
Use your build system of choice. Be that make, SCons, CMake, qmake or something else, and set the required option. Should take all of 30 seconds and you're done.
Or, upgrade your compiler to a version that uses C++11 by default.

Including C++11 header file with in C++ source file

I'm trying to figure out how to make use of C++11 headers in my C++ project. Specifically I'm trying to use FakeIt mocking framework (https://github.com/eranpeer/FakeIt) for unit testing my legacy application which is built with C++.
The FakeIt page says it is supported for both C++11 & C++ projects but when I build my application with the header from the library it complains about not able to resolve the C++11 symbols.
gtest/include/fakeit.hpp:28:25: error: unordered_set: No such file or directory
gtest/include/fakeit.hpp:29:17: error: tuple: No such file or directory
gtest/include/fakeit.hpp:32:18: error: atomic: No such file or directory
I'm new to C++, so would appreciate any pointers here thanks.
C++11 support is often not enabled by default. Compile your program with the -std=c++11 argument. For example:
g++ -std=c++11 -I/path/to/libray file.cpp
Also, do make sure your compiler actually supports C++11, it should complain if it doesn't understand -std=c++11. Here is a list of C++11 features supported by various g++ versions.