Package Management for C++ - c++

I am working in a company that they build a project separated in components that are developed separately by different developer teams. Everything in C++.
They use a lot of libraries in common and to manage all of them, they created a tool to somehow relates the version of the project and versions of libraries.
The question is about the existence of some tool in the market that already does this:
I mean, If I go to this tool, I can download for example the version 4.0 of our project that has exactly the version 4.5 of the library 1 and 3.4 of library 2. If I click "Download", I will Download the source code (or binary) of this entire (project + libraries) project and the concrete version of each library.
For example if I want to Download another project of another developers in the company, using same libraries in different version or platforms, I only have to choose that and is gonna download the project 2 with library 1 version 5.0 and library 2 2.5, and so on.
Is there in the market any tool that aloud me to create some relations like that, and btw, connects with code repo (gitlab in our case)?
I checked Gradle, Conan, ... but they build, not manage "relations" between components.
Something like that:

CMake provides enough functionality to create these kinds of relationships within your build system. Unfortunately you have to use CMake to manage the builds for all of your projects for this to work well. CMake does target Visual Studio as well as GCC, Clang, and ICC. If this interests you keep reading.
Use CMake to construct build configurations for your dependent projects.
Use ExternalProject commands to express the dependencies of the parent projects.
ExternalProject supports Git as well as Mecurial, CSV, SVN, and direct tarball downloads.
You can specify the exact commit, tag, or branch in Git.
Supports Git authentication via SSL or Basic HTTP.
Run CMake against the parent project. All dependencies are downloaded and compiled automatically.
Example Dependency
ExternalProject_Add(
Library1
GIT_REPOSITORY https://git#gitlab.yourdomain.com/repo/library_1.git
GIT_TAG tag_S.33.91
HTTP_USERNAME ciserv
HTTP_PASSWORD Obfusc#t3M3
CMAKE_ARGS
-DBUILD_EXAMPLES:BOOL=OFF
-DBUILD_TESTS:BOOL=OFF
-DBUILD_DOCS:BOOL=OFF
)
target_link_libraries(MyTarget PRIVATE Library1)
There are several other commands within the ExternalProject module that can be used to further customize the dependency if required.

To follow up #norman-b-lancaster's answer, consider looking into the Hunter package manager. It is based on CMake's ExternalProject feature and heavily focused on reproducible builds. Each Hunter release provides the CMake script required to lock down the package versions of all dependencies.
Your question suggests that you're concerned with package management within your company (as opposed to publicly available packages from ex: GitHub). Hunter's maintainers are aware of this issue and seem open to supporting it if the demand is present.

I wrote cget that provides a way to install a dependency just by pointing to the source tarball, which hosting services like github and gitlab provide. You can also provide a requirements.txt to install all the dependencies transitively as well.
It is cmake-based, which it will install with very little changes, but it also supports other non-cmake packages. You can also create a distro of recipes for handling packages that don't follow the standard configure, build and install workflow. There is also a lot recipes already available for many C++ projects already here.

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.

What is the relationship between use of `git submodules` and `ExternalProject_Add` for dependency mangement in CMake?

I've spent a lot of time recently following a long gone developer's vague and incorrect build instructions for a C++ project I'm working on. Therefore, I'm writing a new build system and I'm looking for the best way to do it. I've settled on using the ExternalProject_Add command in CMake for collecting and building dependencies before the project targets but I've also found an excellant article suggesting use of git submodules, which looks like it does a very similar, if not the same thing. So my question: What is the relationship between git submodules and ExternalProject_Add?
You can use ExternalProject_Add without git submodules:
if (SPECIAL_CASE)
include (ExternalProject)
ExternalProject_Add (
project1
PREFIX project1
GIT_REPOSITORY "https://github.com/project.git"
GIT_TAG "v1"
)
endif ()
project will be cloned to CURRENT_BINARY_DIR, built and installed into local system before main project build. Your main project will use #include <project/header.h> from global scope. This solution is suitable for popular projects only, that are available as dependency for part of target operating systems. You can guarantee that your target system will receive required version of dependency.
For example lets look at openssl, your local system 100% have this library installed. Your target operating systems list includes native Win32 (without MinGW or CygWin). All available releases of openssl for Win32 are too ancient, you won't be able to find required version of openssl installer for Win32. So you may use #include <openssl/ssl.h> together with if (WIN32) ExternalProject_Add without submodule. There is no point in adding openssl submodule to your project.
Please review the following example.
If external project is not popular, not available in popular package managers (as rpm, deb, ebuilds, etc) than it is better to use submodules.

Is there a tool for meson similar/equivalent to CPack for CMake?

I have recently started learning meson and I am testing switching to it (from CMake) in one of my projects. The problem is that I usually use cpack to build the project's packages/installers, and after scouring the meson docs for something similar to cpack I am unable to find anything.
Requirements/what I currently use cpack for
Single script to automatically build and package binary releases (such as deb, rpm, windows installer, etc)
Integrates with the build system - Picks up targets automatically, doesn't require redefining installation logic or structure
Supports building at least deb packages and a windows installer (don't care which)
There is the information on building release archives and then using scripts to process them with packaging tools (such as inno). However, this is not really what I am looking for as it is far more awkward and inflexible than cpack (i.e I have to change 3 different scripts if the directory structure changes).
Ultimately I can learn to use the meson system and manually write packaging scripts, no doubt it will make me a better scripter, however, I am eager to know if there is a better way of doing this which is not advertised in the docs or if there is some unofficial project which will automate the process.
Edit
By package I mean like a deb package - a package for a system package manager, not something like conan
I suggest that you use conan. Please take a look at conan configuration in the Meson.
It might be worth considering using meson rpm packaging module RPM module:
It autodetects installed files, dependencies and so on
This module as of now supports only generation of RPM spec file:
rpm = import('rpm')
rpm.generate_spec_template()

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

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.