How to Integrate a CMake Project with GYP-Based Libraries - c++

I've been building cross-platform applications using C++ and CMake. Unfortunately many libraries do not include CMake project descriptions. For example Google supported projects frequently use GYP.
Here are some of the approaches I've taken for this problem:
Find a CMake project description for the library on the web
Write a project description using CMake
Finding or writing CMakeLists.txt descriptions for libraries is a maintenance problem. As the library is updated, so too must my CMake description. Also the project files created by the library's authors are more likely to be correct.
How specifically should I integrate GYP projects into my CMake-based software? Is duplicating the project description in CMake the best approach, or is there some feature of CMake that I am missing?
What are some of the general approaches to dealing with this class of problems in CMake? What about libraries that include a set of project files for various platforms/IDEs? Does CMake provide a way to integrate these projects into mine?

Use the ExternalProject module
http://www.cmake.org/cmake/help/v3.0/module/ExternalProject.html

Not sure if the output is usable for your purposes but gyp can generate Cmake projects gyp -f cmake mygypfile.gyp. Your CMakeLists.txt will be in out/[Configuration] (configuration can be Debug, Release, etc)

Related

How to setup complex project with Visual Studio 2022?

I have project that I was developing for years in Linux.
It depends on MKL, libxml++, GSL and armadillo library.
Its installation structure is done in CMake and project is formed by building a shared library and couple of executables that link to it. There are about 20 classes in the library.
Project structure is:
--src
--executable1.cpp
--executable2.cpp
--mysharedlib
--class1.h
--class1.cpp
--...
My question is how to install and run this code in Visual Studio in Windows.
I never used VS before and am still going through tutorials. I managed to run my code by installing Ubuntu on WSL, but I I'd like a VS solution as it'd be handy to pass to user not familiar with Linux.
I tried opening the project directory with VS, hoping CMAKE would do all the magic, but expectedly it cannot locate the dependent libraries, so I am now going through web looking how to integrate each to VS. I managed to find armadillo and mkl guide, but I am lost on how to link these libraries to my project codes and whether I should abandon its current cmake setup and start building the code structure differently in VS.
Any links to useful VS tutorials and advices how to this are greatly appreciated.
VS does have support for CMake, although I have no idea how well VS integrates CMake. If you're not set on using VS, you might want to look into an IDE that uses CMake at it's core, Clion comes to mind. That being said, when coming from Linux you don't have the (initial) luxury of simply installing all the dependencies via a preinstalled package manager.
In order for CMake to find your dependencies (assuming you've configured them by using find_package()) you should add the sources of your dependencies to your project in a thirdparty folder (name is up to you) and add these dependencies using add_subdirectory() instead. This will compile all your dependencies from source, so you might have to configure these dependencies yourself (look into the documentation of your dependencies on how to build them from source).
Another way is to use a package manager that is available on Windows to download, compile and provide your dependencies to your build tools. vcpkg comes to mind, claiming to integrate well with CMake by providing a toolchain file that you can pass to CMake when building your project. You might even be able to configure VS to automatically pass this toolchain to CMake whenever it's invoked.
From personal experience, there is no need to convert an existing project to the VS project structure. There's plenty of available solutions and tools available on Windows to work with CMake projects. Going with the cross-platform approach should be preferred unless you're only targeting Windows, using VS to it's fullest then might give you some additional quality of life.
If you have more specific questions regarding this, I suggest that you update your original post or to create separate, specific questions regarding the processes involved in setting up an existing CMake project on Windows.

C++ how to manage dependencies (use libraries from github for example)

I'm very new to C++ world, so please, sorry for such a dummy question. I googled a little, but wasn't able to find a proper answer.
My question is fairly simple - how should I use libraries in C++ world. For example in Java - there is maven and gradle for this task. In Python - I use pip. In javascript npm and bower do all the stuff. In C# you use nuget or just adding DLL lib to your project. But looks like in C++ things isn't such easy.
I found a tool, called conan but amount of libraries they have is pretty small and does not include any what I'm looking for.
So, for example - I want to use nlp lib meta but it seems like they don't provide any installer files. So I assume I need to get sources from Github. Should I compile them and then try to add the compiled files to my project or do I need to have a lib folder in my project, and put meta's sources in those folder and after operate with meta's sources as they are in my project?
My question isn't about how to install specific meta lib, but more from the source management point of view. If I use Visual Studio on Windows for example, but my colleague will be coding Clion under Linux. And I don't know the proper way of managing dependencies in C++ world.
C++ doesn't have anything like pip or npm/bower. I don't know if maven or gradle can be persuaded to handle C++ libraries.
In general, you are going to have to end up with
Header files in a directory somewhere
library files (either static libraries, or DLLs/shared objects). If the library is a header-only library like some of the boost libraries, then you won't need this.
You get hold of the library files, either by building them on your machine (typical for open source projects, and projects aimed at Linux platforms), or by downloading the pre-compiled binaries (typical for Windows libraries, particularly paid-for).
Hopefully, the instructions for building the library will be included on the library website. As noted in the comments, 'meta' seems to be quite good at that.
When you try to compile with the library, you may need a command line option (eg -I) to specify the directory containing the header files, and you may need a linker option (eg -l) to tell the linker to link against your library.
Cget will install any package that uses standard cmake, and works for linux and windows. It has shorten syntax for getting packages directly from github(such as cget install google/googletest).
In addition, dependencies can be automatically downloaded as well by listing them in a requirements.txt file.
There is also recipes for installing non-cmake packages and the repository here has over 300 libraries(and growing). So you can install curl with just cget install pfultz2/cget-recipes curl.
C++ sadly has no package manager for libraries. Some are out there and try to be one which are still small and scattered though (like conan).
In linux you have some "-dev" packages you can install but they are also not "all".
You most likely end up downloading them yourself. Next though is you have the problem of integrating those libraries. You have different build systems per operating system so you have to see how you build c++ files.
Like in windows with Visual studio you have to get a visual studio project or a nmake compatible makefile to build the libraries and then add them to your project. Same with linux makefiles.
There are several build frameworks who are higher level like cmake. The example you have in your post also works with CMake. So integrating that one into a cmake build environment would be easier but this only applies for other libraries also trying to use/integrate cmake build environments to it (e.g. boost / qt is doing this).
Yeah these are some thoughts to this. Sadly there won't be an easy/definitive answer to this because there is no real central c++ packet repository which is also integrated into a build system.
It appears to me that the Crascit/DownloadProject could be of help in your situation. It provides CMake plugins for downloading projects from a git repository by specifying tags, etc. Then you can use add_custom_target to run commands you need to have the project built.
There are a number of popular C++ released via nuget packages.
You can search on the gallery for them, usually using the native or c++ tags. Obviously you need a nuget manager for your OS, and I'm pretty sure that the C++ nuget packages rely on MSBuild for a lot of the grunt work, so you may have trouble getting a non-Visual Studio oriented setup to work nicely.
Also Gradle actually does have some support for native dependencies as well. I had a look at little while ago but the work on it was curtailed because the support for VS 2015 was lacking.
I recommend vcpkg for cross platform development. It has a number of IDE integrations. GitHub project is here.
I do cross platform development using tools like CMake, Visual Studio, WSL. vcpkg was incredibly helpful.
I started new project... in cureent time it's just "source package manager" you can provide some source code on github and then it will be just copy to you project (based on cmake + auto generating cmake files)
So links here:
https://github.com/wsjcpp/wsjcpp

Configuring a CMake project with dependencies on multiple other CMAKE projects

I have a CMAKE project that depends on other projects built with CMAKE. These are : glfw, oglplus, portaudio etc.
How should I set up my project to work well in a cross platform fashion? What is the recommended way to go about it? I have been trying to read the CMAKE documentation but could only find examples to simple scenarios.
Just add the dependencies to your project README and expect the user stored them (already compiled) in system scope.
Add CMake options to request the path to dependency files.
Use add_subdirectory to chain your project with dependencies.

Generate Find Cmake automatically and install it for importing

Is there any way to create a FindXXX.cmake automatically where XXX is my Cmake project? I see many projects that they created their FindXXX.cmake manually but I believe it's possible to create it automatically.
And, where I should install my project on Linux?
Thanks!
Take a look at CMake's project config file mechanism (along with the CMakePackageConfigHelper module; you might also want to take a look at this wiki page).
Find scripts are most useful for locating dependencies that are not aware of CMake themselves. If on the other hand the dependency was also built using CMake, you can let CMake auto-generate a project config file for you as part of that project's build process. This config file will allow you to refer to the targets of that project from an enclosing project as if they were being built as part of the enclosing project's CMake run. This is even more powerful than using find scripts, as it allows for example distinct handling of configurations beyond the debug/optimized options available to traditional find scripts.
On Windows, projects generating config files this way will register themselves with CMake, so that depending projects building on the same machine can find them automatically without any additional configuration. If you are building on non-Windows platforms (or you are building the two libraries on different machines) you will have to place the config file in a default directory (the docs for find_package describe which directories are searched) or explicitly point CMake to the location using CMAKE_MODULE_PATH.
Modern CMake-aware libraries should always prefer this approach over traditional find scripts. A prominent example of a library that does this already is Qt5.
CMake supports templating with configure_file() command.
Standard dirs where CMake searches for FindXXX.cmake modules are listed in the documentation of find_package() command.

Windows package-manager for C++ libraries

I've been working on various open-source projects, which involve the following C++ libraries (& others):
MuPDF
Boost
FreeType
GTKmm
hummus PDF libraries
LibTiff
LibXML2
Wt xpdf
xpdf
Poppler
ZLib
It often takes a long time to configure these libraries, when setting them up on a clean machine. Is there a way to automate the grabbing of all dependencies on a windows machine?
The closest I've found is CMake, which checks to make sure you have the dependencies installed/extracted before generating your project files. But I haven't found anything for Windows which can parse the list of dependencies and then download+install the required versions.
Please recommend a package manager for Windows with up-to-date C++ libraries.
Vcpkg, a Microsoft open source project, helps you get C and C++ libraries on Windows.
Take a look at the Hunter package manager when you already use CMake to setup your project. It automatically downloads and builds your dependencies whith only a few lines of extra cmake code. Hunter is based on cmake export and import targets.
For example if you want to use the GoogleTest library in your cmake based project you would add the following lines to your root CMakeLists.txt
# file root CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
# To get hunter you need to download and include a single cmake file
# see documentation for correct name
include("../gate.cmake")
project(download-gtest)
# set the location of all your hunter-packages
set( HUNTER_ROOT_DIR C:/CppLibraries/HunterLibraries )
# This call automaticall downloads and compiles gtest the first time
# cmake is executed. The library is then cached in the HUNTER_ROOT_DIR
hunter_add_package(GTest)
# Now the GTest library can be found and linked to by your own project
find_package(GTest CONFIG REQUIRED)
add_executable(foo foo.cpp)
target_link_libraries(foo GTest::main)
Not all the libraries you list are available as "hunter-packages" but the project is open source so you can create hunter-packages for your dependencies and commit them to the project. Here is a list of libraries that are already available as hunter packages.
This will not solve all your problems out of the box because you have to create hunter-packages for your dependencies. But the existing framework already does a lot of the work and it is better to use that instead of having a half-assed selfmade solution.
Biicode is a new dependency manager for C++. It also has a few libraries that you listed. Biicode automatically scans your source files for dependencies, downloads and builds them. See here for a very cool example that includes Freeglut.
What I've found:
Closest thing to what I'm looking for:
NuGET
Unfortunately it doesn't have any of the libraries I require in its repository.
So I ended getting most of the libraries from the KDE4windows project and custom building the rest.
Npackd is a package manager for Windows. There is a default repository for C++ libraries and also a third party repository for Visual Studio 2010 64 bit libraries. Boost and zlib are already in the default repository. If you decide to use Npackd, you could file an issue if you need other libraries.
Windows does not have a package manager. Go to the libraries' website and download the Windows builds if they provide any.
There are some alternatives, but not without drawbacks:
Cygwin: provides a nice package manager, but all binaries are built for Cygwin, which means they run slower than their native equivalent, any apps using them will link to the Cygwin DLL, and you're stuck with that license. Also the use of the native Win32 API is sometimes troublesome due to incompatibility with the POSIX emulation offered. Only for GCC.
MinGW-get: is a package manager for the MinGW.org compiler. These are native Win32 binaries, but only for use with MinGW's GCC.
There is no package manager or slightly equivalent thing for anything Visual Studio or MinGW-w64 related.
There is no package management on Windows. On Windows developers typically use full-blown everything-and-the-kitchen-sink development environments and produce monolithic applications themselves, shipped with all dependencies.