I'm trying to compile C++ 11 code on a server running Ubuntu from my home computer using Putty. I'm using a makefile to compile and include shared pointers in the code, but it gives me this error:
/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.
However, when I try to compile the code from the server hosting the files (when I'm at university), it compiles perfectly. Here is my makefile:
all: huffmandriver.o huffmannode.o huffmantree.o
g++ -o huffencode huffmandriver.o huffmannode.o huffmantree.o -std=c++11
huffmannode.o: huffmannode.cpp huffmannode.h
g++ -c huffmannode.cpp -std=c++11
huffmantree.o: huffmantree.cpp huffmantree.h
g++ -c huffmantree.cpp -std=c++11
clean:
#rm -f *.o
#rm -f huffencode
I have also tried adding the flags -stdlib=libc++ -std=gnu++, but that does not work either. Here is a snippet of the code where the error is being thrown:
// Huffman Node class header
#ifndef HUFFMANNODE_H
#define HUFFMANNODE_H
#include <memory>
#include <string>
namespace YNGMAT005 {
class HuffmanNode {
private:
std::shared_ptr<HuffmanNode> left;
std::shared_ptr<HuffmanNode> right;
std::shared_ptr<HuffmanNode> parent;
std::string letter;
int frequency;
public:
HuffmanNode(std::string l, int freq);
~HuffmanNode();
std::shared_ptr<HuffmanNode> & get_left();
std::shared_ptr<HuffmanNode> & get_right();
std::shared_ptr<HuffmanNode> & get_parent();
void set_left(std::shared_ptr<HuffmanNode> & l);
void set_right(std::shared_ptr<HuffmanNode> & r);
bool has_left();
bool has_right();
void set_parent(std::shared_ptr<HuffmanNode> & p);
bool has_parent();
std::string get_letter();
int get_frequency();
};
}
#endif
Many thanks!
I don't know why you're seeing different behaviour from a different login context (check which g++; g++ --version on both and see if your .profile, .bash_profile or .bashrc does anything weird based on ssh-vs-local login).
Nonetheless, you should be able to getting it working in both settings by providing -std=c++11 to the default rule for .cpp to .o thus:
CXXFLAGS = -std=c++11
Additionally, (shamelessly stealing from Daniel's answer) you can remove the explicit rules for the other .cpp files, just leaving the .h dependencies:
huffmannode.o: huffmannode.h
huffmantree.o: huffmantree.h
These will then automatically pick up the CXXFLAGS setting.
You might need to compile huffmandriver.cpp with -std=c++11 as well. Currently, you have rules for compiling huffmannode.cpp and huffmantree.cpp with the -std=c++11 compiler option, but not huffmandriver.cpp.
You can create a custom pattern rule for making .o files from .cpp files and specifying the header dependencies like so:
huffmannode.o: huffmannode.h
huffmantree.o: huffmantree.h
%.o: %.cpp
g++ -std=c++11 -c -march=native -o $# $<
An alternative approach is to define the CXXFLAGS implicit variable to -std=c++11. This way, the built-in rule ‘$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c’ for compiling C++ source files will use the -std=c++11 compiler option.
Related
I'm trying to compile a C++ test file, which is supposed to compile from files that are in adjacent folders in the project file structure. I have the following:
Project/TestFiles/makefile
Project/TestFiles/test.cpp
Project/OtherFiles/my_stuff.cpp
Project/OtherFiles/my_stuff.hpp
For the compile, I'm trying to leave the my_stuff.o file in the OtherFiles folder, so if I have other makefiles, they dont have to recompile separate versions each.
My makefile looks as follows:
CC = g++
CFLAGS = -std=c++11 -Wall -Wcomment -Werror -Wextra -Weffc++ -pedantic
run: test.out
test.out: test.cpp catchMain.cpp ../OtherFiles/my_stuff.o
$(CC) $(CFLAGS) $^ -o $#
my_stuff.o: ../OtherFiles/my_stuff.cpp ../OtherFiles/my_stuff.hpp
$(CC) $(CFLAGS) -c $<
I thought for a while that this setup worked, but then I started getting some weird problems and couldn't compile. For instance, having a static const map produced error: expected ';' after top level declarator. At first, Internet seemed to indicate that Mac compilers sometimes aren't able to compile static const maps with member initialisation lists (which it also complained about, if I removed the static const part). However, when I commented out everything to do with the std::map (leaving the makefile as described above) OR placed all files in the same folder (rewriting both the makefile as well as the #includes in test.cpp), everything is ok, but I'd like to use both std::maps AND the chosen file structure. Oh, and removing the extra warning flags doesn't work either.
Any ideas how I could do that?
Edit
my_stuff.hpp:
namespace my_stuff {
void function();
}
my_stuff.cpp:
#include "my_stuff.hpp"
#include <map>
namespace my_stuff {
static const std::map<char, char> the_map {{'a', 'b'}, {'c', 'd'}};
void my_function() {
// map stuff
}
}
The test part is both a vanilla catchMain.cpp:
#define CATCH_CONFIG_MAIN
#include "../../Catch2/catch.hpp" //which is outside the project specifics
and the actual tests, my_tests.cpp:
#include "../../Catch2/catch.hpp"
#include "../OtherFiles/my_stuff.hpp"
#include <map>
SCENARIO("", "") {
GIVEN("") {
WHEN("") {
THEN("") {
my_function();
// Other stuff
}
}
}
}
As #S.M. pointed out, you must change the my_stuff.o rule, but you must change the recipe as well as the target, so that it will actually build the thing you want:
../OtherFiles/my_stuff.o: ../OtherFiles/my_stuff.cpp ../OtherFiles/my_stuff.hpp
$(CC) $(CFLAGS) -c $< -o $#
More generally, you must understand the language before you attempt to manipulate it. Swapping patches in and out to see what works is a very inefficient way to write code.
I wanted to use the unordered_map STL in c++, but as soon as I use the header, it gives me this error:
This file requires support for the compiler and library support for the ISO C++11 standard. This support is currently experimental and must be enabled with -std=c++11 or -std=gnu++11 compiler options.
I am attaching my code that I wanted to run, below. (Any inputs on the code are welcome too. thanks)
#include <iostream>
#include <unordered_map>
using namespace std;
class Node
{
public:
string a,b;
Node()
{
a="hello";
b="world";
}
};
int main ()
{
unordered_map<Node> mymap;
Node mynode;
mymap.insert(mynode);
std::cout << "myrecipe contains:" << std::endl;
for (auto& x: mymap)
std::cout << x.a << ": " << x.b << std::endl;
}
Edit: I got it to work by using the following commmand: g++ -std=c++11 [filename].cpp
Thanks for the help.
The main answer to your question: specify -std=c++11 in your compile command.
Precisely which C++11 features are available will depend on your version of GCC. Here are two links that might help:
https://gcc.gnu.org/projects/cxx0x.html
http://wiki.apache.org/stdcxx/C++0xCompilerSupport
First Option:
You can remove to error with -std=c++11 in compile time.
g++ -o binary yourFile.cpp -std=c++11
Second Option to integrate the development with c++11:
You can use a makefile with the CXXFLAGS set with -std=c++11 A makefile is a simple text file with instructions about how to compile your program. Create a new file named Makefile (with a capital M). To automatically compile your code just type the make command in a terminal. You may have to install make.
Here is the code :
CXX=clang++
CXXFLAGS=-g -std=c++11 -Wall -pedantic
BIN=prog
SRC=$(wildcard *.cpp)
OBJ=$(SRC:%.cpp=%.o)
all: $(OBJ)
$(CXX) -o $(BIN) $^
%.o: %.c
$(CXX) $# -c $<
clean:
rm -f *.o
rm $(BIN)
It assumes that all the .cpp files are in the same directory as the makefile. But you can easily tweak your makefile to support a src, include and build directories.
compile with:
g++ -o binary source.cpp -std=c++11
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
I'm trying to write a class that needs to deallocate some memory, so I've defined a custom destructor. This is compiled as a shared library. However, when I try to compile a basic program to use that library, I'm getting the usual "undefined reference" error when a definition cannot be found. If I remove the destructor, this does not occur.
Here's a stripped-down example:
Header file:
#ifndef _SKYMAP_H_
#define _SKYMAP_H_
#include <vector>
#include "TCanvas.h"
class BL_Skymap {
public:
BL_Skymap();
~BL_Skymap();
protected:
TCanvas mCanvas;
};
#endif //_BENSLIBRARY_SKYMAP_H_
Source file:
\#include "BL_Skymap.h"
BL_Skymap::BL_Skymap()
{
}
BL_Skymap::~BL_Skymap()
{
}
Now the program I'm using is simply this:
\#include "BL_Skymap.h"
int main()
{
BL_Skymap map;
return(0);
}
Note that I'm using the ROOT analysis package (that's the TCanvas object). When I compile the small program above, I get the following errors (the Skymap class is compiled into libMyLibrary.so):
g++ test.cpp -o test -lMyLibrary `root-config --cflags --glibs`
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/libMyLibrary.so: undefined reference to 'TCanvas::~TCanvas()'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/libMyLibrary.so: undefined reference to 'TCanvas::TCanvas(bool)'
Please note that the root package gives a utility to generate the required compiler flags, which is the purpose of root-config --cflags --glibs above.
What am I missing here?
UPDATE: I've written a Makefile to perform the compilation of my library, which executes the following:
g++ -Wall -Wextra -ansi -pedantic --std=c++11 -Isrc -Ihdr -MM -MT 'obj/BL_Skymap.o' src/BL_Skymap.cpp -MF BL_Skymap.d `root-config --cflags --glibs`
g++ -Wall -Wextra -ansi -pedantic --std=c++11 -Isrc -Ihdr -fPIC -o obj/BL_Skymap.o -c src/BL_Skymap.cpp `root-config --cflags --glibs`
g++ -Wall -Wextra -ansi -pedantic --std=c++11 -shared obj/*.o -o libMyLibrary.so
UPDATE2: I found the problem - in the final step in the compilation above, I was forgetting to add the call to root-config and therefore libMyLibrary.so wasn't linking to the ROOT libraries like it should have.
As stated in an update to the original question, my problem was that I was using the relevant flags for the ROOT libraries when I was compiling the BL_Skymap.o object file, but not when I was linking the object file together to make the libMyLibrary.so file.
Adding the ROOT flags to this final step fixed the problem.
How can I get precompiled headers working with GCC?
I have had no luck in my attempts and I haven't seen many good examples for how to set it up. I've tried on Cygwin GCC 3.4.4 and using 4.0 on Ubuntu.
I have definitely had success. First, I used the following code:
#include <boost/xpressive/xpressive.hpp>
#include <iostream>
using namespace std;
using namespace boost::xpressive;
// A simple regular expression test
int main()
{
std::string hello("Hello, World!");
sregex rex = sregex::compile( "(\\w+) (\\w+)!" );
smatch what;
if( regex_match( hello, what, rex ) )
{
std::cout << what[0] << '\n'; // Whole match
std::cout << what[1] << '\n'; // First capture
std::cout << what[2] << '\n'; // Second capture
}
return 0;
}
This was just a Hello, World! program from Boost Xpressive. First, I compiled with the -H option in GCC. It showed an enormous list of headers that it used. Then, I took a look at the compile flags my IDE (Code::Blocks) was producing and saw something like this:
g++ -Wall -fexceptions -g -c main.cpp -o obj/Debug/main.o
So I wrote a command to compile the Xpressive.hpp file with the exact same flags:
sudo g++ -Wall -fexceptions -g /usr/local/include/boost/xpressive/xpressive.hpp
I compiled the original code again with the -H and got this output:
g++ -Wall -fexceptions -H -g -c main.cpp -o obj/Debug/main.o
! /usr/local/include/boost/xpressive/xpressive.hpp.gch
main.cpp
. /usr/include/c++/4.4/iostream
.. /usr/include/c++/4.4/x86_64-linux-gnu/bits/c++config.h
.. /usr/include/c++/4.4/ostream
.. /usr/include/c++/4.4/istream
main.cpp
The ! means that the compiler was able to use the precompiled header. An x means it was not able to use it. Using the appropriate compiler flags is crucial. I took off the -H and ran some speed tests. The precompiled header had an improvement from 14 seconds to 11 seconds. Not bad, but not great.
Note: Here's the example. I couldn't get it to work in the post.
BTW: I'm using the following g++:
g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Firstly, see the documentation here.
You compile headers just like any other file but you put the output inside a file with a suffix of .gch.
So for example if you precompile stdafx.h you will have a precompiled header that will be automatically searched for called stdafx.h.gch anytime you include stdafx.h
Example:
stdafx.h:
#include <string>
#include <stdio.h>
a.cpp:
#include "stdafx.h"
int main(int argc, char**argv)
{
std::string s = "Hi";
return 0;
}
Then compile as:
> g++ -c stdafx.h -o stdafx.h.gch
> g++ a.cpp
> ./a.out
Your compilation will work even if you remove stdafx.h after step 1.
The -x specifier for C++ precompiled headers is -x c++-header, not -x c++. Example usage of PCH follows.
pch.h:
// Put your common include files here: Boost, STL as well as your project's headers.
main.cpp:
#include "pch.h"
// Use the PCH here.
Generate the PCH like this:
$ g++ -x c++-header -o pch.h.gch -c pch.h
The pch.h.gch must be in the same directory as the pch.h in order to be used, so make sure that you execute the above command from the directory where pch.h is.
Call GCC the same way as if you call it for your source file, but with a header file.
E.g.,
g++ $(CPPFLAGS) test.h
This generates a file called test.h.gch.
Every time GCC searches for test.h, it looks first for test.h.gch and if it finds it it uses it automatically.
More information can be found under GCC Precompiled Headers.
I have managed to get precompiled headers working under gcc once in the past, and I recall having problems then as well. The thing to remember is that gcc will ignore the file (header.h.gch or similar) if certain conditions are not met, a list of which can be found on the gcc precompiled header documentation page.
Generally it's safest to have your build system compile the .gch file as a first step, with the same command line options and executable as the rest of your source. This ensures the file is up to date and that there are no subtle differences.
It's probably also a good idea to get it working with a contrived example first, just to remove the possibility that your problems are specific to source code in your project.
Make sure to -include your_header.h
This is how I precompiled and used bits/stdc++.h collection.
Code
#include <bits/stdc++.h>
Then I located the lib by compiling my file with -H and looking at output
g++ sol.cpp -H -O3 -pthread -lm -std=c++14 -o executable
where I saw
. /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h
So I made a new directory bits inside of current one and copied stdc++.h from there.
Then I ran
g++ bits/stdc++.h -O3 -std=c++14 -pthread
which generated bits/stdc++.gch
Normally I compiled my code via
g++ sol.cpp -O3 -pthread -lm -std=c++14 -o executable
, but I had to modify that to
g++ sol.cpp -include bits/stdc++.h -O3 -pthread -lm -std=c++14 -o executable
as it only resolved to .gch file instead of .h with -include bits/stdc++.h
That was key for me. Other thing to keep in mind is that you have to compile *.h header file with almost the same parameters as you compile your *.cpp. When I didn't include -O3 or -pthread it ignored the *.gch precompiled header.
To check if everything's correct you can measure time difference via comparing result of
time g++ sol.cpp ...
or run
g++ sol.cpp -H -O3 -pthread -lm -std=c++14 -o executable
again and look for header paths and if you now get ! before library path, for example
! ./bits/stdc++.h.gch
....
A subtle tip about the file extension that tripped me up, because I wasn't paying close enough attention: the .gch extension is added to the precompiled file's full name; it doesn't replace .h. If you get it wrong, the compiler won't find it and silently does not work.
precomp.h => precomp.h.gch
Not:
precomp.h => precomp.gch
Use GCC's -H to check if it's finding/using it.