Deploying IoT C/C++ projects with Conan and

This is a guest post written by Luis Martínez de Bartolomé, Senior Software Engineer at Jfrog

Creating C/C++ applications for IoT devices can be a challenge. It requires setting up the compiler and toolchain to cross-build for the embedded architecture, managing the application’s dependencies, and finding a simple and smart way to deploy the application.

In this blog post, we will demonstrate an easier method by building and deploying the following application, comprised of three services, to a Raspberry Pi 3 with Conan and

  • Eclipse mosquitto: Includes the mosquitto (MQTT broker) application. It will receive and send the MQTT messages from/to the connected applications.
  • Thermometer: Sends a MQTT message with the temperature of a city in a specific topic to the mosquitto broker.
  • Home Assistant domotic hub instance, subscribed to the broker to display the MQTT messages received, in this case the temperature of our city.

Both the mosquitto and the thermometer service use several third party libraries. Cross-building and linking them would be difficult without the following tools:

  1. Eclipse PAHO-C library for sending the message.
  2. Libcurl library to check the city temperature using a public rest API, using the “” free service.
  3. JSON-c library to parse the JSON received from the rest API service.
  4. C-ares library as a dependency of the mosquitto broker.
  5. OpenSSL as a dependency of both mosquitto and libcurl.
  6. Zlib as a transitive dependency of OpenSSL and libcurl.

All the third parties and the thermometer service are built as Conan packages for this tutorial, so let’s first explain what Conan is and how we cross-build our applications and dependencies.

What is Conan?

