C++ library in using boost library - c++

I wrote a test.cpp:
#include <iostream>
#include <stack>
#include <boost/lexical_cast.hpp>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
using namespace std;
namespace phoenix = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
struct calculator
{
bool interpret(const string& s);
void do_neg();
void do_add();
void do_sub();
void do_mul();
void do_div();
void do_number(const char* first, const char* last);
int val() const;
private:
stack<int> values_;
int *pn1_, n2_;
void pop_1();
void pop_2();
};
......................
....................
But when I use g++ test.cpp -o test, there are errors like boost/lexical_cast.hpp: No such file or directory, but I have copy all of files in boost (download from boost.org) to the test.cpp folder, how to make g++ know the headers paths? Thanks
I used g++ test.cpp -o test
Using " " is not possible, I have a lot of header's dependency.

You have to make sure you modify the include to g++'s command. Reading from the man page (which is your best friend for this sorta stuff):
Add the directory dir to the list of directories to be searched for
header files. Directories named by -I are searched before the
standard system include directories. If the directory dir is a
standard system include directory, the option is ignored to ensure
that the default search order for system directories and the
special treatment of system headers are not defeated . If dir
begins with "=", then the "=" will be replaced by the sysroot
prefix; see --sysroot and -isysroot.
For you the command should look like this:
g++ -I path/to/boost test.cpp

Related

G++ Not Finding Included .cpp Files When Compiling

