:lang: en
:toc:

= Building LinuxCNC

== Introduction

This document describes how to build the LinuxCNC software and
documentation from source.  This is primarily useful if you are a
developer who is modifying LinuxCNC.  It can also be useful if you're
a user who is testing developer branches, though then you also have
the option of just installing Debian packages from the buildbot:
http://buildbot.linuxcnc.org

[[Quick-Start]]
=== Quick Start

For the impatient, try this:

----
$ git clone https://github.com/LinuxCNC/linuxcnc.git linuxcnc-dev
$ cd linuxcnc-dev/src
$ ./autogen.sh
$ ./configure --with-realtime=uspace
$ make
----

That will probably fail!  That doesn't make you a bad person, it just
means you should read this whole document to find out how to fix your
problems.  Especially the section on <<Satisfying-Build-Dependencies,
Satisfying Build Dependencies>>.

If you are running on a realtime-capable system (such as an install from
the LinuxCNC Live/Install Image, see the <<sub:realtime,Realtime>> section
below), one extra build step is needed at this time:

-----
$ sudo make setuid
-----

After you've successfully built LinuxCNC it's time to run the tests:

-----
$ source ../scripts/rip-environment
$ runtests
-----

This might fail too!  Read this whole document, but especially the section
on <<Setting-up-the-environment,Setting up the test environment>>.

== Supported Platforms

The LinuxCNC project targets modern Debian-based distributions, including
Debian, Ubuntu, and Mint.

We continuously test on the platforms listed at
http://buildbot.linuxcnc.org.

LinuxCNC builds on most other Linux distributions, though dependency
management will be more manual and less automatic. Patches to improve
portability to new platforms are always welcome.

[[sub:realtime]]
=== Realtime

LinuxCNC is a machine tool controller, and it requires a realtime platform
to do this job. This version of LinuxCNC supports three realtime platforms

RTAI::
  From https://www.rtai.org. A Linux kernel with the RTAI patch is
  available from the Debian archive at http://www.linuxcnc.org. See
  <<cha:getting-linuxcnc,Getting LinuxCNC>> for installation instructions.

Xenomai::
  From https://xenomai.org. You will have to compile or obtain a Xenomai
  kernel yourself.

Preempt-RT::
  From https://rt.wiki.kernel.org. A Linux kernel with the
  Preempt-RT patch is occasionally available from the Debian
  archive at https://www.debian.org, and from the wayback machine at
  https://snapshot.debian.org.

To make use of the realtime capabilities of LinuxCNC, certain parts of
LinuxCNC need to run with root privileges.  To enable root for these
parts, run this extra command after the `make` that builds LinuxCNC:

-----
$ sudo make setuid
-----

=== Non-realtime

LinuxCNC can also be built and run on non-realtime platforms, such as
a regular install of Debian or Ubuntu without any special realtime kernel.

In this mode LinuxCNC is not useful for controlling machine tools, but
it is useful for simulating the execution of G-code and for testing the
non-realtime parts of the system (such as the user interfaces, and some
kinds of components and device drivers).

== Build modes

There are two ways to build LinuxCNC: the developer-friendly "run in
place" mode and the user-friendly Debian packaging mode.

=== Building for Run In Place

In a Run-In-Place build, the LinuxCNC programs are compiled from source
and then run directly from within the build directory.  Nothing is
installed outside the build directory.

This is quick and easy, and suitable for rapid iteration of changes.

The LinuxCNC test suite runs only in a Run-In-Place build.

Most LinuxCNC developers primarily build using this mode.

Building for Run-In-Place follows the steps in the <<Quick-Start,Quick Start>>
section at the top of this document, possibly with different arguments
to `src/configure` and `make`.

[[src-configure-arguments]]
==== `src/configure` arguments

The `src/configure` script configures how the source code will be
compiled.  It takes many optional arguments.

List all arguments to `src/configure` by running this:

-----
$ cd linuxcnc-dev/src
$ ./configure --help
-----

The most commonly used arguments are:

