Gentoo: Converting no-multilib to multilib

So it’s said that it’s not possible. Not supported perhaps, but definitely possible. Writing this here for reference, it’s also not supported in any way seeing that I’m not even close to what can even remotely be considered an expert in the field. I just figured someone else will run into the same situation, and might find this useful as a base to work from.

Well, the reason why “it’s not possible” is because your toolchain is broken. Not really, but there are requirements and either you need to go building a cross-toolchain using crossdev, or you need to obtain the required toolchain in some other way. Frankly, the thought of going through crossdev is an interesting one, but there exists a simpler strategy. Compiling the toolchain on the box itself fails. Note, compiling, not portage failures. This means that we are likely able to install binary packages, and this is the crucial clue.

In the case where a multilib machine is available, just create binary packages there, otherwise, follow instructions below.

chroot environment

Well, the normal strategy is a re-install. We’re going to cheat, we’re going to somewhat install a new system, then build binary packages and just use those. So download a stage3 AMD64 stage tarball. I then did this (for obvious reasons as root):

mkdir /home/multilib
tar xvpf /path/to/stage3-amd64-??.tar.bz2 -C /home/multilib
mkdir /home/multilib/usr/portage
for i in usr/portage dev sys proc; do
    # Changed to use --rbind from --bind - as per the manpage this
    # mounts sub-mounts too, incl. /dev/shm which has recently become a problem.
    mount --rbind /$i /home/multilib/$i
cp /etc/resolv.conf /home/multilib/etc/
cp /etc/make.conf /home/multilib/etc/
mkdir /home/multilib/etc/portage
cp /etc/portage/package.* /home/multilib/etc/portage/
chroot /home/multilib

Updating portage

Probably not required, but I want portage inside of and outside of my root to be the same to reduce the risk of things going wrong:

emerge -uav portage

At this point, also double check that you’ve got a sane profile selected, I just use the base one:

tiny ~ # eselect profile list
Available profile symlink targets:
  [1]   default/linux/amd64/10.0 *
  [2]   default/linux/amd64/10.0/desktop
  [3]   default/linux/amd64/10.0/desktop/gnome
  [4]   default/linux/amd64/10.0/desktop/kde
  [5]   default/linux/amd64/10.0/developer
  [6]   default/linux/amd64/10.0/no-multilib
  [7]   default/linux/amd64/10.0/server
  [8]   hardened/linux/amd64/10.0
  [9]   hardened/linux/amd64/10.0/no-multilib
  [10]  selinux/2007.0/amd64
  [11]  selinux/2007.0/amd64/hardened
  [12]  selinux/v2refpolicy/amd64
  [13]  selinux/v2refpolicy/amd64/desktop
  [14]  selinux/v2refpolicy/amd64/developer
  [15]  selinux/v2refpolicy/amd64/hardened
  [16]  selinux/v2refpolicy/amd64/server
tiny ~ #

Updating the toolchain

The question here really is what’s all part of the toolchain. This is a valid question, and frankly I’m not an expert. The easy way is to just make binary packages of the entire default system, you probably want to recompile most of your libraries etc anyway, so we can just as well do this inside the chroot and use the binary packages outside. So by wasting some extra cycles we make this easy:

emerge -euav --buildpkg system

After a while you’ll be prompted to recompile everything in the stage tarball, probably most things will be upgraded anyway (probably). I’m not a fan of wasting CPU cycles for the heck of it, however, I’ve got other things I need to be busy with. So I’ll just burn the CPU in the background and be done with it for now.

Returning to the no-multilib system

Right, now we switch the profile:

eselect profile set default/linux/amd64/10.0

And now we remerge system (remember the binary packages was created in a bind mounted /usr/portage so there is no need to copy things around).

emerge -euavk1 system

Before saying yes, make sure that anything that looks critical says “binary” and not “ebuild”. On my system everything was labeled binary so I just proceeded.


Whether or not world needs to be rebuild or not I do not know. I’m not going to waste that number of cycles at the moment, but if/when time permits and you’d rather be on the “save” side, you’re welcome to remerge world with:

emerge -1euakv world

This will include system, but for system it will use the binary packages if they are still applicable, meaning it won’t waste as much time (especially on things like glibc which can take a while to compile).

I can confirm working by having merged wine after this, and actually starting up winbox.

