C++ How to link boost libraries with my shared library to work on the target machine? - c++

I try to make jni shared library.
I use boost library in the code of this library.
I successfuly make shared library on the development machine and test's done.
I make boost lib folder which have libboost_*.so files in on target machine and add it to LD_LIBRARY_PATH.
So, I try to test on the target machine (same OS platform with development machine) but target machine cannot link it.
So, my java program find my .so (libsample.so) but libsample.so can't find boost library and throw message ( undefined symbol: _ZTIN5boost6detail16thread_data_baseE)
How can I solve this problem?
I want to pack the boost libaries on my shared library
or I want to dynamically linking with boost library with my shared libarary.
my project's CMakeLists.txt following
cmake_minimum_required(VERSION 3.0)
### This CMakeLists.txt : Root CMake of this project
################## complie settings of this project ##################
set(ARTIFACT_NAME "sample-plugin")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread ")
add_definitions("-Wno-deprecated-declarations")
add_definitions("-Wno-write-strings")
################## Boost Settings ##################
set(Boost_NO_SYSTEM_PATH ON)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME ON)
set(BOOST_INCLUDE_DIR "${BOOST_ROOT}/boost")
include_directories(${BOOST_INCLUDE_DIR})
link_directories(${BOOST_INCLUDE_DIR})
link_directories(${BOOST_LIBRARY_DIR})
find_package(Boost 1.58.0 REQUIRED)
include_directories("$ENV{JAVA_HOME}/include")
if (WIN32)
include_directories("$ENV{JAVA_HOME}/include/win32")
else ()
include_directories("$ENV{JAVA_HOME}/include/linux")
endif ()
add_library(${ARTIFACT_NAME} SHARED ${SOURCES} )
target_link_libraries(${ARTIFACT_NAME} ${Boost_LIBRARIES})

