Skip to Content
Course content

127: Managing Dependencies with vcpkg or Conan

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I remember the first time I tried to bring a third-party library into a professional project. I just downloaded the source code for a JSON parser, tossed it into a folder called /third_party, and manually added the include paths to my build script. At the time, it felt like the most direct way to get the job done. No fancy tools, no abstraction—just the code I needed, right there in my directory. It worked perfectly on my machine, and for about a week, I thought I'd cracked the code on efficiency.

The "It Works on My Machine" Wall

The problem with the manual approach—whether you're vendoring code directly into your repo or relying on apt-get install to put libraries in /usr/local/lib—is that you aren't actually managing dependencies; you're just documenting a coincidence. The moment I pushed that code to a teammate, everything exploded. They had a slightly different version of the compiler, a different OS patch level, and they didn't have the same system-level libraries I'd installed six months prior. We spent an entire afternoon debugging "missing header" errors instead of actually writing features.

When you rely on system-wide installations, you're playing a dangerous game of version roulette. What happens when Project A needs OpenSSL 1.1 but Project B requires OpenSSL 3.0? You can't easily have both installed globally without creating a linking nightmare. I've seen developers spend days fighting with LD_LIBRARY_PATH just to get a binary to run, and frankly, it's a waste of your talent.

Moving to a Manifest-Based World

The professional way to handle this is to treat your dependencies as a declared list, not a manual chore. This is where vcpkg and Conan come in. Instead of "installing" things in the traditional sense, you create a manifest file—like vcpkg.json or a conanfile.txt—that explicitly states: "This project requires fmt version 10.1.1 and nlohmann-json version 3.11.2."

When a new developer clones your repo, they don't have to go on a scavenger hunt for libraries. They run a single command, and the package manager handles the downloading, patching, and compiling of those libraries specifically for their current compiler and architecture. It turns a four-hour onboarding process into a five-minute automated script. I prefer this because it decouples the library's existence from the operating system; the library belongs to the project, not the machine.

The Trade-off: Tooling Overhead vs. Sanity

Now, I'll be honest with you: adding a package manager introduces a new layer of complexity. You have to learn how to integrate the tool with your CMake configuration, and occasionally, the package manager itself might have a bug or a missing version of a niche library. You're trading a bit of initial setup time for a massive increase in long-term stability.

If you're deciding between the two major players, here is how I usually look at it:

  • vcpkg feels more integrated with the Microsoft ecosystem (though it's cross-platform) and generally plays very nicely with CMake via a "toolchain file." It's often easier to get started with if you want something that "just works" with Visual Studio.
  • Conan is more of a powerhouse. It's designed for complex enterprise environments where you might need to host your own private binaries (a "Conan server") to avoid recompiling the same heavy library on every single build agent in your CI/CD pipeline.

Regardless of which one you pick, the goal is the same: your build should be reproducible. If I can check out your code on a clean Linux VM and have it compile without me manually installing a single -dev package, you've won.




📋 Practical Task

Integrating fmt and nlohmann_json via vcpkg

Your goal is to move a project from "manual header inclusion" to a managed dependency system. You have a small utility that parses a configuration file and prints a formatted status report, but currently, it only compiles if the user has manually installed fmt and nlohmann_json to their system paths.

The Requirements:

  • Create a vcpkg.json manifest file in your project root that declares dependencies for fmt and nlohmann-json.
  • Modify your CMakeLists.txt to use find_package() for both libraries instead of relying on hardcoded include paths.
  • Link the libraries to your executable using target_link_libraries().
  • Successfully compile the project by passing the vcpkg toolchain file to CMake (e.g., -DCMAKE_TOOLCHAIN_FILE=[vcpkg root]/scripts/buildsystems/vcpkg.cmake).

Verification: The program should successfully compile and run, using nlohmann::json to parse a string and fmt::print to output the result to the console, without any libraries being installed globally on your operating system.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.