11 Responses to “Gentoo: Converting no-multilib to multilib”

  1. Jeff says:

    jkroon, you helped me twice now revive two broken Gentoo boxes. Thanks!

  2. Jonas Lihnell says:

    Please update ” mount –bind /$i /home/multilib/$i” to use –rbind instead.

  3. Jaco Kroon says:

    Thanks. Update made.

  4. Jonas Lihnell says:

    This btw, should be listed in the official documentations on how to convert non-multilib to multilib. It was painless, straight forward, easy to understand and worked like a charm. Thanks.

  5. Jaco Kroon says:

    Yea well. Officially you shouldn’t make mistakes that requires this kind of trickery :). But then again – I’ve never re-installed a Gentoo box – EVER. Other than stolen laptops and completely buggered hardware.

  6. Tiago says:

    Going back and forth from multilib to no-multilib shouldn’t be considered a mistake nor require trickery – and in fact I don’t consider what you suggested here trickery, it’s actually a very clever solution.
    I just bookmarked this page and will give it a try this evening.
    You should consider adding this to the gentoo wiki 🙂

  7. Tiago says:

    Worked like a charm, as expected.
    Just a few other useful tips:
    – Avoid using /dev/shm as temp folder for portage, both in the chroot and in the main system, as it may run short when using buildpkg and create an unecessary mess
    – I rebooted (just to unmount everything) and deleted the binary packages before rebuilding world. Takes a bigger while, but satisfies my paranoia

  8. Kholan says:

    After setting CONFIG_IA32_EMULATION in my kernel config, which of course is necessary, it worked like a charm.
    Being a clean and easy solution this really should be on gentoo-wiki

  9. Dmitry says:

    Whoa… Although rebuilding @system just to get binary packages may be entertaining, I would like to add some shortcuts for Gentoo systems of a recent vintage:
    1) Actually, the only binary package we really need to go multilib is glibc. However, it would be wise to take precompiled gcc too, just for the sake of timesaving.
    2) So, grab a multilib stage3 and unpack it to, say, /var/tmp/gentoo:
    # mkdir /var/tmp/gentoo && tar xpC /var/tmp/gentoo -f stage3-amd64-latest.tar.bz2
    Bind mount the Portage tree (and $PKGDIR, in case you have set it to a non-default location, don’t forget to update the make.conf of the stage in that case).
    # mkdir /var/tmp/gentoo/usr/portage && mount –rbind /usr/portage /var/tmp/gentoo/usr/portage
    You don’t need to mount anything else – we ain’t gonna run emerge.
    3) Since we are working with stage3, we already have a compiled toolchain. There’s no need to rebuild it, unless your target system (the one, that should be converted to multilib) has a glibc of a different slot (in that case, you must sync versions first). Instead, we’ll just make tarballs of in-stage packages:
    # chroot /var/tmp/gentoo quickpkg glibc gcc
    4) umount what you have mounted and get rid of /var/tmp/gentoo – we don’t need it anymore
    5) Now, in the target system, switch to multilib profile
    # eselect profile list
    # eselect profile set $profilenumber
    # env-update && . /etc/profile
    6) Install the binaries from multilib stage3:
    # emerge -1K glibc gcc
    Switch to the binary gcc:
    # gcc-config -l
    # gcc-config $binarygccnumber
    # env-update && . /etc/profile
    7) Now, we have a binary multilib toolchain from the stage3 in the target system. You may use it as is, but, technically, it’s cross-compiled, so I encourage you to sequentially rebuild both glibc (be careful with CFLAGS) and gcc to reveal possible problems with headers/dependencies/useflags:
    # emerge glibc && emerge gcc
    And switch to the freshly built gcc:
    # gcc-config -l
    # gcc-config $newgccnumber
    # env-update && . /etc/profile
    8) Remove old gcc versions, it there are any
    9) Tune Portage configs, if that is required. Proceed as usual on a profile switch:
    # emerge -DuN @world && emerge -DuN @system && emerge @preserved-rebuild
    # revdep-rebuild

    That’s it, basically.

  10. jhon987 says:

    Thank you very much for the guide!
    I’m not sure all this (emerge system twice) is necessary but it eventually got me on the right track, so I wanted to show my appreciation.

    On a side-note, I too share Dmitry’s (comment above me) notion that all we really need is gcc and glibc. Once we have those I believe it’s basically should be enough to emerge -auND world (or not, depends on what we wish to do with our system).

    Anyways I cannot confirm since I followed your guide initially then Dmitry’s comment, got lost along the way and had to improvise, at the end of it I did emerged system once then gcc and glibc as per Dmitry suggestion and once I did that I could convert fully to multilib…

  11. jhon987 says:

    Alright, so I had to repeat this experiment (of going back and forth from no-multilib to multilib and vice versa) I can now confirm Dmity’s method 100% working (at least for me) and it’s certainly is a shortcut…

Leave a Reply

This blog is kept spam free by WP-SpamFree.