How to stop cmake add wxjpeg.lib to visual studio project? - c++

I have a project that uses both OpenCv and wxWidgets in a static library. These two libraries have definitions for jpeg and hence are generating conflicts during compilation.
As I am not using jpeg which is inside wxwidget, I would like to remove this library from my application. I tested my application and if I remove this library manually from MSVC poroject, it works well.
In cmake I have this line to add wxwidgets to my project:
set(wxWidgets_CONFIGURATION msvc)
find_package(wxWidgets COMPONENTS core base adv REQUIRED)
include(${wxWidgets_USE_FILE})
How can I instruct cmake not to add wxjpeg.lib to the requested linked libraries?

Based on the documentation to this cmake module (link) I would say that adding
set(wxWidgets_EXCLUDE_COMMON_LIBRARIES TRUE)
before using the find_package command would be enough to exclude wxjpeg.lib. Since this also excludes other common libraries (e.g. png), you may have to explicitly include more in your call to find_package
find_package(wxWidgets COMPONENTS core base adv png REQUIRED)

Related

CMake: Create DLL including dependencies instead of separate dll's

Im writing a SDK for Windows and Mac OS in C++, and im using CMake.
On windows, I'd like the compiled DLL to contain all necessary dependencies, instead of having separate DLLs for all third party libraries im using.
Here are the relevant sections of the MakeFile:
find_package(OpenSSL REQUIRED)
find_package(CURL CONFIG REQUIRED)
find_package(nlohmann_json 3.2.0 REQUIRED)
find_package(spdlog REQUIRED)
find_package(unofficial-sqlite3 CONFIG REQUIRED)
....
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
...
target_link_libraries(${PROJECT_NAME} PRIVATE OpenSSL::Crypto CURL::libcurl nlohmann_json::nlohmann_json spdlog::spdlog_header_only unofficial::sqlite3::sqlite3)
This generates the following separate DLLs:
fmt.dll
libcrypto-1_1.dll
libcurl.dll
sqlite3.dll
zlib1.dll
Is it possible to create a library containing all dependecies, like it is on Mac OS with the generated dylib?
I'm using Vcpkg for simplicity but you should compile your dependencies as static libraries instead of shared.
If you're using vcpkg you can install the dependencies as static like such
vcpkg.exe install openssl:x86-windows-static
Make sure you run CMake with VCPKG_TARGET_TRIPLET set to x86-windows-static or whatever platform you're on.
As you can see example.dll is now statically linked to OpenSSL.
Cheers

VisualStudio CMake dynamic library: include/link all used functions in *single* dll

I have a VisualStudio-2019 C++ Project which uses CMake and Ninja to build a dll, the Project uses functions from a few Libraries like protobuf and spdlog, which I have installed using vcpkg.
When building, the output gets written to four distinct dll files and all of them are needed for the main-dll to run.
Below are two screenshots: left the current state and right the expected state.
The main.dll file should include all the functions it imports, the compiler shouldn't create separate dlls for each library.
I don't know knob I need to turn, I can imagine several ways to edit:
The C++ Code of the Project (Classes, inlining functions ?)
The CMakeList.txt
The Arguments of MSVC (compiler, linker flags)
The Arguments of Ninja
Where should I start ?
Setting the mentioned flags or appending -static to the import library components had no effect, I went as far as
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "-static")
set(CMAKE_MODULE_LINKER_FLAGS "-static")
set(CMAKE_SHARED_LINKER_FLAGS "-static")
set(CMAKE_STATIC_LINKER_FLAGS "-static")
But this didn't help a bit.
As it turned out this is a problem with vcpkg:
I had installed the packages with the triplet x64-windows, which builds for dynamic linkage, installing the packages with
vcpkg install --triplet=x64-windows-static protobuf spdlog makes static linking possible. If the static variants are not installed, the build proceeds silently with the dynamic ones.

Include Boost library in C++ cross platform project using CMake

