My motivation to using Conan is a project I’ve been working on, on and off, for several years now. The project uses several third party libraries which have been manually managed. Because of this it made it nearly impossible to use any continuous integration build system. Thus, I started out to do two things:

  • modernize the binary package management system of third party libraries
  • add support for Travis-CI and Appveyor (though, since Travis-CI now supports Windows building, Appveyor will probably be unnecessary)

The libraries used in my project are:

  • Qt
  • boost
  • libcurl
  • Lua
  • Hunspell
  • tidy-html5
  • log4qt

Adding support for boost and libcurl was pretty trivial once I learned the idea of managing remotes.

Remotes

Conan remotes are pretty much the same idea as git remotes, just different endpoints with which you can work. The one issue I ran into with remotes was the “Not implemented endpoint” error, which I blame on a poor interface on bintray.com.

When I was looking to add libcurl to my project via Conan, I found it here. I realized quickly that the bintray remote was not in my local configuration, and a quick Google search pointed me how to add remotes:

conan remote add <REMOTE> <REMOTEURL>

Easy enough! Looking at bincrafter’s page for libcurl, the first thing I saw was this:

Well, there’s an URL and it even has a button that copies the URL to the clipboard. Surely that’s the REMOTEURL I seek! No. Which I found out only after I tried using it and got a “Not implemented endpoint” error. It wasn’t immediately obvious that the “SET ME UP” button had the URL I needed to use.

Custom Packages

With this info in hand, I was easily able to add boost and libcurl to my project and delete them my manual binary distribution. I felt bold and adventurous and decided to try my hand at Qt. Nope, not as easy. I was trying this on Windows and got two mysterious linking errors, I decided to come back to that later. Now it was time to start tackling the packages that didn’t have a Conan package that did what I needed.

Hunspell was the first one I tackled because I found a recipe on Github here. It wasn’t exactly what I needed, since it only worked on Windows and my project runs on macOS and Linux, but it was a good starting point. I forked the project here, cloned it locally and started messing around.

Really, it was pretty simple. I followed the example code, knowing I had to (1) write code to build the repo (which I suppose is optional) and (2) write code to package the repo. The process I followed was here in the Conan docs.

After a couple hours, I am now able to build on my Mac and Windows machines, using several packages from Conan. The only issue I have so far is building Debug builds on Windows. Now that I know about conan install -s build_type=Debug ..., I will see if this fixes the Debug build errors.

Uploading

I signed up for an account at https://bintray.com which was simple. Creating a repo was simple and adding it as a remote was easy enough, but I hit the “Not Implemented Endpoint” problem once again because I clicked the copy button!

Conclusion

I am going to push through with Conan. I realize now I will likely have to write recipes and package binaries for Lua, html-tidy and log4qt, but to cost-benefit ratio suggests it’s well worth the effort. Being able to get my project into Travis-CI and eventually a coverage tool will drastically improve development and hopefully even encourage me to work on the project more.

Step-by-Step Instructions

Here are the instructions I executed to build/develop my Hunspell package. These can be found in the Conan docs (linked above) but I provide them here with my own thoughts on the operations.

  1. At this point it is assumed that I have already cloned the repo locally and am in its working directory.
  2. conan source . --source-folder=source - This seems to “prepare” the folder and source folder to receive the source-code as per the build() function and scm settings in the conanfile.py.
  3. conan install . --install-folder=source - Now we’re declaring that we’re getting ready to start developing a Conan package!
  4. conan build . --source-folder=source --build-folder=source - Run the code in the build() which should build the code and the end result should be the binaries for your local system.
  5. conan package . --source-folder=source --build-folder=source --package-folder=package - Run the code in the package() method, which essentially takes the results of Step 3 and puts all the headers, libraries and binaries in the appropriate folders under the specified package-folder.
  6. conan export-pkg . user/channel --source-folder=source --build-folder=source - Here user/channel is how you want to refer to this file in conanfile.txt.
  7. conan upload libname/2.7.1@user/channel -r remotename --all - Here I upload the resulting package to my bintray account (added as remotename). The libname and 2.7.1 are the name and version as specified in conanfile.py.

By no means do I claim that this is what each step is doing. This is simply my internal rationalization of the steps and how I think about them, wrong or not.