Difference between revisions of "DeveloperWiki:Building in a Clean Chroot"

From ArchWiki
Jump to: navigation, search
(remove deprecated step as now aufs2 is not needed anymore)
m (use redirect + style fixes, see Help:Style and related)
(29 intermediate revisions by 14 users not shown)
Line 1: Line 1:
 
[[Category: DeveloperWiki]]
 
[[Category: DeveloperWiki]]
 
+
== Introduction ==
= Introduction =
+
  
 
This article is part of the [[DeveloperWiki]].
 
This article is part of the [[DeveloperWiki]].
  
= Why =
+
== Why ==
 +
 
 +
Building in a clean chroot prevents missing dependencies in packages, whether due to unwanted linking or packages missing in the depends array in the PKGBUILD.  It also allows users to build a package for the stable repositories (core, extra, community) while having packages from [testing] installed.
 +
 
 +
== Convenience Way ==
 +
To quickly build a package in a chroot without any further tinkering, one can use the helper scripts from the devtools package.
 +
 
 +
These helper scripts should be called in the same directory where the PKGBUILD is, just like with makepkg. For instance, {{ic|extra-i686-build}} automatically sets up chroot in {{ic|/var/lib/archbuild}}, updates it, and builds a package for the extra repository. For multilib builds there is just {{ic|multilib-build}} without an architecture.
 +
 
 +
{{Tip|Consult the table below for information on which script to use when building for a specific repository and architecture.}}
 +
 
 +
{{Note|[core] is omitted because those packages are required to go through [testing] first before landing in [core].}}
 +
 
 +
{| class="wikitable"
 +
! Target repository || Architecture || Build script to use
 +
|-
 +
| extra / community || i686 || extra-i686-build
 +
|-
 +
| extra / community || x86_64 || extra-x86_64-build
 +
|-
 +
| testing / community-testing || i686 || testing-i686-build
 +
|-
 +
| testing / community-testing || x86_64 || testing-x86_64-build
 +
|-
 +
| staging / community-staging || i686 || staging-i686-build
 +
|-
 +
| staging / community-staging || x86_64 || staging-x86_64-build
 +
|-
 +
| multilib || x86_64 || multilib-build
 +
|-
 +
| multilib-testing || x86_64 || multilib-testing-build
 +
|-
 +
| multilib-staging || x86_64 || multilib-staging-build
 +
|}
 +
 
 +
== Classic Way ==
 +
=== Setting Up A Chroot ===
 +
 
 +
The devtools package provides tools for creating and building within clean chroots. Install it if not done already:
 +
 
 +
# pacman -S devtools
 +
 
 +
To make a clean chroot, create a directory in which the chroot will reside.  For example, {{ic|$HOME/chroot}}.
 +
 
 +
$ mkdir ~/chroot
 +
 
 +
Define the {{ic|CHROOT}} variable:
  
Building in a clean chroot prevents missing dependancies in packages, whether due to unwanted linking or packages missing in the depends array in the PKGBUILD. It also allows you to build a package for the stable repositories (core, extra, community) while having packages from [testing] installed on your system.
+
  # CHROOT=$HOME/chroot
  
= Setting Up A Chroot =
+
Now create the chroot (the sub directory {{ic|root}} is required because the {{ic|$CHROOT}} directory will get other sub directories for clean working copies):
  
The devtools package provides tools for creating and building within clean chroots. To make a clean chroot, create a directory you want it to reside in (example: <tt>~/chroot</tt>). For the purposes of this article this will be called <tt><chrootdir></tt>.  Now create your chroot:
+
  # mkarchroot $CHROOT/root base-devel
  
$ sudo mkarchroot <chrootdir>/root base base-devel sudo
+
{{Note|One can also define the {{ic|CHROOT}} variable in {{ic|$HOME/.bashrc}} using the export command if the location is to be repeatedly used. }}
  
