Use two different Versions of boost - c++

i try to build a cmake which use two different version of boost. ( I use a framework which only runs with boost 1.55 but my application needs boost 1.57)
My idea was to make 2 Cmake build processes
Application Cmake boost 1.57
cmake_minimum_required (VERSION 2.6)
project (Application)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=auto -std=c++0x ")
set(Boost_DEBUG ON)
set(Boost_NO_SYSTEM_PATHS TRUE)
set(BOOST_ROOT /opt/boost/boost_1_57)
find_package(Boost 1.57 REQUIRED COMPONENTS thread filesystem log system)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
SYSTEM /opt/boost/boost_1_57/include
)
ADD_LIBRARY( AppLib SHARED testVersion.cpp ...)
Framework Cmake boost 1.55
cmake_minimum_required(VERSION 2.8.3)
project(Test)
add_subdirectory(Application)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=auto -std=c++0x ")
set(Boost_NO_SYSTEM_PATHS TRUE)
set(BOOST_ROOT $ENV{BOOST_ROOT})
find_package(Boost 1.55 REQUIRED COMPONENTS thread filesystem log system)
include_directories(
SYSTEM ${Boost_INCLUDE_DIRS}
)
add_executable(test test.cpp)
target_link_libraries( test AppLib )
test.cpp
#include "testVersion.hpp"
int main() {
std::cout << "Main call Using Boost "
<< BOOST_VERSION / 100000 << "." // major version
<< BOOST_VERSION / 100 % 1000 << "." // minior version
<< BOOST_VERSION % 100 // patch level
<< std::endl;
std::cout << "library : " << std::endl;
Version v;
v.callVersion();
}
testVersion
#include "testVersion.hpp"
void Version::callVersion()
{ std::cout << "Using Boost "
<< BOOST_VERSION / 100000 << "." // major version
<< BOOST_VERSION / 100 % 1000 << "." // minior version
<< BOOST_VERSION % 100 // patch level
<< std::endl;
}
testVersion.hpp
#include <boost/version.hpp>
class Version
{
public:
void callVersion();
};
If i do it this way it runs well :
Output:
Main call Using Boost 1.55.0
Using Boost 1.57.0
But when I eliminate the testVersion.cpp file and inline my callVersion I get the output:
Main call Using Boost 1.55.0
library :
Using Boost 1.55.0
because the compiler use for the headers boost 1.55 only when i include boost in the source files he takes 1.57. How i can solve that ? is that possible?
Conclusion:
I need an empty header :
all_boost_includes.hpp
with a all_boost_includes.cpp
#include "boost..."
#include ...
which will just include all boost headers. And then i have to include this header in every header in my application. Is that correct?
This is similar to an precompiled boost header or?
I tried include "boost_headers.hpp" which is empty and has a boost_header.cpp which includes boost versions
I added on my Application cmake
ADD_LIBRARY( AppLib SHARED boost_headers.cpp)
But when i try
#include "precompiled_boost.hpp"
#include <fstream>
#include <iostream>
class Version
{
public:
void callVersion(){
std::cout << "Using Boost "
<< BOOST_VERSION / 100000 << "." // major version
<< BOOST_VERSION / 100 % 1000 << "." // minior version
<< BOOST_VERSION % 100 // patch level
<< std::endl;
}
};
He don't know BOOST_VERSION. What I have to do there ? If i include precompiled_boost.cpp i get the wrong output

1. If you do not inline callVersion
Compiling library compiles code for Version::callVersion within the library. As library uses boost 1.55 Version::callVersion will return 1.55.
2. If you do inline callVersion
Compiling library does not compile code for Version::callVersion within the library, because it will bi inlined! Your Version::callVersion will actually be compiled on the test side. As test uses boost 1.57, Version::callVersion will return 1.57
Conclusion
You should not inline you calls. More, you cannot use classes that refer to any boost in their declarations in both application and library projects that use different versions of boost. If you have to, you should consider creating some proxy objects or functions, so all boost stuff will be encapsulated inside your library.

Related

Cmake: How to build custom compiler binary and then use it for some targets?