Conan is an open source package manager for C/C++. It uses “recipes” ( to build libraries, applications, etc. Each “recipe” can generate multiple binary packages for different operating systems and architectures. All the binaries and the recipe can coexist in the same Conan repository. You can setup your own Conan repository for free, using JFrog Artifactory Community Edition for C/C++ (on-premises solution) or JFrog Bintray (universal central distribution service).

Once the recipe and binary packages are in a Conan repository, only the binaries matching our configuration will be retrieved; for example, those meant for the Linux/armv7hf system architecture.

Building the application

Our Raspberry Pi runs an armv7hf Linux architecture, so we will:

  • Cross-build our application for Linux/armv7hf
  • Upload the recipe and generated packages to a Conan repository, in this case a Bintray repository.

Later, when we deploy the application to our device with, it will download the built application directly, saving time and reducing the complexity of the deployment.

Deploying IoT C/C++ projects with Conan and

Cross-building the mosquitto service

The mosquitto service is built in the Conan package mosquitto. The mosquitto Conan package is: mosquitto/[email protected]/stable

There are prebuilt binaries in conan-center for many operating systems, but not for linux-armv7hf. We will use a Docker container prepared to cross-build our applications for lasote/conangcc49-armv7hf. This Docker image comes with Conan and Linux armv7hf cross-compiler ready:

$ docker run -it --rm lasote/conangcc49-armv7hf /bin/bash
$ sudo pip install conan --upgrade # Get the latest Conan available
$ conan remote add iot -i 0
$ conan install mosquitto/[email protected]/stable --build missing

Conan will build the whole dependency tree for linux/armv7hf architecture:

Deploying IoT C/C++ projects with Conan and

Cross-building packages is much faster than building native packages directly on the Raspberry Pi, and is much faster than using emulators like QEMU.

Finally, we upload all the built packages and the recipe to a personal repository with $ conan upload “*” -r iot --all -c. This repository will be used by to retrieve all the precompiled libraries needed to build the images, so we won’t need to build anything when our applications are deployed.

Building the thermometer service

Now we’ll build the thermometer service of our application, following almost exactly the same steps.

This is the “recipe” of our thermometer application,

class MyTempSensorConan(ConanFile): name = "my_temp_sensor" version = "1.0" license = "MIT" url = "" description = "Simple example of MQTT application sending a fake temperature" settings = "os", "arch" generators = "cmake" exports_sources = "src/*" requires = ("paho-c/[email protected]/stable", "libcurl/[email protected]/stable","json-c/[email protected]/stable") def build(self): cmake = CMake(self) cmake.configure(source_folder="src") def package(self): self.copy("thermometer", dst="bin", src="bin")

The thermometer application is calling a REST API service (with libcurl), parsing the JSON (with JSON-c) and finally sending a MQTT message to the mosquitto broker (with paho-c). We can see the declared “requires” in our recipe.

Now let’s cross-build our application for Linux/ armv7hf:

$ docker run -it --rm -v$(pwd)/thermometer:/home/conan/thermometer lasote/conangcc49-armv7hf /bin/bash
$ cd thermometer
$ sudo pip install conan --upgrade
$ conan remote add iot -i 0
$ conan create . conan/stable --build missing
$ conan upload “*” -r iot --all -c

We have cross-built the dependency tree (except for zlib and OpenSSL, which were already built in the previous step for our configuration), so Conan directly downloads and links the prebuilt binary for them:

Deploying IoT C/C++ projects with Conan and

Deploying the application with

Our applications are now in Conan packages that have been uploaded to our Bintray repository. Let’s see how to deploy them to the Raspberry Pi with

Writing the Dockerfiles for our apps

Dockerfile for mosquitto
FROM resin/armv7hf-python WORKDIR /usr/src/app ENV LD_LIBRARY_PATH /usr/src/app/bin RUN sudo pip install conan --upgrade RUN conan remote add iot -i 0 \ && conan profile new default --detect \ && conan profile update settings.arch=armv7hf default \ && conan profile update settings.arch_build=armv7hf default \ && conan install mosquitto/[email protected]/stable --update RUN sed -i "s|#user mosquitto|user root|g" bin/mosquitto.conf \ && sed -i "s|#allow_anonymous true|allow_anonymous false|g" bin/mosquitto.conf \ && sed -i "s|#password_file|password_file /data/mosquitto/mosquitto_pass|g" bin/mosquitto.conf COPY /usr/src/app/ CMD ["/usr/src/app/"] 

The Dockerfile does the following:

  • Adds our IoT Conan remote where we have all the uploaded applications:
    conan remote add iot -i
  • Adjusts the default profile to match the armv7hf architecture.
  • Runs a conan install libmosquitto/[email protected]/stable that will retrieve all the precompiled binaries we’ve built for mosquitto.
  • Declares a deploy() method, so that if we install the package using the full reference libmosquitto/[email protected]/stable, it will copy all the needed built libraries and executables to a local directory.
Dockerfile for thermometer
FROM resin/armv7hf-python WORKDIR /usr/src/app ENV LD_LIBRARY_PATH /usr/src/app/bin RUN pip install conan --upgrade RUN conan remote add iot -i 0 \ && conan profile new default --detect \ && conan profile update settings.arch=armv7hf default \ && conan profile update settings.arch_build=armv7hf default \ && conan install thermometer/[email protected]/stable --update COPY /usr/src/app/ CMD ["/usr/src/app/"] 
Dockerfile for HomeAssistant
FROM homeassistant/raspberrypi3-homeassistant:0.71.0 WORKDIR /usr/src/app COPY /usr/src/app/ CMD ["/usr/src/app/"] 

This is a standard image distributed from the official Home Assistant DockerHub

Docker compose.yml

To coordinate the three services we will use Docker Compose. This way we can easily connect home-assistant and our thermometer application to the mosquitto MQTT broker. Lucky for us, supports deploying and running multiple containers on an IoT device with Docker Compose.

version: "2" volumes: resin-data:
services: mosquitto: privileged: true restart: always build: context: ./mosquitto volumes: - resin-data:/data ports: - 1883:1883 thermometer: privileged: true restart: always build: context: ./thermometer depends_on: - mosquitto hass: privileged: true restart: always build: ./resin-homeassistant expose: - 80 ports: - 80:8123 depends_on: - mosquitto volumes: - resin-data:/data

All the applications will share a /data directory where they can write the configuration files and store any other needed files.

Creating the application in

We have signed up for and created a new application called ConanDemo. We can now add a new device (Raspberry Pi 3), enter our wifi credentials, and download the operating system image already prepared:

Deploying IoT C/C++ projects with Conan and

Using Etcher, we flash an SD card with resinOS:

Deploying IoT C/C++ projects with Conan and

A new device is created and connected after a few minutes:

Deploying IoT C/C++ projects with Conan and

Deploying the application

From the application dashboard, we retrieve the git remote URL where we will push our Dockerfiles:

Deploying IoT C/C++ projects with Conan and

We push the code to our repository with the Dockerfiles to deploy the app:

$ git push resin master

Docker builds the images, the application deploys to the device, and the device uploads the images:

Deploying IoT C/C++ projects with Conan and

Deploying IoT C/C++ projects with Conan and

Configuring the application

Once the application services are all deployed to the device, we can SSH into the individual service containers and configure them as needed:

Home Assistant

SSH into the hass service and edit the /data/hass_conf/configuration.yml to add information about how to connect to the mqtt broker and our temperature sensor publishing to the topic home/bedroom/temperature.

mqtt: broker: mosquitto username: admin password: ******* discovery: true discovery_prefix: homeassistant sensor: - platform: mqtt name: City Temperature state_topic: "home/bedroom/temperature" unit_of_measurement: ' degrees' value_template: "{{ value_json.temperature }}"

Mosquitto and Thermometer

We also need to configure the environment variables containing the credentials to connect to the mosquitto broker and the city where we want to check the temperature. We can globally configure the mosquitto credentials, and configure them only for the thermometer service in the city:

Deploying IoT C/C++ projects with Conan and

Remove the mosquitto config file to be regenerated with the new user and password specified in the environment:

$ rm /data/mosquitto/mosquitto.conf
$ rm /data/mosquitto/mosquitto.pass

Now we can reboot the services from the dashboard.

Once the services have rebooted we can access the URL:

Deploying IoT C/C++ projects with Conan and

And we can see a new sensor connected to the platform, indicating 34º in our city!


The application services in this demonstration are simple examples of what can be developed and deployed to IoT devices. With Conan, we have been able to manage seven dependencies (some of them, like OpenSSL and libcurl, quite complex), without concern for how to build or link them. By including them as a require in our file, we were able to cross-build the entire dependency tree in one step.

We generated binary packages for linux/armv7hf and uploaded them to a repository. Binary management is a must for IoT; the software deployed to the devices should not be source code. With Conan, we can use a CI to cross-build all of the required packages for different architectures and upload them to a Conan repository (JFrog Bintray or JFrog Artifactory).

With, we then deploy the applications by writing a Dockerfile and a simple “git push,” allowing us to easily manage any number of configured applications and devices.

To learn more about the Conan project you can access to the Conan docs and the Conan github repository. And visit to sign up for an account – your first 10 devices are always free!