Inkey.cpp and Key.cpp are in the same directory, /root/src.
Compile.bat is in /root.
When I run Compile.bat, I am given the message "Key.cpp: No such file or directory".
Thanks in advance for any advice.
Inkey.cpp
#include <iostream>
#include <Key.cpp>
using namespace std;
int main(int argc, char *argv[]) {
cout << "Hello from InKey" << endl;
Key key1;
return 0;
}
Key.cpp
#include <iostream>
using namespace std;
class Key {
public:
Key() {
cout << "New Key instantiated." << endl;
};
};
Compile.bat
#ECHO OFF
g++ "src/Inkey.cpp" -o "out/InKey.exe"
"out\Inkey.exe"
Look up the difference between #include "filename" and #include <filename>. The former starts at the current directory, the latter uses a search path (or set of such paths). (Note that #include "filename" will fall back on the search strategy of #include <filename> if no file is found starting from the current directory).
Also, you do not usually include .cpp files, you pass them as separate arguments to the compiler and then combine them using the linker.
First off, rename Key.cpp to Key.h. Put the declaration in Key.h. Then put the definition in Key.cpp (Don't forget to include Key.h here). Then include your Key.h in all files using Key objects.
Now, compile them with g++ -o filename.out file1.cpp file2.cpp -O3 -Wall
Also, learn to use boilerplate code
P.S. as #SoronelHaetir has suggested, use "" to include custom header files

When using bazel to build TensorFlow C++ call model, .so file doesn't work

I want to use TensorFlow C++ api to call model and predict answers.
At fisrt, I clone the tensorflow repo
git clone --recursive https://github.com/tensorflow/tensorflow
Then I write the C++ code like below:
One code is a class to call TensorFlow api, the header file is like:
#ifndef _DEEPMODEL_H_
#define _DEEPMODEL_H_
#include <iostream>
#include <string>
#include <vector>
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/protobuf/meta_graph.pb.h"
#include "tensorflow/cc/client/client_session.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/tensor.h"
using namespace std;
using namespace tensorflow;
class DeepModel{
public:
DeepModel(const string graph_path, const string checkpoint_path);
virtual ~DeepModel();
bool onInit();
void unInit();
vector<float> predict(vector<vector<float>>& x, string input_name, string output_name);
private:
string graph_path;
string checkpoint_path;
MetaGraphDef graph_def;
Session* my_sess;
};
#endif
After this, I write a simple encapsulation code. I want to compile a .so, and use the .so without tensorflow source code in the future. And my encapsulation code is like below:
#ifndef _MODEL_HELPER_H_
#define _MODEL_HELPER_H_
#include <vector>
#include <string>
using namespace std;
class ModelHelper{
public:
ModelHelper(const string graph_path, const string checkpoint_path);
virtual ~ModelHelper();
vector<float> predict(vector<vector<float> >& x, string input_name, string output_name);
private:
string graph_path;
string checkpoint_path;
};
#endif
I have write code to test above code, it works well. Then I want to compile .so using bazel.
My BUILD file is like below:
load("//tensorflow:tensorflow.bzl", "tf_cc_binary")
tf_cc_binary(
name = "my_helper.so",
srcs = ["model_helper.cc", "model_helper.h", "deepmodel.cc", "deepmodel.h"],
linkshared = 1,
deps = [
"//tensorflow/cc:cc_ops",
"//tensorflow/cc:client_session",
"//tensorflow/core:tensorflow"
],
)
then I rename model_helper.so to libmodel_helper.so, and write cpp code to test the .so file. And I want to compile the code, command is like this
g++ -std=c++11 test_so.cpp -L./ -lmy_helper -I./ -o my_helper
Then I meet the error:
.//libmy_helper.so: undefined reference to `stream_executor::cuda::ScopedActivateExecutorContext::~ScopedActivateExecutorContext()'
.//libmy_helper.so: undefined reference to `stream_executor::cuda::ScopedActivateExecutorContext::ScopedActivateExecutorContext(stream_executor::StreamExecutor*)'
.//libmy_helper.so: undefined reference to `tensorflow::DeviceName<Eigen::GpuDevice>::value[abi:cxx11]'
collect2: error: ld returned 1 exit status
I really don't know why. I can't use the .so alone?
You should reference libtensorflow_frameowork.so in your makefile. Just like code below:
g++ -std=c++11 test_so.cpp -L./ -lmy_helper -ltensorflow_framework -I./ -o my_helper
I guess bazel misses some source code in tensorflow into .so when compile my code.

How to link boost thread with Xcode

I have built Boost from the website using
./bootstrap.sh
./b2 install
I think all are installed properly. I have headers in /usr/local/include/boost and libs in /usr/local/lib.
Everything links as long as don't include boost/thread.hpp:
//
// main.cpp
// ising3
//
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
#include <boost/tuple/tuple_io.hpp>
#include <iostream>
#include <boost/date_time.hpp>
//#include <boost/thread.hpp>
using namespace ::boost::tuples;
using namespace ::boost;
int main(int argc, const char * argv[])
{
// insert code here...
std::cout << "Hello, World!\n";
tuple<int,int> a,b,c;
a=make_tuple(1,1);
b=make_tuple(3,2);
std::cout<<a;
return 0;
}
Runs and prints:
Hello, World!
(1 1)
However, if uncommented, it fails:
I have linked the dynamic library libboost_thread.a and libboost_thread.dylib and included /usr/local/include into header search path and /usr/local/lib into library search path.
You should also link to boost_system.
The error indicates that it needs boost::system::system_category (which exists for error reporting).

Linking boost with own headers and source code

I'm working with the boost libraries and opencv, and now I have to implement my own headers and source code (additional to main.cpp) that requires the libraries as well.
The main.cpp looks like (just in principle):
// STL includes
#include <stdlib.h>
...(some other STL stuff)
// Boost includes
#include <boost/array.hpp>
...(a lot of other boost stuff)
//OpenCV
#include <opencv2/opencv.hpp>
// Own header files
#include <myHeader.hpp>
main() do_some_stuff;
This works, if I don't have anything related to boost in myStuff.hpp. But if I add something in it (the function descriptions are in myStuff.cpp), like:
class aClass{
public:
aClass(int);
void doSomething(boost::shared_ptr<int>);
void doSomethingElse(cv::Mat);
};
then it says 'boost' had not been declared, or 'cv' does not name a type.
I was like, ok, I just need to include the headers in this file as well, so I added the same includes, but then when it tries to link it gives a lot of errors like:
/usr/include/boost/operators.hpp:308:35: error: expected identifier before numeric constant
/usr/include/boost/operators.hpp:308:35: error: expected ‘>’ before numeric constant
/usr/include/boost/operators.hpp:310:1: error: expected class-name before ‘{’ token
/usr/include/boost/operators.hpp:311:3: error: expected unqualified-id before numeric constant
...(a lot more of these errors)
I'm using a Makefile to build this project, that looks like:
OPENCV_I = `pkg-config --cflags opencv`
#it finds boost without any additional -I or -L options...
INCLUDEPATHS = $(OPENCV_I)\
-I.\
-L.
LIBS=-lGL -lGLU -lm -lboost_program_options -lboost_system -lboost_thread -pthread -lrt -lopencv_core -lopencv_highgui
SRCCXX := main.cpp myStuff.cpp
OBJSCXX := $(SRCCXX:%.cpp=${BUILDDIR}/%.o)
$(BUILDDIR)/%.o : %.cpp
$(CXX) $(CXXFLAGS) $(INCLUDEPATHS) -c $< -o $# -DdDOUBLE $(LIBS)
all: ${OBJSCXX}
$(CXX) $(LDFLAGS) $(INCLUDEPATHS) -o $(OUTNAME) $? -DdDOUBLE $(LIBS)
Previously I was using CMake, and it worked quite well with these kind of projects, just this one is a part of a bigger project where they use Makefiles for everything. So I guess the main problem is with the makefile, probably when I list my source codes SRCCXX := main.cpp Visualisation.cpp it doesn't like it...
Any suggestions?
Thank you in advance.
EDIT....................................
So my whole myStuff.hpp looks like:
#define _USE_MATH_DEFINES
#include <math.h>
#define RINGS 5
#define SECTIONS 12
// Boost includes
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/assign/ptr_list_of.hpp>
#include <boost/assign.hpp>
#include <boost/bind.hpp>
#include <boost/date_time.hpp>
#include <boost/foreach.hpp>
#include <boost/function.hpp>
#include <boost/make_shared.hpp>
#include <boost/math/constants/constants.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/program_options.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <opencv2/opencv.hpp>
class Sensor{
public:
Sensor(int);
void Update(boost::shared_ptr<char[RINGS][SECTIONS]>);
int Id();
private:
char data[RINGS][SECTIONS];
int id;
};
and the myStuff.cpp:
#include "myStuff.hpp"
void Sensor::Update(boost::shared_ptr< char[RINGS][SECTIONS] > buffer){
for(int i=0;i<RINGS;i++) for(int j=0;j<SECTIONS;j++) data[i][j]=buffer[i][j];
};
Sensor::Sensor(int a){
id=0;
};
int Sensor::Id(){
return id;
};
and my main.cpp:
// STL includes
#include <stdlib.h>
#include <iostream>
#include <mutex>
#include <string.h>
#include <typeinfo>
#include <queue>
#include <memory>
// Boost includes
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/assign/ptr_list_of.hpp>
#include <boost/assign.hpp>
#include <boost/bind.hpp>
#include <boost/date_time.hpp>
#include <boost/foreach.hpp>
#include <boost/function.hpp>
#include <boost/make_shared.hpp>
#include <boost/math/constants/constants.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/program_options.hpp>
#include <boost/numeric/ublas/matrix.hpp>
//OpenCV
#include <opencv2/opencv.hpp>
// Own header files
#include "myStuff.hpp"
////////////////////////////////////////// Main
int main (int argc, char **argv)
{
Sensor sensor(0);
return 0;
}
Well first things first... when including your own headers from within your project I would recommend that you use "mine.hpp" instead of <mine.hpp>. This ensures that the compiler won't search the complete include path and accidentally find some other include of the same name (different version for example).
Second, when you have a dependency within a class then you include the header for that dependency within that class. You cannot make assumptions that someone will include all your dependencies in a main class or some other class. Sometimes someone will just want to use your class by itself. You don't want them to then have to figure out your dependencies. Don't worry about replication either as the include guard (or pragma) will prevent that.
As for your particular problems you will need to give use your code. You have certainly managed to correctly include your headers at that point. I would guess that they might stem from a missing { or ; somewhere. Look at your very first error and solve that one.
EDIT
The issue appears to be with how you are using boost. I had a look at what in operators.hpp and in version 1_44 what I see is a struct definition with 4 template parameters, one of which is defaulted to boost::detail::empty_base<T>. Only thing I can say is to make sure that you have your entire boost library on your include path, and link path.
EDIT2
From your newly posted code I see a couple of problems. First is that you have WAY too many includes in your header. You should only ever have class dependency includes in your header, and always prefer to put your header files into your implementation (.cpp) file. This helps to prevent extremely long compilation times. So first modify your header to include only the dependencies you need:
#include <boost/shared_ptr.hpp>
#define RINGS 5
#define SECTIONS 12
class Sensor{
public:
Sensor(int);
void Update(boost::shared_ptr<char[RINGS][SECTIONS]>);
int Id();
private:
char data[RINGS][SECTIONS];
int id;
};
Then in your implementation the only change is to put braces around your for loops (this is for clarity and safety... understand why you put it on one line but it is not worth it). Also put your CTOR first:
#include "myStuff.hpp"
Sensor::Sensor(int a){
id=0;
};
void Sensor::Update(boost::shared_ptr< char[RINGS][SECTIONS] > buffer){
for(int i=0;i<RINGS;i++) {
for(int j=0;j<SECTIONS;j++) {
data[i][j]=buffer[i][j];
}
}
};
int Sensor::Id(){
return id;
};
Main
#include "myStuff.hpp"
int main (int argc, char **argv)
{
Sensor sensor(0);
return 0;
}
The ONLY dependency you need is boost::shared_ptr. To be honest though, I'm pretty sure you don't need that either. Anyway I would recommend that you start with the above and then build up by adding one dependency at a time.
After a couple of hours I figured it out. myStuff.cpp also requires the header inclusion. Silly mistake, but still why can't the compiler says something like non defined or can't find instead of a couple of pages of messed up errors...?
Thanks anyway for your help.

How to use header files?

I wanted to learn using header files. and I got an error. here is my code:
printmyname.h:
void printMyName();
printmyname.cpp:
#include "printmyname.h"
void printMyName() {
cout << "omer";
}
try.cpp (main file):
#include <iostream>
#include "printmyname.h"
using namespace std;
int main() {
printMyName();
return 0;
}
Here is the error:
undefined reference to `printMyName()`
What's is the problem?
Undefine reference has nothing to do with your header file in this case. It means the linker cannot find the implementation of printMyName which is in printmyname.cpp. If you are using g++, you should try:
g++ try.cpp printmyname.cpp -o yourBinaryName
If you are using a makefile, you should add dependency(printmyname.cpp) correctly for try.cpp.
Edit:
As #zmo suggest in his comment:
you can also do it through a two times compilation (more suitable with Makefiles):
g++ -c printmyname.cpp
g++ try.cpp printmyname.o -o yourBinaryName
If you are using Windows, you need to add the printmyname.cpp to your project too.
Consider adding an include guard to your header
#ifndef PRINTMYNAME_INCLUDED
#define PRINTMYNAME_INCLUDED
void printMyName();
#endif
You will also need to move the #include <iostream> and using namespace std; from the try.cpp to the printmyname.cpp file.
You need to add code/definition in printMyName.cpp inside printMyName.h only.
void printMyName();
{
cout << "omer";
}