`--with-realtime=uspace`::
  Build for any realtime platform, or for non-realtime.
  The resulting LinuxCNC executables will run on both a Linux kernel
  with Preempt-RT patches (providing realtime machine control) and
  on a vanilla (un-patched) Linux kernel (providing G-code simulation
  but no realtime machine control).  If development files are installed
  for Xenomai (typically from package libxenomai-dev) or RTAI (typically
  from a package with a name starting "rtai-modules"), support for
  these real-time kernels will also be enabled.

`--with-realtime=/usr/realtime-$VERSION`::
  Build for the RTAI realtime platform using the older "kernel realtime"
  model.
  This requires that you have an RTAI kernel and the RTAI modules
  installed in `/usr/realtime-$VERSION`. The resulting LinuxCNC
  executables will only run on the specified RTAI kernel. As of
  LinuxCNC 2.7, this produces the best realtime performance.

`--enable-build-documentation`::
  Build the documentation, in addition to the executables.  This option
  adds significantly to the time required for compilation, as building
  the docs is quite time consuming.  If you are not actively working
  on the documentation you may want to omit this argument.

[[make-arguments]]
==== `make` arguments

The `make` command takes two useful optional arguments.

Parallel compilation::
  `make` takes an optional argument `-jN` (where N is a number).
  This enables parallel compilation with N simultaneous processes, which
  can significantly speed up your build.
+
A useful value for N is the number of CPUs in your build system.  You can
discover the number of CPUs by running `nproc`.

Building just a specific target::
  If you want to build just a specific part of LinuxCNC, you can name
  the thing you want to build on the `make` command line.  For example,
  if you are working on a component named `froboz`, you can build its
  executable by running:
+
-----
$ cd linuxcnc-dev/src
$ make ../bin/froboz
-----

=== Building Debian Packages

When building Debian packages, the LinuxCNC programs are compiled from
source and then stored in a Debian package, complete with dependency
information.  This takes more time, and the programs can't be used until
the Debian package is installed on a target machine.

This build mode is primarily useful when packaging the software for
delivery to end users, and when building the software for a machine
that doesn't have the build environment installed, or that doesn't have
internet access.

Building Debian packages requires the `dpkg-buildpackage` tool, from the
`dpkg-dev` package:

-----
$ sudo apt-get install dpkg-dev
-----

Building Debian packages also requires that all build dependencies are
installed, as described in the section <<Satisfying-Build-Dependencies,
Satisfying Build Dependencies>>.

Once those prerequisites are met, building the Debian packages consists
of two steps.

The first step is generating the Debian package scripts and meta-data
from the git repo by running this:

-----
$ cd linuxcnc-dev/debian
$ ./configure uspace
$ cd ..
-----

[NOTE]
=====
The `debian/configure` script is different from the `src/configure`
script!

The `debian/configure` script needs different arguments depending on the
platform you're building on/for, see the <<debian-configure-arguments,
`debian/configure` arguments>> section.
=====

Once the Debian package scripts and meta-data are configured, build the
package by running `dpkg-buildpackage` (note that it needs to run from
the `linuxcnc-dev` directory, *not* from `linuxcnc-dev/debian`):

-----
$ dpkg-buildpackage -b -uc
-----

[[debian-configure-arguments]]
==== `debian/configure` arguments

The `debian/configure` script configures the Debian packaging.  It must
be run before `dpkg-checkbuilddeps` and `dpkg-buildpackage` can be run.

It takes a single argument which specifies the realtime or non-realtime
platform to build for.  The normal values for this argument are:

`uspace`::
  Configure the Debian package for Preempt-RT realtime or for
  non-realtime (these two are compatible).

`noauto`::
`rtai`::
`xenomai`::
  Normally, the lists of RTOSes for uspace realtime to support is detected
  automatically.  However, if you wish, you may specify one or more of these
  after `uspace` to enable support for these RTOSes.  Or, to disable
  autodetection, specify `noauto`.
+
If you want just the traditional RTAI "kernel module" realtime, use
`-r` or `$KERNEL_VERSION` instead.

`rtai=<package name>`::
  If the development package for rtai lxrt does not start with
  "rtai-modules", or if the first such package listed by apt-cache search
  is not the desired one, then explicitly specify the package name.

