libzengithub - how to build portable conan.io C/C++ packages with multiple CI platforms
This project has been featured at the SwampUp conference (talk recording) and the Volkswagen Azure Days.
libzengithub
prints out a random Zen of Github whenever you call its only function.
#include <zengithub.h>
int main() {
zen_of_github();
}
will provide you something like
MMM. .MMM
MMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMM _________________________________________
MMMMMMMMMMMMMMMMMMMMM | |
MMMMMMMMMMMMMMMMMMMMMMM | Anything added dilutes everything else. |
MMMMMMMMMMMMMMMMMMMMMMMM |_ _____________________________________|
MMMM::- -:::::::- -::MMMM |/
MM~:~ 00~:::::~ 00~:~MM
.. MMMMM::.00:::+:::.00::MMMMM ..
.MM::::: ._. :::::MM.
MMMM;:::::;MMMM
-MM MMMMMMM
^ M+ MMMMMMMMM
MMMMMMM MM MM MM
MM MM MM MM
MM MM MM MM
.~~MM~MM~MM~MM~~.
~~~~MM:~MM~~~MM~:MM~~~~
~~~~~~==~==~~~==~==~~~~~~
~~~~~~==~==~==~==~~~~~~
:~==~==~==~==~~
See the zenofgithub for a conan.io based application that makes use of this package.
libzengithub is relying on libcurl to call the https://api.github.com/octocat
endpoint and retrieve a random Zen of GitHub.
Its main purpose is to demonstrate how to build portable conan.io packages that rely on conan.io packages (libcurl) themselves.
conan.io is a great package manager for C and C++ libraries which works for various platforms including Linux, Mac OS and Windows.
The only thing needed for libzengithub
to declare a dependency to libcurl
is to declare that dependency in its conanfile.py:
...
class ZenGithubConan(ConanFile):
name = "ZenGitHub"
version = "1.0"
license = "Apache 2.0"
url = "https://github.com/jonico/libzengithub"
settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False], "fPIC": [True, False]}
default_options = {"shared": False, "fPIC": True}
generators = "cmake"
exports_sources = "zengithub/*"
requires = "libcurl/7.75.0"
...
conan will then automatically build the following dependency tree:
conan info . --graph deps.html
open deps.html
and automatically downloads the packages it depends upon from the conan repository. If it should find pre-built packages for the dependencies, it will build them locally.
See zenofgithub for an example application that consumes this library.
First, install the conan.io package manager locally. Then, add the remote to my conan.io repo:
conan remote add conan-jonico https://jonico.jfrog.io/artifactory/api/conan/libzengithub-conan
Now, you can install the library:
conan install ZenGitHub/1.0@jonico/stable
If conan complains about missing dependencies (like libCurl or libz or OpenSSL), this is an indication that your current conan.io do not have a pre-built version of those dependent packages and you can build them locally instead:
conan install ZenGitHub/1.0@jonico/stable --build missing
If you rather want to install the shared library instead of a static library, use
conan install ZenGitHub/1.0@jonico/stable -o ZenGitHub:shared=True --build missing
If you handle multiple dependencies in your project is better to add a conanfile.txt
[requires]
ZenGitHub/1.0@jonico/stable
[options]
ZenGitHub:shared=False # True
[generators]
cmake
[imports]
bin, *.dll -> ./bin # Copies all dll files from packages bin folder to my "bin" folder
lib, *.dylib* -> ./bin # Copies all dylib files from packages lib folder to my "bin" folder
Complete the installation of requirements for your project running:
conan install .
Project setup installs the library (and all his dependencies) and generates the files conanbuildinfo.txt and conanbuildinfo.cmake with all the paths and variables that you need to link with your dependencies.
I was following https://github.com/conan-io/conan-package-tools to provide a range of different operating system, compiler version, debug and release builds for this library.
I am using Travis CI for Linux and Mac builds and AppVeyor for Windows builds and Azure Pipelines for Windows, Linux and Mac.
I am now using GitHub Actions for all builds as it supports all hardware configurations ☝️ with one config file.
I had to exclude certain platforms as libcurl
and OpenSSL packages were not built for all possible mutations. Packages are uploaded to https://jonico.jfrog.io/artifactory/api/conan/libzengithub-conan
Here are the results:
conan search ZenGitHub/1.0@jonico/stable -r=conan --table build_matrix.html
open build_matrix.html
If you are a consumer of libzengithub
, you would not need to build this package by yourself but get it as part of your consumer build or pre-built from my conan.io repo
Checkout zenofgithub for an example application that consumes this library.
If you still like to build, test and install libzengithub
directly, clone this repository, get the conan CLI and run
conan create . jonico/testing
conan export . ZenGitHub/1.0@jonico/stable
If tests run through successfully, a picture like this should appear
MMM. .MMM
MMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMM _____________________
MMMMMMMMMMMMMMMMMMMMM | |
MMMMMMMMMMMMMMMMMMMMMMM | Design for failure. |
MMMMMMMMMMMMMMMMMMMMMMMM |_ _________________|
MMMM::- -:::::::- -::MMMM |/
MM~:~ 00~:::::~ 00~:~MM
.. MMMMM::.00:::+:::.00::MMMMM ..
.MM::::: ._. :::::MM.
MMMM;:::::;MMMM
-MM MMMMMMM
^ M+ MMMMMMMMM
MMMMMMM MM MM MM
MM MM MM MM
MM MM MM MM
.~~MM~MM~MM~MM~~.
~~~~MM:~MM~~~MM~:MM~~~~
~~~~~~==~==~~~==~==~~~~~~
~~~~~~==~==~==~==~~~~~~
:~==~==~==~==~~
First of all, configure the remote to your local conan.io server.
conan remote add <your conan remote> <conan.io, artifactory or bintray url>
conan upload ZenGitHub/1.0@jonico/stable --all -r=<your conan remote>
We have a winner 🎉
The first one who creates a PR with a working example on how to build and publish ARM/ARM64 packages for libzengithub
using self-hosted runners is in for a special treat.
Enjoy ❤️