linking mongocxx using cmakelists file in Linux - linux

i am new to cmake and also to mongocxx. I have installed the mongocxx using the instructions given on the site http://mongocxx.org/mongocxx-v3/. My installatio is fine. Now I am trying to connect with mongodb using cmake in my project. When i write the following cmakelists.txt file
cmake_minimum_required(VERSION 3.15)
project(PROJECT_NAME)
set(CMAKE_CXX_STANDARD 14)
add_executable(PROJECT_NAME main.cpp)
find_package(libmongocxx REQUIRED)
find_package(libbsoncxx REQUIRED)
include_directories(${LIBMONGOCXX_INCLUDE_DIR})
include_directories(${LIBBSONCXX_INCLUDE_DIR})
include_directories("/usr/local/include/mongocxx/v_noabi")
include_directories("/usr/local/include/bsoncxx/v_noabi")
include_directories("/usr/local/include/libmongoc-1.0")
include_directories("/usr/local/include/libbson-1.0")
include_directories("/usr/local/lib")
target_link_libraries(PROJECT_NAME ${LIBMONGOCXX_LIBRARIES})
target_link_libraries(PROJECT_NAME ${LIBBSONCXX_LIBRARIES})
it gives me following error :
CMake Error at CMakeLists.txt:8 (find_package):
By not providing "Findlibmongocxx.cmake" in CMAKE_MODULE_PATH this project
has asked CMake to find a package configuration file provided by
"libmongocxx", but CMake did not find one.
Could not find a package configuration file provided by "libmongocxx" with
any of the following names:
libmongocxxConfig.cmake
libmongocxx-config.cmake
Add the installation prefix of "libmongocxx" to CMAKE_PREFIX_PATH or set
"libmongocxx_DIR" to a directory containing one of the above files. If
"libmongocxx" provides a separate development package or SDK, be sure it
has been installed.
-- Configuring incomplete, errors occurred!
See also "/home/fedora/testmongo/build/CMakeFiles/CMakeOutput.log".
I also tried to run my cpp file with this method given on above website.
code of my cpp file is
#include <cstdint>
#include <iostream>
#include <vector>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/stdx.hpp>
#include <mongocxx/uri.hpp>
#include <mongocxx/instance.hpp>
#include <bsoncxx/builder/stream/helpers.hpp>
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/builder/stream/array.hpp>
using bsoncxx::builder::stream::close_array;
using bsoncxx::builder::stream::close_document;
using bsoncxx::builder::stream::document;
using bsoncxx::builder::stream::finalize;
using bsoncxx::builder::stream::open_array;
using bsoncxx::builder::stream::open_document;
mongocxx::instance instance{}; // This should be done only once.
int main() {
std::cout << "Hello, World!" << std::endl;
mongocxx::client conn{ mongocxx::uri{ "mongodb://localhost:27017" } };
auto coll = conn["test"]["coll"];
std::vector<bsoncxx::document::value> documents;
for(int i = 0; i < 100; i++) {
documents.push_back(bsoncxx::builder::stream::document{} << "i" << i
<< finalize);
}
coll.insert_many(documents);
return 0;
}
and im trying to compile it with this command. its not giving any error
c++ --std=c++11 .cpp
-I/usr/local/include/mongocxx/v_noabi -I/usr/local/include/libmongoc-1.0
-I/usr/local/include/bsoncxx/v_noabi -I/usr/local/include/libbson-1.0
-L/usr/local/lib -lmongocxx -lbsoncxx
It complies without any errors and also generate output file a.out, but i don't know how to run that output file. its not running with
./a.out
gives following error
./a.out: error while loading shared libraries:
libmongocxx.so._noabi: cannot open shared object file: No such file
or directory """" This is the exact error i got
what should i do to correct this error or run the below executable file?

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/mongo-cxx-driver/lib64
These step resolved my problem

Use this as your CMakeLists.txt. Change $YOUR_PROJECT_NAME with your project's name.
cmake_minimum_required(VERSION 3.5)
if(POLICY CMP0025)
cmake_policy(SET CMP0025 NEW)
endif()
project($YOUR_PROJECT_NAME CXX)
if(NOT DEFINED CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 11)
endif()
set(CMAKE_CXX_EXTENSIONS OFF)
if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
endif()
find_package(mongocxx REQUIRED)
add_executable(${PROJECT_NAME} main.cpp)
# Visual Studio pre 2017 requires boost polyfill.
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND CMAKE_CXX_STANDARD LESS 17)
find_package(Boost 1.56.0 REQUIRED)
if (CMAKE_VERSION VERSION_LESS 3.15.0)
target_include_directories(${PROJECT_NAME} PRIVATE ${Boost_INCLUDE_DIRS})
else()
target_link_libraries(${PROJECT_NAME} PRIVATE Boost::boost)
endif()
endif()
target_link_libraries(${PROJECT_NAME}
PRIVATE mongo::mongocxx_shared
)
add_custom_target(run
COMMAND ${PROJECT_NAME}
DEPENDS ${PROJECT_NAME}
WORKING_DIRECTORY ${CMAKE_PROJECT_DIR}
)
get_target_property(LIBMONGOCXX_DEFINITIONS mongo::mongocxx_shared INTERFACE_COMPILE_DEFINITIONS)
list(FIND LIBMONGOCXX_DEFINITIONS "BSONCXX_STATIC" LIST_IDX)
if (${LIST_IDX} GREATER -1)
message(FATAL_ERROR "Expected BSONCXX_STATIC to not be defined")
endif()
list(FIND LIBMONGOCXX_DEFINITIONS "MONGOCXX_STATIC" LIST_IDX)
if (${LIST_IDX} GREATER -1)
message(FATAL_ERROR "Expected MONGOCXX_STATIC to not be defined")
endif()

Related

Linker error compiling c-source using wininet with Mingw-w64

I have a problem compiling c-source on windows. I use functions of wininet and got a linker error.
I use this version g++.exe (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 8.1.0
sample code:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <wininet.h>
int main (int argc, char **argv)
{
InternetOpen("WebReader", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
return 0;
}
the compile statement wirh error:
"C:\Program Files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin\g++.exe" -lwininet -g test.c -o test.exe
C:\Users\peter\AppData\Local\Temp\ccfXocKI.o: In function `main':
D:\source\mingw\ShellHost/test.c:9: undefined reference to `_imp__InternetOpenA#20'
collect2.exe: error: ld returned 1 exit status
Can anyone help?
You should link with Wininet.lib as InternetOpenA documentation says (see Requirements part).
I realize this was posted almost two years ago, but I wanted to expand on nevilad's answer to help someone in the future:
As nevilad said, adding the Wininet library as an additional dependency should fix this issue.
In Visual Studios IDE... Project > Properties > Configuration Properties > Linker > Input > Additional Dependencies > add "Wininet.lib" to the list

How do I write the cmake script for clion to include glfw?

cmake_minimum_required(VERSION 3.15)
project(hello)
find_package(PkgConfig REQUIRED)
pkg_search_module(GLFW REQUIRED glfw3)
set(CMAKE_CXX_STANDARD 11)
add_executable(hello main.cpp)
INCLUDE_DIRECTORIES(${GLFW_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(hello ${GLFW_STATIC_LIBRARIES})
It tells me
CMake Error at /home/user/.local/share/JetBrains/Toolbox/apps/CLion/ch-0/193.5233.144/bin/cmake/linux/share/cmake-3.15/Modules/FindPkgConfig.cmake:696 (message):
None of the required 'glfw3' found
when I try to build it. My glfw folder is located at /usr/local/include/GLFW.
AFAIK, glfw3 is using CMake as the build system,
(src: packages.debian.org/fr/sid/amd64/libglfw3-dev/filelist)
which uses modern CMake, so you don't need GLFW_INCLUDE_DIRS etc...
Inside this file /usr/lib/cmake/glfw3/glfw3Targets.cmake (loaded by /usr/lib/cmake/glfw3/glfw3Config.cmake), you'll see:
...
# Create imported target glfw
add_library(glfw SHARED IMPORTED)
set_target_properties(glfw PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "GLFW_DLL"
INTERFACE_INCLUDE_DIRECTORIES "/usr/include"
)
...
So you can simply use:
find_package(glfw3 REQUIRED)
...
target_link_libraries(Foo glfw)
ps: same as my previous comment

linking SDL2 libraries with pkg-config

I am using Ubuntu 14.04LTS. I have installed the SDL2 libraries both by compiling from source (method1 https://askubuntu.com/questions/344512/what-is-the-general-procedure-to-install-development-libraries-in-ubuntu) and using sudo apt-get install libsdl2-dev.
As I understand, the former installed the libraries and headers in /usr/local/(lib and include), while the latter installs them system wide in /usr/(lib and include).
When I tried to compile a simple code to test the functionality:
#include <SDL.h>
#include <stdio.h>
int main(int argc, char* argv[]) {SDL_Window *window;
// Declare a pointer
SDL_Init(SDL_INIT_VIDEO); // Initialize SDL2
// Create an application window with the following settings:
window = SDL_CreateWindow(
"An SDL2 window", // window title
SDL_WINDOWPOS_UNDEFINED, // initial x position
SDL_WINDOWPOS_UNDEFINED, // initial y position
640, // width, in pixels
480, // height, in pixels
SDL_WINDOW_OPENGL // flags - see below
);
// Check that the window was successfully created
if (window == NULL) {
// In the case that the window could not be made...
printf("Could not create window: %s\n", SDL_GetError());
return 1;
}
// The window is open: could enter program loop here (see SDL_PollEvent())
SDL_Delay(3000); // Pause execution for 3000 milliseconds, for example
// Close and destroy the window
SDL_DestroyWindow(window);
// Clean up
SDL_Quit();
return 0;
using: g++ sdl_test.cpp -o sdlout
the compiler outputs:
sdltest.cpp:2:17: fatal error: SDL.h: No such file or directory
#include <SDL.h>
^
compilation terminated.
if I change to #include <SDL2/SDL.h> I get the following error:
/tmp/cc05JSKn.o: In function `main':
sdltest.cpp:(.text+0x15): undefined reference to `SDL_Init'
sdltest.cpp:(.text+0x3a): undefined reference to `SDL_CreateWindow'
sdltest.cpp:(.text+0x4a): undefined reference to `SDL_GetError'
sdltest.cpp:(.text+0x6d): undefined reference to `SDL_Delay'
sdltest.cpp:(.text+0x79): undefined reference to `SDL_DestroyWindow'
sdltest.cpp:(.text+0x7e): undefined reference to `SDL_Quit'
collect2: error: ld returned 1 exit status
Which are the basic functions, so I assume that the shared object libraries are not linked correctly.
I also tried: g++ -Wall sdltest.cpp -o outsdl -I /usr/local/include -L /usr/local/lib
to specify the paths, but again I get:
sdltest.cpp:2:17: fatal error: SDL.h: No such file or directory
#include <SDL.h>
^
compilation terminated.
The only command that worked and successfully compiled, is when using pkg-config g++ sdltest.cpp -o outsdl $(pkg-config --cflags --libs sdl2)
Therefore, I have the following questions:
1) Why is pkg-config necessary and how do compilation and linking flags work?
2) Is it possible to do something else in order to make the compilation command simpler?
3) (if not explained previously) What is the difference between pkg-config and using -I and -L which do not work?
4) what does $(...) actually do in the command line and is it completely the same as `...` ?
Thank you.
The pkg-config command is a more-or-less cross-platform or cross-distro way to provide the correct flags to your compiler to allow it to find header and library files. That way, your system can store files in different locations and everyone can use the same commands to compile your code. It also helps resolve any special requirements of the library you're trying to use.
Using $() is the same as using backticks, so you can execute what is inside the parentheses in order to see what extra arguments are being passed to your compiler to make it work. Here is what I get on my machine when I run pkg-config --cflags --libs sdl2:
-D_REENTRANT -I/usr/include/SDL2 -lSDL2
The reason you're getting SDL.h: No such file or directory is because pkg-config adds -I/usr/include/SDL2 to the include search paths so you can include SDL.h in your code (without the SDL2 subdirectory).
The reason you get undefined reference errors is because you don't have -lSDL2 (which tells the compiler to link libSDL2).

Getting load library or linking error for XCB plugin of statically linked Qt5

Trying to create C++ Qt5.6.1 application and start it on Debian.
Getting either link error or load library error.
Qt build to a static libs, used configuration
configure -release -confirm-license -opensource -static -no-dbus -no-openssl -no-qml-debug -no-opengl -qt-freetype -qt-xcb -nomake tools -nomake tests -nomake examples -no-sql-db2 -no-sql-oci -no-sql-tds -no-sql-sqlite2 -no-sql-odbc -no-sql-ibase -no-sql-psql -skip doc -skip imageformats -skip webchannel -skip webengine -skip webview -skip sensors -skip serialport -skip script -skip multimedia
Project created with Cmake, libs are specified in this way:
SET(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "${QT5_LIB_ROOT}/cmake")
FIND_PACKAGE(Qt5Core REQUIRED)
FIND_PACKAGE(Qt5Gui REQUIRED)
FIND_PACKAGE(Qt5Widgets REQUIRED)
FIND_PACKAGE(Qt5Network REQUIRED)
FIND_PACKAGE( PNG REQUIRED )
FIND_PACKAGE( ZLIB REQUIRED)
FIND_PACKAGE( Threads REQUIRED )
IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
SET(QT_LIBS
libqtharfbuzzng_debug.a
libqtpcre_debug.a
libQt5PlatformSupport_debug.a
libxcb-static_debug.a
)
ELSE()
SET(QT_LIBS
libqtharfbuzzng.a
libqtpcre.a
libQt5PlatformSupport.a
libxcb-static.a
)
ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug")
SET(OS_SPECIFIC_LIBS
dl
Qt5::QXcbIntegrationPlugin
${CMAKE_THREAD_LIBS_INIT}
${ZLIB_LIBRARIES}
${PNG_LIBRARY} )
FOREACH(lib_name ${QT_LIBS})
IF(NOT EXISTS ${QT5_LIB_ROOT}/${lib_name})
MESSAGE(FATAL_ERROR "Could not locate required Qt lib ${QT5_LIB_ROOT}/${lib_name}")
ENDIF()
LIST(APPEND OS_SPECIFIC_LIBS ${QT5_LIB_ROOT}/${lib_name})
ENDFOREACH(lib_name)
And if I'm importing XCB plugin in the code ( Q_IMPORT_PLUGIN(QXcbIntegrationPlugin) it gives me link error:
/Qt5/plugins/platforms/libqxcb.a(qxcbmain.o): In function `QXcbIntegrationPlugin::create(QString const&, QStringList const&, int&, char**)':
qxcbmain.cpp:(.text+0x67): undefined reference to `QXcbIntegration::QXcbIntegration(QStringList const&, int&, char**)'
Anf if I don't import plugin - it just not start with error:
This application failed to start because it could not find or load the Qt platform plugin "xcb"
Any help? advice?
Thanks.
Solution was simple - just link with proper system libs:
fixed with adding
FIND_PACKAGE( X11 REQUIRED )
SET(OS_SPECIFIC_LIBS
...
xcb
X11-xcb
${X11_LIBRARIES}
)
(nvm the comment above, I found the problem)
To add to Ation answer, the "future proof" way I found to debug this is to use qmake for a minimal sample.
testcase.pro:
QT += core gui
QTPLUGIN.platforms = qminimal qxcb
CONFIG -= import_plugins
CONFIG += static
SOURCES += main.cpp
main.cpp:
#include <QCoreApplication>
#include <QDebug>
#include <QtPlugin>
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
qDebug() << "Does something!";
return app.exec();
}
Once this exist, run qmake and make. The make output will contain all -l**** you need to put in the CMake project CMAKE_CXX_LINK_EXECUTABLE variable. I can be automated.
The solution isn't simple. Maybe you doing something wrong if you are here. But you need to link res/archdatadir/plugins/platforms/libqxcb.a and lib/libQt{$Qt_MAJOR_VERSION}XcbQpa.a
Dirty example for cmake is here https://github.com/Jihadist/StaticQtPlugin/blob/master/CMakeLists.txt#L56 and dont't forget Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)
Thanx to https://stackoverflow.com/users/1672598/emmanuel-lepage-vallee

Getting CMake to build shared library for MSVC [duplicate]

This question already has answers here:
CMake link shared library on Windows
(3 answers)
Closed 6 years ago.
I've been building C and C++ projects in unix environments using CMake. However, I want to also start compiling in MSVC and I'm trying to get my head around the cmake documentation but I'm getting stuck.
I keep getting the following message when I try to build.
LINK : fatal error LNK1104: cannot open file 'Debug\MyLibrary.lib' [C:\sandbox\projects\cpp\DummyChelloWorld\build\ma
inProgram.vcxproj]
Can you tell me what I'm doing wrong?
CMakeLists.txt
cmake_minimum_required(VERSION 3.4)
project(helloWorld)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
include(GenerateExportHeader)
ADD_LIBRARY(MyLibrary SHARED myShared.cpp)
set(SOURCE_FILES main.cpp)
GENERATE_EXPORT_HEADER( MyLibrary
BASE_NAME MyLibrary
EXPORT_MACRO_NAME MyLibrary_EXPORT
EXPORT_FILE_NAME ${CMAKE_BINARY_DIR}/MyLibrary_Export.h
STATIC_DEFINE MyLibrary_BUILT_AS_STATIC
)
add_executable(mainProgram ${SOURCE_FILES})
TARGET_LINK_LIBRARIES(mainProgram MyLibrary)
TARGET_INCLUDE_DIRECTORIES(mainProgram PUBLIC exports)
main.cpp
#include "myShared.h"
int main() {
sayHI();
return 0;
}
myShared.cpp
#include <iostream>
#include "myShared.h"
using namespace std;
void sayHI() {
cout << "Hello World lib" << endl;
}
myShared.h
#ifndef HELLOWORLD_HELLO_H
#define HELLOWORLD_HELLO_H
void sayHI();
#endif //HELLOWORLD_HELLO_H
Turning my comment into an answer
For CMake Version >= 3.4
Just use CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS:
cmake_minimum_required(VERSION 3.4)
project(helloWorld)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS 1)
add_library(MyLibrary SHARED myShared.cpp)
set(SOURCE_FILES main.cpp)
add_executable(mainProgram ${SOURCE_FILES})
TARGET_LINK_LIBRARIES(mainProgram MyLibrary)
For CMake Version < 3.4
You need to declare your functions/symbols as exported. So in your case, you have to modify the following files:
myShared.h
#ifndef HELLOWORLD_HELLO_H
#define HELLOWORLD_HELLO_H
#include "MyLibrary_Export.h"
void MyLibrary_EXPORT sayHI();
#endif //HELLOWORLD_HELLO_H
CMakeLists.txt
cmake_minimum_required(VERSION 3.4)
project(helloWorld)
set(CMAKE_CXX_STANDARD 11)
include(GenerateExportHeader)
add_library(
MyLibrary
SHARED
myShared.cpp
myShared.h
MyLibrary_Export.h
)
GENERATE_EXPORT_HEADER(
MyLibrary
BASE_NAME MyLibrary
EXPORT_MACRO_NAME MyLibrary_EXPORT
EXPORT_FILE_NAME MyLibrary_Export.h
STATIC_DEFINE MyLibrary_BUILT_AS_STATIC
)
target_include_directories(MyLibrary PUBLIC "${CMAKE_CURRENT_BINARY_DIR}")
set(SOURCE_FILES main.cpp)
add_executable(mainProgram ${SOURCE_FILES})
TARGET_LINK_LIBRARIES(mainProgram MyLibrary)
I've
added MyLibrary_EXPORT to your function declaration
added the CMAKE_CURRENT_BINARY_DIR to the shared libraries include paths (to point to the generated export definitions header)
made use of the more cross-platform CMAKE_CXX_STANDARD definition.
Alternative
References
cmake link shared library on Windows
Export all symbols when creating a DLL

Resources