Tech: punpun

Here I'll write some incoherent stuff about the lower-level customization and specifics of my main computer. I should be learning right now but instead I'm doing this...

Distro & kernel

Like on pretty all my other machines, I'm running CRUX.

CRUX is a lightweight Linux distribution for the x86-64 architecture targeted at experienced Linux users. The primary focus of this distribution is keep it simple, which is reflected in a straightforward tar.gz-based package system, BSD-style initscripts, and a relatively small collection of trimmed packages. The secondary focus is utilization of new Linux features and recent tools and libraries. CRUX also has a ports system which makes it easy to install and upgrade applications.

In my opinion CRUX is pretty much to most minimalist you can get without giving up functionality (that I actually care about). There are distros like Alpine and Sabotage which are more minimalist in some ways, but since they use musl you can't use proprietary programs such as the closed source nNidia driver.

The thing I love most about CRUX is the extremely simple port creation. Even distros that use similar package/port templates (like Alpine Linux, Void Linux, Arch Linux, et cetera), none of them come close to the simplicity of CRUX port creation.

Most of these distros try to implement their own fancy functions that detect how a package should be build and try to automate it, for example, Void Linux has some variable where you specify how a port gets build, with cmake or gnu-make for example, another prime example is the extremely complicated Gentoo ebuilds, I'm not saying it doesn't have it's merits, it's just not for me. With CRUX Pkgfiles you literally just write down the built instructions and glue them together with bash.

You don't have to think about optional dependencies (although you can list them in a comment), you don't have to separate build dependencies from runtime dependencies. You don't need to learn a bunch of custom functions, just knowing bash and the basics of compiling programs (or using google) should be enough. There aren't USE-FLAGS so you don't need to think about what compile time flag adds which dependencies, though the user can customize ports to a certain degree, by either:


Here I will compare the fish package template between various distros:

# Contributor: William Pitcock <nenolod@dereferenced.org>
# Maintainer: William Pitcock <nenolod@dereferenced.org>
pkgname=fish
pkgver=2.3.1
pkgrel=0
pkgdesc="a modern interactive commandline shell"
url="http://www.fishshell.com/"
arch="all"
license="GPL2"
depends=""
depends_dev="ncurses-dev"
makedepends="$depends_dev libtool doxygen"
install="$pkgname.post-install $pkgname.post-upgrade $pkgname.pre-deinstall"
subpackages="$pkgname-doc"
source="https://github.com/fish-shell/fish-shell/releases/download/${pkgver}/${pkgname}-${pkgver}.tar.gz"

builddir="$srcdir"/$pkgname-$pkgver
build() {
	cd "$builddir"
	./configure \
		--build=$CBUILD \
		--host=$CHOST \
		--prefix=/usr \
		--sysconfdir=/etc \
		--mandir=/usr/share/man \
		--localstatedir=/var \
		|| return 1
	make || return 1
}

package() {
	cd "$builddir"
	make install DESTDIR="$pkgdir" || return 1
}

md5sums="2d13852a5c8e9e5bca00502b93e046a4  fish-2.3.1.tar.gz"
sha256sums="328acad35d131c94118c1e187ff3689300ba757c4469c8cc1eaa994789b98664  fish-2.3.1.tar.gz"
sha512sums="dd0fa77f218cc84943c577ff8abafcde92fa953797757a62db317d87c2af82de6493810ce91012e20d46be9a52bffda9a40526328714ba1e4e389e5f2aa3fea5  fish-2.3.1.tar.gz"
# Maintainer: Levente Polyak <anthraxx[at]archlinux[dot]org>
# Contributor: Bartłomiej Piotrowski <bpiotrowski@archlinux.org>
# Contributor: Kaiting Chen <kaitocracy@gmail.com>
# Contributor: Abhishek Dasgupta <abhidg@gmail.com>
# Contributor: Eric Belanger <eric@archlinux.org>
# Contributor: Jan Fader <jan.fader@web.de>

pkgname=fish
pkgver=2.3.1
pkgrel=1
pkgdesc='Smart and user friendly shell intended mostly for interactive use'
url='http://fishshell.com/'
arch=('i686' 'x86_64')
license=('GPL2')
depends=('bc' 'gcc-libs' 'inetutils' 'ncurses' 'which')
optdepends=('python: for manual page completion parser and web configuration tool')
makedepends=('doxygen')
install=fish.install
source=(${pkgname}-${pkgver}.tar.gz::https://github.com/fish-shell/fish-shell/archive/${pkgver}.tar.gz)
sha512sums=('ec229509a777b0c20669bbad3634265f2b8a9827ca207508e10889096262f0731b31514f1523f3228b38e9be082fc72fd8efe8d9a69fe68d655325027a176674')

prepare() {
  cd fish-shell-${pkgver}
  echo ${pkgver} > version
  autoconf -i
}

build() {
  cd fish-shell-${pkgver}
  ./configure --prefix=/usr \
    --sysconfdir=/etc
  make
}

package() {
  cd fish-shell-${pkgver}
  make DESTDIR="${pkgdir}" install
}
# Template file for 'fish-shell'
pkgname=fish-shell
version=2.3.1
revision=2
build_style=gnu-configure
hostmakedepends="automake libtool"
makedepends="ncurses-devel"
depends="bc"
register_shell="/usr/bin/fish"
conf_files="/etc/fish/config.fish"
wrksrc="fish-${version}"
maintainer="Juan RP <xtraeme@voidlinux.eu>"
homepage="http://fishshell.com/"
license="GPL-2"
short_desc="User friendly shell intended mostly for interactive use"
distfiles="https://github.com/fish-shell/fish-shell/releases/download/${version}/fish-${version}.tar.gz"
checksum=328acad35d131c94118c1e187ff3689300ba757c4469c8cc1eaa994789b98664

if [ -n "$CROSS_BUILD" ]; then
	case "$XBPS_TARGET_MACHINE" in
	*-musl)	# Nothing to add
		;;
	*)	# Add CXXFLAGS required for glibc
		CXXFLAGS="-D_GNU_SOURCE=1 -D_ISO99_SOURCE=1"
		;;
	esac
	export ac_cv_file__proc_self_stat=yes
