C / C++ Library Linking with CMake - c++

I need to use MongoDB C Drivers in a c++ project. I want to use CMake because the IDE i'm using is well integrated with it but the compiler doesn't recognize the MongoDB drivers
So, I've tried a couple more things and to provide you with a bit more information. I've made the following script:
cmake_minimum_required(VERSION 3.2)
project(sorting)
set(ENV{PKG_CONFIG_PATH} "/usr/lib64")
find_package(PkgConfig REQUIRED)
pkg_search_module(MONGO REQUIRED mongoc-1.0)
message(SEND_ERROR "A ${MONGO_FOUND}") # Error:A 1
message(SEND_ERROR "B ${MONGO_LIBRARIES}") # Error:B ssl;crypto;rt;mongoc-1.0;bson-1.0
message(SEND_ERROR "C ${MONGO_LIBRARY_DIRS}") # Error:C /usr/lib64
message(SEND_ERROR "D ${MONGO_LDFLAGS}") # Error:D -L/usr/lib64;-lssl;-lcrypto;-lrt;-lmongoc-1.0;-lbson-1.0
message(SEND_ERROR "E ${MONGO_LDFLAGS_OTHER}")# Error:E
message(SEND_ERROR "F ${MONGO_INCLUDE_DIRS}") # Error:F /usr/include/libmongoc-1.0;/usr/include/libbson-1.0
message(SEND_ERROR "G ${MONGO_CFLAGS}") # Error:G -I/usr/include/libmongoc-1.0;-I/usr/include/libbson-1.0
message(SEND_ERROR "H ${MONGO_CFLAGS_OTHER}") # Error:H
include_directories(${MONGO_LIBRARY_DIRS})
include_directories(${MONGO_INCLUDE_DIRS})
#link_directories(${MONGO_LIBRARY_DIRS})
#link_directories(${MONGO_INCLUDE_DIRS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_executable(sorting ${SOURCE_FILES})
target_link_libraries(sorting ${MONGO_LIBRARIES})
When i remove all the message() functions from my cmake file and try to build run the project whith the include_directories uncomented i get this error:
error while loading shared libraries: libmongoc-1.0.so.0: cannot open shared object file: No such file or directory
When i comment the include_directories and uncomment link_directories i get this error:
fatal error: mongoc.h: No such file or directory
#include <mongoc.h>
Also, just out of curiosity why is it that if i chage the name MONGO in pkg_search_module to something like MONGODB or MONG i get this error:
Error:None of the required 'mongoc-1.0' found

You need to tell cmake to link to the monog library, that is achieved by means of the
TARGET_LINK_LIBRARIES
command, in your specific case it would go right after the ADD_EXECUTABLE command, and exactly like
TARGET_LINK_LIBRARIES(sorting ${MONGO_DB_LIBRARIES})
Also, your PKG_SEARCH_MODULE seems to be wrong, it seems that it should be
PKG_SEARCH_MODULE(MONGO_DB REQUIRED libmongoc-1.0)

I am able to compile the mongo sample code given using
cmake_minimum_required(VERSION 2.8)
project(sorting)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
include_directories(/usr/include/libmongoc-1.0 /usr/include/libbson-1.0)
find_library(MONGODB_LIBRARY mongoc-1.0)
find_library(BSON_LIBRARY bson-1.0)
add_executable(sorting ${SOURCE_FILES})
target_link_libraries(sorting ${MONGODB_LIBRARY} ${BSON_LIBRARY})
Can you try with this CMakeFiles.txt ?
BTW it exists a mongo driver c++ for c++ projects !