Thanks, Martin Bonner.
I solve this problem.
Here is my edited CMakeLists.txt
################## complie settings of this project ##################
set(ARTIFACT_NAME "sample-plugin")
#set(CMAKE_CXX_STANDARD 11) # 아래에 -std=c++11 옵션과 중복
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -shared -fPIC -std=c++11 -pthread ")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
add_definitions("-Wno-deprecated-declarations")
add_definitions("-Wno-write-strings")
################## Boost Settings ##################
set(Boost_NO_SYSTEM_PATH ON)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME ON)
set(BOOST_INCLUDE_DIR "${BOOST_ROOT}/boost")
include_directories(${BOOST_INCLUDE_DIR})
link_directories(${BOOST_INCLUDE_DIR})
link_directories(${BOOST_LIBRARY_DIR})
unset(Boost_INCLUDE_DIR CACHE)
unset(Boost_LIBRARY_DIRS CACHE)
find_package(Boost 1.58.0 REQUIRED COMPONENTS thread date_time filesystem system program_options )
################## Target Settings ##################
add_library(${ARTIFACT_NAME} SHARED ${SOURCES})
set_target_properties(${ARTIFACT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_link_libraries(${ARTIFACT_NAME} ${Boost_LIBRARIES})
Before this cmake run, I recompile boost libraries with -cxxflags=-fPIC because of this issue
I successfuly make .so library including boost libraries as static in it.

Related

How can I make fat execuatable file in CMAKE?

I am newbie on CMAKE. I am trying to make "fat executable file".
The term, fat executeable file, I mentioned, is a executable binary file which contains all shared libraries and can be just run in another environment.
Example (Trouble Situation)
There is ComputerA which is a computer that I used for developing. There is GCC, Boost libraries, librados etc.
And there is ComputerB which is a computer that I wanted to execute the binary that I built.
* Of course, Both Computer A and B have some conditions. Same Intel CPU Arch. (i7), Same CentOS.
I built binary file in ComputerA using CMAKE with this command, cmake .. && make. And I copied this file to ComputerB and executed.
When I execute the copied binary file in Computer B, it said like below.
[root#ComputerB ~]# ./binaryFile 123.123.123.123
./binaryFile: error while loading shared libraries: libboost_json.so.1.80.0: cannot open shared object file: No such file or directory
I understand what this error message say. There is no shared library which it needed. So, what I want to ask in this community is, What is CMAKE Command for containing shared libraries.
Similar thing :: fat JAR
The reason, why I called "fat executable file", is that there is a word "fat JAR" in Java. I am not familiar with Java. But it is commonly used word in Java community.
My CMAKE File
It contains some libraries like Boost, Rados, RBD etc. (There will be more according to progress of developing)
cmake_minimum_required(VERSION 3.2.0)
project(BinaryHelper VERSION 0.1.0)
find_package(Boost REQUIRED COMPONENTS json)
include_directories(${Boost_INCLUDE_DIR})
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lrados -std=c++17")
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
add_executable(
${PROJECT_NAME}
main.cpp
utils/binary.cpp
utils/message.cpp
utils/header.cpp
)
target_link_libraries (
${PROJECT_NAME}
${Boost_LIBRARIES}
rados
rbd
Threads::Threads
)
Thanks to #HolyBlackCat, I solved the problem with static link.
Modified CMAKE
cmake_minimum_required(VERSION 3.2.0)
project(BinaryHelper VERSION 0.1.0)
find_package(Boost REQUIRED COMPONENTS json)
include_directories(${Boost_INCLUDE_DIR})
set(Boost_USE_STATIC_LIBS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lrados -std=c++17")
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
add_library(
boost_json
STATIC
IMPORTED
)
set_target_properties(
boost_json
PROPERTIES
IMPORTED_LOCATION /usr/local/lib/libboost_json.a
)
add_executable(
${PROJECT_NAME}
main.cpp
utils/binary.cpp
utils/message.cpp
utils/header.cpp
)
# target_link_libraries (
# ${PROJECT_NAME}
# ${Boost_LIBRARIES}
# rados
# rbd
# Threads::Threads
# )
target_link_libraries(
${PROJECT_NAME}
boost_json
rados
rbd
Threads::Threads
)
There is additional(modified) keywords, add_library, set_target_properties, target_link_libraries.

How to use intel opencl sdk in Clion in windows 10?

I have installed Intel opencl sdk for windows and opencl variable are added to the environment variables. I want to use this sdk with my Clion ide which I am unable to include it in my current project since it was CL/cl.hpp not found. How can add it to my project in Clion?
Cl/cl.hpp is located atC:\Program Files(x86)\IntelSWTools\OpenCL\sdk\include\CL
following is my CMakeLists.txt
project(tpch_framework)
# enable c++11
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_BUILD_TYPE "Release")
find_package(OpenMP REQUIRED)
find_package(OpenCL REQUIRED)
if (OPENMP_FOUND)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
# Configure required Boost libraries
set(BOOST_ROOT "" CACHE PATH "Boost build root (useful on Windows)")
option(Boost_USE_STATIC_LIBS
"Search for static boost libs" OFF)
option(Boost_USE_MULTITHREADED
"Search for multithreaded boost libs" ON)
option(Boost_USE_STATIC_RUNTIME
"Search for boost libs linked against static C++ runtime" OFF)
find_package(Boost 1.47.0 REQUIRED filesystem system)
# ensure that dependant libraries not explicitly specified here
# are found by the linker:
link_directories(${Boost_LIBRARY_DIRS})
include_directories(${Boost_INCLUDE_DIRS})
set(LIBS ${LIBS} ${Boost_LIBRARIES})
#Bring the headers into the project
include_directories(include)
FILE(GLOB_RECURSE INC_ALL "include/*.hpp")
#However, the file(GLOB...) allows for wildcard additions:
file(GLOB SOURCES "src/*.cpp")
add_library(tpch_framework ${SOURCES})
add_executable(framework main.cpp ${INC_ALL})
target_link_libraries(framework tpch_framework)
#target_link_libraries(framework stdc++fs)
target_link_libraries(framework ${LIBS})
You need to provide information about include directory for OpenCL headers like you provided for Boost headers. Also, you need to link OpenCL libraries with your target.
In your CMakeLists...
For include and link directories:
link_directories(${Boost_LIBRARY_DIRS} ${OpenCL_LIBRARY})
include_directories(${Boost_INCLUDE_DIRS} ${OpenCL_INCLUDE_DIRS})
For linking libraries:
set(LIBS ${LIBS} ${Boost_LIBRARIES} ${OpenCL_LIBRARY})

CPPREST SDK on CLion using CMake on Mac

I am attempting to use the CPPREST SDK in CLion on a Mac using CMake. I'm almost there, but I cannot seem to resolve the following linker error:
Undefined symbols for architecture x86_64:
"_ERR_remove_thread_state", referenced from:
boost::asio::ssl::detail::openssl_init_base::do_init::~do_init() in PongRemote.cpp.o
I have specified -lssl and -lcrypto, but still get this "thread state" error. Based on some research, it looks like it is coming from OpenSSL. I used Homebrew to install CPPREST.
I have tested this with literally just a main and the basic includes:
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
with a CMake of:
project(cpprest)
cmake_minimum_required(VERSION 3.8)
set(CMAKE_CXX_STANDARD 14)
# BOOST PACKAGE
find_package(Boost REQUIRED COMPONENTS
atomic
chrono
date_time
exception
filesystem
random
regex
serialization
system
thread
)
include_directories(${Boost_INCLUDE_DIRS})
IF (!Boost_FOUND)
MESSAGE("*** ERROR *** Boost package not found")
RETURN()
ENDIF ()
# Microsoft RESTful API Package (Casablanca)
set(CPPREST_LIBRARIES "/usr/local/opt/openssl/lib")
include_directories("/usr/local/opt/openssl/include")
# Compile and link
# Build the core library and executable
include_directories(${CMAKE_SOURCE_DIR})
set(SOURCE_FILES
main.cpp
)
set(LINK_LIBRARIES
${Boost_LIBRARIES}
${CPPREST_LIBRARIES}
-lssl
-lcrypto
)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${LINK_LIBRARIES})
After taking some time, the linking problem was due to the CMake find commands not working properly. I manually pointed directly to the libraries for both OpenSSL and RESTCPP and the problem was fixed.
Project(cpprest)
cmake_minimum_required(VERSION 3.8)
set(CMAKE_CXX_STANDARD 17)
# BOOST PACKAGE
set(Boost_USE_MULTITHREADED ON) # Default ON
set(Boost_USE_STATIC_LIBS ON) # Default OFF
set(Boost_USE_DEBUG_RUNTIME OFF) # Default ON
set(Boost_USE_DEBUG_PYTHON OFF) # Default OFF
set(Boost_USE_STLPORT OFF) # Default OFF
find_package(Boost REQUIRED COMPONENTS
atomic
chrono
date_time
exception
filesystem
program_options
random
regex
system
serialization
thread
)
IF (!Boost_FOUND)
MESSAGE("*** ERROR *** Boost package not found")
RETURN()
ENDIF ()
include_directories(${Boost_INCLUDE_DIRS})
MESSAGE("Boost_INCLUDE_DIRS:\t" ${Boost_INCLUDE_DIRS})
# Open SSL Package
set(OpenSSL_INCLUDE /usr/local/opt/openssl/include)
set(OpenSSL_LIBRARIES
/usr/local/opt/openssl/lib/libcrypto.dylib
/usr/local/opt/openssl/lib/libssl.dylib)
include_directories(${OpenSSL_INCLUDE})
# Microsoft RESTful API Package (Casablanca)
set(CppREST_INCLUDE /usr/local/opt/cpprestsdk/include)
set(CppREST_LIBRARIES /usr/local/opt/cpprestsdk/lib/libcpprest.dylib)
include_directories(${CppREST_INCLUDE})
# Compile and link
# Build the core library and executable
set(SOURCE_FILES main.cpp)
set(LINK_LIBRARIES
${Boost_LIBRARIES}
${OpenSSL_LIBRARIES}
${CppREST_LIBRARIES}
)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${LINK_LIBRARIES})

CMake with Boost 1.62.0: "No Boost libraries were found"

Using the following CMake code:
cmake_minimum_required(VERSION 3.6)
project(TrustLineManager)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(BOOST_ROOT D:/Tools/boost_1_62_0/)
set(Boost_INCLUDE_DIRS D:/Tools/boost_1_62_0/boost)
set(Boost_LIBRARY_DIRS D:/Tools/boost_1_62_0/libs)
set(BOOST_INCLUDEDIR C:/MinGW/include)
set(BOOST_LIBRARYDIR C:/MinGW/lib)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
find_package(Boost
1.62.0
COMPONENTS system
filesystem
REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(TrustLineManager ${Boost_LIBRARIES})
I get this error:
Error:Unable to find the requested Boost libraries.
Boost version: 1.62.0
Boost include path: D:/Tools/boost_1_62_0
Could not find the following static Boost libraries:
boost_system boost_filesystem
No Boost libraries were found. You may need to set BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.
What should I do to solve it?
EDIT:
I modified my CMake code into:
cmake_minimum_required(VERSION 3.6)
project(TrustLineManager)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
set(BOOST_ROOT "D:/Tools/boost_1_62_0")
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
find_package(Boost)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(TrustLineManager ${SOURCE_FILES})
target_link_libraries(TrustLineManager Boost::filesystem Boost::thread)
I have now this error:
Error:Target "TrustLineManager" links to target "Boost::filesystem" but the target was not found. Perhaps a find_package() call is missing for an IMPORTED target, or an ALIAS target is missing?
Here is a screenshot of Boost directory contents:
Obviously CMake finds Boost as it is able to detect its version (1.62.0).
CMake uses the file FindBoost.cmake to determine what libraries to link against.
This file is updated continuously when new boost versions appear.
There, support for Boost 1.62.0 is available only for CMake >= 3.7.0.
So just update your CMake version (or just the file FindBoost.cmake) and you will be fine.

Link boost libraries statically using CMake in CLion

CLion 1.2, with bundled CMake 3.3.2 and MinGW-w64 4.8.4
I need to get a single DLL in a result of building that no need any other libraries to work. But can't link Boost libraries statically. I bootstrapped and built Boost with corresponding MinGW.
cmake_minimum_required(VERSION 3.3)
project(SampleProject)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(BOOST_ROOT "..\\lib\\boost_1_59_0")
set(Boost_USE_STATIC_LIBS ON)
set(BOOST_COMPONENTS_NEEDED filesystem )
find_package(Boost 1.59.0 REQUIRED COMPONENTS ${BOOST_COMPONENTS_NEEDED})
if(NOT Boost_FOUND)
message(FATAL_ERROR "Could not find boost!")
endif()
include_directories(${Boost_INCLUDE_DIR})
set(SOURCE_FILES main.cpp)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--kill-at -static-libgcc -static-libstdc++")
add_library(${CMAKE_PROJECT_NAME} SHARED ${SOURCE_FILES})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}\\..\\..\\output")
target_link_libraries(${CMAKE_PROJECT_NAME} ${Boost_LIBRARIES})
Build output:
O:/SampleProject/Cpp/lib/boost_1_59_0/stage/lib/libboost_filesystem-mgw48-mt-d-1_59.a(operations.o): In function error':
O:\SampleProject\Cpp\lib\boost_1_59_0/libs/filesystem/src/operations.cpp:286: undefined reference toboost::system::system_category()'
What else should I do to link with boost?
UPDATE: there is a list of built libraries
libboost_filesystem-mgw48-1_59.a
libboost_filesystem-mgw48-d-1_59.a
libboost_filesystem-mgw48-mt-1_59.a
libboost_filesystem-mgw48-mt-d-1_59.a
libboost_filesystem-mgw48-mt-s-1_59.a
libboost_filesystem-mgw48-mt-sd-1_59.a
libboost_filesystem-mgw48-s-1_59.a
libboost_filesystem-mgw48-sd-1_59.a
libboost_system-mgw48-1_59.a
libboost_system-mgw48-d-1_59.a
libboost_system-mgw48-mt-1_59.a
libboost_system-mgw48-mt-d-1_59.a
libboost_system-mgw48-mt-s-1_59.a
libboost_system-mgw48-mt-sd-1_59.a
libboost_system-mgw48-s-1_59.a
libboost_system-mgw48-sd-1_59.a
This looks like a linker error suggesting that you are not linking to Boost::system
You need to add system to BOOST_COMPONENTS_NEEDED. Change this line and see if it helps
set(BOOST_COMPONENTS_NEEDED system filesystem )