Looking at a musl C library Powered Linux

I’d known about Musl as an alternative C library for embedded systems, but only recently discovered that it’s the default system C library for the Alpine Linux distribution since version 3.0. So, I decided to give it a go. The images available on the source site are very lean (lean – it’s their motto, sorta) – and it takes a little jiggling to get the system working with X and a browser. Since I’d already jumped the hoops, I decided to write it up in case someone else didn’t want to jump them.

OK, so I started with the “extended” ISO image, and burned and booted it. It booted to the root prompt. There was no automatic installer. So, I found the /sbin/setup-alpine program and ran it. It is an interactive installer that puts a basic system on some kind of writable media, which in my case was a hard drive:

/sbin/setup-alpine

At this point there was still no browser (not even a text browser) – to cruise the internet. However; the internet was working with the minimal utilities (ping, wget, etc). Moving forward, I ran the setup-xorg-base program (also found in the sbin directory):

/sbin/setup-xorg-base

It created a basic xorg installation.  I added a video driver (specific to my system), and a window manager (i3 = ‘my fav’), and a few other things. Instead of executing another of the “special programs” to install those additional things, I used the package manager itself. By default, I found that the package manager (apk) pointed to the “main” repo (which didn’t have much of the extra stuff I wanted). So I edited the /etc/apk/repositories file, and un-remarked the community repository at the bottom of the file. Doing this added around 8000 packages. Later I would add another repo (edge/testing) to get some of the other things on my list:

General form of repo entry in /etc/apk/repositories:

http://the-mirror-wanted/alpine/v3.5/main
http://the-mirror-wanted/alpine/v3.5/community
http://the-mirror-wanted/alpine/edge/testing

The usual disclaimers are attached to the last two repo sources, of course. After adding the new entries in /etc/apk/repositories, I updated the db:

     apk update

Then, I started adding extra packages:

apk add i3wm
apk add xf86-video-nv
apk add xf86-video-nouveau
apk add xf86-input-mouse
apk add xf86-input-keyboard
apk add xterm
apk add dbus

And, I started the dbus service:

rc-service dbus start

I edited the /etc/X11/xinit/xinitrc file to contain exec i3 (placed towards the bottom of the file). Note that this would be a different entry when using other window managers. I put a comment sign in front of the xcfe window manager exec line, which would otherwise be the default setting as created by the X meta-package.

At this point I could add firefox as a browser:

  • apk add firefox-esr
  • apk add font-bitstream-speedo
  • apk add fontconfig-dev
  • apk add font-bh-100dpi
  • apk add font-sun-misc
  • apk add font-bh-lucindatypewriter-100spi
  • apk add font-adobe-utopia-type1
  • apk add ttf-dejavu

Still, I found that Firefox crashed until a slight bit more tidying was done. Apparently, there is a musl library porting issue (I don’t know this for sure, but there is a referenced bug report with the fix) – that causes firefox to be unable to use fonts. The fix (currently) is a little script that can be run to enable a work-around:

wget https://bugs.alpinelinux.org/attachments/download/364/ff-fix.sh.txt

After downloading the fix file, I ran firefox once (to create a profile).  Then, in my home directory (since the script will modify the Firefox config) I executed the fixer:

  • chmod 555 ff-fix.sh.txt
  • ./ff-fix.sh.txt

At this point, I could start X, open a terminal, and run firefox:

startx — -nolisten tcp

As of this writing, Firefox version 45 is in the packages repo (for Alpine Linux version 3.5). I always like to have a local cache of all the packages that I install. I looked in the debian-way place for this (/var/cache/apk) and found repo tarballs, but no actual packages. To remedy this, I found I could run another /sbin helper program:

  • /sbin/setup-apkcache
  • apk cache -v sync

The first line sets up the local cache, and the second line downloads (any missing) packages to whatever directory was specified in the first line (I used /var/cache/apk). Since I had no local packages at that point, the second line caused all of the installed package archive files to be downloaded from the repo and saved in the cache directory.

apk search *stuff*with*wildcards*and*patterns

The preceding line is the way to search for packages, and works pretty well. It’s about the same as other package managers I’ve used.  I wanted to be able to build some unique software programs I often use, from source.  So, I needed to install a build environment.  The following packages seemed to do that task (but I have yet to test):

  • apk add –update alpine-sdk
  • apk add build-base

IIRC, I added autoconf manually. Subsequently, I was able to build fldigi (a third party ham radio program) from source.  After running ldd against the completed fldigi program, I cut a snippet of the output, so that the musl libc alternate C library can be seen as a dependency:

sys:/home/jake/build/fldigi-3.23.21/src# ldd ./fldigi
        /lib/ld-musl-x86_64.so.1 (0x7a29129c3000)
        libportaudio.so.2 => /usr/lib/libportaudio.so.2 (0x7a2911705000)
        libfltk_images.so.1.3 => /usr/lib/libfltk_images.so.1.3 (0x7a29114f9000)
        libpng16.so.16 => /usr/lib/libpng16.so.16 (0x7a29112cc000)
        libfltk.so.1.3 => /usr/lib/libfltk.so.1.3 (0x7a2910fd2000)
        libX11.so.6 => /usr/lib/libX11.so.6 (0x7a2910caf000)
        libsndfile.so.1 => /usr/lib/libsndfile.so.1 (0x7a2910a46000)
        libsamplerate.so.0 => /usr/lib/libsamplerate.so.0 (0x7a29106db000)
        libpulse-simple.so.0 => /usr/lib/libpulse-simple.so.0 (0x7a29104d7000)
        libpulse.so.0 => /usr/lib/libpulse.so.0 (0x7a291028e000)
        libintl.so.8 => /usr/lib/libintl.so.8 (0x7a2910080000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7a290fd2f000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7a290fb1d000)
        libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7a29129c3000)

What are the advantages of using the musl library replacement?  According to the following link, picked randomly from a search engine query result, the advantages are mixed bag.  Some musl lib operations are faster, some are much faster, but more often the items (selected on the etalabs page) were a little slower than glibc.  OTOH, for musl, the sizes were much smaller, in some cases 15x smaller.  This comes naturally from a library targeted to the embedded world.  Maybe the more interesting thing is the feature set difference.  Surprisingly, musl seems to have the edge over glibc:

http://www.etalabs.net/compare_libcs.html

So, the experience so far is pretty good.  I have a pretty lean little system, yet one that can run a high-end browser. It seems pretty quick and stable so far.

To be continued …

Alpine Linux is done by the people at http://www.alpinelinux.org, and this site and author has no affiliation with them. The Musl C library is maintained by the people at https://www.musl-libc.org – and this author and site has no affiliation with them.  Firefox is maintained by Mozilla at mozilla.org.  This author and site has no affiliation with them.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s