C++ Use shared library in other project without specifying -I - c++

I have built a shared object to later use a function DoSomethingUseful() from the shared object in other projects. It uses external libraries as well as a bunch of headers that I am using across multiple projects.
Using CMake, I created a project MySharedLib with a header file called library.h:
#ifndef MYSHAREDLIB_LIBRARY_H
#define MYSHAREDLIB_LIBRARY_H
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <cstdio>
// own header files
#include <header1.h>
#include <header2.h>
#define PI 3.14159265
//tesseract
#include <tesseract/baseapi.h>
#include <leptonica/allheaders.h>
//openCV
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
//face detection
#include "opencv2/objdetect.hpp"
#include "opencv2/imgproc.hpp"
void DoSomethingUseul(int[] inparray);
#endif
With library.cpp as
#include "library.h"
void DoSomethingUseful(int[] inparray){...}
My CMake file is as such:
cmake_minimum_required(VERSION 3.10)
project(MYSHAREDLIB)
find_package( OpenCV REQUIRED )
set(CMAKE_CXX_STANDARD 11)
set(MY_INCLUDE_DIR ../source/)
set(MY_OPENCV_CASCADES /opencvpath/openCV34/opencv/sources/data/haarcascades/)
include_directories(${MY_INCLUDE_DIR} ${MY_OPENCV_CASCADES} /usr/include)
link_directories(${MY_INCLUDE_DIR})
add_library(MYSHAREDLIB SHARED library.cpp library.h
${MY_INCLUDE_DIR}header1.cpp
${MY_INCLUDE_DIR}header1.h
${MY_INCLUDE_DIR}header2.cpp
${MY_INCLUDE_DIR}header2.h
)
set_target_properties(MYSHAREDLIB PROPERTIES VERSION 3.10)
target_link_libraries(MYSHAREDLIB lept tesseract ${OpenCV_LIBS})
The *.so file is created sucessfully, i. e. using Clion, no errors are thrown and the file libMySharedLib.so is there.
I then want to use the function DoSomethingUseful() in another file DoSomething.cpp:
#include <iostream>
#include "library.h"
using namespace std;
int main()
{
int[2] myarray; myarray[0]=1; myarray[1] =2;
DoSomethingUseful(myarray);
return 0;
}
And
g++ -g -Wall -Wl,-rpath -Wl,'pwd' -o DoSomething DoSomething.cpp -I ../source/ -L. libMYSHAREDLIB.so
I can then call the programm by ./DoSomething just properly.
The problem is, that this is not what I want. I want to compile a new project file such as ./DoSomethingOnlyDependentOnMYSHAREDLIB. Although I already link header1.h and header2.h in MySharedLib.so in the Cmake file:
add_library(MYSHAREDLIB SHARED library.cpp library.h
${MY_INCLUDE_DIR}header1.cpp
${MY_INCLUDE_DIR}header1.h
${MY_INCLUDE_DIR}header2.cpp
${MY_INCLUDE_DIR}header2.h
)
I do still need the information of the directive of header1.h and header2.hduring linking and compiling by
-I ../source/
How can I avoid this? I only want to copy my *.so somewhere and create new function calls in new *.cpp's only based on MySharedLib.so (i. e. only dependent on one file).
Thanks so much for your help!

Related

How to define F_CPU for external libraries?

I want to write library for avr which uses <util/delay.h> and it requires F_CPU to be defined, so i faced the problem, is there any way in C/C++ for libraries to get defines for attributes which user writes in main file? I guess the question is kinda dumb, since libraries compiles first, then the main file. I've come to a solution with using init.h file, which contains user initial setups, still doesn't solve the problem with already compiled libraries. Still, maybe there are some other workarounds or standardized approach for this type of problem. here's the code:
main.cpp
#include "myLib.h"
#include <avr/io.h>
#include <util/delay.h>
int main(){
DDRD = 0xFF;
PORTD = 0;
while (1)
{
blink();
}
return 0;
}
init.h
#pragma once
#define F_CPU 16000000UL
myLib.h
#pragma once
#include "init.h"
#include <avr/io.h>
#include <util/delay.h>
void blink();
myLib.cpp
#include "myLib.h"
void blink(){
PORTD ^= 0xFF;
_delay_ms(500);
}
In your Makefile add -DF_CPU=16000000UL to the C_FLAGS.
Adding -DF_CPU to C_FLAGS is how this is commonly done.

Fatal error when compiling #include <sys/uio.h> on project [windows]

trying to compile a file for class, using the mingw compiler on windows 10. Compiling with g++ gives me an error stating
\projectFile.o
mingw32-g++.exe -o D:\GitHub\GitRepo\projectFile.exe D:\GitHub\GitRepo\projectFile.o
D:\GitRepo\projectFile.cpp:16:20: fatal error: sys/uio.h: No such file or directory
compilation terminated.
From what ive read this header file
#include <sys/uio.h>
is a unix header and is generally included with most unix build environments. I am working on Windows 10 build and have been unsuccessful in trying to get this to work. Is there a work around for windows using different headers? Is there a while to install this file somehow?
The project is a generalized XML parser that as a student my job is to extract functions from the main file so that they can be reused (OOP design space)
#include <iostream>
#include <iterator>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/io.h>
#include <unistd.h>
#include <errno.h>
#include <vector>
#include <algorithm>
#include <ctype.h>
#include "XMLParser.hpp"
Built on Windows 10 (lastest build) with Mingw-64 (lastest version)
This will not compile for me
This fixed my problem creating this uio.h file in sys directory of mingw64
#ifndef SYS_UIO_H
#define SYS_UIO_H
#include <inttypes.h>
#include <unistd.h>
struct iovec
{
void *iov_base; /* Base address of a memory region for input or output */
size_t iov_len; /* The size of the memory pointed to by iov_base */
};
ssize_t readv(int fildes, const struct iovec *iov, int iovcnt);
ssize_t writev(int fildes, const struct iovec *iov, int iovcnt);
#endif /* SYS_UIO_H */

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.

"unresolved external symbol _triangulate" when using triangle library

I'm currently using the triangle library in my program. The library contains only .c and .h files (no .lib). I get the following error on Visual Studio C++ 2010:
1>data.obj : error LNK2019: unresolved external symbol _triangulate referenced in function "struct triangulateio __cdecl readfile(void)" (?readfile##YA?AUtriangulateio##XZ)
The header file of my data.cpp is the following:
#ifndef DATA_H
#define DATA_H
#include <WinSock2.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <string>
#include <time.h>
#include <GL/gl.h> //include the gl header file
#include <GL/glut.h> //include the glut header file
#include <GL/glu.h> //include the glut header file
#include <armadillo>
//Namespace
using namespace std;
using namespace arma;
extern "C"
{
#ifdef SINGLE
#define REAL float
#else /* not SINGLE */
#define REAL double
#endif /* not SINGLE */
#include "triangle.h"
}
triangulateio readfile();
#endif
Data.cpp
triangulate("pczAevn", &in, &mid, &vorout);
I've already made my program work with a Makefile of mine on Ubuntu, but I need to run my program on windows.
Feel free to ask for more information.
EDIT #1:
If you use the triangle library with VS, you have to put the following instruction on top of the triangle.c file #define TRILIBRARY
Now it compile. Thank you very much for the help.
The linker can't find a definition for "triangulateio readfile()", if it's defined in the .c file my guess is that it isn't built. If you include it in the project it could work.