Programming environment for a testing workstation

Installing programming tools on our example Debian testing workstation/desktop machine

Author: Francesco Poli
Contact: invernomuto@paranoici.org
Version: 0.39
Copyright: Expat license
Notice:

Copyright (c) 2008-2022 Francesco Poli

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

About this document
Web form HyperText Markup Language
Source form reStructuredText
Web stylesheet Cascading StyleSheets
Build directives Makefile

Contents

Summary of previous episodes

In another document (HTML, reST) you saw how to install scientific and engineering tools on our example Debian testing workstation/desktop box. Now it's time for some coding: let's set up a programming environment.

Compilers and interpreters

In the following subsections, we will install packages needed for programming in various languages.

Ruby

Install the interpreter:

# aptitude install ruby

If the package is already present, you can mark it as manually installed:

# aptitude unmarkauto ruby

Python

Install the interpreter:

# aptitude install python3

If the package is already present, you can mark it as manually installed:

# aptitude unmarkauto python3

If you need to port old Python2 code to Python3, you may want to install the following converter:

# aptitude install 2to3

Debugging

Install the GNU Debugger:

# aptitude install gdb

and a dynamic analysis tool:

# aptitude install valgrind

Version control systems

Install a distributed revision control system:

# aptitude install git

some related tools:

# aptitude install git-email

and a useful git tree visualizer:

# aptitude install gitk

Configure Git for you regular user:

$ cat ~/.gitconfig
[user]
        name = Full Name (GPG key comment)
        email = address@example.org

[core]
        pager = view -n -
        editor = vim

[color]
        ui = auto
        pager = false
        diff = never

[diff]
        tool = meld

[init]
        defaultBranch = latest

where you should obviously put your actual full name, GPG key comment and e-mail address.

Tools for creating Debian packages

If you want to prepare Debian packages, you are recommended to install the following packages:

# aptitude install build-essential dh-make fakeroot lintian quilt

Some features of package po-debconf (an indirect dependency of package dh-make) are enhanced by the following package:

# aptitude install libmail-box-perl

Another useful package (for maintainers) is:

# aptitude install devscripts

Moreover, the following package can help in some cases:

# aptitude install cdbs

You may also install an automatic debian/copyright file generator:

# aptitude install decopy

If you want to package applications or libraries written in Ruby and distributed with Rubygems, you may find the following package useful:

# aptitude install gem2deb

You may also want to set appropriate environment variables to describe your identity as a Debian packager; add the following lines to your regular user's ~/.bashrc:

# set variables for Debian packaging
export DEBFULLNAME="Full Name (GPG key comment)"
export DEBEMAIL="address@example.org"

where you should again put your actual full name, GPG key comment and e-mail address. Please note that it's important that:

$ gpg --list-key "$DEBFULLNAME <$DEBEMAIL>"

is actually able to find your GPG key.

Setting up chroots for building Debian packages

In order to build Debian packages in a clean room environment, it is recommended to do so inside a proper chroot. The following package helps creating and maintaining chroot environments:

# aptitude install pbuilder

You may be asked which default mirror site to use: you may enter http://deb.debian.org/debian. If the main configuration file is not already properly set, edit it so that:

# grep MIRRORSITE /etc/pbuilderrc
MIRRORSITE=http://deb.debian.org/debian

Prepare directories for chroot environments and for configuration files, inside your regular user's home directory:

$ mkdir -p ~/var/cache/pbuilder/result/sid \
  ~/var/cache/pbuilder/aptcache/sid ~/.pbuilder

Create the following configuration file:

