{"id":27828,"date":"2021-03-31T18:28:10","date_gmt":"2021-03-31T18:28:10","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cppblog\/?p=27828"},"modified":"2021-03-31T20:49:54","modified_gmt":"2021-03-31T20:49:54","slug":"vcpkg-host-dependencies","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/vcpkg-host-dependencies\/","title":{"rendered":"vcpkg Host Dependencies for Cross-Compilation"},"content":{"rendered":"<\/p>\n<p>If you\u2019re not familiar with our C++ library manager vcpkg, welcome! This post covers an intermediate\/advanced topic, so you may want to first get an overview and try things out from the <a href=\"https:\/\/github.com\/Microsoft\/vcpkg\">vcpkg GitHub page<\/a> or some of <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/?s=vcpkg\">our previous blogs<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<h3>Introduction<\/h3>\n<p>One of the best features of C++ is that it generates tailored, specialized code for each specific machine, enabling you to squeeze every ounce of performance per watt. It enables clean abstractions to coexist peacefully with low-level platform-specific bit twiddling. However, this comes at a price for many developers that venture beyond their own machine: you must build different binaries for your developer machine compared to your final target, be it a phone, a cloud server, or an embedded microcontroller.<\/p>\n<p>For most small-to-medium sized projects, this isn\u2019t a problem. You already have a compiler, a code editor, and a build system, which is plenty to make tons of incredible applications. However, since time immemorial some developers need even more flexibility, extensibility, and power than just the compiler; they need to generate sophisticated code at build time. Maybe it\u2019s computing a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Perfect_hash_function\">perfect hash function<\/a> over your known data set, maybe it\u2019s a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Yacc\">table-driven parser<\/a>, or maybe it\u2019s a bunch of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Foreign_function_interface\">foreign function interface<\/a> boilerplate into your embedded scripting language. For whatever reason, you need the flexibility of C++ <em>for your development environment<\/em> in addition to the final runtime target.<\/p>\n<p>In this blog post we\u2019ll cover the newly shipped vcpkg feature designed to enable all these scenarios and more: <strong>Host Dependencies<\/strong>.<\/p>\n<p>&nbsp;<\/p>\n<h3>Simultaneous Compilation<\/h3>\n<p>As mentioned in the introduction, because C++ compiles all the way down to the metal, you generally can\u2019t use the same compiler and flags to simultaneously target your final runtime and your developer machine. If you\u2019re using a multi-targeting compiler like Clang\/LLVM you\u2019ll need at least different flags and if you\u2019re using a single-target compiler like GCC or MSVC you\u2019ll need an entirely different compiler.<\/p>\n<p>If you\u2019re lucky, your buildsystem has specific documentation for how to handle this case. Even then, it can sometimes be extremely subtle to ensure things are wired up correctly: Did you accidentally pass the flags for the target to the developer machine build? What if you need libraries for your code generator to run? What about code generators generating code for other code generators? It\u2019s a tricky problem space that has ramifications on every aspect of the build environment.<\/p>\n<p>&nbsp;<\/p>\n<h3>Triplets<\/h3>\n<p>In vcpkg, we label each target universe as a separate &#8220;triplet&#8221;. For example, x64 Windows Desktop using dynamic CRT and MSVC, but building static libraries might be named <code>x64-windows-static-md<\/code>. Each library built within that universe links against other libraries from that universe, keeping everything super consistent. We include many triplet definitions in the box, but you can easily make your own to tweak compiler flags or adjust settings on a per-library basis (maybe you\u2019d like Qt to be built dynamically, but your JSON parser built statically).<\/p>\n<p>Naturally, your developer environment also matches one of these universes. By default, we pick <code>x64-windows<\/code>, <code>x64-linux<\/code>, or <code>x64-osx<\/code> as appropriate but it\u2019s fully configurable at runtime via <a href=\"https:\/\/github.com\/microsoft\/vcpkg\/blob\/master\/docs\/users\/host-dependencies.md#specifying-the-host-triplet\">several methods<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<h3>Host Dependencies<\/h3>\n<p>Despite having a triplet matching the developer environment, vcpkg didn\u2019t have syntax for libraries to express a dependency upon a port built for that environment. We\u2019ve gotten very far with imperfect approaches, like dynamically attempting to consume libraries from a hardcoded set of fallback triplets, however these would always fall short of the ideal and required imperfect, copied code between different ports. These workarounds also fall completely flat in <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/vcpkg-accelerate-your-team-development-environment-with-binary-caching-and-manifests\/\">manifest mode<\/a>, which is specifically designed to prevent the flaky behaviors that occur with these sorts of \u201cdynamic\u201d accesses. The fix is, of course, a way to naturally and directly express a requirement upon ports built for the developer environment.<\/p>\n<p><strong>Enter: Host Dependencies. Available now, ports and consumers can now declare dependencies upon other ports built against the developer environment.<\/strong><\/p>\n<p>The syntax to activate this is simply setting <code>\"host\"<\/code> to <code>true<\/code> in the manifest dependency object:<\/p>\n<pre class=\"prettyprint\">{\r\n    \"dependencies\": [\r\n        { \"name\": \"contoso-cgen\", \"host\": true }\r\n    ]\r\n}<\/pre>\n<p>During execution, a port can rely on all host dependencies having been installed to <code>CURRENT_HOST_INSTALLED_DIR<\/code> (the analog of <code>CURRENT_INSTALLED_DIR<\/code>) and they can get the currently configured host triplet via <code>HOST_TRIPLET<\/code> (the analog of <code>TARGET_TRIPLET<\/code>).<\/p>\n<pre class=\"prettyprint\">set(CGEN ${CURRENT_HOST_INSTALLED_DIR}\/tools\/contoso-cgen\/cgen${VCPKG_HOST_EXECUTABLE_SUFFIX})\r\nvcpkg_cmake_configure(\r\n    SOURCE_PATH ${SOURCE_PATH}\r\n    OPTIONS -DCODE_GENERATOR=${CGEN}\r\n)<\/pre>\n<p>For projects that have their own code generators embedded inside, it\u2019s perfectly valid to require <em>yourself<\/em> built for the host:<\/p>\n<pre class=\"prettyprint\">{\r\n    \"name\": \"protobuf\",\r\n    \"dependencies\": [\r\n        { \"name\": \"protobuf\", \"host\": true }\r\n    ]\r\n}<\/pre>\n<p>Then, the port can determine if it is cross-building or native-building by comparing the triplets:<\/p>\n<pre class=\"prettyprint\">if(HOST_TRIPLET STREQUAL TARGET_TRIPLET)\r\n  # Native compilation, set build flags to build and install the code generator\r\nelse()\r\n  # Cross compilation, set build flags to consume the prebuilt code generator\r\n  # from ${CURRENT_HOST_INSTALLED_DIR}\r\nendif()<\/pre>\n<p>&nbsp;<\/p>\n<h3>Give us your feedback!<\/h3>\n<p>Try out vcpkg by visiting our <a href=\"https:\/\/github.com\/microsoft\/vcpkg\">GitHub repo<\/a>. We welcome your feedback on the tool and the new features <a href=\"https:\/\/github.com\/microsoft\/vcpkg\/issues\">in our issue tracker<\/a>.\u00a0<\/p>\n<p>We&#8217;ve only just begun incorporating this powerful new facility into the existing catalog, such as for Boost.Build (<a href=\"https:\/\/github.com\/microsoft\/vcpkg\/blob\/b5bb1511f0a07be530e0bde3ae098eb3d8e83e68\/ports\/boost-date-time\/vcpkg.json#L10-L13\">vcpkg\/vcpkg.json at master \u00b7 microsoft\/vcpkg (github.com)<\/a>) and Protobuf (<a href=\"https:\/\/github.com\/microsoft\/vcpkg\/blob\/b5bb1511f0a07be530e0bde3ae098eb3d8e83e68\/ports\/protobuf\/vcpkg.json#L8-L11\">vcpkg\/vcpkg.json at master \u00b7 microsoft\/vcpkg (github.com)<\/a>). It&#8217;s an enormous step forward for vcpkg users targeting important platforms such as iOS, Android, and Emscripten\/WebAssembly.<\/p>\n<p>The current up-to-date documentation on Host Dependencies can be found on our GitHub at <a href=\"https:\/\/github.com\/microsoft\/vcpkg\/blob\/master\/docs\/users\/host-dependencies.md\">vcpkg\/host-dependencies.md at master \u00b7 microsoft\/vcpkg (github.com)<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you\u2019re not familiar with our C++ library manager vcpkg, welcome! This post covers an intermediate\/advanced topic, so you may want to first get an overview and try things out from the vcpkg GitHub page or some of our previous blogs. &nbsp; Introduction One of the best features of C++ is that it generates tailored, [&hellip;]<\/p>\n","protected":false},"author":56728,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-27828","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus"],"acf":[],"blog_post_summary":"<p>If you\u2019re not familiar with our C++ library manager vcpkg, welcome! This post covers an intermediate\/advanced topic, so you may want to first get an overview and try things out from the vcpkg GitHub page or some of our previous blogs. &nbsp; Introduction One of the best features of C++ is that it generates tailored, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/27828","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\/56728"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=27828"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/27828\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=27828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=27828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=27828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}