fi
pre_configure() {
	if [ -n "$CROSS_BUILD" ]; then
		patch -p0 < ${FILESDIR}/no-glibc-check.patch
	fi
	autoreconf -fi
}
# Copyright 1999-2016 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id$

EAPI=6

PYTHON_COMPAT=( python{2_7,3_3,3_4,3_5} )

DESCRIPTION="fish is the Friendly Interactive SHell"
HOMEPAGE="http://fishshell.com/"
SRC_URI="http://fishshell.com/files/${PV}/${P}.tar.gz"

LICENSE="GPL-2"
SLOT="0"
KEYWORDS="~amd64 ~ppc ~ppc64 ~x86 ~amd64-linux ~x86-linux ~ppc-macos ~x86-macos ~x86-solaris"
IUSE="X"

DEPEND="sys-libs/ncurses:0=
	sys-devel/bc
	sys-devel/gettext
	X? ( x11-misc/xsel )"

RDEPEND="${DEPEND}"

src_configure() {
	# Set things up for fish to be a default shell.
	# It has to be in /bin in case /usr is unavailable.
	# Also, all of its utilities have to be in /bin.
	econf \
		docdir="${EPREFIX}"/usr/share/doc/${PF} \
		--bindir="${EPREFIX}"/bin
}

src_test() {
	if has_version ~${CATEGORY}/${P} ; then
		emake test
	else
		ewarn "The test suite only works when the package is already installed"
	fi
}

pkg_postinst() {
	elog "fish is now installed on your system."
	elog "To run fish, type 'fish' in your terminal."
	elog
	elog "To use fish as your login shell:"
	elog "* add the line '${EPREFIX}/bin/${PN}'"
	elog "* to the file '${EPREFIX}/etc/shells'."
	elog "* use the command 'chsh -s ${EPREFIX}/bin/${PN}'."
	elog
	elog "To set your colors, run 'fish_config'"
	elog "To scan your man pages for completions, run 'fish_update_completions'"
	elog "To autocomplete command suggestions press Ctrl + F or right arrow key."
	elog
	elog "Please add a \"BROWSER\" variable to ${PN}'s environment pointing to the"
	elog "browser of your choice to get acces to ${PN}'s help system:"
	elog "  BROWSER=\"/usr/bin/firefox\""
	elog
	elog "In order to get lzma and xz support for man-page completion please"
	elog "emerge one of the following packages:"
	elog "  dev-python/backports-lzma"
	elog "  >=dev-lang/python-3.3"
	elog
	elog "Have fun!"
}
# Description: A smart and user-friendly command line shell for OSX, Linux, and the rest of the family.
# URL:         http://fishshell.com
# Maintainer:  6c37 Team, https://github.com/6c37/crux-ports/issues
# Depends on:  git doxygen libpcre2
# Optional:    python xsel

name=fish
version=2.3.1
release=1
source=(https://github.com/fish-shell/fish-shell/archive/$version.tar.gz)

build() {
	cd $name-shell-$version

	autoconf
	./configure \
		--prefix=/usr \
		--sysconfdir=/etc \
		--without-included-pcre2

	make
	make DESTDIR=$PKG install

	install -d $PKG/bin
	ln -s /usr/bin/fish $PKG/bin

	rm -rf $PKG/usr/share/locale
}

Erhm, well, yeah... I like CRUX the most, anyways, enough about package templates.


Another thing I like about CRUX port management is how it uses small collections of ports. The default ones are:

There are also quite a few unofficial user-maintained repos, I'll list the ones I use:

The thing that sets CRUX repos apart from for example the Gentoo repos is that they are decentralized in some way. For example, since I don't use any 32-bit ports I don't clone the compat-32 repo, with Gentoo you have to pull in it's entire ~1Gb port database (I'm pretty sure anyways), in essence CRUX repos are a bunch of Gentoo overlays.

CRUX can also pull in repos in multiple ways, for example with rsync or git.


CRUX uses a simple BSD-like set of rc scripts. Just like the package templates, the rc service scripts are extremely simple. They make use of start-stop-deamon, which I like a lot.


the CRUX package management tools do not handle the kernel, the user is expected do download his or her kernel sources, apply patches & customizations, compile it, and install it, easy peasy. I'm currently running Linux 4.8.6 with the muqss CPU scheduler patches, the bfq I/O scheduler patches, and a patch that makes gcc use march=native when compiling the kernel. I also often use the zen patchset which is pretty much a all of the paches I just listed combined, it also changes some default config values, for example it disables most debugging and logging stuff in the kernel.

Software

By this point it should be pretty clear that a CRUX install comes with the bare minimum pre-installed, so like most other "minimalst" distros you just install what you want & need.

I'll just list the lower-level interesting software I use here, when it comes to window managers and such, I'll talk about them in a "High-level rice: punpun" post someday.

I compile all my software with the march=native and O2 flags for that extra performance, and use the fstack-protector-strong and D_FORTIFY_SOURCE=2 for that sweet security placebo. So ehh, besides the march=native flag, I'm using pretty standard flags, I'm not too much of a ricer.