Edit the <tt><chrootdir>/root/etc/makepkg.conf</tt> file to set the packager name and any makeflags.  Also adjust the mirror list in <tt><chrootdir>/root/etc/pacman.d/mirrorlist</tt> and enable '''[testing]''' in <tt><chrootdir>/root/etc/pacman.conf</tt> if desired.
+
Edit {{ic|~/.makepkg.conf}} to set the packager name and any makeflags.  Also adjust the [[Pacman#Repositories|mirrorlist]] in {{ic|$CHROOT/root/etc/pacman.d/mirrorlist}} and enable the [[testing]] repository in {{ic|$CHROOT/root/etc/pacman.conf}}, if desired.
  
Alternatively, you can provide your own <tt>pacman.conf</tt> and <tt>makepkg.conf</tt> files with the following:
+
==== Custom pacman.conf ====
$ sudo mkarchroot -C <pacman.conf> -M <makepkg.conf> <chrootdir>/root base base-devel sudo
+
  
It is recommended however that you do not use custom <tt>pacman.conf</tt> and <tt>makepkg.conf</tt> files during the initial creation of clean chroot to ensure no user-specific adjustments are made. ''Use with caution.''
+
Alternatively, provide a custom {{ic|pacman.conf}} and {{ic|makepkg.conf}} with the following:
 +
 +
# mkarchroot -C <pacman.conf> -M <makepkg.conf> $CHROOT/root base-devel
  
= Building in the Chroot =
+
{{Warning|
 +
Using a custom {{ic|pacman.conf}} or {{ic|makepkg.conf}} during the initial creation of clean chroot can result in unintended custom adjustments to the chroot environment. ''Use with caution.''}}
  
Firstly, make sure your chroot is up to date with:
+
=== Building in the Chroot ===
  
$ sudo mkarchroot -u <chrootdir>/root
+
Firstly, make sure the chroot is up to date with:
  
Then, to build a package in your chroot run the following from the dir containing the PKGBUILD:
+
# arch-nspawn $CHROOT/root pacman -Syu
  
$ sudo makechrootpkg -c -r <chrootdir>
+
Then, to build a package in the chroot, run the following from the dir containing the PKGBUILD:
  
A unionfs is used to maintain the clean chroot during building. All installed dependencies or makedepends and other changes made during building are done in <chrootdir>/rw.  Passing the -c flag to makechrootpkg ensures that this directory is cleaned before building starts.
+
  # makechrootpkg -c -r $CHROOT
  
= Handling Major Rebuilds =
+
Passing the -c flag to makechrootpkg ensures that the working chroot (named {{ic|$CHROOT/$USERNAME}}) is cleaned before building starts.
  
The cleanest way to handle a major rebuild is to create a new chroot and build your first package (typically the package you are doing the rebuild for).  Then create a local repo in your new chroot.  To do this:
+
=== Manual package installation ===
 +
Packages can be installed manually to the working chroot by using:
  
  $ sudo mkdir <chrootdir>/root/repo
+
  # makechrootpkg -r $CHROOT -I package-1.0-1-i686.pkg.tar.xz
$ sudo chmod 777 <chrootdir>/root/repo
+
  
The chmod statement allows you to copy package files and create the local repo as your user rather than root.
+
If done from a directory that contains a PKGBUILD, the package will then be built. Avoid being in such a directory if you want to just install the package.
  
$ cp <package> <chrootdir>/root/repo
+
=== Installation after building ===
$ cd <chrootdir>/root/repo
+
Tell makechrootpkg to simply install a package to the rw layer of the chroot after building by passing the -i arg. Unrecognized args get passed to makepkg, so this calls `makepkg` with the -i arg.
$ repo-add local.db.tar.gz <package>
+
  
Then add the local repo to <chrootdir>/root/etc/pacman.conf
+
# makechrootpkg -r $CHROOT -- -i
  
[local]
+
== Handling Major Rebuilds ==
Server = file:///repo
+
  
and update your repo
+
The cleanest way to handle a major rebuild is to use the [staging] repositories. Build the first package against [extra] and push it to [staging]. Then rebuild all following packages against [staging] and push them there.
  
$ sudo mkarchroot -u <chrootdir>/root
+
If you can't use [staging], you can build against custom packages using a command like this:
  
With every additional package rebuilt, copy the package to the local repo directory, add it to the repo database and update your chroot.
+
# extra-x86_64-build -- -I ~/packages/foobar/foobar-2-1-any.pkg.tar.xz
  
= Alternate Rebuild Handling =
+
You can specify more than one package to be installed using multiple -I arguments.
  
The above directions will work fine, but they can dirty the "pristine" chroot that makechrootpkg tries to keep in check (that is the point of using unionfs - dirtying a separate 'rw' directory).
+
A simpler, but dirtier way to handle a major rebuild is to install all built packages in the chroot, never cleaning it. Build the first package using:
  
== Using a custom repo ==
+
# extra-x86_64-build
Follow the steps above to setup a local repo inside the chroot.
+
  
Build packages using:
+
And build all following packages using:
$ sudo makechrootpkg -r <chrootdir> -u
+
The -u will update the chroot before building (-Syu) but updates will be installed to the rw layer, maintaining a clean chroot.
+
  
== Manual package installation ==
+
  # makechrootpkg -n -r /var/lib/archbuild/extra-x86_64
Packages can be installed manually to the rw layer of the chroot by using:
+
  $ sudo makechrootpkg -r <chrootdir> -I package-1.0-1-i686.pkg.tar.gz
+
  
== Installation after building ==
+
Running namcap (the -n argument) implies installing the package in the chroot. *-build also does this by default.
You can tell makechrootpkg to simply install a package to the rw layer of the chroot after building by passing the -i arg. Unrecognized args get passed to makepkg, so this calls `makepkg` with the -i arg.
+
$ sudo makechrootpkg -r <chrootdir> -- -i
+

Revision as of 03:54, 7 December 2013

Introduction

This article is part of the DeveloperWiki.

Why

Building in a clean chroot prevents missing dependencies in packages, whether due to unwanted linking or packages missing in the depends array in the PKGBUILD. It also allows users to build a package for the stable repositories (core, extra, community) while having packages from [testing] installed.

Convenience Way

To quickly build a package in a chroot without any further tinkering, one can use the helper scripts from the devtools package.

These helper scripts should be called in the same directory where the PKGBUILD is, just like with makepkg. For instance, extra-i686-build automatically sets up chroot in /var/lib/archbuild, updates it, and builds a package for the extra repository. For multilib builds there is just multilib-build without an architecture.

Tip: Consult the table below for information on which script to use when building for a specific repository and architecture.
Note: [core] is omitted because those packages are required to go through [testing] first before landing in [core].
Target repository Architecture Build script to use
extra / community i686 extra-i686-build
extra / community x86_64 extra-x86_64-build
testing / community-testing i686 testing-i686-build
testing / community-testing x86_64 testing-x86_64-build
staging / community-staging i686 staging-i686-build
staging / community-staging x86_64 staging-x86_64-build
multilib x86_64 multilib-build
multilib-testing x86_64 multilib-testing-build
multilib-staging x86_64 multilib-staging-build

Classic Way

Setting Up A Chroot

The devtools package provides tools for creating and building within clean chroots. Install it if not done already:

# pacman -S devtools

To make a clean chroot, create a directory in which the chroot will reside. For example, $HOME/chroot.

$ mkdir ~/chroot

Define the CHROOT variable:

# CHROOT=$HOME/chroot

Now create the chroot (the sub directory root is required because the $CHROOT directory will get other sub directories for clean working copies):

# mkarchroot $CHROOT/root base-devel
Note: One can also define the CHROOT variable in $HOME/.bashrc using the export command if the location is to be repeatedly used.

Edit ~/.makepkg.conf to set the packager name and any makeflags. Also adjust the mirrorlist in $CHROOT/root/etc/pacman.d/mirrorlist and enable the testing repository in $CHROOT/root/etc/pacman.conf, if desired.

Custom pacman.conf

Alternatively, provide a custom pacman.conf and makepkg.conf with the following:

# mkarchroot -C <pacman.conf> -M <makepkg.conf> $CHROOT/root base-devel
Warning: Using a custom pacman.conf or makepkg.conf during the initial creation of clean chroot can result in unintended custom adjustments to the chroot environment. Use with caution.

Building in the Chroot

Firstly, make sure the chroot is up to date with:

# arch-nspawn $CHROOT/root pacman -Syu

Then, to build a package in the chroot, run the following from the dir containing the PKGBUILD:

# makechrootpkg -c -r $CHROOT

Passing the -c flag to makechrootpkg ensures that the working chroot (named $CHROOT/$USERNAME) is cleaned before building starts.

Manual package installation

Packages can be installed manually to the working chroot by using:

# makechrootpkg -r $CHROOT -I package-1.0-1-i686.pkg.tar.xz

If done from a directory that contains a PKGBUILD, the package will then be built. Avoid being in such a directory if you want to just install the package.

Installation after building

Tell makechrootpkg to simply install a package to the rw layer of the chroot after building by passing the -i arg. Unrecognized args get passed to makepkg, so this calls `makepkg` with the -i arg.

# makechrootpkg -r $CHROOT -- -i

Handling Major Rebuilds

The cleanest way to handle a major rebuild is to use the [staging] repositories. Build the first package against [extra] and push it to [staging]. Then rebuild all following packages against [staging] and push them there.

If you can't use [staging], you can build against custom packages using a command like this:

# extra-x86_64-build -- -I ~/packages/foobar/foobar-2-1-any.pkg.tar.xz

You can specify more than one package to be installed using multiple -I arguments.

A simpler, but dirtier way to handle a major rebuild is to install all built packages in the chroot, never cleaning it. Build the first package using:

# extra-x86_64-build

And build all following packages using:

# makechrootpkg -n -r /var/lib/archbuild/extra-x86_64

Running namcap (the -n argument) implies installing the package in the chroot. *-build also does this by default.