Can you build Rust for old (Redhat 5 vintage) Linux? - rust

Redhat 5 has the required 2.6.18 kernel but not the latest glibc, g++ and certainly no clang. The binary distribution doesn't run, complaining about glibc version.
Has anyone made an attempt to back port to old Linux? I could imagine cobbling together a frankensystem with an old kernel but new compilers and try to compile against old glibc or statically compile in some of new glibc but it seems like a fraught course.
Just wondering if anyone has tried and can offer guidance?
I'm thinking there must be a distro setup to do such builds. Anaconda, for example, includes lots of new technologies but works fine on Redhat 5. I wonder how they build it?
Update: Once you get some newer compilers working on RHEL5 it's still not possible to build Rust because it depends on a working binary of itself to bootstrap. See: https://github.com/rust-lang/rust/issues/9545#issuecomment-54865031

Anaconda packages are built against CentOS 5 (which is equivalent to Redhat 5). The important thing is to compile against an old enough glibc, as it is strictly forward compatible (as you saw). The version of glibc is typically tied to the version of the distro, so your best bet is to make a VM with CentOS 5 and build on that.
The version of the compiler used is not as important, and in fact in some cases it is necessary to use a newer compiler than the old one that comes with the system to get things to work. I have gcc 4.8 built for CentOS 5 which you can get with conda (conda install -c asmeurer gcc).

I hit this very issue this weekend, because Skylight supports Linux 2.6.18, including CentOS 5.10, and we use Rust in our agent.
Alex Crichton of the Rust core team was kind enough to get this working again by using CentOS 5.10 boxes for the build, which uses glibc 2.5 and Linux 2.6.18.

Related

How to safely reconfigure gcc on my Linux system?

