When you create your application using C/C++, there are several options for working with external dependencies, such as libraries like:
- libcurl
- rapidjson
- libuv
and so on.
Some of the libraries, along with header files, are available for installation using a Linux package manager thus we typically do the following:
sudo apt-get install libcurl4-openssl-dev
sudo apt-get install libuv1-dev
In Linux package managers, development-related libraries often have -dev
or -devel
as a suffix. For example:
libcurl4-openssl-dev
includes the library and headers required for building applications.- Libraries like
zlib
oropenssl
follow a similar pattern, e.g.,zlib1g-dev
.
Also, these packages include headers that are necessary for C/C++ compilers:
-dev
packages include header files (.h
) needed for compiling C/C++ applications, along with the.so
shared libraries for linking.
Another popular option is to build these dependencies from source (for cases when we want to fix vulnerabilities, need functionality that is not yet available in the packages, or enable experimental options, etc.). After building, we typically run configure
with parameters that point to these dependencies. Typically we are required to point C/C++ compiler to the header files directory and linker to the lib files.
Git submodule is what you should use in order to control versions of dependencies . The whole workflow with gtest for example would look like this
git submodule add https://github.com/google/googletest.git external/googletest
git submodule update --init
and then in CMakeList.txt you just point to this directory
add_subdirectory(external/googletest)
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
the benefit of this approach is that you use concrete version of the library and track any changes using git.
In the Windows world, there were different approaches, but after a long time, I see that CMake has become a powerful tool used by many companies and teams.
Cmake except many things supports also ability to fetch dependencies from git repository using FetchContent and ExternalProject_Add
Here is possible implementation with FetchContent
include(FetchContent)
FetchContent_Declare(
rapidjson
GIT_REPOSITORY https://github.com/Tencent/rapidjson.git
GIT_TAG master
)
FetchContent_MakeAvailable(rapidjson)
add_executable(your_target main.cpp)
target_link_libraries(your_target PRIVATE rapidjson)
But as I mentioned, I haven’t been using C/C++ for a long time and recently discovered that there is a vcpkg package manager, supported by the Microsoft, which is a high-level alternative to CMake. You can add any dependencies supported by vcpkg in a way similar to NuGet in C#. It supports integration with Visual Studio, MSBuild, CMake, etc., keeping configuration trivial.
To integrate with msbuild just execute:
vcpkg new --application
vcpkg.exe integrate install
to add any/install additional packages:
vcpkg add port fmt sqlitecpp zlib
vcpkg install

after execution install command vcpkg will download and build library then make it available for your project. Basically it works in a similar manner to package managers in other languages (like pip
for Python, npm
for JavaScript, or brew
for macOS).
Internally vcpkg relies heavily on CMake and also caches precompiled binaries, which speeds up the installation process. If a library has already been built for your configuration, vcpkg will simply fetch the binary instead of rebuilding it.
Comparing to other tools vcpkg downloads and built package on your host leveraging maximum binary compatibility. You have local repository of precompiled modules that benefits in total build time as it requires only including header files and linking with resultant lib files. The workflow looks like the following
./vcpkg install nlohmann-json
we install 3-rd party module (behind installation the source is downloaded and built) and then can include it to our project using CMake
find_package(nlohmann_json CONFIG REQUIRED)
target_link_libraries(main PRIVATE nlohmann_json::nlohmann_json)
or for integration with MSBuild just execute in your project directory vcpkg
c:/projects/vcpkg/vcpkg add port nlohmannjson
for integration with the build from Visual Studio IDE (when you develop locally) also configure projects settings by settings Use Vcpkg Manifest = yes

you should see the warning in IDE:
You may want to enable vcpkg manifests in your properties page or pass /p:VcpkgEnableManifest=true to the msbuild invocation.
Now during the building you’ll see all the process starting from downloading. Of course these dependencies are cache to reduce compilation time.
1>-- Downloading https://github.com/google/googletest/archive/v1.14.0.tar.gz -> google-googletest-v1.14.0.tar.gz...
1>-- Extracting source C:/projects/vcpkg/downloads/google-googletest-v1.14.0.tar.gz
1>-- Applying patch 001-fix-UWP-death-test.patch
1>-- Applying patch clang-tidy-no-lint.patch
When you install Vistual Sudio with installer and select Desktop development with C/C++ the vcpkg manager is already included in new versions of Visual Studio

therefore you don’t need to clone and install it separatelly. If you install new version of Vistual Studio with the already configured vcpkg you may get this warning