$ cat ~/.pbuilder/sid.conf
export HOME=/home/username
DISTRIBUTION="sid"
COMPONENTS="main"
MIRRORSITE="http://deb.debian.org/debian"
APTCACHE="${HOME}/var/cache/pbuilder/aptcache/${DISTRIBUTION}/"
APTCACHEHARDLINK="no"
AUTOCLEANAPTCACHE="yes"
BASETGZ="${HOME}/var/cache/pbuilder/${DISTRIBUTION}-base.tgz"
BUILDPLACE="${HOME}/var/cache/pbuilder/build/"
BUILDRESULT="${HOME}/var/cache/pbuilder/result/${DISTRIBUTION}/"
HOOKDIR=""
DEBBUILDOPTS="-i -I"
SOURCE_ONLY_CHANGES="yes"
BINDMOUNTS=""
USE_PDEBUILD_INTERNAL="yes"
DEBOOTSTRAPOPTS[0]="--variant=buildd"
DEBOOTSTRAP="debootstrap"
EXTRAPACKAGES="gnupg debian-archive-keyring"
USEPROC="yes"
USEDEVPTS="yes"
USEDEVFS="no"
REMOVEPACKAGES="lilo elilo grub-legacy grub-pc"
BUILDSOURCEROOTCMD="fakeroot"
PBUILDERROOTCMD="sudo"
BUILDUSERID="9999"
BUILDUSERNAME="pbuilder"
export DEBIAN_FRONTEND="noninteractive"
AUTO_DEBSIGN="yes"
PKGNAME_LOGFILE="yes"
PKGNAME_LOGFILE_EXTENSION=".buildlog"
export debian_chroot="pbuild$$"

where username should be substituted by your actual username. Create and populate a hook directory for pbuilder build:

$ mkdir -p ~/.pbuilder/build-hooks-sid
$ EXDIR=/usr/share/doc/pbuilder/examples
$ ln -s $EXDIR/B90lintian $EXDIR/B91dpkg-i $EXDIR/B92test-pkg \
  $EXDIR/C10shell ~/.pbuilder/build-hooks-sid

Then, create a hook directory for pdebuild:

$ mkdir -p ~/.pbuilder/pdeb-hooks-sid

and populate it with the following hook scripts:

$ cd ~/.pbuilder/pdeb-hooks-sid
$ WEBDIR=http://www.inventati.org/frx/progs/scripts
$ wget $WEBDIR/pdeb_common \
  $WEBDIR/D05prepare_pdeb $WEBDIR/prepare_pdeb.conf \
  $WEBDIR/B05cleanup_pdeb $WEBDIR/B10lintian_pdeb \
  $WEBDIR/B20testinst_pdeb $WEBDIR/B50shell_pdeb
$ chmod u+x [DB]*pdeb
$ ln -s B50shell_pdeb C50shell_pdeb

Now, create file /etc/sudoers.d/50pbuilder in order to give your regular user limited root privileges necessary to run pbuilder:

# cat /etc/sudoers.d/50pbuilder
User_Alias PBUILDER_USERS = listofusers
Cmnd_Alias PBUILDER_CMNDS = /usr/sbin/pbuilder
PBUILDER_USERS ALL = PBUILDER_CMNDS

where listofusers should be substituted with a comma-separated list of usernames which will be allowed to run pbuilder with root privileges. Then make sure the file has the right permissions:

# chmod 0440 /etc/sudoers.d/50pbuilder

Now, create the Debian unstable chroot environment:

$ sudo pbuilder create --configfile ~/.pbuilder/sid.conf

Before building packages, remember to update the chroot environment:

$ sudo pbuilder update --configfile ~/.pbuilder/sid.conf

In order to build a package you may use pbuilder build on an already created Debian source package:

$ sudo pbuilder build --configfile ~/.pbuilder/sid.conf \
  --hookdir ~/.pbuilder/build-hooks-sid  package_x.y.z-w.dsc

Alternatively, you may use pdebuild inside the package directory. For instance, if you start from an already created Debian source package, you can do the following:

$ dpkg-source -x package_x.y.z-w.dsc
$ cd package_x.y.z/
$ pdebuild --configfile ~/.pbuilder/sid.conf \
  -- --hookdir ~/.pbuilder/pdeb-hooks-sid

Obviously you may make any modification you like to the package before invoking pdebuild. Please note that the latter command will attempt to sign the package with the GPG key of the last modifier; if you do not have the modifier's secret key (e.g. because you are not the person specified in the Debian changelog), you can sign the package with another secret key:

$ pdebuild --configfile ~/.pbuilder/sid.conf --debsign-k $MYID \
  -- --hookdir ~/.pbuilder/pdeb-hooks-sid

where $MYID should be substituted with your name, e-mail address, comment, or key identifier.

If you need some packages from Debian experimental in order to build the package, you may enable an additional repository for that branch:

$ pdebuild --configfile ~/.pbuilder/sid.conf \
  -- --hookdir ~/.pbuilder/pdeb-hooks-sid \
  --othermirror 'deb http://deb.debian.org/debian experimental main' \
  --override-config

Remember to add a line starting with 'UPDATE' to the ~/.pbuilder/pdeb-hooks-sid/prepare_pdeb.conf configuration file, in order for the above to work correctly.