I am trying to install a program on CentOS 6.10 and at the end of the installation, it gave an error saying that Glibc-2.14 is necessary. I upgraded the current Glibc and this time the error below occurred:
* These critical programs are missing or too old: gcc
* Check the INSTALL file for required versions.
I upgraded the gcc and tried to configure again. However, the same error persists. Hence I read the INSTALL file as it suggests, and I see this section:
You may also need to reconfigure GCC to work with the new library. The
easiest way to do that is to figure out the compiler switches to make
it work again (`-Wl,--dynamic-linker=/lib/ld-linux.so.2' should work
on GNU/Linux systems) and use them to recompile gcc.
So should I go to where gcc is built and do:
$ ./configure -Wl,--dynamic-linker=/lib/ld-linux.so.2 ?? Do I understand the instructions correctly? If so, then how will I be able to configure only gcc and not the other executable files as they are all in the same folder? (e.g gcc-5, git, idle, python, python-build.. etc) The directory is something like: home/linuxbrew/.linuxbrew/bin/gcc
I'm asking this because GNU compiler and GCC are fundamental in Linux system, and I'm not sure if those are the correct steps.
You are probably using a really old compiler (the one that comes with CentOS by default).
You need to install Red Hat Developer Toolset which provides up-to-date versions, see https://www.softwarecollections.org/en/scls/rhscl/devtoolset-7/ for more details:
Developer Toolset is designed for developers working on CentOS or Red Hat Enterprise Linux platform. It provides current versions of the GNU Compiler Collection, GNU Debugger, and other development, debugging, and performance monitoring tools.

How can I compile php-cgi binary using a custom glibc for suse enterprise linux out of cygwin?

Pretty straight to the point I think. Is this do-able?
Background: I'm doing this because I need to run php-cgi on suse enterprise 9 and can't get LD_PRELOAD or LD_LIBRARY_PATH to use other-than-system version of glibc.
php-cgi: /lib/tls/libc.so.6: version `GLIBC_2.7' not found
I downloaded 2.7 from here
http://rpmfind.net/linux/rpm2html/search.php?query=libc.so.6(GLIBC_2.7)
more precisely
ftp://rpmfind.net/linux/sourceforge/r/ro/roblinux/64-32_pkg/core/i686/glibc-2.7-2rt.i686.rpm
and unpacked it using rpm2cpio.
I need php-cgi because I can't install php and want to try JavaBridge for running php out of tomcat.
How can I compile php-cgi binary using a custom glibc for suse enterprise linux out of cygwin?
Pretty straight to the point I think.
No, a very confused and circuitous question.
First, cygwin has absolutely nothing to do with your question: it's for running UNIX programs on Windows, which is not at all what you are asking about.
Second, your question appears to be: "how do I run pre-build php-cgi binary on a system that has older glibc than the one php-cgi has been built on?", and not about compiling anything.
To that question, the answer is: you can't (easily) -- UNIX systems do not support forward binary compatibility (build on a new system, run on an older one). Only backward compatibility is supported (old dynamically-linked binaries continue to run on newer systems).
Your best approach is to try to build php-cgi on your system (which would eliminate its dependency on GLIBC_2.7. If you can't, you should still be able to run such a binary against unpacked glibc-2.7 build, if that binary doesn't re-exec itself. The way to do that, assuming you unpacked glibc-2.7 into e.g. /tmp/glibc-2.7 is something like:
/tmp/glibc-2.7/lib/ld-linux.so.2 --library-path \
/tmp/glibc-2.7/lib:/lib:/usr/lib \
/path/to/php-cgi <args>
(The library path above may need some adjustments to make the loader find all the required libraries.)
Update:
is it practical to compile stuff for my linux box in cygwin
It is possible, but significantly more pain then simply compiling on the linux box itself (and so isn't really practical). You appear to lack any reason to want to do that, other than mis-guided belief that cygwin solves all problems.

Running a C program compiled here causes a GLIBC library not found error on another server - is it my fault or theirs?

A C program compiled here runs fine on our Ubuntu servers. But when a somebody else tries to run it on their particular Linux server they get the following errors:
./myprog-install: /lib/tls/libc.so.6: version `GLIBC_2.4' not found (required by ./myprog-install)
./myprog-install: /lib/tls/libc.so.6: version `GLIBC_2.7' not found (required by ./myprog-install)
Do I need to upgrade our glibc libraries and recompile? Or are they missing something on their server?
If I run apt-cache show libc6 my Ubuntu tells me the version is:
Package: libc6
Priority: required
Section: libs
Installed-Size: 9368
Maintainer: Ubuntu Core developers <ubuntu-devel-discuss#lists.ubuntu.com>
Original-Maintainer: GNU Libc Maintainers <debian-glibc#lists.debian.org>
Architecture: i386
Source: eglibc
Version: 2.11.1-0ubuntu7.10
If I look at http://packages.ubuntu.com/hardy/libc6 the current version appears to be 2.7-10ubuntu8.1.
I'm confused by the numbers. On the one hand 2.11-1-0 is a higher number than 2.7-11. On the other hand 7.10 is a lower number than 8.1.
Is it just a matter of me upgrading the C library package and recompiling do you think? Or is the other person's server missing some needed library there for compatibility?
You have built on glibc-2.11 system. You are trying to run on a system with glibc-2.3 or older. That's not going to work.
Is it just a matter of me upgrading the C library package
No: upgrading your glibc will only make things worse.
You may want to try solutions listed here.
Is this something we can reasonably request the other party to upgrade their system to support, rather than downgrade our compiler?
Usually the client will strongly resist requests to upgrade their system: it's working fine for them as is, and any upgrade can break other existing applications.
If you are planning to distribute binaries on Linux (as opposed to building them on the target system), then you need to learn how to make binaries that will run everywhere, or you need to state your requirements (minimum kernel and libc versions, etc.) and turn clients who can't meet these requirements away.
Update:
Why did they get two errors. Why didn't they just get one for GLIBC_2.11.1 which is apparently what I built with?
Symbol versioning doesn't work that way.
When a new symbol is introduced, it is marked with the current libc version, e.g. readdir64##GLIBC_2.2, posix_spawn##GLIBC_2.15, etc.
When you link a program that uses both of the above symbols, and try to run it on e.g. glibc-2.1 system, you would get two errors.
But if you link a program that doesn't use any of the above symbols, e.g.
int main() { return 0; }
then your program will just run without any errors.
Update 2:
they don't have to add both GLIBC_2.4 and GLIBC2.7 to their Linux system, do they?
No, they don't. The GLIBC_2.11 will have all the previous symbols in it. In fact, they couldn't install both glibc-2.4 and 2.7 even if they wanted to: it is quite difficult to have multiple versions installed at the same time, and impossible to have multiple versions installed in default location.
You've built it against a version of glibc that is too new. Build it against an older version of glibc, preferably the one that they are using.
you need to build on a system that uses same versions of libraries as you do. This is where docker and VM's are very convenient. There is probably a pre-made docker image for whatever version the customer has.

What's the best way to build software that doesn't require the newest glibc?

I'm attempting to build a binary package that can be run on multiple Linux distributions. It's currently built on Ubuntu 10.04, but it fails on Ubuntu 8.04 with the following error:
./test: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./test)
./test: /usr/lib/libstdc.so.6: version `GLIBC_2.11' not found (required by ./test)
What's the preferred way to solve this problem? Is there a way to install an old glibc on a new box and build against it, or do I have to build on an old distribution? And if I build against an old glibc, will it work on a new glibc?
Or, alternatively, are there just some handy compiler flags or packages I could install to solve the problem?
The best solution I've found is to install a virtual machine running Debian stable, and build on that. Debian stable is old enough that any packages built with it will run on any other Debian-based distribution like Ubuntu. You may have to work around non-critical bugs that have been fixed in later versions of various software but not backported to Debian stable.
If you really want to make sure it runs on every recent distribution, you might also consider statically linking against a libC you select. However you may then still run into problems if you use features that are only provided by newer kernels (newer system calls e.g.).

Compile for CentOS on Ubuntu

Can I install an older version of gcc/g++ (4.1.3) on the latest Ubuntu (which comes with 4.4.3) and use it to compile a .so which should run on CentOS? The binary compiled with the Ubuntu version of gcc fails to load on CentOS because of missing imports (GLIB_2_11, ...). I need C++ (including exceptions), so I can't just statically link against glibc, which I already tried.
Can I install the older gcc without removing the newer one? How do I go about the libs required by the older gcc?
I'm currently developing code in CentOS, but it's such a pain to use. I really want to move to an Ubuntu desktop.
g++-4.1 is available for Ubuntu; just run apt-get install g++-4.1 then run g++-4.1 instead of g++. However, simply using an older compiler may not fix all of your library issues.
Like Joachim Sauer said, your best bet is to do your development on Ubuntu then do the final compilation on CentOS.
Even though you're using C++, static linking should still be an option. (However, you're much better off compiling on CentOS and using dynamic linking.)
Edit: A virtual machine is the most straightforward way to build on CentOS, but if you want to avoid the memory and CPU overhead of running a VM and don't care about differences between Ubuntu's and CentOS's kernel, then you can create a subdirectory containing a CentOS or Fedora filesystem and chroot do that to do your builds. This blog posting has details.

Resources