I need to include a Boost library (specifically Context) in a C++ project that uses CMAKE as build management system.
Since, given the source code of the repository, the project needs to be built using cmake and make without any other software or library installation in the target system (unix,windows or whatever), I need to configure Cmake to take the source of Boost from my repository, compile it, and link it to my project without installing Boost library in the target system in a separated step.
Is this feasible?
CMake has a specific module for handling boost` libraries, see FindBoost.
The CMakeLists.txt file normally includes something like this to link to a boost library:
find_package(Boost REQUIRED COMPONENTS context )
if(Boost_FOUND)
target_include_directories(${PROJECT_NAME} PRIVATE ${Boost_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} INTERFACE Boost::context)
endif(Boost_FOUND)
This will just link the boost::context library. You must either build the boost::context lib files as suggested in #Hugo's answer, download them from somewhere like here or use a package manager to install them on linux.
If Context was header only, you would only require:
find_package(Boost REQUIRED COMPONENTS boost)
if(Boost_FOUND)
target_include_directories(${PROJECT_NAME} PRIVATE ${Boost_INCLUDE_DIRS})
endif(Boost_FOUND)
In either case you can include the boost::context files in your project and then set the variables BOOST_ROOT or BOOST_INCLUDEDIR as described in the FindBoost documentation.
Yes, you can use ExternalProject_Add, see the documentation at https://cmake.org/cmake/help/latest/module/ExternalProject.html
Take a look at the link below for an example of use which compiles boost
https://github.com/arnaudgelas/ExternalProject/blob/master/External-Boost.cmake
HTH

C++ How to run programs in Clion when you need to include OpenGL libraries?

Hello I need to work with OpenGL and want to create my project in Clion. But Clion cannot compile and run my projects because of the libraries I need to include. I can create my own makefile and run the program in terminal, but I want to do it in the IDE. How can I make this happen?
First make sure you installed all libraries correctly using the compiler you configured in clion/cmake. Assuminf you have a fresh CMakeLists.txt like
cmake_minimum_required(VERSION 3.3.2)
project(MyGL CPP)
add_executable(demo-run main.cpp)
For linking your libraries you need two things. First tell the compiler where to find the include files and second which libraries to link. You could just hard code you local installation like
target_link_libraries(demo-run path/to/glfw.lib path/to/opengl.lib path/to/jpeg.lib ...)
target_include_directories(demo-run PRIVATE path/to/glfw/include path/to/opengl/include path/to/jpeg/include ...)
however this is not very portable and if you want to work with another compiler or on another machine your project file will fail. Instead you can use the package system of cmake
find_package(PkgConfig REQUIRED)
pkg_search_module(GLFW REQUIRED glfw3)
find_package(JPEG REQUIRED)
find_package(GLEW REQUIRED)
find_package (OpenGL REQUIRED)
find_package (GLM REQUIRED)
target_link_libraries(demo-run ${GLFW_LIBRARIES} ${GLEW_LIBRARIES} ${JPEG_LIBRARIES} ${OPENGL_LIBRARIES})
target_include_directories(demo-run PRIVATE ${GLFW_INCLUDE_DIRS} ${GLEW_INCLUDE_DIR} ${JPEG_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} ${GLM_INCLUDE_DIR})
The glfw part is a bit tricky and works only on linux i guess see http://www.glfw.org/docs/3.0/build.html.
This code is not tested at all and you may need to specify some enviroment variables so cmake can find the packages or provide additional find scripts like https://github.com/lighttransport/nanogi/blob/master/cmake/FindGLM.cmake.
I would recommend to use the CMake build tool which does the work generating Makefiles for you and is also directly supported by clion. When you open the directory containing a CMakeLists.txt (CMake Project File) with clion, it should be automatically be loaded and compiled (if not just hit build)
A very simple example CMake project would look like this
cmake_minimum_required (VERSION 2.8.9)
project (OpenGl-Stuff)
include_directories(src)
add_executable(your-binary src/your-code.c src/your-code.h)
target_link_libraries(your-binary opengl)
# target_link_libraries will search for libopengl on standard system paths,
# maybe the library is not called libopengl, then you have to adjust the name above
this cmake project will generate the binary for you and link it against opengl

How to link QtMain in CMake with Qt5?

I upgraded my project code from Qt4 to Qt5. It uses CMake.
The conversion got well except for one line of Cmake commands related to Qt.
I can’t find in current documentation, like
http://qt-project.org/doc/qt-5.0/qtdoc/cmake-manual.html
http://qt-project.org/doc/qt-5.0/qtdoc/qtmain.html
How to link with QtMain from CMake (with Qt5)?
It is the only missing bit to convert my project.
Can someone point me to a doc explaining this or explain how to do it with Qt5? My Qt4 code worked correctly but I can't find the Cmake macro for Qt5.
EDIT> Here is the CMake file I have at the moment: https://bitbucket.org/klaim/aos_qt5/src/593c195c4c6889f6968d68fca018ef425783a063/tools/aosdesigner/CMakeLists.txt?at=wip_qt5
All qt5 necessary CMake macros have been set correctly I belive, the only thing that don't work is the linking to QtMain that do nothing, as expected since there should be a Qt5 specific way of doing it that I don't find in the Qt5 documentation.
You can browse the file history to see how it was working with Qt4.
From the Qt docs you linked to, it seems you can find Qt5Core instead of Qt5Widgets. That will create an imported target named Qt5::WinMain. From the Qt docs:
Imported targets are created for each Qt module. That means that the Qt5<Module>_LIBRARIES contains a name of an imported target, rather than a path to a library.
...
Each module in Qt 5 has a library target with the naming convention Qt5::<Module>
find_package( Qt5Widgets REQUIRED )
find_package( Qt5Core REQUIRED )
...
add_executable( aosdesigner WIN32 ${AOSDESIGNER_ALL_FILES} )
target_link_libraries( aosdesigner
${Boost_LIBRARIES}
utilcpp
aoslcpp
Qt5::WinMain # <-- New target available via find_package ( Qt5Core )
)
qt5_use_modules( aosdesigner Widgets )
I'd also recommend that you remove your two link_libraries calls since it's a deprecated command and I'd specify CMake version 2.8.9 rather than just 2.8 as the minimum required at the top of your CMakeLists.txt, since that's required for qt5_use_modules.
As of CMake 2.8.11 and Qt 5.1, linking to Qt5::WinMain is automatic/implicit if you specify WIN32 in your add_executable call, or otherwise set the WIN32_EXECUTABLE target property.
The presentation at
https://devdays.kdab.com/wp-content/uploads/2012/cmake.pdf
with video at
http://www.youtube.com/watch?feature=player_detailpage&v=GJ0kMsLbk6Q#t=751
describes the features which made it into CMake 2.8.11.
For more about CMake with Qt see
http://www.kdab.com/modern-cmake-with-qt-and-boost/
EDIT : Thanks to Archi comment (see below), simply add
target_link_libraries(<your_app> Qt5::WinMain)
or
target_link_libraries(<your_app> ${Qt5Core_QTMAIN_LIBRARIES})
in your application's CMakeLists.txt. Both syntaxes worked for me.