How are binary packages (rpm, deb, etc) created for binutils, gcc and other packages that link to different libs depending on what exists on the host system?

In the LFS project, to isolate the new system from the host, cross compilation is faked by using a different target-triplet for the new system (here). This prevents packages from linking to libs that exists only on the host system. But if a similar method is used to build binary packages, then surely these packages would have a different target triplet than that of the system they were built on.

I read this email correspondence which discussed building a host-isolated gcc. But it came to the conclusion that faking cross-compiling like LFS is the only rational way to build gcc isolated from the host system.

I tried building binutils with --prefix and --with-sysroot set to an empty directory but the resulting binaries were linking to libfl on my host system.


I think my original explanation is not clear. Allow me to give a more specific example:

GNU's binutils does not depend on GNU flex, I can validate this by running ldd /usr/bin/ar on my arch system and I see that it does not link to libfl.so. Dispite this I still have flex installed on my host system. Now, I would like to compile a binutils binary which I will copy to another system with the same architecture. This new system does not have GNU flex installed, but this should not matter since binutils does not depend on GNU flex. The problem is that when I compile binutils on my host system, it links to libfl.so.2! I assume this is because when I built binuitls it "noticed" I had flex installed so decided to link to it. I would like to know how I can compile software (like binutils) without it linking to optional dependencies (like flex) that exist on my host system. Surely binary package maintainers face this same problem when they try to compile their software?

Binutils is just an example in this case, I am really looking for a more general method that package maintainers use to stop their software linking to optional dependencies in the host system.

  • Can you provide example commands and describe what happens and what you expected to happen? I’m having trouble understanding Commented Oct 30, 2022 at 13:19
  • random keywords and links that come to mind for build isolation or related topics: chroot, fakechroot, fakeroot, containers, reproducible-builds.org/#how
    – A.B
    Commented Oct 30, 2022 at 13:54
  • binutils, gcc and other packages that link to different libs depending on what exists on the host system? honestly, these are exactly the types of software where you can configure which system to build for, which libraries to use etc during build configuration. Else, there would never be any cross compilers! It's perfectly "normal" to compile –on an x86_64 Linux build host– a GCC that generates baremetal ARM code and runs on a SPARC. So, maybe simply not the best examples for the point you're trying to make – or I'm totally misinterpreting you! Commented Oct 30, 2022 at 15:36
  • I think my initial explanation was not very clear, I have edited the question to describe a specific instance of my problem.
    – C. Lang
    Commented Oct 30, 2022 at 17:31

2 Answers 2


I may be mistaken but I think the answer (often) is that they are not isolated from the host system.

How are binary packages (rpm, deb, etc) created for binutils, gcc and other packages that link to different libs depending on what exists on the host system?

They don't. rpm, deb etc specify the dependencies, including version and have different RPMs for different architectures. In other words rpms and debs are based on the idea that the target systems will all look alike.

Do the target system and build system look the same? I'm not a package maintainer so there may be some magic I'm not aware of. My understanding is that this is achieved by building on the same type of system as the target system. At least the build environment will be some chroot laid out just like the target environment.

There's a subtlety of LFS that I don't think they called out when I read it (15? years ago). In LFS you start with no system, so you get some tools and start building the basic blocks of your system. But you have to do this from the outside looking in, because otherwise you have a chicken and egg problem. With no system initially, you can't build inside your system.

What I don't think they really call out in LFS is that once you have a system installed, you don't need to compile packages from the outside looking in. You can use that system to build its own packages. This works both if you intend to use those to replace bits of that system itself, or if you intend to use them to distribute to other similar systems.

It's a bit of a maddening concept initially. Rather like writing a C compiler in C. You start by compiling your C compiler with someone else's then re-compile your C compiler with your C compiler. You can then throw away the one you got from someone else.


In the rpm-based world, we use Mock build tool. Mock creates an isolated environment using systemd-nspawn containers. It install only a minimal set of dependencies and the build is done in the container. So it is completely shielded from the host environment. In fact, the build environment can even have different architecture.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .