2

I have a target system Astra Linux Smolensk, which has access to very outdated packages with GCC 6 among them. It does not support C++17, which is required for some very useful 3rd party libraries and language features. At some point I am considering a possibility of using concepts from 20 standard. But there is no easy way to achieve that.
Basically, I see 2 ways:

  1. Compile needed version of GCC by myself and have a custom version of Astra Linux for building with additional packages (which is not a good option since we have restrictions for system modification). I am about to try out this option, but it is not the subject of this question.
  2. Cross-compile with latest GCC on Ubuntu using a toolchain.

So, what do I need in order to create a toolchain for a custom version of Linux? The only thing I am sure of is the Linux Core version. Can I use an existing Linux toolchain or do I have to export system libraries and create a custom toolchain?


Here I found out some tools that seem to be helpful. For instance:

Buildroot
Buildroot is a complete build system based on the Linux kernel configuration system and supports a wide range of target architectures. It generates root file system images ready to be written to flash. In addition to having a huge number of packages which can be compiled into the image, it also generates a cross toolchain to build those packages from source. Even if you don't want to use buildroot for your root filesystem, it is a useful tool for generating a toolchain. Buildroot supports uClibc-ng, glibc and musl.

I wonder if it does what I need and can I use a latest GCC compiler with those generated toolchains.


I found similar questions:
How to build C++17 application in old linux distro with old stdlib and libc?
https://askubuntu.com/questions/162465/are-gcc-versions-tied-to-kernel-versions
How can I link to a specific glibc version?


Some clarification is needed: The project relies heavily on a lot of 3rd party dependencies from the target linux's package repository. Moreover, I use dynamic .so modules that may be loaded both implicitly and explicitly.

Sergey Kolesnik
  • 3,009
  • 1
  • 8
  • 28
  • Compiling gcc on target system would be much simplier because in this case you only need to setup the compiler. When cross-compiling you would also need to set up not only the compiler but all the dependencies you would link like glibc, openssl, libxml etc. – dewaffled Jun 14 '21 at 09:18
  • @dewaffled I've linked one of the questions that mentions building C++17 for an older core and glibc version. I have a similar situation. I can't use new version of glibc on the target system since it is not available. – Sergey Kolesnik Jun 14 '21 at 09:23
  • I don't get it. You can download the compiler sources and build it on target system, so it would pick the system glibc and other dependencies. There is also libstdc++ which implements C++ standard library features, you would need to distribute it with the app and you would need to regardless of the build method. – dewaffled Jun 14 '21 at 09:32
  • @dewaffled you are right. This is number one on my list that I am going to try. I am also interested in number 2, which is a more general question. That is how to make a custom toolchain – Sergey Kolesnik Jun 14 '21 at 09:35
  • Build a cross tool chain https://crosstool-ng.github.io/ – Knud Larsen Jun 14 '21 at 15:18
  • @KnudLarsen looks promising. I suppose I have to build it using target Linux image? – Sergey Kolesnik Jun 14 '21 at 15:27
  • Using docker instead of a cross compiler is also a choice. – prehistoricpenguin Jun 15 '21 at 08:33
  • @prehistoricpenguin we are using docker in our pipeline. – Sergey Kolesnik Jun 15 '21 at 09:11
  • I think with docker, we don't need a cross compiler, did I missed something? – prehistoricpenguin Jun 15 '21 at 09:16
  • When linked with `musl`, we don't have libc captivity issues. – prehistoricpenguin Jun 15 '21 at 09:17
  • @prehistoricpenguin I am not the one who sets the pipeline etc, so I don't know. Is it possible to specify in `musl` which core version to use when linking? – Sergey Kolesnik Jun 15 '21 at 09:26
  • What do you mean by `core version`? You may google for musl related articles. – prehistoricpenguin Jun 15 '21 at 09:29
  • @prehistoricpenguin I mean Linux Core version. – Sergey Kolesnik Jun 15 '21 at 09:52
  • 1
    I think you are reference the Kernel version, according to the doc: `musl is built on the Linux syscall layer. Linux kernel >=2.6.39 is necessary for POSIX conformant behaviour, older kernels will work with varying degrees of non-conformance, 2.4 kernels will only work for simple single-threaded applications.` – prehistoricpenguin Jun 15 '21 at 10:01
  • 1
    @prehistoricpenguin I have `4.15.3` Kernel version. You can post it as an answer, I suppose. – Sergey Kolesnik Jun 15 '21 at 10:04

1 Answers1

1

Today with docker and modern CI/CD pipelines based on container, we don't rely on process compile very often as old days.

With the help of musl, we can even create universal Linux binaries with static linkage: We use all static libraries rather than dynamic libraries. Then we ship one executable file.

According to musl's doc, it needs

Linux kernel >=2.6.39

This is a very old version released around 2011, so even old Linux distro's can run our binaries.

Musl is widely used in many projects, especially in Rust projects, we provide Musl builds for users as conveniences.

Note that we may need to fix our codebase when using Musl, there are very slight differences with GNU libc, which we should be aware.

prehistoricpenguin
  • 6,130
  • 3
  • 25
  • 42
  • what if I link to an `.so` that is not compiled with `musl`? Or I have an application that uses other `.so` files for dynamic linking? – Sergey Kolesnik Jun 15 '21 at 10:18
  • @SergeyKolesnik Mix dynamic with `musl` seems dangerous or not working. Do you have the source code of dependency libraries? – prehistoricpenguin Jun 15 '21 at 10:43
  • No, I rely on many 3rdparty libraries from the target linux package repository. Also I use my own standalone `.so` libraries for modularity. This is not a subject to change. – Sergey Kolesnik Jun 15 '21 at 10:45
  • @SergeyKolesnik Then my answer may not be suitable for you. But build 3rdparty from source and static linkage is the future trend. We can use multiple static libraries for modularity and link them together too. – prehistoricpenguin Jun 15 '21 at 10:57
  • While your answer may not be well suited, it is generally useful. Using dynamic libraries provides the possibility of extending behavior via dynamically loaded plugins. Also implicitly loaded dynamic libraries help to modular update. – Sergey Kolesnik Jun 15 '21 at 11:12
  • @SergeyKolesnik I just think about it again, we can still use docker without static linkage and musl, but we need to change the makefiles slightly to make the C++17 compiler use `c++11` ABI in order to reuse the prebuilt old 3rdparty libraries. Actually, in my company, we are reusing old libraries in such a way. – prehistoricpenguin Jun 17 '21 at 01:56
  • That's more like it. So do we have to copy glibc and libcstd++ to docker from the target system? – Sergey Kolesnik Jun 17 '21 at 05:24
  • @SergeyKolesnik We build a new version of GCC on old Linux, then we don't have libc capability issues, we can also make them a container image, then share it in a dev environment and CI environment. Astra Linux is not widely used, we can choose some other distros with the same libc version, I think they will be interchangeable. – prehistoricpenguin Jun 17 '21 at 06:02