Sometimes you need to hide the details of distributable programs which provide functionality on Raspbian. For example, you might have a program which encrypts/decrypts data and you don't necessarily want to make the source available as a result.
All the examples below assume an ARMv7 architecture as found on a Raspberry Pi 3B, 3B+ or A+ models. The Raspberry Pi Zero W, for example, is an ARMv6 architecture so adjustments to the instructions would be necessary (though not included below).
If you compile on a Raspberry Pi Zero W, the executable can be distributed to and run on a Raspberry Pi 3B (at least, in theory). It is rumored that the reverse is true, noting that your mileage may vary.
Throughout all these examples it is to be noted that you'll compile on one Raspberry Pi and distribute just the resulting executable for other Raspberry Pi computers. (You won't need to install anything else on the receiving computer.)
One of the easiest methods of hiding the details of your code would be to pre-compile a Python script and to only deliver that version.
It would be nice to use pyinstaller but it doesn't seem to include a pre-compiled bootloader for ARMv7, for what it's worth. I'm taking the Cython route here. I'm assuming Python2.7 throughout.
- Begin with a standard Raspbian installation
- Remote into the Pi using
ssh
, for example mkdir -p ~/scripts/hello-py-src && cd ~/scripts/hello-py-src
touch hello.py && nano hello.py
Note the use of single quotes to surround a string.
#!/usr/bin/env python
print 'Hello, World!\n'
If this is running as a script within an OctoPrint-imaged Pi, the first line needs to instead be
#!/home/pi/oprint/bin/python
5. [Required only once]: pip --version
6. [Required only once]: If pip is not installed yet: sudo apt-get install -y python-pip
If this is running as a script within OctoPrint and you didn't find pip, you should stop and run
source ~/oprint/bin/activate
to enter the virtual environment and then repeat the lastpip --version
command, continuing from here without attempting to install pip.
7. [Required only once]: pip install Cython
8. [Required only once]: sudo apt-get install -y python2.7-dev
9. ~/.local/bin/cython -2 --embed -o hello.c hello.py
Note that I'm indicating the location of cython since it didn't happen to be in my $PATH variable.
10. cc -Os -I /usr/include/python2.7 -o hello hello.c -lpython2.7 -lpthread -lm -lutil -ldl
11. cp hello ..
12. cd .. && ls -l
-rwxr-xr-x 1 pi pi 15216 Jan 10 20:16 hello # = 15KB
drwxr-xr-x 2 pi pi 4096 Jan 10 20:14 hello-py-src
13. ./hello
Hello, World!
So now you have an executable program which was originally a Python script, compiled to a C program and finally linked into an executable. You may now distribute just the stand-alone hello
program which will run on any ARMv7 architecture computer like another Raspberry Pi 3.
You do not need the original hello-py-src
folder or any of its contents for distribution. You do not need to install anything else on the receiving Raspberry Pi computer.
It's easy enough to compile a C or C++ script on Raspian and then just distribute the executable version of same.
- Begin with a standard Raspbian installation
- Remote into the Pi using
ssh
, for example mkdir -p ~/scripts/hello-c-src && cd ~/scripts/hello-c-src
touch hello.c && nano hello.c
Note the use of double quotes in C to surround a string.
#include <stdio.h>
void main() {
printf("Hello, World!\n");
}
5. gcc -o hello-c hello.c
6. cp hello-c .. && cd ..
7. ls -l
-rwxr-xr-x 1 pi pi 8148 Jan 10 20:41 hello-c # = 8KB
drwxr-xr-x 2 pi pi 4096 Jan 10 20:40 hello-c-src
8. ./hello-c
Hello, World!
So now you have an executable program as in the previous example. You may now distribute just the stand-alone hello-c
program which will run on any ARMv7 architecture computer like another Raspberry Pi 3.
You do not need the original hello-c-src
folder or any of its contents for distribution. You do not need to install anything else on the receiving Raspberry Pi computer.
The Go language is relatively new and compiles into an executable.
- Begin with a standard Raspbian installation
- Remote into the Pi using
ssh
, for example - [Required only once]:
mkdir ~/tmp && cd ~/tmp
- [Required only once]:
wget https://dl.google.com/go/go1.10.7.linux-armv6l.tar.gz
- [Required only once]:
sudo tar -C /usr/local -xzf go1.10.7.linux-armv6l.tar.gz
- [Required only once]:
nano ~/.profile
export PATH=$PATH:/usr/local/go/bin
7. [Required only once]: source ~/.profile
8. [Required only once]: go version
9. mkdir ~/scripts/hello-go-src && cd ~/scripts/hello-go-src
10. [Required only once]: rm -Rf ~/tmp
11. touch hello.go && nano hello.go
package main
import (
"fmt"
)
func main() {
fmt.Printf("Hello, World!\n")
return
}
12. go build
13. cp hello-go-src ../hello-go && cd ..
14. ls -l
drwxr-xr-x 2 pi pi 4096 Jan 10 20:59 hello-go-src
-rwxr-xr-x 1 pi pi 1826069 Jan 10 21:02 hello-go # = 1.8MB
So now you have an executable program as in the previous example. You may now distribute just the stand-alone hello-go
program which will run on any ARMv7 architecture computer like another Raspberry Pi 3.
You do not need the original hello-go-src
folder or any of its contents for distribution. You do not need to install anything else on the receiving Raspberry Pi computer.
Zeit.co provides a great Node compiler, allowing you to distribute just an executable out of your JavaScript code.
Dependency: You must first install
NodeJS
andnpm
for ARMv7 on your Raspberry Pi.
- Begin with a standard Raspbian installation
- Remote into the Pi using
ssh
, for example - [Required only once]:
mkdir ~/tmp && cd ~/tmp
- [Required only once]:
wget https://nodejs.org/dist/v8.9.3/node-v8.9.3-linux-armv7l.tar.xz
- [Required only once]:
tar -xvf node-v8.9.3-linux-armv7l.tar.xz
- [Required only once]:
cd node-v8.9.3-linux-armv7l
- [Required only once]:
sudo cp -R * /usr/local/
- [Required only once]:
node --version && npm --version
- [Required only once]:
sudo npm install -g pkg
mkdir ~/scripts/hello-js-src && cd ~/scripts/hello-js-src
- [Required only once]:
rm -Rf ~/tmp
touch hello.js && nano hello.js
#!/usr/bin/env node
console.log('Hello, World!\n');
13. pkg -t node8-linux-armv7 -o hello-js hello.js
14. cp hello-js .. && cd ..
15. ls -l
-rwxr-xr-x 1 pi pi 31303361 Jan 10 21:20 hello-js # = 31.3MB
drwxr-xr-x 2 pi pi 4096 Jan 10 21:19 hello-js-src
So now you have an executable program as in the previous example. You may now distribute just the stand-alone hello-js
program which will run on any ARMv7 architecture computer like another Raspberry Pi 3.
You do not need the original hello-js-src
folder or any of its contents for distribution. You do not need to install anything else on the receiving Raspberry Pi computer.
Here's a table of the executable file sizes as produced from the four Hello, World!
versions (plus an additional C++ alternative).
Version | Size in bytes | Comments |
---|---|---|
C | 8,148 | Obviously, this is the smallest executable of the collection here. Note that the difference versus a C++ file would have been similarly-sized. |
C++ | 8,416 | Almost as small as C. Note the differences in the C example: 1) The source file should end in .cpp , 2) the main function needs to be changed to int main() , 3) the return command becomes return 0; , 4) the compile command becomes gcc -o hello-cpp hello.cpp . |
Python | 15,216 | This isn't too bad as file size goes. Given the compilation step to a C object file as an intermediate step, this is to be expected. |
Go | 1,826,069 | This comes in fairly heavy by comparison, noting that the Go language has a rich collection of packages. |
NodeJS | 31,303,361 | Although this weighs in as the heaviest file, the NodeJS engine (V8) allows for some pretty sophisticated programming and the ease, familiarity and convenience of JavaScript programming. |
Description | Version | Author | Last Update |
---|---|---|---|
raspi-executables | v1.0.2 | OutsourcedGuru | January 11, 2019 |
Donate | Cryptocurrency | |
---|---|---|
![]() |
![]() |
|
Ethereum | Bitcoin |