`-r`::
  Configure the Debian package for the currently running RTAI kernel.
  You must be running an RTAI kernel on your build machine for this
  to work!

`$KERNEL_VERSION`::
  Configure the debian package for the specified RTAI kernel version
  (for example "3.4.9-rtai-686-pae").  The matching kernel headers
  debian package must be installed on your build machine (for example
  "linux-headers-3.4.9-rtai-686-pae").  Note that you can _build_
  LinuxCNC in this configuration, but if you are not running the
  matching RTAI kernel you will not be able to _run_ LinuxCNC, including
  the test suite.

[[Satisfying-Build-Dependencies]]
== Satisfying Build Dependencies

On Debian-based platforms we provide packaging meta-data that knows
what external software packages need to be installed in order to build
LinuxCNC.  This is called the Build Dependencies of LinuxCNC.  You can
use this meta-data to easily list the required packages missing from
your build system.

Debian systems provide a program called `dpkg-checkbuilddeps` that
parses the package meta-data and compares the packages listed as build
dependencies against the list of installed packages, and tells you
what's missing.

First, install the `dpkg-checkbuilddeps` program by running:

-----
$ sudo apt-get install dpkg-dev
-----

Then ask your LinuxCNC git checkout to generate its Debian package
meta-data:

-----
$ cd linuxcnc-dev/debian
$ ./configure uspace
$ cd ..
-----

Finally ask `dpkg-checkbuilddeps` to do its job (note that it needs to
run from the `linuxcnc-dev` directory, *not* from `linuxcnc-dev/debian`):

-----
$ dpkg-checkbuilddeps
-----

It will emit a list of packages that are required to build LinuxCNC
on your system, but that are not installed yet.  Install them all with
`sudo apt-get install`, followed by the package names.

You can rerun `dpkg-checkbuilddeps` any time you want, to list any
missing packages.

[[Setting-up-the-environment]]
== Setting up the environment

This section describes the special steps needed to set up a machine to
run the LinuxCNC programs, including the tests.

=== Increase the locked memory limit

LinuxCNC tries to improve its realtime latency by locking the memory it
uses into RAM.  It does this in order to prevent the operating system from
swapping LinuxCNC out to disk, which would have bad effects on latency.

Normally locking memory into RAM is frowned upon, and the operating system
places a strict limit on how much memory a user is allowed to have locked.

When using the Preempt-RT realtime platform LinuxCNC runs with enough
privilege to raise its memory lock limit itself.  When using the RTAI
realtime platform it does not have enough privilege, and the user must
raise the memory lock limit.

If LinuxCNC displays the following message on startup, the problem is
your system's configured limit on locked memory:

-----
RTAPI: ERROR: failed to map shmem
RTAPI: Locked memory limit is 32KiB, recommended at least 20480KiB.
-----

To fix this problem, add a file named
`/etc/security/limits.d/linuxcnc.conf` (as root) with your favorite
text editor (e.g., `sudo gedit /etc/security/limits.d/linuxcnc.conf`).
The file should contain the following line:

-----
* - memlock 20480
-----

Log out and log back in to make the changes take effect.  Verify that
the memory lock limit is raised using the following command:

-----
$ ulimit -l
-----

== Options for checking out the git repo

The <<Quick-Start,Quick Start>> instructions at the top of this
document clone our git repo at
https://github.com/LinuxCNC/linuxcnc.git.  This is the quickest, easiest
way to get started.  However, there are other options to consider.

=== Fork us on Github

The LinuxCNC project git repo is at http://github.com/LinuxCNC/linuxcnc.
github is a popular git hosting service and code sharing website.
You can easily (and for no cost) create a fork of our git repo at github,
and use that to track and publish your changes.

After creating your own github fork of LinuxCNC, clone it to your
development machine and proceed with your hacking as usual.

We of the LinuxCNC project hope that you will share your changes with
us, so that the community can benefit from your work.  Github makes this
sharing very easy: after you polish your changes and push them to your
github fork, send us a Pull Request.

// vim: set syntax=asciidoc:
