#+title: Building or installing

I provide packages for a number of distros. If possible, please use these
instead of building from source. If you're interested in packages for a
not-yet-supported distro, please contribute! You can email me for help.

* Installing from packages
:PROPERTIES:
:CUSTOM_ID: installing-from-packages
:END:

mrcal is included in recent versions of Debian and Ubuntu. So if you're running
at least Debian 12 (bookworm) or Ubuntu 22.04 (jammy), you can install with a
single command. For instance the commandline tools and the C development library
and the Python library can be installed with

#+begin_src sh
apt install mrcal libmrcal-dev python3-mrcal
#+end_src

For older distros or if you want to get the latest release of mrcal, you can use
the mrcal APT repository. I currently distribute packages for

- Debian/buster (10)
- Debian/bullseye (11)
- Debian/bookworm (12)
- Debian/sid (bleeding-edge)
- Ubuntu/bionic (18.04 LTS)
- Ubuntu/focal (20.04 LTS)
- Ubuntu/jammy (22.04 LTS)

=amd64= and =arm64= architectures only (except Debian/buster and Ubuntu/bionic,
which are =amd64-only=). To use these, add to your =/etc/apt/sources.list=:

#+begin_example
deb [trusted=yes] http://mrcal.secretsauce.net/packages/DISTRO/public/ DISTRO main
#+end_example

where =DISTRO= is one of

- =buster=
- =bulleye=
- =bookworm=
- =bionic=
- =focal=
- =jammy=

Then, =apt update && apt install mrcal=. The chessboard corner finder, while not
strictly required, is needed if you're doing chessboard-based calibrations. =apt
install mrgingham=

* Building from source
If you cannot use the packages for whatever reason, you must build from source.
This isn't /difficult/, but requires you to obtain all the dependencies. They're
listed in the =Build-Depends= section of the [[https://salsa.debian.org/science-team/mrcal/-/blob/master/debian/control][debian package definition]]. Most of
these are available in most distros. Things that may not be:

- [[https://www.github.com/dkogan/mrbuild][=mrbuild=]]: the build system. If you can't get it from the package manager,
  just run =make=, and follow the printed message to get a local copy of
  =mrbuild=.

- [[https://github.com/dkogan/libdogleg/][=libdogleg-dev=]]: the optimization library. You need at least version 0.15.3.

- [[https://github.com/dkogan/vnlog/][=vnlog=]]: the toolkit to manipulate textual tables. You only /need/ this for
  the test suite. There's nothing to build. Simply downloading the sources and
  pointing the =PATH= there is sufficient.

- [[https://github.com/dkogan/numpysane/][=python3-numpysane=]]: The make-numpy-reasonable library. You absolutely need at
  least version 0.35. Available in the usual places Python libraries live. This
  is a python-only library. Simply downloading the sources and pointing the
  =PYTHONPATH= there is sufficient.

- [[https://github.com/dkogan/gnuplotlib/][=python3-gnuplotlib=]]: The plotting library used in all the visualizations. You
  need at least version 0.38. Available in the usual places Python libraries
  live. This is a python-only library. Simply downloading the sources and
  pointing the =PYTHONPATH= there is sufficient.

- [[https://github.com/dkogan/mrgingham/][=mrgingham=]]: the chessboard corner finder. This isn't strictly a requirement -
  any corner finder can be used. If you want to use this one (and you can't use
  the packages), you need to build it.

- [[https://re2c.org/][=re2c=]]: parser-generator for the C code to parse =.cameramodel= files. At
  least version 2 is required.

- [[https://github.com/yaml/pyyaml][=python3-yaml=]]: yaml parser used for the OpenCV, Kalibr model reading

- [[https://pyfltk.sourceforge.io/][=python3-fltk=]]: Python bindings for the [[https://www.fltk.org/][FLTK]] GUI toolkit. Optional. Used only
  in the visualizer in the [[file:mrcal-stereo.html][=mrcal-stereo=]] tool.

- [[https://github.com/dkogan/GL_image_display][=python3-gl-image-display=]]: an image widget for FLTK. Optional. Used only in
  the visualizer in the [[file:mrcal-stereo.html][=mrcal-stereo=]] tool.

- [[https://freeimage.sourceforge.io/][=libfreeimage-dev=]]: an image reading/writing library. Most distros have this
  available.

- [[https://www.cvlibs.net/software/libelas/][=libelas-dev=]]: the ELAS stereo matcher. Used as an option in the
  [[file:mrcal-stereo.html][=mrcal-stereo=]] tool. Optional.

Once these are all downloaded and built (where needed), we can talk about
building mrcal. The build-time executables (=re2c=) must be found in the =PATH=,
the Python libraries in =PYTHONPATH=, and the C headers and libraries must be
findable via the flags in =CFLAGS= and =LDFLAGS= respectively. Anything that
hasn't been installed to a standard location must be pointed to via the
environment. So to build:

#+begin_src sh
export PATH=$PATH:extra_path_to_executables
export PYTHONPATH=extra_path_to_python_libraries

CFLAGS=-Iextra_path_to_c_headers LDFLAGS="-Lextra_path_to_libraries -Wl,-rpath=extra_path_to_libraries" make
#+end_src

If everything has been installed to a standard location, you just run =make=
without any of the extra stuff. The build should then complete successfully, and
the test suite should pass:

#+begin_src sh
make test-nosampling
#+end_src

If stuff doesn't work, feel free to bug me.

* code                                                             :noexport:
Need to install =ca-certificates= in all the chroots so that I can talk to the
https://mrcal APT server

#+begin_src sh
for distro (buster bullseye bookworm sid bionic focal jammy) {
    sudo schroot -c source:${distro}-amd64 -- sh -c 'apt update && apt -y upgrade && apt -y install ca-certificates'
}
#+end_src

If that's already installed, still bring all the chroots up-to-date:

#+begin_src sh
for distro (buster bullseye bookworm sid bionic focal jammy) {
    sudo schroot -c source:${distro}-amd64 -- sh -c 'apt update && apt -y upgrade'
}
#+end_src

To native-build (amd64) any dependency or mrcal itself:

#+begin_src sh
for distro (buster bullseye bookworm sid bionic focal jammy) {
    perl -a -p -i -e 'if($. == 1) { $F[1] =~ s/-([0-9]+).*\)/-$1'$distro'1)/; $F[2] = "'$distro';"; $_ = join(" ",@F) . "\n"; }' debian/changelog;

    DEB_BUILD_OPTIONS=nocheck \
    sbuild \
      --no-apt-update \
      --no-apt-upgrade \
      --host=amd64 \
      --arch-any \
      --arch-all \
      --source \
      -c ${distro}-amd64 \
      --anything-failed-commands '%s' \
      --extra-repository="deb [trusted=yes] http://mrcal.secretsauce.net/packages/$distro/public/ $distro main"

    dput -u digitalocean_mrcal_$distro ../*${distro}*.changes(om[1])
}
#+end_src

To cross-build for arm64:

#+begin_src sh
for distro (bullseye bookworm sid) {
    perl -a -p -i -e 'if($. == 1) { $F[1] =~ s/-([0-9]+).*\)/-$1'$distro'1)/; $F[2] = "'$distro';"; $_ = join(" ",@F) . "\n"; }' debian/changelog;

    DEB_BUILD_OPTIONS=nocheck \
    sbuild \
      --host=arm64 \
      --arch-any \
      --no-arch-all \
      --no-source \
      --profiles=nocheck,cross \
      -c ${distro}-amd64 \
      --anything-failed-commands '%s' \
      --extra-repository="deb [trusted=yes] http://mrcal.secretsauce.net/packages/$distro/public/ $distro main"

    dput -u digitalocean_mrcal_$distro ../*${distro}*.changes(om[1])
}

for distro (focal jammy) {
    perl -a -p -i -e 'if($. == 1) { $F[1] =~ s/-([0-9]+).*\)/-$1'$distro'1)/; $F[2] = "'$distro';"; $_ = join(" ",@F) . "\n"; }' debian/changelog;

    DEB_BUILD_OPTIONS=nocheck \
    sbuild \
      --no-apt-update --no-apt-upgrade \
      --host=arm64 \
      --arch-any \
      --no-arch-all \
      --no-source \
      --profiles=nocheck,cross \
      -c ${distro}-amd64 \
      --anything-failed-commands '%s' \
      --extra-repository="deb [trusted=yes] http://mrcal.secretsauce.net/packages/$distro/public/ $distro main"

    dput -u digitalocean_mrcal_$distro ../*${distro}*.changes(om[1])
}
#+end_src

The ubuntu repos were done differently above because for some idiotic reason
ubuntu puts the non-amd64 packages into a different domain. So I have to
manually add the right sources, and I have to explicitly tell sbuild to not try
to "apt update", because it would try to use the same repos with the different
arch, and it would fail
