0

I wrote a C++ program with multiple classes and divided it into multiple files, which is intended to run on an embedded device (raspi 2 to be specific) that has no internet access. Therefore building the source and installing the dependencies on every device would be very laborious.

Is there a way to compile the program on one of the devices (as an exception to the others, this one has internet access), so that I can just transfer the build files, e.g. via USB, to the other devices? This should also include the various libraries I used so that I don't have to install them on every device. These are mainly std, but also a self-cloned and build library and a with apt installed library (I linked the libraries used as an example, but they shouldn't affect the process, I guess).

I'm using CMake. Is there an option, to make CMake compile a program into a (set of) files that run independently of the system-installed libraries with other words: they run without the need to have the required libraries installed on the system, but shipped with the build files.

Edit:

My main problem is, that I cannot get a certain dependency on the target devices due to a lack of internet access. Can I build the package and also include the library in that build, without me having to install it?

Moritz
  • 378
  • 5
  • 14
  • How many devices are you speaking about ? Is it closer to 10 or 10k ? – Martin Aug 31 '22 at 20:45
  • 1
    Why would you not cross-compile to the Raspberry Pi? – Alex Reinking Sep 01 '22 at 13:33
  • @Martin more like 10 – Moritz Sep 01 '22 at 15:33
  • @AlexReinking because I didn't know there is such a thing. A Quick search scared me, it seems as if this would be a big effort for just setting up like 10 raspis. But for a lager scale this seems as a good solution. please tell me if I'm wrong. – Moritz Sep 01 '22 at 15:37
  • My main problem is, that I cannot get a certain dependency on the target devices due to a lack of internet access. Can I build the package and also include the library in that build, without me having to install it? – Moritz Sep 01 '22 at 16:48
  • There's [`install(IMPORTED_RUNTIME_ARTIFACTS)`](https://cmake.org/cmake/help/latest/command/install.html#imported-runtime-artifacts) which could be used in combination with `cpack` to generate a `.tar.gz` containing the program including all dependencies. You just need to make sure everything is in the right place. Crosscompiling isn't that hard the toolchain file example for cmake is an example for the raspberry target: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-linux – fabian Sep 01 '22 at 19:18

1 Answers1

0

I'm not sure I fully understand why you need internet for your deployment but I can give you several methods and you'll choose the one you seem the best.

Method A: Cloning the SD card image

During your development phase, you ended to successfully have a RPi device working and you want to replicate this. You can use some tools to duplicate your image on another SD card, N times and eventually, this could be sufficient to make it work.

Pros: Very quick method

Cons: Usually, your development phase involve adjustments, trying different tools, different versions, etc.. your original RPi image is not clean and so you'll replicate this. Definitely not valid for an industrial project for could be sufficient for a personal one.

Method B: Create deployments scripts

You can create a deployment script on your computer to copy, configure, install what you need. Assuming you start with a certain version of Raspberry pi OS, you flash it, then you boot your PI that is connected via Ethernet for example. You can start a script on your computer that will:

  • Copy needed sources / packages / binaries
  • (Optional) compile sources (if you have a compiler that suits your need on RPi OS)
  • Miscellaneous configuration

To do all these, a script like this can do the job:

PI_USERNAME="pi"
PI_PASSWORD="raspberry"
PI_IPADDRESS="192.168.0.3"
# example on how to execute a command remotely
sshpass -p ${PI_PASSWORD} ssh ${PI_USERNAME}@${PI_IPADDRESS} sudo apt update
# example on how to copy a local file on the RPI
sshpass -p ${PI_PASSWORD} scp local_dir/nlohmann/json.hpp ${PI_USERNAME}@${PI_IPADDRESS}:/home/pi/sources

Importante note:

  • Hard coded credentials is not recommended.
  • This script is assuming you are using linux but you'll find equivalent tool under Windows.
  • This assume your RPI has a fixed IP but you can still improve this script to automatically find the RPI on the network. (lots of possibilities)

Pros: While you create this deployment script, you'll force yourself to start from a clean image and no dirty environment is duplicated.

Cons: Take a bit longer than method A

Method C: Create your own Raspberry PI image using Yocto

Yocto is a tool to create your own images, suitable for Raspberry PI. You can customize absolutely everything and produce an sdcard image you can just flash your RPis SD cards.

Pros: Very complete tool, industrial process

Cons: Quite complicated to deal with, not suitable for beginners, time cost

Saying in the comments it's only for 10 devices and that you were a bit scared to cross compile, I would not promote the Yocto method for you. I would not recommend the method A as well mostly because of the dirty environment duplication (but up to you in the end). The method B with the deployment script may be the best to go.

Martin
  • 877
  • 8
  • 20