Hello, and welcome to C++ Weekly. I'm your host, Jason Turner. I am available for contracting,
code reviews and on-site training. In this episode I'm going to begin a mini-series on working with
package managers that are available for C++. I am going to start with Conan because it is the
one that I have been aware of for the longest and I have never used it before, so this episode will
be something of a bit of discovery to see just how much work it does or does not take to get it
set up. For all of these examples I will be using Linux and that is because it is the environment
that is easiest for me to work in, but I think it also kind of keeps everything on an even ground.
So we will see what exactly it takes to get Conan up and running and how we can work with it. Now
for this example I am going to be using the FMT library which is a partial compile-time, partial
runtime, type-safe formatting library for C++, and it is something that I've always wanted to use but
I never have actually tried to before. One reason I'm using it is because all the package managers
that I plan to cover have support for it, so this is not going to be any kind of videos on how to
add package manager support for some library. This is videos on how to use existing package manager
support. So we can see some of the examples of the FMT library look pretty straightforward. They are
kind of in the printf format. Let's go ahead and try to find their most basic, getting started,
full, complete example and it looks like it is quite just this simple. Now this is making a
global variable called 'string s' and we can see what it is going to do, perhaps based on their
examples, but let's go ahead and just start with this and maybe I'll spruce it up just a little
bit so that we can get some actual output to the screen. So I have set up my Conan folder
here and we will start from this, so this is our basic example. Let's put this inside of 'main',
and so that we have some output - something like this. So we're going to format the number 42 and
then we're going to print out that string to std::cout and we need to include our iostream
header. So let's double check this and well, we can see I don't have the 'format' header installed
at all here yet, so this is our basic example. Now we're going to look at the official Conan website,
which is Conan.io and click on 'Get Started." The recommended way of installing it is with pip,
and I am on a Arch Linux distribution here so I'm going to make sure that I have the correct
pip installed, and I'm going to install from there (and I do know that I've use pip before on here).
It looks like the global pip is for Python 3.6 that was the part I wasn't sure about because I
knew I have both Python 2 and Python 3 installed on here. So let's just go ahead and install Conan.
Now I'm wondering if I should have installed this globally instead of as my local user...
and permission denied here. There's something that wanted
to be installed globally. Let's just go ahead and do this again.
Okay so if that worked we have the Conan binary available to us;
and it seems that we do. So let's go back to the 'Getting Started' directions. So
according to this we need to set up some sort of [requires], and now I don't really
know what exactly this field means, but let's just go ahead and give it a shot.
Although we want this to actually be our fmt lib... So this is the official (as far as I can
tell) repository for the packages that have been vetted and are known to be stable in (for) Conan
which is at bintray.com, so it seems the package name is fmt:bincrafters perhaps. So I'm going to
put fmt here, see what happens. So we're going to stick with the default generator of using CMake,
and then it kind of looks like we just need to copy and paste the rest of this here and make
our own CMakeList file. Now it's clear that we can tell here that this add_definitions is not using
the latest and greatest best practices for CMake where you're supposed to just say what standard
do you require and then it would do the correct thing, but to minimize the number of variables
we're just going to start with this. So it looks like it's going to automatically do something with
Conan, and then it's going to do the basic setup required and then we want to use our name here and
this should be all that's required if I'm following this correctly. So the directions
say to make a build directory. This is not how I would normally do it - I would have
a parallel build directory personally, but again in the interest of sticking with the
instructions it looks like this is what we should do. It seems that GCC 8 isn't
a valid compiler. I am using my own, but I do have an older one that seems
to be an allowed version. Well, let's just try some of the standard OS variables. Ok.
Now let's try this. We've gotten a little bit closer by hacking my settings file
to allow GCC 8. Now I have no idea if this is necessary but I guess I'll go ahead and try it.
Ok, let's try to change the compiler. Well, actually, let's stick with our
8.0 and see what it takes to build it. So build it from sources with --build fmt. There we go.
And now it finds GCC 7.3 because I was (had) did that environment variable set up. Try this
again. Okay. I'm gonna start over like this. Okay there we go. I am not using any non-standard,
user-defined compiler at this point although it does seem that Conan needs to be updated
to support GCC 8, but to be fair not very many people have deployed that yet. So this seems to
have been mostly a failure on my part so far, but it looks like we have gotten the Conan build info
and everything set up as we expected to. Let's see if we can actually build and execute our
package. So we were here at the Conan install step. Ah, and look, if I had gone a little bit
further down I could have seen that I had some options for specifying the compiler and OS,
etc. So it says it should finish generating the requested file specified in the generators. Now
here I can run CMake it seems; and I'm going to use the defaults for CMake because I feel
like I'm pretty confident with how that works. I should just be able to do a CMake of one level up;
and we can, you know, peek behind the curtain a little bit here and see if there are any Conan
flags or anything set. No, nothing that I see. Now we have a make file generated for us by CMake,
which theoretically is going to reference this Conan build file, and I should have used Ninja
perhaps but I would like to see exactly what's going on. This seems to have worked - it found
the header file, so it did the correct thing and if we can dig into our Conan info...
Let's see, this is including the 'conanbbuildinfo.cmake.' Then we can
see here where it grabbed the INCLUDE_DIRS and the LIB_DIRS and everything else,
so this seems to have worked. I just have to fix the sample project that I'm trying to build. So
this is supposed to be a compile time check - ah, I see, this is actually supposed to fail if I had
been doing this correctly because it is asking for the second parameter. Let's just go ahead and do
one of the more simple examples; and those of you who know the fmt library probably saw this a long
time ago Let's just do something like this... and it worked. We printed the value 42 to the
screen in probably the most complicated way that we could have, but the lessons learned here are:
first of all, if you want to use Conan be aware of what compiler it is choosing. The actual Conan
configuration file itself is not that complex, the only hard part is knowing the name of the
package that you want to add. And so we did that here, and I think that we can specify
various other things like an asterix or whatever for the version number and the generator. CMake,
you know, it's it's the thing that we all love to hate, but it is kind of the standard right now so
let's stick with CMake. Our CMakeList file is actually very straightforward - all we had to
do was say "include these things from Conan," and then to actually execute Conan. The command
was not that hard. It's just this install, and then what directory you want to run the install
commands from once that is executed, then you can use your CMake to actually configure the project,
and Make or Ninja or whatever else you would to do it. It seems to have all done the right thing;
and just for the fun of it we'll look at some of these output commands here. We can see that
the include directory is here, so my local .Conan file is going to be my cache for all the packages
that Conan has processed and the linker is also grabbing here, and if we had really wanted to
use GCC 8 then we could have. We just had to tell Conan to build that specific package for
us. It would have been interesting if it could have done it automatically, but I would say
overall this was fairly straightforward - just a little bit of a learning curve, and you watched
it all here with me. So starting from absolute scratch and having never used Conan, before that
was about a 25 minute experience. So I would say not too bad. So be sure to subscribe. Follow me
on Twitter, like this video, leave a comment, and check out any of the other video links coming up,
and stay tuned for the next episode that I'm going to do on package managers which will probably be
the Hunter package manager that is designed I believe specifically for integration with CMake.