I need to build a custom C++ compiler binary and then use it for some targets in the project.
What is the best way to do it in modern CMake?
I set a dependency from the compiler target, and it works as expected, but then what, use 'generator expressions' to get the compiler target binary name?
set(CMAKE_CXX_COMPILER ...) -- either it doesn't understand generator expressions or I misuse it somehow.
Is there a way to set the compiler only for specific targets? As I understand, set(CMAKE_CXX_COMPILER) works for current directory and its children.
You can use a toolchain file, which are made to specify cross compilers.
Here's an example I took from the documentation:
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_SYSROOT /home/devel/rasp-pi-rootfs)
set(CMAKE_STAGING_PREFIX /home/devel/stage)
set(tools /home/devel/gcc-4.7-linaro-rpi-gnueabihf)
set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabihf-g++)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
This is okay since it's in a toolchain file. CMake is made to properly handle toolchain files.
You use it by specifying it in the command line arguments:
cmake .. -DCMAKE_TOOLCHAIN_FILE=your_toolchain.cmake
I made an MCVE for a sample application (App/app.cc) with non-C++ source code (App/text.txt) which has to be compiled via intermediate C++ sources.
The sample directory tree:
└┬─ ./
├─── CMakeLists.txt
├─┬─ App/
│ ├─── CMakeLists.txt
│ ├─── app.cc
│ └─── text.txt
└─┬─ Tool/
├─── CMakeLists.txt
└─── tool.cc
The file ./CMakeLists.txt is the main project file (provides the solution for VisualStudio):
project(App)
cmake_minimum_required(VERSION 3.10.0)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_subdirectory(App)
add_subdirectory(Tool)
The source code ./Tool/tool.cc for a build-tool to generate a C++ source and a header out of a text file:
// a sample tool converting a text file to a c++ source
#include <fstream>
#include <iostream>
#include <string>
int main(int argc, char **argv)
{
if (argc < 3) {
std::cerr <<
"ERROR in tool: Missing arguments!\n"
"\n"
"Usage:\n"
"tool TXT_FILE CC_FILE\n";
return -1;
}
std::ifstream fIn(argv[1]);
if (!fIn.good()) {
std::cerr << "ERROR: Cannot open '" << argv[1] << "' for reading!\n";
return -1;
}
const std::string fileH = std::string(argv[2]) + ".h";
std::ofstream fOutH(fileH);
if (!fOutH.good()) {
std::cerr << "ERROR: Cannot open '" << fileH << "' for writing!\n";
return -1;
}
const std::string fileCC = std::string(argv[2]) + ".cc";
std::ofstream fOutCC(fileCC);
if (!fOutCC.good()) {
std::cerr << "ERROR: Cannot open '" << fileCC << "' for writing!\n";
return -1;
}
fOutCC << "#include \"" << fileH << "\"\n\n";
for (std::string buffer; std::getline(fIn, buffer);) {
const size_t i = buffer.find('=');
if (i < buffer.size()) {
fOutH << "extern const char *const " << buffer.substr(0, i) << ";\n";
fOutCC << "const char *const " << buffer.substr(0, i)
<< " = \"" << buffer.substr(i + 1) << "\";\n";
}
}
fOutH.close();
if (!fOutH.good()) {
std::cerr << "ERROR: Couldn't complete writing of '" << fileH << "'!\n";
return -1;
}
fOutCC.close();
if (!fOutCC.good()) {
std::cerr << "ERROR: Couldn't complete writing of '" << fileCC << "'!\n";
return -1;
}
return 0;
}
The file ./Tool/CMakeLists.txt to build the tool:
project(Tool)
add_executable(tool
tool.cc)
set_property(TARGET tool
PROPERTY FOLDER "Tools")
The file ./App/text.txt – a text file which has to be converted to generated sources text.cc and text.h:
text1=Hello World.
text2=Text built with tool -> VC++
The source ./App/app.cc where text.h is included:
// a sample app using an indirect built source file
#include <iostream>
#include "text.h"
int main()
{
std::cout << "text1: '" << text1 << "'\n";
std::cout << "text2: '" << text2 << "'\n";
return 0;
}
Finally, the ./App/CMakeLists.txt which introduces the custom build step:
# custom build step
add_custom_command(
OUTPUT
text.cc text.h
COMMAND
tool "${CMAKE_CURRENT_SOURCE_DIR}/text.txt" text
MAIN_DEPENDENCY
text.txt
DEPENDS
tool
COMMENT
"generate C++ sources from text"
VERBATIM)
# regular C++ build
add_executable(app
app.cc # regular source files
text.cc text.h) # intermediate source files
# add build dir for project to include directories
include_directories(app
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
Having DEPENDS tool in add_custom_command and the OUTPUT of add_custom_command in add_executable grants that:
test.txt is listed as source in the VS-project of app
VS-project tool is included into VS-solution App
tool is compiled and linked, and then used to convert test.txt to test.h and test.cc before app is compiled and linked (successfully).
The generated intermediate sources appear in the build directory (don't pollute the source directory). Hence, the build directory has to be set as include path as well. Otherwise, the #include "text.h" (in app.cc) wouldn't work.

c++ Linker error with static library

I am trying to include a static library that I have created with a static method but getting the following error in runtime when trying to invoke the method:
[ INFO] [1528271039.635221775]: Initializing nodelet with 4 worker threads.
/opt/ros/kinetic/lib/nodelet/nodelet: symbol lookup error:/catkin_ws/devel/lib//libmission_manager_nodelet.so: undefined symbol: _ZN14my_commons10ConsoleLog6ROSLogEiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_
the static library has 2 files:
ConsoleLog.h:
#ifndef CONSOLE_LOG_H
#define CONSOLE_LOG_H
#include "ros/ros.h"
namespace my_commons
{
class ConsoleLog
{
public:
static void ROSLog(int type, std::string message,std::string taskName);
static void STDLog(int logType, std::string msg,std::string taskName);
};
} // namespace my_commons
#endif //CONSOLE_LOG_H
and ConsoleLog.cpp:
#include "ConsoleLog.h"
namespace my_commons
{
void ConsoleLog::ROSLog(int type, std::string message, std::string task)
{
switch (type)
{
case (0):
ROS_DEBUG_STREAM("########## " << task << " DEBUG: " << message << " ##########");
break;
case (1):
ROS_INFO_STREAM("########## " << task << " " << message << " ##########");
break;
case (2):
ROS_WARN_STREAM("########## " << task << " WARNNING: " << message << " ##########");
break;
case (3):
ROS_ERROR_STREAM("########## " << task << " ERROR: " << message << " ##########");
break;
}
}
void ConsoleLog::STDLog(int logType, std::string msg, std::string task)
{
std::cout << msg << std::endl;
}
} // namespace my_commons
the CMakelist.txt:
cmake_minimum_required(VERSION 2.8.3)
project(my_commons)
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")
find_package(catkin REQUIRED COMPONENTS
roscpp
)
catkin_package(CATKIN_DEPENDS
INCLUDE_DIRS include)
include_directories(
${catkin_INCLUDE_DIRS}
include/
)
###########
## Build ##
###########
add_library(my_commons
src/ConsoleLog.cpp
)
## Specify libraries to link a library or executable target against
set_target_properties(my_commons PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(my_commons
${catkin_LIBRARIES}
${roscpp_LIBRARIES}
)
#add_dependencies(name_of_package_nodelet)
install(DIRECTORY include/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
FILES_MATCHING PATTERN "*.h"
PATTERN ".svn" EXCLUDE)
# Install library
install(TARGETS my_commons
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
Edit:
Here is the clients CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.3)
project(my_mission_manager)
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")
find_package(catkin REQUIRED COMPONENTS
roscpp
nodelet
std_msgs
my_commons
message_runtime
std_srvs
)
catkin_package(
CATKIN_DEPENDS
message_runtime
std_msgs
my_commons
)
include_directories(
${catkin_INCLUDE_DIRS}
include/
)
###########
## Build ##
###########
add_library(my_mission_manager_nodelet
src/my_mission_manager_nodelet.cpp
)
## Specify libraries to link a library or executable target against
target_link_libraries( my_mission_manager_nodelet
${catkin_LIBRARIES}
${roscpp_LIBRARIES}
)
#add_dependencies(my_mission_manager_nodelet)
# Install library
install(TARGETS my_mission_manager_nodelet
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
# Install header files
install(DIRECTORY src/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
)
# Install launch files
install(DIRECTORY launch/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
)
# Install xml files
install(FILES nodelet_plugins.xml
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)
What am I missing here?
By the way, I am able to use data from header files in my_commons (enums), the problem occurs when trying to add a cpp file an invoke a static method in it.
Thank you for your help!
Please find below a working example of correct CMake project:
Directory structure:
ROOT
|
+--inc
| +--ConsoleLog.hpp
+--src
| +--ConsoleLog.cpp
| +--main.cpp
+CMakeLists.txt
Your source and header files remains unchanged (I only changed *.h to *.hpp --> after all you write in C++, not C).
main.cpp:
#include "ConsoleLog.hpp"
int main() {
my_commons::ConsoleLog log;
log.ROSLog(1, "xxx", "yyy");
return 0;
}
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.11)
project(my_commons)
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
find_package(catkin REQUIRED COMPONENTS roscpp)
add_library(my_commons STATIC src/ConsoleLog.cpp)
target_include_directories(my_commons PUBLIC inc ${roscpp_INCLUDE_DIRS})
target_link_libraries(my_commons ${catkin_LIBRARIES} ${roscpp_LIBRARIES})
add_executable(MyExec src/main.cpp)
target_link_libraries(MyExec my_commons)
Result of the execution:
./MyExec
[ INFO] [1528280295.971205050]: ########## yyy xxx ##########
I use newer CMake version to be able to use target_include_directories, because I like this feature. I changed your compiler flags to include C++11 standard, because apparently you use it. I also removed INSTALL CMake rules, because they are irrelevant to the question. Let me know if this answer is OK for you.
=============== EDIT(to answer OP comment)==============
Well, I don't have any problems with embedding this lib in another project structure. The error you got means that your directory structure is incorrect (my_commons dir doesn't exist). Your project tree should look like this:
ROOT
|
+--MyCommonsLib (this is the root of your my_commons library)
|
+--src
| +--main.cpp
+CMakeLists.txt
And your project's CMakeLists.txt might look like this:
cmake_minimum_required(VERSION 2.8.11)
project(SomeSimpleProjectUsingMyCommonsLib)
add_subdirectory(MyCommonsLib)
add_executable(MyExec src/main.cpp)
target_link_libraries(MyExec my_commons)
Just remember to remove the add_executable instruction from your MyCommonLib/CMakeLists.txt. Also main.cpp should be like this:
#include "ConsoleLog.hpp"
int main() {
my_commons::ConsoleLog::ROSLog(1, "xxx", "yyy");
return 0;
}
Sorry, before I didn't notice that ROSLog is declared as static.

allegro not working with clion (0xC000007B)

so I've hit a dead end, I'm simplying trying to run the following:
main.cpp:
#include <iostream>
#include <allegro5/allegro.h>
int main(int argc, char **argv) {
std::cout << "Hello, World!" << std::endl;
al_init();
std::cout << "hi" << std::endl;
return 0;
}
CMakeList.txt:
cmake_minimum_required(VERSION 3.6)
project(allegro_test)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
SET(ALLEGRO_ROOT C:/Users/duck-/workspace/cpp/recources/allegro/)
INCLUDE_DIRECTORIES( ${ALLEGRO_ROOT}/include )
LINK_DIRECTORIES( ${ALLEGRO_ROOT}/lib)
add_executable(allegro_test ${SOURCE_FILES})
TARGET_INCLUDE_DIRECTORIES(allegro_test PUBLIC ${ALLEGRO_ROOT})
TARGET_LINK_LIBRARIES(allegro_test allegro)
output:
"C:\Users\duck-\.CLion2016.2\system\cmake\generated\allegro test-50fbd97d\50fbd97d\Debug\allegro_test.exe"
Process finished with exit code -1073741701 (0xC000007B)
I'm using allegro-mingw-gcc6.2.0-x64-dynamic-5.2.2.zip from here and have copyied allegro-5.2.dll, cygintl-1.dll & cygintl-2.dll to
C:\Users\duck-.CLion2016.2\system\cmake\generated\allegro test-50fbd97d\50fbd97d\Debug\
where the program's executed. I've installed .NET Framework 4.6.2. Am I missing something? cheers in advance.
Since you are building the program in a Debug configuration, you'll need to include allegro-debug-5.2.dll, and not just allegro-5.2.dll.

Connecting to MySQL in C++

I am trying to learn C++ and I am having a bit of nightmare doing a test where I connect to a MySQL database.
I've had issues with the MySQL connector not linking properly then was getting issues related to relocation truncated to fitr_x86_64_32 against symbol.
I think I have fixed that by adding a compiler flag and now the app successfully builds and links.
When I run the app, it gets as far as calling get_driver_instance but then it exits. No exception is thrown, no errors nothing just exit code 0.
Below is my DBManager class
#include "DBConnectionManager.h"
using namespace std;
DBConnectionManager::DBConnectionManager() {
cout << "Starting DBConnectionManager - Updated" << endl;
try {
cout << "Getting driver instance" << endl;
driver = get_driver_instance();
cout << "Got driver instance" << endl;
conn = driver->connect("tcp://127.0.0.1:3306", "root", "password");
conn->setSchema("bugs");
cout << "Connected to database" << endl;
}
catch (SQLException ex) {
cout << "Error connecting to DB: " << ex.what() << endl;
}
catch (...) {
cout << "Something has gone wrong" << endl;
}
}
Below is the header file
#ifndef MYSQLTEST_DBCONNECTIONMANAGER_H
#define MYSQLTEST_DBCONNECTIONMANAGER_H
#include <driver.h>
#include <exception.h>
#include <resultset.h>
#include <statement.h>
using namespace sql;
class DBConnectionManager
{
private:
sql::Driver *driver;
sql::Connection *conn;
sql::Statement *statement;
sql::ResultSet *res;
public:
DBConnectionManager();
void performSql();
};
#endif //MYSQLTEST_DBCONNECTIONMANAGER_H
Below is my main method
#include "DBConnectionManager.h"
int main() {
DBConnectionManager dbConnectionManager;
dbConnectionManager.performSql();
return 0;
}
Below is my CMakeLists.txt file
cmake_minimum_required(VERSION 3.6)
project(MySQLTest)
include_directories("C:\\Program Files\\MySQL\\MySQL Connector C++ 1.1.7\\include\\cppconn" "C:\\Program Files\\MySQL\\MySQL Connector C++ 1.1.7\\lib\\opt")
SET(GCC_COVERAGE_LINK_FLAGS "-m64 -Wl,--image-base -Wl,0x10000000 -lpthread -pthread")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -m64 -Wl,--image-base -Wl,0x10000000 -lpthread -pthread ")
set(SOURCE_FILES main.cpp DBConnectionManager.cpp)
add_executable(MySQLTest ${SOURCE_FILES})
add_library(mysqlcppconn.lib)
set_target_properties(MySQLTest PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(mysqlcppconn.lib PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(MySQLTest "C:\\Program Files\\MySQL\\MySQL Connector C++ 1.1.7\\lib\\opt\\mysqlcppconn.lib")
When I create the instance of my DBConnectionManager class it successfully calls the query and prints Starting DBConnectionManager - Updated followed by Getting Driver Instance but then it exits with Process finished with exit code 0 with no clues as to what went wrong.
Update
I'm finally getting somewhere. I found there are some MySQL client libraries within Cygwin so I have download them and referenced them in the cmake file.
My cmake file now looks like this:
cmake_minimum_required(VERSION 3.6)
project(MySQLTest)
SET(CPPCONN_PUBLIC_FUNC=)
SET(GCC_COVERAGE_LINK_FLAGS "-g -m64 -DCPPCONN_PUBLIC_FUNC= -Dmysqlcppconn_EXPORTS -lpthread -pthread -Wl,--image-base -Wl,0x10000000 -lz")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCPPCONN_PUBLIC_FUNC= -Dmysqlcppconn_EXPORTS -std=c++11 -g -m64 -Wl,--image-base -Wl,0x10000000 -lpthread -pthread -lz")
include_directories("C:/mysql_connector/include")
include_directories("C:/boost_1_61_0")
set(BOOST_INCLUDE_DIR C:/boost_1_61_0)
set(BOOST_LIBRARY_DIR C:/boost_1_61_0/libs)
set(SOURCE_FILES main.cpp DBConnectionManager.cpp)
add_executable(MySQLTest ${SOURCE_FILES})
find_package(Boost COMPONENTS REQUIRED)
link_directories(C:/mysql_connector/lib)
target_link_libraries(MySQLTest "C:/mysql_connector/lib/mysqlcppconn.dll" "C:/Program Files/MySQL/MySQL Server 5.7/lib/libmysql.dll" "C:/mysql_connector/lib/libmysqlclient.dll.a" "C:/mysql_connector/lib/libmysqlclient_r.dll.a" ${Boost_LIBRARY_DIR})
Notice how I have linked the libraries libmysqlclient.dll.a and libmysqlclient_r.dll.a which is what I got from Cygwin.
When I run the app now it successfully gets the driver instance and to the console is outputted
Starting DBConnectionManaged - Updated
Getting driver instance
Got driver instance
But when I try and connect with driver->connect I then get the following error
0 [main] MySQLTest 2976 C:\Users\Chris\.CLion2016.2\system\cmake\generated\MySQLTest-8702ae13\8702ae13\Debug\MySQLTest.exe: *** fatal error - Internal error: TP_NUM_C_BUFS too small: 50
When I put it through the debugger, it fails on the driver->connect with
gdb: unknown target exception 0xe06d7363 at 0x7fff11347788
Program received signal ?, Unknown signal.
0x00007fff11347788 in RaiseException () from /cygdrive/c/WINDOWS/System32/KERNELBASE.dll
Update 2
Everything I've read points the mysql connector binaries should work fine, so I started again. Below is now the contents of my cmake file
cmake_minimum_required(VERSION 3.6)
project(MySQLTest)
#add_compile_options("-v")
SET(GCC_COVERAGE_LINK_FLAGS )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(BOOST_INCLUDE_DIR C:/boost_1_61_0)
set(BOOST_LIBRARY_DIR C:/boost_1_61_0/libs)
include_directories("C:/Program\ Files/MySQL/MySQL\ Connector\ C++\ 1.1.7/include" "C:/Program\ Files/MySQL/MySQL\ Connector\ C++\ 1.1.7/include/cppconn" ${BOOST_INCLUDE_DIR})
set(SOURCE_FILES main.cpp DBConnectionManager.cpp)
add_executable(MySQLTest ${SOURCE_FILES})
find_package(Boost COMPONENTS REQUIRED)
link_directories(C:/Program\ Files/MySQL/MySQL\ Connector\ C++\ 1.1.7/lib/opt)
target_link_libraries(MySQLTest C:/Program\ Files/MySQL/MySQL\ Connector\ C++\ 1.1.7/lib/opt/mysqlcppconn.lib ${Boost_LIBRARY_DIR})
Now when I compile I get the original error
C:/Program Files/MySQL/MySQL Connector C++ 1.1.7/lib/opt/mysqlcppconn.lib(mysqlcppconn.dll.b):(.text+0x2): relocation truncated to fit: R_X86_64_32 against symbol `__imp_get_driver_instance' defined in .idata$5 section in C:/Program Files/MySQL/MySQL Connector C++ 1.1.7/lib/opt/mysqlcppconn.lib(mysqlcppconn.dll.b)
That sounds like to me like my app is compiling as 32 bit instead of 64 bit. As a test I ran the following code:
cout << "Int size is: " << sizeof(int) << endl;
The code above prints 4 (shouldn't it be 8 if it was compiled as 64 bit).
If my thinking is correct, why isn't it compiling it as 64 bit, I've tried setting the compiler flag -m64 but makes no difference. I've installed the Cygwinx64 as well which CLion is using.
You can use MySQL Connector C++
This is how to configure using Cmake
cmake_minimum_required(VERSION 3.7)
project(projectname)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
Include the dirs where you extracted the mysql-connector-cpp - download
include_directories(/usr/local/include/mysql-connector-cpp/include)
Create a cmake variable containing the project source files
set(SOURCE_FILES main.cpp)
Create your executable
add_executable(projectname ${SOURCE_FILES})
Link after creating executable
target_link_libraries(projectname mysqlcppconn)
Your CMakeList should at least have this or look like this in this order
cmake_minimum_required(VERSION 3.7)
project(projectname)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
include_directories(/usr/local/include/mysql-connector-cpp/include)
set(SOURCE_FILES main.cpp)
add_executable(projectname ${SOURCE_FILES})
target_link_libraries(projectname mysqlcppconn)
You can use mysql++ library to connect to mysql from c++.
For that install mysql++,
(Ubuntu)
sudo apt-get install mysql-server mysql-client
sudo apt-get install libmysqlclient-dev libmysql++-dev libmysqlcppconn-dev
(Mac)
brew install mysql++
include library by adding,
/usr/include/mysql++
/usr/include/mysql
and add linkers,
-lmysqlpp -lmysqlclient
Example code,
#include <iostream>
#include <string>
#include <mysql++.h>
#include <mysql.h>
#define dbname "dbname"
#define server "localhost"
#define user "username"
#define pass "password"
using namespace std;
using namespace mysqlpp;
int main() {
Connection con(true);
try {
con.connect(dbname, server, user, pass);
cout << "Connected to database\n";
string s = "SELECT * FROM mirrors_mee WHERE id=1";
Query q = con.query(s);
StoreQueryResult sq = q.store();
StoreQueryResult::iterator it;
it = sq.begin();
while (it != sq.end()) {
Row row = *it;
cout << row[5] << " " << row[6] << " " << row[7] << endl;
it++;
}
} catch (Exception &e) {
cout << e.what() << endl;
}
return 0;
}
You will get full documentation of the library here.

Error compiling a cpp file (ros)

I'm working on knowrob package and I already wrote my ontology(XML file) with Protege.
If I parse the owl.file and send some queries I have right answers.
Now my problem is to make a cpp to parse my xml file.
I already read something about json_prolog to send queries from my program to knowrob but is too muddler(http://www.knowrob.org/doc/interact_with_knowrob_via_ros).
I create my launch file and it works,later when i try to compile this cpp file:
#include <string>
#include <ros/ros.h>
#include <json_prolog/prolog.h>
using namespace std;
using namespace json_prolog;
int main(int argc, char *argv[])
{
ros::init(argc, argv, "test_json_prolog");
Prolog pl;
PrologQueryProxy bdgs = pl.query("member(A, [1, 2, 3, 4]), B = ['x', A], C = foo(bar, A, B)");
for(PrologQueryProxy::iterator it=bdgs.begin();
it != bdgs.end(); it++)
{
PrologBindings bdg = *it;
cout << "Found solution: " << (bool)(it == bdgs.end()) << endl;
cout << "A = "<< bdg["A"] << endl;
cout << "B = " << bdg["B"] << endl;
cout << "C = " << bdg["C"] << endl;
}
return 0;
}code here
I have the error:
/tmp/cccLQk3H.o:test_json_prolog.cpp:function main: error: undefined reference to 'ros::init(int&, char**, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)'
and other similar error about the undefined reference.
CMakelist :
cmake_minimum_required(VERSION 2.8.3)
project(json_prolog)
find_package(catkin REQUIRED rosjava_build_tools roscpp rospy json_prolog_msgs)
catkin_rosjava_setup(installApp publishMavenJavaPublicationToMavenRepository writeClasspath)
install(DIRECTORY ${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_MAVEN_DESTINATION}/org/knowrob/${PROJECT_NAME}/
DESTINATION ${CATKIN_GLOBAL_MAVEN_DESTINATION}/org/knowrob/${PROJECT_NAME})
catkin_package(INCLUDE_DIRS include LIBRARIES json_prolog CATKIN_DEPENDS json_prolog_msgs )
# find SWI Prolog libraries
include(FindPkgConfig)
pkg_check_modules(SWIPL REQUIRED swipl)
include_directories(${SWIPL_INCLUDE_DIRS})
link_directories(${SWIPL_LIBRARY_DIRS})
# export Python libraries
catkin_python_setup()
# C++ client library
include_directories(include ${catkin_INCLUDE_DIRS})
find_package(PkgConfig)
pkg_check_modules(JSON_GLIB REQUIRED json-glib-1.0)
add_definitions(${JSON_GLIB_CFLAGS})
link_directories(${JSON_GLIB_LIBRARIY_DIRS})
How can I solve it?
You should start investigating with checking if your call to find_package() (you called find_package(), right?) was successful, so change the snippet you added in your question by adding a debug line,
message(STATUS ${catkin_LIBRARIES})
add_executable(test_json_prolog examples/test_json_prolog.cpp)
target_link_libraries(test_json_prolog json_prolog ${catkin_LIBRARIES})
add_dependencies(test_json_prolog ${catkin_EXPORTED_TARGETS})
Call to message should be printing the libraries you meant to link to.
Besides, see this page if you haven't already, http://wiki.ros.org/catkin/CMakeLists.txt. There they mention a custom macro that you MUST call, i.e. catkin_package(). Also the sections 6, 7, and 8 are all linked to your problem I guess.
You can try to compile it directly using g++ compiler.
Please check this answer:
Compile roscpp without ros (using g++)
There a source code is compiled without cmake or catkin_make