I was finally able to do it!
The environment variable LD_LIBRARY_PATH was being overwritten by my IDE (CLION). I set it in the IDE settings to point to the library dir and now everything works fine.
This was the configuration i used:
cmake_minimum_required(VERSION 3.2)
project(sorting C)
set(ENV{PKG_CONFIG_PATH} "")
find_package(PkgConfig REQUIRED)
pkg_search_module(MONGO REQUIRED mongoc)
include_directories(${MONGO_INCLUDE_DIRS})
include_directories(${MONGO_LIBRARY_DIRS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.c)
add_executable(sorting ${SOURCE_FILES})
target_link_libraries(sorting ${MONGO_LIBRARIES} )

Related

CMake 3.22.4 does not compatible with GTest 1.10.0.20201025-1.1

I've build my unit test code on Ubuntu 21.10, CMake 3.18.4 and GTest 1.10.0.20201025-1.1.
I wrote CMakeList.txt file as this.
# The minimum version of CMake Required
cmake_minimum_required (VERSION 2.8.12)
# Any project name will suffice, this has connotaions when using advanced CMake Features
set(PROJECT_NAME tests)
project (${PROJECT_NAME})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# Just in case someone had the include files in seperate directory
include_directories(../include)
include_directories(..)
# This uses the complete student's library
aux_source_directory(.. SRC_LIST)
list(REMOVE_ITEM SRC_LIST "../main.cpp")
message ( STATUS "Compiling test_lib with following files ${SRC_LIST}" )
add_library(test_lib ${SRC_LIST})
# Now we make the gtests
set(GTEST_ROOT "/usr/src/gtest" CACHE PATH "Path to googletest")
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
if(NOT GTEST_LIBRARY)
message("GTest library not found")
endif()
add_executable(rawTests test_rawdata.cpp)
target_link_libraries(rawTests ${GTEST_LIBRARIES} pthread)
target_link_libraries(rawTests test_lib)
add_executable(timeTests test_time.cpp)
target_link_libraries(timeTests ${GTEST_LIBRARIES} pthread)
target_link_libraries(timeTests test_lib)
It works properly on my end.
But when I deliver this to my friend who uses CMake 3.22.4, it throws error look like this
Error Image
It's kind of weird issue and I didn't ever faced this sort of issue before.
I wonder anybody who has deep knowledge for CMake and GTest can help me to handle this.
Thank you in advance.

CMake build error: undefined reference to 'deflateEnd'

I'm trying to use zlib in my project. The CMakeLists.txt is as follows:
cmake_minimum_required(VERSION 3.5)
project(cmake-demo LANGUAGES CXX)
# The version number.
set(CMDemo_VERSION_MAJOR 0)
set(CMDemo_VERSION_MINOR 1)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(${PROJECT_SOURCE_DIR}/build/conan_paths.cmake)
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/build)
find_package(uwebsockets)
#ZLIB
if(ZLIB_FOUND)
set(INC_DIRS ${INC_DIRS} ${ZLIB_INCLUDE_DIRS})
set(LINK_LIBS ${LINK_LIBS} ${ZLIB_LIBS})
endif()
# Global approach
if(uwebsockets_FOUND)
set(INC_DIRS ${INC_DIRS} ${uwebsockets_INCLUDE_DIRS})
set(LINK_LIBS ${LINK_LIBS} ${uwebsockets_LIBS})
endif()
#libuv
if(libuv_FOUND)
set(INC_DIRS ${INC_DIRS} ${libuv_INCLUDE_DIRS})
set(LINK_LIBS ${LINK_LIBS} ${libuv_LIBS})
endif()
#usockets
if(usockets_FOUND)
set(INC_DIRS ${INC_DIRS} ${usockets_INCLUDE_DIRS})
set(LINK_LIBS ${LINK_LIBS} ${usockets_LIBS})
endif()
include_directories(${INC_DIRS})
add_executable(${PROJECT_NAME} main.cpp)
message("libs=${LINK_LIBS}")
target_link_libraries(${PROJECT_NAME} ${LINK_LIBS})
#output of message("${LINK_LIBS}")
C:/ProgramData/Miniconda3/Library/lib/z.lib;C:/Users/Sunway/.conan/data/libuv/1.41.0/_/_/package/9965605309592d7e617ec929633249a2031e4263/lib/libuv_a.a;C:/Users/Sunway/.conan/data/usockets/0.7.1/_/_/package/a24f5291464b4270092bce2e738cbf9f3cd53bb7/lib/libuSockets.a
I'm sure that ${LINK_LIBS} is correct, but it still doesn't work:
CMakeFiles/cmake-demo.dir/main.cpp.obj: In function `ZN3uWS15DeflationStreamD1Ev':
C:/Users/Sunway/.conan/data/uwebsockets/19.2.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/uWebSockets/PerMessageDeflate.h:186: undefined reference to `deflateEnd'
os: Windows10 x64
IDE: QtCreator4.14.2
compiler: MinGW 32-bit
The thing is, that you have to set the path to the library file as the target_link_libraries argument.
According to the documentation, if you want to link the library, each argument of target_link_libraries can be:
A library target name
A full path to a library file (e.g. /usr/lib/foo.so)
A plain library name (e.g. foo)
In your case I suggest you to add the complete path to the library.
I don't have all the code of your project, so I suggest you consider this minimal example:
add_executable(test main.cpp)
SET (ZLIB_ROOT "/tmp/zlib")
SET (ZLIB_INCLUDE_DIR "/tmp/zlib/include/")
SET (ZLIB_LIBRARY "/tmp/zlib/lib/libz.so.1.2.11")
FIND_PACKAGE (ZLIB REQUIRED)
MESSAGE (" zlib version major is " ${ZLIB_VERSION_MAJOR})
MESSAGE (" zlib version minor is " ${ZLIB_VERSION_MINOR})
MESSAGE (" zlib include is " ${ZLIB_INCLUDE_DIR})
MESSAGE (" zlib libraries are " ${ZLIB_LIBRARIES})
target_link_libraries(test ${ZLIB_LIBRARIES})
After downloading the latest zlib release and installing it in /tmp, everything works as expected.
Update: as #uilianries mentioned, since you are using conan, you have cmake_find_package generator that defines variables with all the necessary paths. So you don't need to set the paths in CMakeLists.txt manually.
It is because the libzlib.a is for x86_64 while the compiler is MinGW-32bit; I solved the problem by execute the command
$conan install .. --build=missing --pr=x86_32
the x86_64 is a profile(x86) generated by conan.

