Is it possible you're using a RHEL 6-Beta DVD on a RHEL 6.0 system?
It looks like RHEL 6 has always had glibc 2.12 but the beta release had glibc 2.11. I really can't find a definitive source that says what the 6-Beta had but find mentions of 2.11 on 6-Beta around the web like here and here. All of the CentOS src.rpms for 6.0 to 6.3 are glic 2.12 so the final release has always had 2.12.
Is it possible you initially installed from the 6-beta DVD but have upgraded to a newer RHEL release since then? If so, you really can't use the packages from an older RHEL DVD. If you're just trying to install gcc, you can run yum install gcc to get GCC 4.4.x. In general, installing through yum is preferred over the DVD since yum will automatically fetch the latest RPMs whereas the DVD might have an older version that has some bugs. If you really want the DVD method, you'll need to get a DVD that matches the RHEL 6 release you have installed.
cat /etc/redhat-release will tell you what version of RHEL you're running. I'm guessing you're on 6.0 since the version of glibc currently installed is from November 2010 (you should look in to upgrading to 6.3 at some point). As for how to tell what version the DVD is, I'm guessing if you boot from it, it will say RHEL 6 Beta or something on the splash screen. Maybe read the docs on the DVD to see if it references being a beta?
Is it possible you're using a RHEL 6-Beta DVD on a RHEL 6.0 system?
It looks like RHEL 6 has always had glibc 2.12 but the beta release had glibc 2.11. I really can't find a definitive source that says what the 6-Beta had but find mentions of 2.11 on 6-Beta around the web like here and here. All of the CentOS src.rpms for 6.0 to 6.3 are glic 2.12 so the final release has always had 2.12.
Is it possible you initially installed from the 6-beta DVD but have upgraded to a newer RHEL release since then? If so, you really can't use the packages from an older RHEL DVD. If you're just trying to install gcc, you can run yum install gcc to get GCC 4.4.x. In general, installing through yum is preferred over the DVD since yum will automatically fetch the latest RPMs whereas the DVD might have an older version that has some bugs. If you really want the DVD method, you'll need to get a DVD that matches the RHEL 6 release you have installed.
cat /etc/redhat-release will tell you what version of RHEL you're running. I'm guessing you're on 6.0 since the version of glibc currently installed is from November 2010 (you should look in to upgrading to 6.3 at some point). As for how to tell what version the DVD is, I'm guessing if you boot from it, it will say RHEL 6 Beta or something on the splash screen. Maybe read the docs on the DVD to see if it references being a beta?
You could download the source RPM and rebuild it so it uses the system libs you have (2.12).
What do I need to do to have a fresh arch install but with glibc-2.33-5-x86_64.pkg.tar.zst
If you just want the dynamic libraries from the other version of glibc you can simply use LD_LIBRARY_PATH. But if you want to fully use the other version you need to compile against the other version to get the static parts. And you might want to compile the other version of glibc as well to get all the hardcoded paths to point to your installation directory for loading datafiles and plugins (for NSS and gconv). Using --prefix=/usr/glibc2.3.4 will also set the soname of the dynamic loader to /usr/glibc2.3.4/lib/ld-linux.so.2 (or something similar depending on your architecture) which will be hardcoded into every program linked against it.
- Extract the 2nd version inside
/opt. - Use
LD_LIBRARY_PATHto look for libraries inside/optfirst.
I'm on gcc 11.2.0 which uses GLIBC 2.35. I'm trying to build for a colleague's VM, but it is complaining about GLIBC versions missing.
How can I either:
-
Compile an executable that can run without dependencies?
-
Control which GLIBC version is used? The best idea I have is to do a custom gcc build, but I'm having issues with my embedded toolchain interfering.
For #1, here is what I believe is the relevant portion of my current CMakeLists:
add_executable(myapp src/main.cpp ${myapp_core} ${myapp_data_structures} ${myapp_parser} ${myapp_utils} ${myapp_tests})
target_include_directories(myapp PRIVATE ./include)
target_include_directories(myapp PRIVATE ${Boost_INCLUDE_DIR})
target_link_libraries(myapp PRIVATE ${Boost_LIBRARIES})
target_link_directories(myapp PRIVATE ${Boost_LIBRARY_DIRS})
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
message(STATUS "Debug build")
set(myapp_warning_flags -Wall -Wextra -Wpedantic -Wno-sign-compare)
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
message(STATUS "Release build")
set(myapp_warning_flags -Wall -Wextra -Wpedantic -Wno-sign-compare)
set(myapp_optimization_flags -O3 -msse4.2)
if(${myapp_static_build})
message(STATUS "Static build")
set(myapp_linker_flags -static-libgcc -static-libstdc++ -static)
set(DBUILD_SHARED_LIBS OFF)
set(BUILD_SHARED_LIBS OFF)
set(Boost_USE_STATIC_LIBS ON)
else()
message(STATUS "Dynamic build")
set(myapp_linker_flags)
set(DBUILD_SHARED_LIBS ON)
set(BUILD_SHARED_LIBS ON)
set(Boost_USE_STATIC_LIBS OFF)
endif()
endif()
target_compile_options(myapp PRIVATE ${myapp_warning_flags} ${myapp_optimization_flags} ${myapp_linker_flags})It turns out I was just not familiar enough with apt-get. I managed to install the necessary glibc version by issuing the following command:
apt-get install libc-bin=2.13-38+deb7u4 libc6=2.13-38+deb7u4
I even downgraded it and everything works okay. Core dump analysis works now.
I wouldn't install it, but unpack it in some work directory and refer to it via LD_LIBRARY_PATH. Downgrading your libc6 package can be quite problematic.
Your customer should be able to supply you with their libc6 version. It might, however, be advisable to use the libc6-dbg package which includes debug symbols. Unfortunately the 7u4 version is an older one and not available anymore.
Hi all, as some of you have already read on my previous post, I'm still testing the latest GLIBC versions on Ubuntu 18.04 to make AppImages compiled from newer distributions like Debian Unstable run smoothly.
Now I have created five scripts, each one will easily compile the latest versions of glibc for you (ie glibc-2.30, glibc-2.31, glibc-2.32, glibc-2.33 and glibc-2.34) into a dedicated directory in /opt.
For now these are for testing purposes only, you can do whatever you want with them.
My goal is to create a simple "glibc-$VERSION" command to run a newer AppImage. For now, the script that you will find in /opt/glibc-$VERSION at the end of the installation returns some errors that may be useful to better understand how to act.
As with any program installed via AM, you'll have the ability to edit the main script without having to use root privileges, and there's the ability to install / remove everything even without using AM.
To install/remove (for example) glibc-2.33 with AM:
sudo am -i glibc-2.33 or sudo am install glibc-2.33
sudo am -r glibc-2.33 or sudo am remove glibc-2.33
To install/remove glibc-2.33 without AM:
wget https://raw.githubusercontent.com/ivan-hc/AM-application-manager/main/programs/x86_64/glibc-2.33 && chmod a+x ./glibc-2.33 && sudo ./glibc-2.33
sudo /opt/glib-2.33/remove
If you want to test a newer AppImage from Debian Unstable (GLIBC 2.33 or newer) on older systems using programs managed by AM, try to install abiword, asunder, audacious, gimp, handbrake or vlc.
Contact me here or at https://github.com/ivan-hc/AM-application-manager
Thanks again to anyone who decides to carry out these experiments with me.
Hello everyone,
Is there a safe way to install older glibc on redhat 8 so I can get legacy applications that support older rhel 7 to run?
I was able to install the older rpm into a second directory, but when I tried to launch the application, it didn't use that glibc. If I try to ld_library_path, it breaks everything else since, of course, rhel 8 uses newer system glibc. Is there a way around this? Or do I need to use chroot or container of centos7?
Thanks
If you need glibc version other than the one shipped with ubuntu, one way is to install manually to a temp location in your $HOME. (installing in /usr would mess up with existing glibc in case something goes wrong)
mkdir $HOME/glibc/ && cd $HOME/glibc
wget http://ftp.gnu.org/gnu/libc/glibc-2.32.tar.gz
tar -xvzf glibc-2.32.tar.gz
mkdir build
mkdir glibc-2.32-install
cd build
~/glibc/glibc-2.32/configure --prefix=$HOME/glibc/glibc-2.32-install
make
make install
Now you should have glibc 2.32 installed in the installation directory.
You may check with ~/glibc/glibc-2.32-install/bin/ldd --version
Building on Shalini's answer,
#!/bin/bash
SOFTWARE_NAME=$1
SOFTWARE_VERSION=$2
export DOWNLOAD_INSTALL_DIR=$SOFTWARE_NAME-$SOFTWARE_VERSION-download-install
if [ -f $DOWNLOAD_INSTALL_DIR ];
then
rm -fr $DOWNLOAD_INSTALL_DIR
echo "Remove $DOWNLOAD_INSTALL_DIR"
fi
mkdir $HOME/$DOWNLOAD_INSTALL_DIR/ && cd $HOME/$DOWNLOAD_INSTALL_DIR
echo "Current directory at $PWD"
export DOWNLOADED_TAR=$HOME/$DOWNLOAD_INSTALL_DIR/$SOFTWARE_NAME-$SOFTWARE_VERSION.tar.gz
if [ ! -f $DOWNLOADED_TAR ]; then
wget https://ftp.gnu.org/gnu/$SOFTWARE_NAME/$SOFTWARE_NAME-$SOFTWARE_VERSION.tar.gz -P $HOME/$DOWNLOAD_INSTALL_DIR
echo "Software is downloaded: $SOFTWARE_NAME, version = $SOFTWARE_VERSION "
else
echo "Software is ALREADY downloaded: $SOFTWARE_NAME, version = $SOFTWARE_VERSION at $DOWNLOADED_TAR"
fi
tar -xvzf $DOWNLOADED_TAR -C $HOME/$DOWNLOAD_INSTALL_DIR
mkdir $HOME/$DOWNLOAD_INSTALL_DIR/build
export SOURCE_DIR=$HOME/$DOWNLOAD_INSTALL_DIR/$SOFTWARE_NAME-$SOFTWARE_VERSION-install
mkdir $SOURCE_DIR
cd $HOME/$DOWNLOAD_INSTALL_DIR/build
~/$DOWNLOAD_INSTALL_DIR/$SOFTWARE_NAME-$SOFTWARE_VERSION/configure --prefix=$SOURCE_DIR
make
make install
export SOFTWARE_PATH=$HOME/$DOWNLOAD_INSTALL_DIR/$SOFTWARE_NAME-$SOFTWARE_VERSION-install/bin/$SOFTWARE_NAME
if [ -f $SOFTWARE_PATH ]; then
echo "Software is found: $SOFTWARE_NAME, version = $SOFTWARE_VERSION at $SOFTWARE_PATH"
mv $SOFTWARE_PATH $GRAND_ROOT_BIN
fi
You can use the script like so bash script-name.sh bison 3.8 for downloading GNU's bison with version number 3.8.
Basically im trying to run a game but it requires at least glibc 2.38 but it seems debian only offers 2.36 at the moment. Any way i can get a newer vesion of it?
EDIT: ended up just downloading the windows version of the game and running it with wine, im an idiot and thought i was having a problem with the sound when i first downloaded, that's why i tried the linux binary, but when i ran it with wine again i found out that the game came muted by default and that i had to press + to get the volume up
I’m currently using GLIBC 2.35 on Ubuntu 22.04, and I want to update it (for gaming purposes).
I’m also aware that updating it isn’t as simple as typing:
“sudo apt update GLIBC yada yada”
or whatever, so I’m not entirely sure how to update it properly without bricking my install.
Any ideas on what to do?
You are correct in that glibc uses symbol versioning. If you are curious, the symbol versioning implementation introduced in glibc 2.1 is described here and is an extension of Sun's symbol versioning scheme described here.
One option is to statically link your binary. This is probably the easiest option.
You could also build your binary in a chroot build environment, or using a glibc-new => glibc-old cross-compiler.
According to the http://www.trevorpounds.com blog post Linking to Older Versioned Symbols (glibc), it is possible to to force any symbol to be linked against an older one so long as it is valid by using the same .symver pseudo-op that is used for defining versioned symbols in the first place. The following example is excerpted from the blog post.
The following example makes use of glibc’s realpath, but makes sure it is linked against an older 2.2.5 version.
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
__asm__(".symver realpath,realpath@GLIBC_2.2.5");
int main()
{
const char* unresolved = "/lib64";
char resolved[PATH_MAX+1];
if(!realpath(unresolved, resolved))
{ return 1; }
printf("%s\n", resolved);
return 0;
}
Setup 1: compile your own glibc without dedicated GCC and use it
Since it seems impossible to do just with symbol versioning hacks, let's go one step further and compile glibc ourselves.
This setup might work and is quick as it does not recompile the whole GCC toolchain, just glibc.
But it is not reliable as it uses host C runtime objects such as crt1.o, crti.o, and crtn.o provided by glibc. This is mentioned at: https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_location Those objects do early setup that glibc relies on, so I wouldn't be surprised if things crashed in wonderful and awesomely subtle ways.
For a more reliable setup, see Setup 2 below.
Build glibc and install locally:
export glibc_install="$(pwd)/glibc/build/install"
git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout glibc-2.28
mkdir build
cd build
../configure --prefix "$glibc_install"
make -j `nproc`
make install -j `nproc`
Setup 1: verify the build
test_glibc.c
#define _GNU_SOURCE
#include <assert.h>
#include <gnu/libc-version.h>
#include <stdatomic.h>
#include <stdio.h>
#include <threads.h>
atomic_int acnt;
int cnt;
int f(void* thr_data) {
for(int n = 0; n < 1000; ++n) {
++cnt;
++acnt;
}
return 0;
}
int main(int argc, char **argv) {
/* Basic library version check. */
printf("gnu_get_libc_version() = %s\n", gnu_get_libc_version());
/* Exercise thrd_create from -pthread,
* which is not present in glibc 2.27 in Ubuntu 18.04.
* https://stackoverflow.com/questions/56810/how-do-i-start-threads-in-plain-c/52453291#52453291 */
thrd_t thr[10];
for(int n = 0; n < 10; ++n)
thrd_create(&thr[n], f, NULL);
for(int n = 0; n < 10; ++n)
thrd_join(thr[n], NULL);
printf("The atomic counter is %u\n", acnt);
printf("The non-atomic counter is %u\n", cnt);
}
Compile and run with test_glibc.sh:
#!/usr/bin/env bash
set -eux
gcc \
-L "${glibc_install}/lib" \
-I "${glibc_install}/include" \
-Wl,--rpath="${glibc_install}/lib" \
-Wl,--dynamic-linker="${glibc_install}/lib/ld-linux-x86-64.so.2" \
-std=c11 \
-o test_glibc.out \
-v \
test_glibc.c \
-pthread \
;
ldd ./test_glibc.out
./test_glibc.out
The program outputs the expected:
gnu_get_libc_version() = 2.28
The atomic counter is 10000
The non-atomic counter is 8674
Command adapted from https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_location but --sysroot made it fail with:
cannot find /home/ciro/glibc/build/install/lib/libc.so.6 inside /home/ciro/glibc/build/install
so I removed it.
ldd output confirms that the ldd and libraries that we've just built are actually being used as expected:
+ ldd test_glibc.out
linux-vdso.so.1 (0x00007ffe4bfd3000)
libpthread.so.0 => /home/ciro/glibc/build/install/lib/libpthread.so.0 (0x00007fc12ed92000)
libc.so.6 => /home/ciro/glibc/build/install/lib/libc.so.6 (0x00007fc12e9dc000)
/home/ciro/glibc/build/install/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007fc12f1b3000)
The gcc compilation debug output shows that my host runtime objects were used, which is bad as mentioned previously, but I don't know how to work around it, e.g. it contains:
COLLECT_GCC_OPTIONS=/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crt1.o
Setup 1: modify glibc
Now let's modify glibc with:
diff --git a/nptl/thrd_create.c b/nptl/thrd_create.c
index 113ba0d93e..b00f088abb 100644
--- a/nptl/thrd_create.c
+++ b/nptl/thrd_create.c
@@ -16,11 +16,14 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#include <stdio.h>
+
#include "thrd_priv.h"
int
thrd_create (thrd_t *thr, thrd_start_t func, void *arg)
{
+ puts("hacked");
_Static_assert (sizeof (thr) == sizeof (pthread_t),
"sizeof (thr) != sizeof (pthread_t)");
Then recompile and re-install glibc, and recompile and re-run our program:
cd glibc/build
make -j `nproc`
make -j `nproc` install
./test_glibc.sh
and we see hacked printed a few times as expected.
This further confirms that we actually used the glibc that we compiled and not the host one.
Tested on Ubuntu 18.04.
Setup 2: crosstool-NG pristine setup
This is an alternative to setup 1, and it is the most correct setup I've achieved far: everything is correct as far as I can observe, including the C runtime objects such as crt1.o, crti.o, and crtn.o.
In this setup, we will compile a full dedicated GCC toolchain that uses the glibc that we want.
The only downside to this method is that the build will take longer. But I wouldn't risk a production setup with anything less.
crosstool-NG is a set of scripts that downloads and compiles everything from source for us, including GCC, glibc and binutils.
Yes the GCC build system is so bad that we need a separate project for that.
This setup is only not perfect because crosstool-NG does not support building the executables without extra -Wl flags, which feels weird since we've built GCC itself. But everything seems to work, so this is only an inconvenience.
Get crosstool-NG and configure it:
git clone https://github.com/crosstool-ng/crosstool-ng
cd crosstool-ng
git checkout a6580b8e8b55345a5a342b5bd96e42c83e640ac5
export CT_PREFIX="$(pwd)/.build/install"
export PATH="/usr/lib/ccache:${PATH}"
./bootstrap
./configure --enable-local
make -j `nproc`
./ct-ng x86_64-unknown-linux-gnu
./ct-ng menuconfig
The only mandatory option that I can see, is making it match your host kernel version to use the correct kernel headers. Find your host kernel version with:
uname -a
which shows me:
4.15.0-34-generic
so in menuconfig I do:
Operating SystemVersion of linux
so I select:
4.14.71
which is the first equal or older version. It has to be older since the kernel is backwards compatible.
Now you can build with:
env -u LD_LIBRARY_PATH time ./ct-ng build CT_JOBS=`nproc`
and now wait for about thirty minutes to two hours for compilation.
Setup 2: optional configurations
The .config that we generated with ./ct-ng x86_64-unknown-linux-gnu has:
CT_GLIBC_V_2_27=y
To change that, in menuconfig do:
C-libraryVersion of glibc
save the .config, and continue with the build.
Or, if you want to use your own glibc source, e.g. to use glibc from the latest git, proceed like this:
Paths and misc optionsTry features marked as EXPERIMENTAL: set to true
C-librarySource of glibcCustom location: say yesCustom locationCustom source location: point to a directory containing your glibc source
where glibc was cloned as:
git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout glibc-2.28
Setup 2: test it out
Once you have built he toolchain that you want, test it out with:
#!/usr/bin/env bash
set -eux
install_dir="${CT_PREFIX}/x86_64-unknown-linux-gnu"
PATH="${PATH}:${install_dir}/bin" \
x86_64-unknown-linux-gnu-gcc \
-Wl,--dynamic-linker="${install_dir}/x86_64-unknown-linux-gnu/sysroot/lib/ld-linux-x86-64.so.2" \
-Wl,--rpath="${install_dir}/x86_64-unknown-linux-gnu/sysroot/lib" \
-v \
-o test_glibc.out \
test_glibc.c \
-pthread \
;
ldd test_glibc.out
./test_glibc.out
Everything seems to work as in Setup 1, except that now the correct runtime objects were used:
COLLECT_GCC_OPTIONS=/home/ciro/crosstool-ng/.build/install/x86_64-unknown-linux-gnu/bin/../x86_64-unknown-linux-gnu/sysroot/usr/lib/../lib64/crt1.o
Setup 2: failed efficient glibc recompilation attempt
It does not seem possible with crosstool-NG, as explained below.
If you just re-build;
env -u LD_LIBRARY_PATH time ./ct-ng build CT_JOBS=`nproc`
then your changes to the custom glibc source location are taken into account, but it builds everything from scratch, making it unusable for iterative development.
If we do:
./ct-ng list-steps
it gives a nice overview of the build steps:
Available build steps, in order:
- companion_tools_for_build
- companion_libs_for_build
- binutils_for_build
- companion_tools_for_host
- companion_libs_for_host
- binutils_for_host
- cc_core_pass_1
- kernel_headers
- libc_start_files
- cc_core_pass_2
- libc
- cc_for_build
- cc_for_host
- libc_post_cc
- companion_libs_for_target
- binutils_for_target
- debug
- test_suite
- finish
Use "<step>" as action to execute only that step.
Use "+<step>" as action to execute up to that step.
Use "<step>+" as action to execute from that step onward.
therefore, we see that there are glibc steps intertwined with several GCC steps, most notably libc_start_files comes before cc_core_pass_2, which is likely the most expensive step together with cc_core_pass_1.
In order to build just one step, you must first set the "Save intermediate steps" in .config option for the intial build:
Paths and misc optionsDebug crosstool-NGSave intermediate steps
and then you can try:
env -u LD_LIBRARY_PATH time ./ct-ng libc+ -j`nproc`
but unfortunately, the + required as mentioned at: https://github.com/crosstool-ng/crosstool-ng/issues/1033#issuecomment-424877536
Note however that restarting at an intermediate step resets the installation directory to the state it had during that step. I.e., you will have a rebuilt libc - but no final compiler built with this libc (and hence, no compiler libraries like libstdc++ either).
and basically still makes the rebuild too slow to be feasible for development, and I don't see how to overcome this without patching crosstool-NG.
Furthermore, starting from the libc step didn't seem to copy over the source again from Custom source location, further making this method unusable.
Bonus: stdlibc++
A bonus if you're also interested in the C++ standard library: How to edit and re-build the GCC libstdc++ C++ standard library source?