# Creating a system image on Raspery Pi 5

**URL:** https://discourse.julialang.org/t/creating-a-system-image-on-raspery-pi-5/108016
**Category:** General Usage
**Tags:** package-compiler, modelingtoolkit
**Created:** [December 24, 2023, 7:46pm UTC](https://discourse.julialang.org/t/creating-a-system-image-on-raspery-pi-5/108016 "2023-12-24T19:46:23Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [December 24, 2023, 7:46pm UTC](https://discourse.julialang.org/t/creating-a-system-image-on-raspery-pi-5/108016/1 "2023-12-24T19:46:23Z")

</div>

I wrote a script to create a system image on the Pi 5 for my current project, see:

> **[GitHub - ufechner7/Tethers.jl: Tether models](https://github.com/ufechner7/Tethers.jl)**
>
> Tether models. Contribute to ufechner7/Tethers.jl development by creating an account on GitHub.

I am using ModelingToolkit and other libraries that result in a very large system image.

This causes some issues, mainly the RAM requirements are huge.  
When using one thread I need at least 24 GB RAM, for multi-threaded system image creation more. This is an issue if you have only 8GB physical RAM. Solution:

1. use a swap file of at least 16 GB
2. use and enable zswap, see: [zswap - ArchWiki](https://wiki.archlinux.org/title/zswap)
3. turn off systemd-oomd, because on Ubuntu 23.10 which I am using it would  
otherwise kill the Julia compilation process even if there is enougth swap  
available

Now the script succeeds in about 52 minutes. On my desktop, based on a 16 core AMD CPU with 32 GB RAM it needs only 7:22 minutes (tested after deleting the .julia folder).

Here the full script, not yet tested on Windows:

```julia
#!/bin/bash -eu
if [[$(basename $(pwd)) == "bin"]]; then
    cd ..
fi

if ! command -v juliaup &> /dev/null; then
    echo "Please install the Julia installer 'juliaup'!"
    echo "See: https://github.com/JuliaLang/juliaup"
    exit 1
fi

juliaup add 1.10
juliaup default 1.10

export KMP_DUPLICATE_LIB_OK=TRUE
export MPLBACKEND=qt5agg
export PYTHON=""

# total memory in kB
MEM=$(grep MemTotal /proc/meminfo | awk '{print $2}')

if (( $MEM < 15000000 )); then
    sudo /bin/bash -c "echo '1' | tee -a /proc/sys/vm/overcommit_memory"
    sudo systemctl disable --now systemd-oomd
    export JULIA_IMAGE_THREADS=1
    export JULIA_PKG_PRESERVE_TIERED_INSTALLED=true
fi

julia_version=$(julia --version | awk '{print($3)}')
julia_major=${julia_version:0:3} 
if [[$julia_major == "1.1"]]; then
    julia_major=${julia_version:0:4} 
fi
if test -f "kps-image-${julia_major}.so"; then
    mv bin/kps-image-${julia_major}.so bin/kps-image-${julia_major}.so.bak
fi

echo "Updating packages..."
if test -f "Manifest.toml"; then
   rm Manifest.toml
fi
julia --pkgimages=no --project -e "using Pkg; Pkg.add(\"PyCall\"); Pkg.build(\"PyCall\")"
julia --pkgimages=no --project -e "using Pkg; Pkg.add(\"Conda\"); using Conda; Conda.add(\"matplotlib\")"
julia --pkgimages=no --project -e "using PyPlot"
julia --pkgimages=no --project -e "include(\"./test/update_packages.jl\");"

julia --pkgimages=no --project -t 4 -e "using Pkg; Pkg.precompile()"
if [[$julia_major == "1.9"]]; then
    julia --pkgimages=no --project -t 4 -e "include(\"./test/create_sys_image.jl\");"
else
    julia --pkgimages=no --project -t 4 --gcthreads=4,1 -e "include(\"./test/create_sys_image.jl\");"
fi
mv kps-image_tmp.so bin/kps-image-${julia_major}.so

```

Questions:

- why does compiling ModelingToolkit.jl needs so much memory?
- any other idea how to bring this time down to \< 30 min on a Pi 5?

When the image is compiled everything runs fast and smooth on the Pi.

---

<div class="post-metadata">

### Author: ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)
#### Post date: [December 24, 2023, 8:34pm UTC](https://discourse.julialang.org/t/creating-a-system-image-on-raspery-pi-5/108016/2 "2023-12-24T20:34:43Z")

</div>

One idea would be to use another ARM system and then set `JULIA_CPU_TARGET` to target the Raspberry Pi.

Try the following for options.

```julia
julia -C help

```

As for why it is such a resource hog, this is mainly the domain of LLVM I think.

You could also use PkgCacheInspector.jl to investigate the pkgimage of ModelingToolkit.jl.

> **[GitHub - timholy/PkgCacheInspector.jl: Inspect the contents of Julia package...](https://github.com/timholy/PkgCacheInspector.jl)**
>
> Inspect the contents of Julia package cache files. Contribute to timholy/PkgCacheInspector.jl development by creating an account on GitHub.

---

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [December 25, 2023, 8:09pm UTC](https://discourse.julialang.org/t/creating-a-system-image-on-raspery-pi-5/108016/3 "2023-12-25T20:09:23Z")

</div>

Not using qt5agg saves 5 minutes:

```julia
#!/bin/bash -eu
if [[$(basename $(pwd)) == "bin"]]; then
    cd ..
fi

if ! command -v juliaup &> /dev/null; then
    echo "Please install the Julia installer 'juliaup'!"
    echo "See: https://github.com/JuliaLang/juliaup"
    exit 1
fi

juliaup add 1.10
juliaup default 1.10

export KMP_DUPLICATE_LIB_OK=TRUE
export PYTHON=""

# total memory in kB
MEM=$(grep MemTotal /proc/meminfo | awk '{print $2}')

if (( $MEM < 15000000 )); then
    sudo /bin/bash -c "echo '1' | tee -a /proc/sys/vm/overcommit_memory"
    sudo systemctl disable --now systemd-oomd
    export JULIA_IMAGE_THREADS=1
    export JULIA_PKG_PRESERVE_TIERED_INSTALLED=true
else
    export MPLBACKEND=qt5agg
fi

julia_version=$(julia --version | awk '{print($3)}')
julia_major=${julia_version:0:3} 
if [[$julia_major == "1.1"]]; then
    julia_major=${julia_version:0:4} 
fi
if test -f "kps-image-${julia_major}.so"; then
    mv bin/kps-image-${julia_major}.so bin/kps-image-${julia_major}.so.bak
fi

echo "Updating packages..."
if test -f "Manifest.toml"; then
   rm Manifest.toml
fi
julia --pkgimages=no --project -e "using Pkg; Pkg.add(\"PyCall\"); Pkg.build(\"PyCall\")"
julia --pkgimages=no --project -e "using Pkg; Pkg.add(\"Conda\"); using Conda; Conda.add(\"matplotlib\")"
julia --pkgimages=no --project -e "using PyPlot"
julia --pkgimages=no --project -e "include(\"./test/update_packages.jl\");"

julia --pkgimages=no --project -t auto -e "using Pkg; Pkg.precompile()"
julia --pkgimages=no --project -t auto --gcthreads=2,1 -e "include(\"./test/create_sys_image.jl\");"

mv kps-image_tmp.so bin/kps-image-${julia_major}.so

```

This needs:

```julia
✔ [31m:42s] PackageCompiler: compiling incremental system image

real	47m11.794s
user	42m14.517s
sys 13m44.359s

```