Linking external HDFql library in CMake

I have downloaded the HDFql library and put the whole lot in /usr/local/ in my linux system. I now wish to use this library in a ROS application, so I have tried to link it in my CMakeList, which looks as following:
cmake_minimum_required(VERSION 3.2)
project(data_generator)
add_compile_options(-std=c++11)
set(CMAKE_BUILD_TYPE Release) # Release, RelWithDebInfo
set(CMAKE_CXX_FLAGS "-std=c++11 -pthread ${CMAKE_CXX_FLAGS}")
find_package(catkin_simple REQUIRED)
catkin_simple(ALL_DEPS_REQUIRED)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
set(HDFQL_ROOT "/usr/local/hdfql-2.1.0")
include_directories(${HDFQL_ROOT}/include)
find_library(HDFQL_LIB HDFql)
if (HDFQL_LIB)
message("Library(HDFQL_LIB) found in ${HDFQL_LIB}")
else()
message(FATAL_ERROR "Library (HDFQL_LIB) not found")
endif()
cs_add_executable(
${PROJECT_NAME}
src/main.cpp
src/data_create.cpp
src/event_definitions.cpp
)
target_include_directories(${PROJECT_NAME}
PUBLIC "${HDFQL_ROOT}/include"
)
target_link_libraries(${PROJECT_NAME}
${OpenCV_LIBRARIES}
${HDFQL_LIB}
)
# CMake Indexing
FILE(GLOB_RECURSE LibFiles "include/*")
add_custom_target(headers SOURCES ${LibFiles})
cs_install()
cs_export()
When I build this, it works fine and outputs the message:
Library(HDFQL_LIB) found in /usr/local/hdfql-2.1.0/lib/libHDFql.so
with the following in my main.cpp file:
#include <HDFql.hpp>
....
std::cout <<"HDFql version: " << HDFql::Version << std::endl;
the output is: HDFql version: 2.1.0.
However, as soon as I try to actually use functions of the library - for example:
#include <HDFql.hpp>
....
std::cout <<"HDFql version: " << HDFql::Version << std::endl;
HDFql::execute("CREATE FILE /home/user/test.h5");
I get the error:
main.cpp:(.text+0x1858): undefined reference to `HDFql::execute(char const*)'
This suggests to me that while CMake has no issue with the includes, it is having trouble linking the actual library (ie including the libHDFql.a/libHDFql.so files). Can anyone tell me what I'm doing wrong here?
Many thanks!
The problem was that I needed to include the library /usr/local/hdfql-2.1.0/wrapper/cpp/libHDFql.so, where I was using /usr/local/hdfql-2.1.0/lib/libHDFql.so. It's pretty maddening, since the reference manual doesn't make any mention of this and I spent way too long figuring this out. Ohwell, I hope this helps anyone else with this problem.
For reference, here is a minimal catkin-style CMakeLists that will work:
cmake_minimum_required(VERSION 3.2)
project(project_name)
add_compile_options(-std=c++11)
find_package(catkin_simple REQUIRED)
catkin_simple(ALL_DEPS_REQUIRED)
set(HDFQL_ROOT "path/to/hdfql-2.1.0")
include_directories(${HDFQL_ROOT}/include)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS "-std=c++11 -pthread ${CMAKE_CXX_FLAGS}")
cs_add_executable(
${PROJECT_NAME}
# your source file 1
# your source file 2
# ...
)
target_include_directories(${PROJECT_NAME}
PUBLIC "${HDFQL_ROOT}/include"
)
target_link_libraries(
${PROJECT_NAME}
${OpenCV_LIBRARIES}
)
target_link_libraries(
${PROJECT_NAME}
"${HDFQL_ROOT}/wrapper/cpp/libHDFql.so"
)
Of course the absolute paths aren't very pretty, the alternative is to add /usr/local/hdfql-2.1.0/lib to the environment variable CMAKE_PREFIX_PATH (eg export CMAKE_PREFIX_PATH="/usr/local/hdfql-2.1.0/lib:$CMAKE_PREFIX_PATH").

CMake does not build the added sub-directory first

I am writing a C++ project that uses Poco Net library. I use CMake to configure the project.
I would like to add Poco as a sub-directory to my project so that it is built in my main project. Here is my shortened main CMakeLists.txt
cmake_minimum_required(VERSION 3.2)
project(FunProj)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
message(STATUS "Building in ${CMAKE_BUILD_TYPE} mode...")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(HEADER_FILES IDataProvider.h DataProvider.h)
set(SOURCE_FILES main.cpp
DataProvider.cpp)
set(POCO_STATIC ON)
ADD_SUBDIRECTORY(poco)
include_directories(${CMAKE_SOURCE_DIR}/poco/Net/include)
include_directories(${CMAKE_SOURCE_DIR}/poco/Foundation/include)
link_directories(${CMAKE_CURRENT_BINARY_DIR}/poco/lib)
add_executable(FunProj ${SOURCE_FILES} ${HEADER_FILES})
target_link_libraries(${EXEC_NAME} PocoNet)
When I run cmake it configures everything including Poco but when I run make it does not compile the Poco libraries. It only compiles the main.o and DataProvider.o and then the linker fails with an error that libPocoNet.a does not exist.
What is the problem and how may one solve it?
Thank you.

Building wxWidgets 3.1.0 on CLion (Ubuntu)

I am currently trying to build wxWidgets-3.1.0 on a CLion 1.3 project. I use Ubuntu 16.04 (64 bit). Basically, I edited the CMakeLists.txt file like this:
cmake_minimum_required(VERSION 3.5)
project(WxProva)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules"
${CMAKE_MODULE_PATH})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_executable(WxProva ${SOURCE_FILES})
find_package(wxWidgets)
include_directories(${wxWidgets_INCLUDE_DIRS})
target_link_libraries(WxProva ${wxWidgets_LIBRARIES})
The "External Libraries" section also shows me wxWidgets, but when it comes to write some lines on my main.cpp, everything related with the library seems to be unreachable by the compiler (it's all written in red, like an error). Anyway, if I try to compile, that's the result:
/home/federico/ClionProjects/WxProva/main.cpp:2:35: fatal error: wxWidgets-3.1.0/include: File o directory non esistente
compilation terminated.
Which is like "File or directory doesn't exists."
How can I fix this?
After some experiments here solution. You can just copy it and change some information and ready to build and run.
cmake_minimum_required(VERSION 3.7)
project(Your_Project_Name) //any name for your project
set(CMAKE_CXX_STANDARD 11)
set(wxWidgets_ROOT_DIR </usr/include/wx-3.0-unofficial>) // here I am giving where to search for wxwidgets library. it can be different for you
set(wxWidgets_CONFIGURATION mswu)
find_package(wxWidgets COMPONENTS core base REQUIRED)
include(${wxWidgets_USE_FILE})
set(SOURCE_FILES main.cpp)
add_executable(FirstC ${SOURCE_FILES})
target_link_libraries(FirstC ${wxWidgets_LIBRARIES})
For more Information read https://wiki.wxwidgets.org/CMake
Edit 1
Here you shouldn't even add some compile and link config (wx-config --cxxflags and wx-config --libs) as it is necessary in NetBeans
Here is example configuration for macOS 10.14.4 (Mojave) and CLion 2019.1
(/usr/local is folder where I installed wxWidgets)
cmake_minimum_required(VERSION 3.14)
project(wx1Test)
set(CMAKE_CXX_STANDARD 14)
set(wxWidgets_ROOT_DIR </usr/local/include/wx-3.1>)
set(wxWidgets_CONFIGURATION mswu)
find_package(wxWidgets COMPONENTS core base REQUIRED)
include(${wxWidgets_USE_FILE})
set(SOURCE_FILES main.cpp)
add_executable(wx1Test ${SOURCE_FILES})
target_link_libraries(wx1Test ${wxWidgets_LIBRARIES})