{"id":31151,"date":"2022-09-28T21:55:20","date_gmt":"2022-09-28T21:55:20","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cppblog\/?p=31151"},"modified":"2023-11-07T03:04:39","modified_gmt":"2023-11-07T03:04:39","slug":"using-system-package-manager-dependencies-with-vcpkg","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/using-system-package-manager-dependencies-with-vcpkg\/","title":{"rendered":"Using system package manager dependencies with vcpkg"},"content":{"rendered":"<p>According to the C++ 2022 developer survey, the top 3 ways to manage C++ libraries were having the library source code as part of the build, compiling the library separately from instructions, and acquiring the library from a system package manager. Language package managers, such as vcpkg, simplify library management by offering the ease of use of a system package manager with the power, flexibility, and portability of building from source.<\/p>\n<p>vcpkg brings several advantages to C++ library management. First, vcpkg supports a wide range of customizations for each library. vcpkg installs libraries with a specific version. For additional configuration, each library supports various features and flags. Second, the vcpkg catalog supports over 1900 libraries. Third, vcpkg brings finer control: once a library and feature set are selected, that library&#8217;s configuration will be consistent on any platform.<\/p>\n<p>However, there are certain scenarios where using a system package manager is the better choice. You can deploy ABI compatible security and bug fixes without deploying the entire application. Multiple applications can use the same shared library, which reduces deployment size. And sometimes, company policy requires using a particular system package dependency.<\/p>\n<p>In the first example, we will show what it will look like if we strictly use dependencies from vcpkg. In the second example, we will replace some dependencies with system package manager ones.<\/p>\n<p>This blogpost is for advanced users of vcpkg. To get started with vcpkg instead, see <a href=\"https:\/\/github.com\/microsoft\/vcpkg\">https:\/\/github.com\/microsoft\/vcpkg<\/a>.<\/p>\n<h3>Building an application with dependencies from the vcpkg catalog<\/h3>\n<p>In this example, we are using Ubuntu 22.04 and the x64-linux triplet. First, create three files in an empty project directory: vcpkg.json, main.cpp, and CMakeLists.txt.<\/p>\n<pre class=\"prettyprint\">\/\/vcpkg.json\r\n{\r\n    \"name\": \"test-project\", \r\n    \"version\": \"1.0.0\",\r\n    \"dependencies\": [\r\n        \"azure-core-cpp\",\r\n        \"curl\"\r\n    ]\r\n}<\/pre>\n<pre class=\"prettyprint\">\/\/main.cpp\r\n#include &lt;iostream&gt;\r\n\r\n#include &lt;curl\/curl.h&gt;\r\n#include &lt;azure\/core.hpp&gt;\r\n\r\nusing namespace std;\r\n\r\nint main() {\r\n    cout &lt;&lt; curl_version() &lt;&lt; endl;\r\n    cout &lt;&lt; Azure::DateTime(std::chrono::system_clock::now()).ToString() &lt;&lt; endl;\r\n}<\/pre>\n<pre class=\"prettyprint\"># CMakeLists.txt\r\ncmake_minimum_required(VERSION 3.22)\r\nproject(test-project)\r\nadd_executable(main main.cpp)\r\nfind_package(CURL REQUIRED)\r\nfind_package(azure-core-cpp CONFIG REQUIRED)\r\ntarget_link_libraries(main PUBLIC Azure::azure-core CURL::libcurl)<\/pre>\n<p>Configuring the project:<\/p>\n<pre class=\"prettyprint\">cmake &lt;path to project&gt; -DCMAKE_TOOLCHAIN_FILE=&lt;path to vcpkg&gt;\/scripts\/buildsystems\/vcpkg.cmake\r\n\r\n... [build output]\r\nDetecting compiler hash for triplet x64-linux...\r\nThe following packages will be built and installed:\r\nazure-core-cpp[core,curl,http]:x64-linux -&gt; 1.7.1\r\ncurl[core,non-http,openssl,ssl]:x64-linux -&gt; 7.84.0#1\r\n* openssl[core]:x64-linux -&gt; 3.0.5#4\r\n* vcpkg-cmake[core]:x64-linux -&gt; 2022-07-18\r\n* vcpkg-cmake-config[core]:x64-linux -&gt; 2022-02-06#1\r\n* zlib[core]:x64-linux -&gt; 1.2.12#1\r\nAdditional packages (*) will be modified to complete this operation.\r\n...<\/pre>\n<p>Building and running main:<\/p>\n<pre class=\"prettyprint\">cmake --build . &amp;&amp; .\/main\r\n\r\n[ 50%] Building CXX object CMakeFiles\/main.dir\/main.cpp.o\r\n[100%] Linking CXX executable main\r\n[100%] Built target main\r\nlibcurl\/7.82.0-DEV OpenSSL\/3.0.2 zlib\/1.2.12\r\n2023-11-07T02:58:10.0215004Z<\/pre>\n<p>We can use ldd to list the shared libraries:<\/p>\n<pre class=\"prettyprint\">ldd main\r\n\r\nlinux-vdso.so.1 (0x00007ffc32bf1000)\r\nlibstdc++.so.6 =&gt; \/lib\/x86_64-linux-gnu\/libstdc++.so.6 (0x00007f816357a000)\r\nlibm.so.6 =&gt; \/lib\/x86_64-linux-gnu\/libm.so.6 (0x00007f8163493000)\r\nlibgcc_s.so.1 =&gt; \/lib\/x86_64-linux-gnu\/libgcc_s.so.1 (0x00007f8163473000)\r\nlibc.so.6 =&gt; \/lib\/x86_64-linux-gnu\/libc.so.6 (0x00007f816324b000)\r\n\/lib64\/ld-linux-x86-64.so.2 (0x00007f8163cf0000)<\/pre>\n<h3>Using curl and OpenSSL from the system package manager<\/h3>\n<p>You can use <a href=\"https:\/\/github.com\/microsoft\/vcpkg\/blob\/master\/docs\/specifications\/ports-overlay.md\" target=\"_blank\" rel=\"noopener\">port overlays<\/a> to configure vcpkg to use the system package manager dependencies. We will build the previous example and use curl and OpenSSL from the system package manager.<\/p>\n<p>Install the developer dependencies for curl with an OpenSSL backend and OpenSSL:<\/p>\n<pre class=\"prettyprint\">sudo apt-get install libcurl4-openssl-dev libssl-dev<\/pre>\n<p>Create the port overlay directory and file structure:<\/p>\n<pre class=\"prettyprint\">mkdir -p &lt;path to project&gt;\/overlays\/curl &lt;path to project&gt;\/overlays\/openssl<\/pre>\n<pre class=\"prettyprint\">\/\/&lt;path to project&gt;\/overlays\/curl\/vcpkg.json\r\n{\r\n    \"name\": \"curl\",\r\n    \"version\": \"1.0.0\",\r\n    \"port-version\": 0,\r\n    \"features\": {\r\n        \"ssl\": {\r\n            \"description\": \"\"\r\n        }\r\n    }\r\n}<\/pre>\n<pre class=\"prettyprint\"># &lt;path to project&gt;\/overlays\/curl\/portfile.cmake\r\nset(VCPKG_POLICY_EMPTY_PACKAGE enabled)<\/pre>\n<pre class=\"prettyprint\">\/\/&lt;path to project&gt;\/overlays\/openssl\/vcpkg.json\r\n{\r\n    \"name\": \"openssl\",\r\n    \"version\": \"3.0.5\"\r\n}<\/pre>\n<pre class=\"prettyprint\"># &lt;path to project&gt;\/overlays\/openssl\/portfile.cmake\r\nset(VCPKG_POLICY_EMPTY_PACKAGE enabled)<\/pre>\n<p>Building with CMake (we\u2019re using the same project in the previous example):<\/p>\n<pre class=\"prettyprint\">cmake &lt;path to project&gt; -DVCPKG_OVERLAY_PORTS=&lt;path to project&gt;\/overlays -DCMAKE_TOOLCHAIN_FILE=&lt;path to vcpkg&gt;\/scripts\/buildsystems\/vcpkg.cmake\r\n\r\n-- Running vcpkg install\r\nDetecting compiler hash for triplet x64-linux...\r\nThe following packages will be built and installed:\r\nazure-core-cpp[core,curl,http]:x64-linux -&gt; 1.7.1\r\ncurl[core,non-http,openssl,ssl]:x64-linux -&gt; 7.84.0#1 -- &lt;path to project&gt;\/overlays\/curl\r\n* openssl[core]:x64-linux -&gt; 3.0.5#4 -- &lt;path to project&gt;\/overlays\/openssl\r\n* vcpkg-cmake[core]:x64-linux -&gt; 2022-07-18\r\n* vcpkg-cmake-config[core]:x64-linux -&gt; 2022-02-06#1\r\nAdditional packages (*) will be modified to complete this operation.\r\n...<\/pre>\n<p>Building and running main:<\/p>\n<pre class=\"prettyprint\">cmake --build .\r\n.\\main\r\n\r\nlibcurl\/7.81.0 OpenSSL\/3.0.2 zlib\/1.2.11 brotli\/1.0.9 zstd\/1.4.8 libidn2\/2.3.2 libpsl\/0.21.0 (+libidn2\/2.3.2) libssh\/0.9.6\/openssl\/zlib nghttp2\/1.43.0 librtmp\/2.3 OpenLDAP\/2.5.11\r\n2023-11-07T03:02:26.8637898Z<\/pre>\n<p>Checking whether we\u2019ve linked the correct shared libraries (libssl and libcurl):<\/p>\n<pre class=\"prettyprint\">ldd main\r\n\r\nlibcurl.so.4 =&gt; \/lib\/x86_64-linux-gnu\/libcurl.so.4 (0x00007f632c1c0000)\r\nlibssl.so.3 =&gt; \/lib\/x86_64-linux-gnu\/libssl.so.3 (0x00007f632c11c000)\r\nlibcrypto.so.3 =&gt; \/lib\/x86_64-linux-gnu\/libcrypto.so.3 (0x00007f632bcda000)\r\nlibstdc++.so.6 =&gt; \/lib\/x86_64-linux-gnu\/libstdc++.so.6 (0x00007f632baae000)\r\nlibm.so.6 =&gt; \/lib\/x86_64-linux-gnu\/libm.so.6 (0x00007f632b9c7000)\r\n... (25+ more dependencies)<\/pre>\n<p>You will notice curl and openssl from the system package manager have more dependencies than the curl and openssl from the vcpkg catalog. In the above example, we only added port overlays for the dependencies that we use. If you were to build a more complex application that would depend on other dependencies, you would need to add additional overlays.<\/p>\n<p>Both the vcpkg and the system packager catalogs can contain the same library, and we need to make sure the application only links one copy of each library. Linking two different versions of the same library could lead to ODR violations.\nIn the example, curl from the system package manager pulls in OpenSSL as a dependency. We overlayed the OpenSSL dependency in vcpkg to prevent vcpkg from also acquiring OpenSSL from its catalog.<\/p>\n<h4>How did CMake find curl?<\/h4>\n<p>When find_package(CURL) is called, CMake searches for the CURL libraries in the vcpkg_installed directory. If the CURL libraries are not found on the CMake paths, it defaults to the FindCurl module which finds the system dependency.<\/p>\n<h3>Learn More<\/h3>\n<p>If you would like to contribute to vcpkg and its library catalog, or want to give us feedback on anything, check out our <a href=\"https:\/\/github.com\/microsoft\/vcpkg\/\" target=\"_blank\" rel=\"noopener\">GitHub repo<\/a>. Please report bugs or request updates to ports in our <a href=\"https:\/\/github.com\/microsoft\/vcpkg\/issues\" target=\"_blank\" rel=\"noopener\">issue tracker<\/a> or join a more general discussion in our <a href=\"https:\/\/github.com\/microsoft\/vcpkg\/discussions\" target=\"_blank\" rel=\"noopener\">discussion forum<\/a>. For an overview of our top priorities and backlog, take a look at our <a href=\"https:\/\/github.com\/microsoft\/vcpkg\/wiki\/Roadmap\" target=\"_blank\" rel=\"noopener\">roadmap<\/a> page.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>According to the C++ 2022 developer survey, the top 3 ways to manage C++ libraries were having the library source code as part of the build, compiling the library separately from instructions, and acquiring the library from a system package manager. Language package managers, such as vcpkg, simplify library management by offering the ease of [&hellip;]<\/p>\n","protected":false},"author":102125,"featured_media":28096,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,272],"tags":[],"class_list":["post-31151","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","category-vcpkg"],"acf":[],"blog_post_summary":"<p>According to the C++ 2022 developer survey, the top 3 ways to manage C++ libraries were having the library source code as part of the build, compiling the library separately from instructions, and acquiring the library from a system package manager. Language package managers, such as vcpkg, simplify library management by offering the ease of [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/31151","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/102125"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=31151"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/31151\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/28096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=31151"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=31151"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=31151"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}