Add article on building an AppImage with Docker
This commit is contained in:
parent
3ecb2a874b
commit
d644cb1d1b
1 changed files with 276 additions and 0 deletions
276
articles/2019-09-10-kicad-docker.md
Normal file
276
articles/2019-09-10-kicad-docker.md
Normal file
|
@ -0,0 +1,276 @@
|
|||
---
|
||||
title: KiCad compilation through Docker
|
||||
date: 2019-09-10 18:30:00
|
||||
---
|
||||
|
||||
While trying to compile [KiCad](http://kicad-pcb.org/download/debian/) from
|
||||
the latest sources, I had problems installing the large number of required
|
||||
dependencies with the correct versions on my two computers.
|
||||
|
||||
I already know of a tool that allows building a system image that is in
|
||||
a known state and can be executed independently of the host system : Docker.
|
||||
|
||||
In this article, I will summarize the different steps I took to compile KiCad
|
||||
from the sources into an AppImage that can then be copied onto the different
|
||||
systems that I use for my keyboard project.
|
||||
|
||||
## Packaging the dependencies
|
||||
The first step is to package the dependencies needed for the compilation into a
|
||||
Docker image that can then be used. The KiCad website lists the required
|
||||
packages for Debian, we will thus start from this list to build our image.
|
||||
|
||||
Some of the dependencies required have been updated. The final list I obtained
|
||||
through trial and error was the following.
|
||||
|
||||
```
|
||||
FROM debian:10
|
||||
|
||||
# Install kicad deps
|
||||
RUN apt-get update -q && \
|
||||
apt-get install --no-upgrade -qqy \
|
||||
git cmake build-essential curl ccache \
|
||||
libcurl4 libcurl4-gnutls-dev \
|
||||
libboost-dev libboost-test-dev libboost-filesystem-dev libboost-regex-dev \
|
||||
liboce-foundation-dev liboce-ocaf-dev \
|
||||
ca-certificates libssl-dev \
|
||||
libngspice0-dev \
|
||||
libglew-dev libglm-dev swig \
|
||||
libcairo2-dev doxygen graphviz \
|
||||
python3-wxgtk4.0 \
|
||||
libwxgtk3.0-dev libwxgtk3.0-gtk3-dev python3 python3-dev \
|
||||
&& \
|
||||
apt-get clean && \
|
||||
apt-get purge && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
```
|
||||
|
||||
This Dockerfile will allow us to build a base system that allows us to
|
||||
then manually compile the sources through Docker. The following command
|
||||
can be executed from a clone KiCad repository on your computed containing
|
||||
the sources. We will create a build directory from inside the container,
|
||||
configure the build and compile the sources to check that everything needed
|
||||
has been packaged.
|
||||
|
||||
```none
|
||||
host $ docker run --rm -ti -v $(pwd):/kicad 196c68cf5e05 /bin/bash
|
||||
ctnr $ cd kicad/
|
||||
ctnr $ mkdir build
|
||||
ctnr $ cmake \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DKICAD_SCRIPTING_PYTHON3=on \
|
||||
-DKICAD_SCRIPTING_WXPYTHON_PHOENIX=on \
|
||||
../
|
||||
ctnr $ make -j16
|
||||
```
|
||||
|
||||
You should get no error during the compilation, otherwise it means that
|
||||
some dependency must be updated or installed. I followed the different errors
|
||||
to build the list of dependencies given above.
|
||||
|
||||
## Generating an AppImage
|
||||
|
||||
[AppImage](https://appimage.org/) builds everything needed for the execution into one executable,
|
||||
allowing me to copy a single file to a new computer and not having to
|
||||
worry about installing any dependency and thus testing the generated
|
||||
executable quickly.
|
||||
|
||||
I extended the Docker image to also include the necessary tools for building
|
||||
a basic AppImage :
|
||||
|
||||
```
|
||||
FROM debian:10
|
||||
|
||||
# Install kicad deps
|
||||
RUN apt-get update -q && \
|
||||
apt-get install --no-upgrade -qqy \
|
||||
git cmake build-essential curl ccache \
|
||||
libcurl4 libcurl4-gnutls-dev \
|
||||
libboost-dev libboost-test-dev libboost-filesystem-dev libboost-regex-dev \
|
||||
liboce-foundation-dev liboce-ocaf-dev \
|
||||
ca-certificates libssl-dev \
|
||||
libngspice0-dev \
|
||||
libglew-dev libglm-dev swig \
|
||||
libcairo2-dev doxygen graphviz \
|
||||
python3-wxgtk4.0 \
|
||||
libwxgtk3.0-dev libwxgtk3.0-gtk3-dev python3 python3-dev \
|
||||
&& \
|
||||
apt-get clean && \
|
||||
apt-get purge && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
# Download and install linuxdeploy tool
|
||||
RUN curl -O -J -L https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage && \
|
||||
chmod +x linuxdeploy-x86_64.AppImage && \
|
||||
mv linuxdeploy-x86_64.AppImage /usr/bin/linuxdeploy && \
|
||||
curl -O -J -L https://raw.githubusercontent.com/TheAssassin/linuxdeploy-plugin-conda/master/linuxdeploy-plugin-conda.sh && \
|
||||
mv linuxdeploy-plugin-conda.sh /usr/bin/linuxdeploy-plugin-conda && \
|
||||
chmod +x /usr/bin/linuxdeploy-plugin-conda
|
||||
```
|
||||
|
||||
The first `linuxdeploy` tools allows us to easily build an AppImage. The
|
||||
second `linuxdeploy-plugin-conda` eases working with packaging applications
|
||||
that needs Python.
|
||||
|
||||
We can build the new Docker image and execute it again on the folder used
|
||||
previously. As we used a volume, our previous build will still be available
|
||||
allowing us to continue directly with the packaging.
|
||||
|
||||
```
|
||||
host $ docker run --rm -ti -v $(pwd):/kicad cae4d304d730 /bin/bash
|
||||
ctnr $ cd /kicad/build
|
||||
ctrn $ make install DESTDIR=AppDir
|
||||
```
|
||||
|
||||
This will install our compiled sources into an AppDir directory. We will now
|
||||
need to also copy some Python dependencies that will be required and not
|
||||
automatically handled :
|
||||
|
||||
```
|
||||
ctnr $ mkdir -p AppDir/usr/lib/python3/dist-packages/
|
||||
ctnr $ cp -r /usr/lib/python3/dist-packages/wx \
|
||||
/usr/lib/python3/dist-packages/wxPython-4.0.4.egg-info \
|
||||
AppDir/usr/lib/python3/dist-packages/
|
||||
```
|
||||
|
||||
Then, we also need to update our KiCad binary so that the packaged Python
|
||||
will be used and not the system one. For that, we will replace the KiCad
|
||||
binary with a script that will simply extract the path at which the AppImage
|
||||
will be mounted and export the `PYTHON_PATH` variable accordingly.
|
||||
|
||||
```
|
||||
ctnr $ mv AppDir/usr/bin/kicad AppDir/usr/bin/kicad_bin
|
||||
ctnr $ cat << "EOF" > AppDir/usr/bin/kicad
|
||||
#!/bin/sh
|
||||
HERE="$(dirname "$(readlink -f "${0}")")/../../"
|
||||
export PYTHON_PATH="${HERE}"/usr/lib/python3:${PYTHON_PATH}
|
||||
exec "${HERE}/usr/bin/kicad_bin" "$@"
|
||||
EOF
|
||||
ctnr $ chmod +x AppDir/usr/bin/kicad
|
||||
```
|
||||
|
||||
Now that everything is ready, we can package the AppDir into an AppImage
|
||||
using `linuxdeploy`.
|
||||
|
||||
```
|
||||
ctnr $ LD_LIBRARY_PATH=$(pwd)/AppDir/usr/lib/x86_64-linux-gnu/ linuxdeploy \
|
||||
--appimage-extract-and-run \
|
||||
--appdir AppDir \
|
||||
-d $(pwd)/AppDir/usr/share/applications/kicad.desktop \
|
||||
--output appimage
|
||||
```
|
||||
|
||||
This will generate a `KiCad-*-x86_64.AppImage` file in your build folder
|
||||
that can be executed on your host OS without having to install any
|
||||
dependency. It will not be possible to execute the AppImage from inside
|
||||
the container for multiple reasons, first of which that FUSE is needed to
|
||||
mount the AppImage content and is not available in a container. Second,
|
||||
an X Server will be needed to start the application and is also not available
|
||||
in the container.
|
||||
|
||||
## Build script
|
||||
Building manually without having to worry about dependencies is great but
|
||||
we can do better by simply scripting the different steps so that everything
|
||||
happens in one command line.
|
||||
|
||||
Once the steps have been verified, we can put them in a build script
|
||||
`build-docker.sh` that we include in the Docker image that will be called
|
||||
when starting the container.
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
cd "$1"
|
||||
|
||||
BUILD_TYPE="$2"
|
||||
if [ -z "$BUILD_TYPE" ]; then
|
||||
BUILD_TYPE="Debug"
|
||||
fi
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
rm -rf AppDir
|
||||
|
||||
cmake \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DKICAD_SCRIPTING_PYTHON3=on \
|
||||
-DKICAD_SCRIPTING_WXPYTHON_PHOENIX=on \
|
||||
../
|
||||
|
||||
make -j$(nproc) --output-sync
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 10
|
||||
fi
|
||||
|
||||
make install DESTDIR=AppDir
|
||||
|
||||
mkdir -p AppDir/usr/lib/python3/dist-packages/
|
||||
|
||||
cp -r /usr/lib/python3/dist-packages/wx \
|
||||
/usr/lib/python3/dist-packages/wxPython-4.0.4.egg-info \
|
||||
AppDir/usr/lib/python3/dist-packages/
|
||||
|
||||
mv AppDir/usr/bin/kicad AppDir/usr/bin/kicad_bin
|
||||
|
||||
cat << "EOF" > AppDir/usr/bin/kicad
|
||||
#!/bin/sh
|
||||
HERE="$(dirname "$(readlink -f "${0}")")/../../"
|
||||
export PYTHON_PATH="${HERE}"/usr/lib/python3:${PYTHON_PATH}
|
||||
exec "${HERE}/usr/bin/kicad_bin" "$@"
|
||||
EOF
|
||||
|
||||
chmod +x AppDir/usr/bin/kicad
|
||||
|
||||
LD_LIBRARY_PATH=$(pwd)/AppDir/usr/lib/x86_64-linux-gnu/ linuxdeploy \
|
||||
--appimage-extract-and-run \
|
||||
--appdir AppDir \
|
||||
-d $(pwd)/AppDir/usr/share/applications/kicad.desktop \
|
||||
--output appimage
|
||||
|
||||
mv KiCad*.AppImage ../KiCad-$(git describe).AppImage
|
||||
```
|
||||
|
||||
```
|
||||
FROM debian:10
|
||||
|
||||
# Install kicad deps
|
||||
RUN apt-get update -q && \
|
||||
apt-get install --no-upgrade -qqy \
|
||||
git cmake build-essential curl ccache \
|
||||
libcurl4 libcurl4-gnutls-dev \
|
||||
libboost-dev libboost-test-dev libboost-filesystem-dev libboost-regex-dev \
|
||||
liboce-foundation-dev liboce-ocaf-dev \
|
||||
ca-certificates libssl-dev \
|
||||
libngspice0-dev \
|
||||
libglew-dev libglm-dev swig \
|
||||
libcairo2-dev doxygen graphviz \
|
||||
python3-wxgtk4.0 \
|
||||
libwxgtk3.0-dev libwxgtk3.0-gtk3-dev python3 python3-dev \
|
||||
&& \
|
||||
apt-get clean && \
|
||||
apt-get purge && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
# Download and install linuxdeploy tool
|
||||
RUN curl -O -J -L https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage && \
|
||||
chmod +x linuxdeploy-x86_64.AppImage && \
|
||||
mv linuxdeploy-x86_64.AppImage /usr/bin/linuxdeploy && \
|
||||
curl -O -J -L https://raw.githubusercontent.com/TheAssassin/linuxdeploy-plugin-conda/master/linuxdeploy-plugin-conda.sh && \
|
||||
mv linuxdeploy-plugin-conda.sh /usr/bin/linuxdeploy-plugin-conda && \
|
||||
chmod +x /usr/bin/linuxdeploy-plugin-conda
|
||||
|
||||
COPY build-docker.sh /build-docker.sh
|
||||
|
||||
ENTRYPOINT ["/bin/bash", "/build-docker.sh"]
|
||||
CMD ["/kicad"]
|
||||
```
|
||||
|
||||
We can then simply build an AppImage from the latest sources with just one
|
||||
command line, without having to worry about updating our host system with
|
||||
the latest dependencies : `docker run --rm -it -v $(pwd):/kicad kicad-builder-docker kicad Release`
|
Loading…
Add table
Reference in a new issue