If you need to use your chroot environment in a quick throw-away manner (for debugging purposes or the like), you may log in to it with the following command:

$ sudo pbuilder login --configfile ~/.pbuilder/sid.conf

Sometimes you have to build packages in a clean Debian stable or oldstable environment. For instance, you can set up a wheezy chroot environment:

$ mkdir -p ~/var/cache/pbuilder/result/wheezy \
  ~/var/cache/pbuilder/aptcache/wheezy

Create the following configuration file:

$ cat ~/.pbuilder/wheezy.conf
export HOME=/home/username
DISTRIBUTION="wheezy"
COMPONENTS="main"
MIRRORSITE="http://deb.debian.org/debian"
OTHERMIRROR="deb http://deb.debian.org/debian-security wheezy/updates main"
APTCACHE="${HOME}/var/cache/pbuilder/aptcache/${DISTRIBUTION}/"
APTCACHEHARDLINK="no"
AUTOCLEANAPTCACHE="yes"
BASETGZ="${HOME}/var/cache/pbuilder/${DISTRIBUTION}-base.tgz"
BUILDPLACE="${HOME}/var/cache/pbuilder/build/"
BUILDRESULT="${HOME}/var/cache/pbuilder/result/${DISTRIBUTION}/"
HOOKDIR=""
DEBBUILDOPTS="-i -I"
SOURCE_ONLY_CHANGES="yes"
BINDMOUNTS=""
USE_PDEBUILD_INTERNAL="yes"
DEBOOTSTRAPOPTS[0]="--variant=buildd"
DEBOOTSTRAP="debootstrap"
EXTRAPACKAGES="gnupg debian-archive-keyring"
USEPROC="yes"
USEDEVPTS="yes"
USEDEVFS="no"
REMOVEPACKAGES="lilo elilo grub-legacy grub-pc"
BUILDSOURCEROOTCMD="fakeroot"
PBUILDERROOTCMD="sudo"
BUILDUSERID="9999"
BUILDUSERNAME="pbuilder"
export DEBIAN_FRONTEND="noninteractive"
AUTO_DEBSIGN="yes"
PKGNAME_LOGFILE="yes"
PKGNAME_LOGFILE_EXTENSION=".buildlog"
export debian_chroot="pbuild$$"

where, again, username should be substituted by your actual username. Now, create the wheezy chroot environment:

$ sudo pbuilder create --configfile ~/.pbuilder/wheezy.conf

This chroot environment may be used with the same commands described for the Debian unstable chroot: just replace sid.conf with wheezy.conf. The hook scripts in ~/.pbuilder/pdeb-hooks-sid may be used without any modification.

Configuring your account for the use of Salsa

If you are going to use the Debian collaborative development server named Salsa, you may want to configure your regular user's environment in order to make your life easier.

If you are not a Debian Developer, you need to create an account on Salsa by using the self-service interface. You can add your public SSH keys to your Salsa account.

If you have the official list of Debian SSH known hosts, you can save it as ~/.ssh/debian_known_hosts and use it for all *.debian.org hosts. You can also automatically use your Salsa account username (in case it differs from your regular username):

$ cat >> ~/.ssh/config << EOF

Host *.debian.org
    User salsa-user-name
    UserKnownHostsFile ~/.ssh/debian_known_hosts
EOF

where salsa-user-name should obviously replaced by your Salsa account username.

Moreover, you can configure git to automatically translate Salsa https URLs into ssh URLs (for push operations):

$ cat >> ~/.gitconfig << EOF

[url "git@salsa.debian.org:"]
        pushInsteadOf = https://salsa.debian.org/
EOF

This will work for all git repositories cloned from Salsa, in the past, present, or future.

Internationalization

When developing software, it's important to internationalize it, so that the needed infrastructure is ready to accept contributions from translators who localize the work for many human languages.

Programs may be internationalized by taking advantage of gettext, which you should, at this point, find already installed:

$ aptitude search '^gettext$'
i A gettext                         - GNU Internationalization utilities

You may wish to install a checking tool for internationalization files:

# aptitude install i18nspector

Non-programmatic works (such as documentation, books, and so forth) may be internationalized by using the following package:

# aptitude install po4a

Conclusions

Now you have the tools to program. However, even programmers have some spare time to play... More details in a separate document (HTML, reST).