Shared libraries and static linking?

133 views
Skip to first unread message

Kendall Bennett

unread,
Feb 18, 2003, 8:57:16 PM2/18/03
to
Hi Guys,

We have come across a rather nasty issue that I want to try and solve,
but at present I don't have a clean solution. If I wish to compile a
program on Red Hat 8.0 that will run on any Linux distribution, I really
need to staticly link my program against glibc. If I link against the
shared library version, I will need to distribute different versions of
my program for all the different Linux platforms which have different
versions of glibc, right?

So static linking would seem to be the best solution, especially for
smaller programs (these are console apps, not X11 apps).

However things get complicated if there is a requirement that something
be in a shared library. For instance for our XFree86 module, we need to
do stuff that is Linux specific so we need to dlopen() a shared library
to do what we need. As far as I can figure out, that shared library
*must* be linked against the same version of glibc that the XFree86
server itself is, or there will be serious problems.

Consider malloc/free inside the shared library. If the shared library is
staticly linked to a version of glibc, when the shared library loads it
will initialise the heap itself using sbrk(), which will be at the end
of the current heap for the program that loaded the shared library at
the time the library is loaded. Once the the shared library mallocs()
any memory, that memory will be tromped on my the main program code if
the program code also mallocs more memory, because when it calls sbrk()
it will recieve access to all the memory that the shared library is
already using for it's own heap!

The way I see it is that with shared libraries (just like DLL's on
Windows), your program code and any shared libraries/DLL that you link
to must all be linked to the same version of the C runtime library. Am I
seeing things correctly, or is this incorrect?

I imagine things get worse when we start trying to build X11 apps - is
there any way around this, or are we going to end up building apps
specifically for different versions of Linux? Ie: Red Hat 7.3, Red Hat
8.0, SUSE 8.0 etc etc?

--
Kendall Bennett
Chief Executive Officer
SciTech Software, Inc.
Phone: (530) 894 8400
http://www.scitechsoft.com

~ SciTech SNAP - The future of device driver technology!

John Reiser

unread,
Feb 19, 2003, 12:29:29 AM2/19/03
to
Kendall Bennett wrote:

> We have come across a rather nasty issue that I want to try and solve,
> but at present I don't have a clean solution. If I wish to compile a
> program on Red Hat 8.0 that will run on any Linux distribution, I really
> need to staticly link my program against glibc. If I link against the
> shared library version, I will need to distribute different versions of
> my program for all the different Linux platforms which have different
> versions of glibc, right?

Please change your goal slightly: be compatible with dynamic linking
to glibc-2.2 or later. This is back to autumn 2000, more than two
years ago, and covers all but the first month or so of RedHat Linux 7.0.
(For a brief period, RHL7.0 used glibc-2.1.94.) Please _do_ link -lc
and -lm and -ldl and -lX11 dynamically; but -lstdc++ and -lg++
[if needed] statically.

For each application a.out, do
nm -g a.out | grep GLIBC_
and see which symbol versions the app uses. Then figure out _why_.
The various GLIBC_* symbols show _where_ the application is not portable,
depending on which GLIBC_* versions are supplied by the various platforms.
Many times, the problem lies in the design of the app. For instance,
if the app uses the locale-adapting character functions such as isupper_l,
etc., then the app implicitly depends on GLIBC_2.3, which is quite new
(not even in RedHat Linux 7.3, for instance). The only symbol versions
beyond GLIBC_2.2 but before GLIBC_2.3 are
__nss_hostname_digits_dot@@GLIBC_2.2.2
sockatmark@@GLIBC_2.2.4
__rpc_thread_svc_max_poll@@GLIBC_2.2.3
pivot_root@@GLIBC_2.2.1
sprofil@@GLIBC_2.2.3
posix_openpt@@GLIBC_2.2.1
dl_iterate_phdr@@GLIBC_2.2.4
__nanosleep@@GLIBC_2.2.6
fnmatch@@GLIBC_2.2.3
__rpc_thread_svc_pollfd@@GLIBC_2.2.3
getgrouplist@@GLIBC_2.2.4
__rpc_thread_svc_fdset@@GLIBC_2.2.3
__rpc_thread_createerr@@GLIBC_2.2.3
Use of these is unlikely by an app that has any intention of being portable.
If the app uses the locale-adapting features of glibc-2.3+ [again: costly
in terms of field deployment] then extract those manually from libc.a
using /usr/bin/ar, and link statically with those *.o.

There may be hassles from gcc-3.x, which has versioned symbols
_Unwind_Find_FDE@@GCC_3.0
__register_frame_info_bas@@GCC_3.0
__deregister_frame_info_b@@GCC_3.0
__register_frame_info_tab@@GCC_3.0
but these should present a problem only for g++, and the app should link
-lstdc++ and -lg++ statically anyway because the runtime APIs of g++-3.[012]
and g++-2.95 are all mutually incompatible.

As a last resort: collect the needed files from RedHat Linux 7.3 (ld-linux.so.2,
libc.so.6, libc.a, all the crt*.o), modify a 'specs' file [see the output of
"gcc -v"] to produce a "gcc-compat-rhl7.3", and use that to build the app.

> [remainder snipped]

Paul Pluzhnikov

unread,
Feb 19, 2003, 1:05:17 AM2/19/03
to
Kendall Bennett <Kend...@scitechsoft.com> writes:

> We have come across a rather nasty issue that I want to try and solve,
> but at present I don't have a clean solution. If I wish to compile a
> program on Red Hat 8.0 that will run on any Linux distribution, I really
> need to staticly link my program against glibc. If I link against the
> shared library version, I will need to distribute different versions of
> my program for all the different Linux platforms which have different
> versions of glibc, right?

Wrong. Unless your program is extremely low-level, you could link
it against e.g. RedHat-6.2's glibc-2.1, and it will work on 99.9%
of installed systems.

> So static linking would seem to be the best solution, especially for
> smaller programs (these are console apps, not X11 apps).

Static linking is almost never a good solution. Things that
are likely to break have to do with host name resolution, NIS,
locales ...

> However things get complicated if there is a requirement that something
> be in a shared library. For instance for our XFree86 module, we need to
> do stuff that is Linux specific so we need to dlopen() a shared library
> to do what we need. As far as I can figure out, that shared library
> *must* be linked against the same version of glibc that the XFree86
> server itself is, or there will be serious problems.

Now you've opened a pandoras box: you are no longer talking about
static executable, and a dynamic one will have an ld-linux.so.2
dependency. A mismatch between the version of glibc you statically
linked into your exe and users installed ld-linux.so version will
result in anything from executable refusing to run, to crashes during
early startup, to subtle failures you will not notice immediately.

> I imagine things get worse when we start trying to build X11 apps - is
> there any way around this, or are we going to end up building apps
> specifically for different versions of Linux? Ie: Red Hat 7.3, Red Hat
> 8.0, SUSE 8.0 etc etc?

The easiest solution is to build on the lowest OS level you plan
to support. A slightly more complicated solution is to replicate
that "lowest level" environment on a more modern box.

Cheers,
--
In order to understand recursion you must first understand recursion.

Kieran O'Sullivan

unread,
Feb 19, 2003, 5:16:27 AM2/19/03
to
It is true that if you use share libs the person who runs your program
must have that lib installed or you must give it to them to install
but I have compiled many concole apps and run them on many different
flavours. My suggestions to you are:

1. Distribute the source code and let the people compile it
themselves.
2. Get your hands on a few old computers and install a couple of
Distros on them and try out your program. You are going to have to do
this for quality controle at some stage anyway.

I don't know the exact details of what you are writing but I think and
this is only an opinion that unless explicitly stated programs are
compiled using static libraries.

Kendall Bennett <Kend...@scitechsoft.com> wrote in message news:<0wB4a.1485$nz3.30...@newssvr13.news.prodigy.com>...

Wolfram Gloger

unread,
Feb 19, 2003, 5:35:28 AM2/19/03
to
Kendall Bennett <Kend...@scitechsoft.com> writes:

> We have come across a rather nasty issue that I want to try and solve,
> but at present I don't have a clean solution. If I wish to compile a
> program on Red Hat 8.0 that will run on any Linux distribution, I really
> need to staticly link my program against glibc. If I link against the
> shared library version, I will need to distribute different versions of
> my program for all the different Linux platforms which have different
> versions of glibc, right?

Not at all. John Reiser and Paul Pluzhnikov have explained this
already very well, I'm not going to repeat their points.

I'd just like to point out a few additional facts:

First of all, glibc is distributed under the LGPL. This means that if
you link something statically against it and distribute the resulting
binary, you _must_ provide a way for the recipient to re-link against
another version of glibc. So you would need at least to distribute
_another_ .o file with your executable that can be re-linked against
glibc. Using dynamic linking avoids this hassle and redundancy very
nicely.

> Consider malloc/free inside the shared library. If the shared library is
> staticly linked to a version of glibc, when the shared library loads it
> will initialise the heap itself using sbrk(), which will be at the end
> of the current heap for the program that loaded the shared library at
> the time the library is loaded.

Yes.

> Once the the shared library mallocs()
> any memory, that memory will be tromped on my the main program code if
> the program code also mallocs more memory, because when it calls sbrk()
> it will recieve access to all the memory that the shared library is
> already using for it's own heap!

No, there is no problem like this in general. The malloc
implementation in glibc is safe against "foreign" sbrk()'s, including
those from another instance of itself in the (e.g. dlopen()ed) shared
library. Whenever new memory needs to be allocated from the system,
the current brk value is checked, any "foreign" memory is reserved and
not touched by the implementation.

However, you could of course _not_ malloc() within your shared library
with its own malloc implementation, hand a pointer thus obtained to
the main program, and expect to be able to free() that memory from the
main program. Anyway, I assume this is not what you meant, instead I
suspect your shared library would be "self-contained" with regard to
dynamic memory.

This latter potential problem would of course also go away with
dynamic linking against libc. Just to state it again, dynamic linking
has huge advantages.

Regards,
Wolfram.

Moritz Franosch

unread,
Feb 19, 2003, 10:48:01 AM2/19/03
to

John Reiser <jre...@BitWagon.com> writes:

> Kendall Bennett wrote:
>
> > We have come across a rather nasty issue that I want to try and solve,
> > but at present I don't have a clean solution. If I wish to compile a
> > program on Red Hat 8.0 that will run on any Linux distribution, I really
> > need to staticly link my program against glibc. If I link against the
> > shared library version, I will need to distribute different versions of
> > my program for all the different Linux platforms which have different
> > versions of glibc, right?
>
> Please change your goal slightly: be compatible with dynamic linking
> to glibc-2.2 or later. This is back to autumn 2000, more than two
> years ago, and covers all but the first month or so of RedHat Linux 7.0.
> (For a brief period, RHL7.0 used glibc-2.1.94.) Please _do_ link -lc
> and -lm and -ldl and -lX11 dynamically; but -lstdc++ and -lg++
> [if needed] statically.

The OP could also link his program dynamically, look with ldd which
shared libraries it needs and distribute these together with your
program. Then the program ist started by a shell-script wrapper that
sets LD_LIBRARY_PATH accordingly.

This way the LGPL requirement that the user should be able to relink
with other library versions are fulfilled, because the user can change
the shell-script wrapper to point to his own shared
libraries. Libstdc++ is also no problem because the version needed
comes with the program.

The dlopen() problem could probably be solved if you dynamically link
against the glibc that comes with the user's system. Just ensure
compatibilility with older versions of glibc like John Reiser
described.


Moritz


--
Dipl.-Phys. Moritz Franosch
http://Franosch.org

John Reiser

unread,
Feb 19, 2003, 2:20:27 PM2/19/03
to
Moritz Franosch wrote:
>> Please _do_ link -lc
>> and -lm and -ldl and -lX11 dynamically; but -lstdc++ and -lg++
>> [if needed] statically.
>
>
> The OP could also link his program dynamically, look with ldd which
> shared libraries it needs and distribute these together with your
> program. Then the program ist started by a shell-script wrapper that
> sets LD_LIBRARY_PATH accordingly.
>
> This way the LGPL requirement that the user should be able to relink
> with other library versions are fulfilled, because the user can change
> the shell-script wrapper to point to his own shared
> libraries. Libstdc++ is also no problem because the version needed
> comes with the program.

That is a very good strategy: code for backward compatibility with older
glibc, link everything dynamically, ship and install a local copy of
any .so that the app uses (other than -lc/-lm/-ldl/-lX11 which is covered
by backward compatibility), provide a wrapper that sets LD_LIBRARY_PATH.
It may be the best strategy, particularly when users are technically adept.

But watch out. A running app then requires at least 3 pieces: the app,
the library(ies), the wrapper. Even with standards such as Linux
Standard Base, Filesystem Hierarchy Standard, etc., the opportunities for
trouble are much greater than if a running app requires "only" the a.elf.
Also, if the app instantiates any other executables (such as via system(),
popen(), or exec*()) then for best interoperability it is necessary to
_undo_ any app-specific changes to LD_LIBRARY_PATH before calling
system/popen/execve.

Kendall Bennett

unread,
Feb 19, 2003, 3:17:33 PM2/19/03
to
John Reiser wrote:

> Please change your goal slightly: be compatible with dynamic linking
> to glibc-2.2 or later. This is back to autumn 2000, more than two
> years ago, and covers all but the first month or so of RedHat Linux 7.0.
> (For a brief period, RHL7.0 used glibc-2.1.94.)

Whew, I am glad that someone has actually worked out a way to solve this
problem! We had problems just the other week when some RH 8.0 compiled
programs did not run on a SUSE install that a customer sent us for
development testing, so I probably over reacted to the problem ;-)

> Please _do_ link -lc and -lm and -ldl and -lX11 dynamically;
> but -lstdc++ and -lg++ [if needed] statically.

Ok. How would I got about changing the build environment so that
-lstdc++ and -lg++ are staticly linked into all my apps, but the others
are dynamic? I know how to use -static, but that makes all libs
statically linked.

> For each application a.out, do
> nm -g a.out | grep GLIBC_
> and see which symbol versions the app uses. Then figure out _why_.

Interesting. Right now my apps are pretty simple, but I get a bunch of
non GLIBC_2.0 stuff showing up in the symbol tables. Namely:

U __ctype_b_loc@@GLIBC_2.3
U __ctype_tolower_loc@@GLIBC_2.3
U fclose@@GLIBC_2.1
U fopen@@GLIBC_2.1

I assume the glibc 2.1 stuff should be OK (and I don't think I want to
stop using fopen/fclose!!), but what platforms will this work on? Is
there a place I can find out what Linux distro's use which versions of
GLIBC for compatibility purposes?

But how about the 2.3 stuff above? These are coming from the use of
<ctype.h> in my code, which is all basic ANSI C stuff. I can't exactly
not use this, unless I want to write my own portable ctype.h
implementation (which I could probably do if necessary). Any suggestions
on how to fix this?

> As a last resort: collect the needed files from RedHat Linux 7.3
> (ld-linux.so.2,
> libc.so.6, libc.a, all the crt*.o), modify a 'specs' file [see the
> output of
> "gcc -v"] to produce a "gcc-compat-rhl7.3", and use that to build the
> app.

So you are saying that if I build my files on Red Hat 7.3, that it would
be more upwards compatible with Red Hat 8.0 and other systems? In the
GLIBC installed on Red Hat 8.0, does it include the backwards compatible
functions for earlier versions of GLIBC (ie: fclose@@GLIBC_2.0 for
instance) so that stuff compiled with ealier versions will still run?

If so that is a *really* neat system! Which leads to my next question.
When I do an nm -a and grep for my own shared library functions, they
all show up as just plain old functions with versioning. How can I apply
the same versioning system that glibc uses so that I can also build
portable shared libraries so that we can better support future binary
compatibility with our shared libs?

Thanks!

Kendall Bennett

unread,
Feb 19, 2003, 3:27:39 PM2/19/03
to
Paul Pluzhnikov wrote:

> Wrong. Unless your program is extremely low-level, you could link
> it against e.g. RedHat-6.2's glibc-2.1, and it will work on 99.9%
> of installed systems.

Ok, that is good information to know. I was getting worried about
compatibility ;-)

> The easiest solution is to build on the lowest OS level you plan
> to support. A slightly more complicated solution is to replicate
> that "lowest level" environment on a more modern box.

What would be a good 'lowest OS level' to build and support with? I am
building with Red Hat 8.0 now, but perhaps I should go back to Red Hat
6.2 or something earlier? What would you recommend?

We also have issues with XFree86 4.0 that are similar to this, but I am
not sure there is a solution due to their strict module versioning.
Essentially if we build an XFree86 device driver module with 4.0, it
will only work with 4.0.x and we need to build a different module for
4.1.x and 4.2.x (at least that is what the XFree86 folks told me).

Thankfully the XFree86 driver modules are small, so our installer can
easily include all three compiled versions and then install the
necessary module when we detect what XFree86 4.x version is installed.

John Reiser

unread,
Feb 19, 2003, 7:17:52 PM2/19/03
to
Kendall Bennett wrote:
> > Please _do_ link -lc and -lm and -ldl and -lX11 dynamically;
> > but -lstdc++ and -lg++ [if needed] statically.
>
> Ok. How would I got about changing the build environment so that
> -lstdc++ and -lg++ are staticly linked into all my apps, but the others
> are dynamic? I know how to use -static, but that makes all libs
> statically linked.

"-Wl,-Bstatic -lstdc++ -lg++ -Wl,-Bdynamic" somewhere towards the end of
the link command (after all of the app's *.o, *.a, etc.) "-Wl," passes
loader-specific commands through gcc/g++. See "info ld" for -B.

>
>> For each application a.out, do
>> nm -g a.out | grep GLIBC_
>> and see which symbol versions the app uses. Then figure out _why_.
>
>
> Interesting. Right now my apps are pretty simple, but I get a bunch of
> non GLIBC_2.0 stuff showing up in the symbol tables. Namely:
>
> U __ctype_b_loc@@GLIBC_2.3
> U __ctype_tolower_loc@@GLIBC_2.3
> U fclose@@GLIBC_2.1
> U fopen@@GLIBC_2.1
>
> I assume the glibc 2.1 stuff should be OK (and I don't think I want to
> stop using fopen/fclose!!), but what platforms will this work on?

Any platform which has symbol version GLIBC_2.1 in libc.so. This is roughly
the class which includes RedHat Linux 6.2, approximately spring 2000,
nearly three years ago; and/or any subsequent glibc.

> Is there a place I can find out what Linux distro's use which versions of
> GLIBC for compatibility purposes?

Consult each distro. Often the heritage can be deduced from symlinks:
$ ls -l /lib/libc.so.6
lrwxrwxrwx 1 root root /lib/libc.so.6 -> libc-2.2.5.so
so that one is glibc-2.2.5.

>
> But how about the 2.3 stuff above? These are coming from the use of
> <ctype.h> in my code, which is all basic ANSI C stuff. I can't exactly
> not use this, unless I want to write my own portable ctype.h
> implementation (which I could probably do if necessary). Any suggestions
> on how to fix this?

Look at <ctype.h>, compile a few test routines, and figure out how
"tolower(c)" [etc.] got implemented as something involving __ctype_tlower_loc
[which is a function, by the way.] It looks like it has something to do
with __OPTIMIZE__, __NO_CTYPE, __cplusplus, etc. This is an example of
an area where the C standard and the glibc implementation are changing
under the feet of existing code. For instance, character classes
can be locale-dependent, and each thread can have its own locale!
However, the plain-vanilla, un-optimized example that I tried produced
a reference to tolower@@GLIBC_2.0 . Your app must be doing something else.

>
>> As a last resort: collect the needed files from RedHat Linux 7.3
>> (ld-linux.so.2,
>> libc.so.6, libc.a, all the crt*.o), modify a 'specs' file [see the
>> output of
>> "gcc -v"] to produce a "gcc-compat-rhl7.3", and use that to build
>> the app.
>
>
> So you are saying that if I build my files on Red Hat 7.3, that it would
> be more upwards compatible with Red Hat 8.0 and other systems? In the
> GLIBC installed on Red Hat 8.0, does it include the backwards compatible
> functions for earlier versions of GLIBC (ie: fclose@@GLIBC_2.0 for
> instance) so that stuff compiled with ealier versions will still run?

Yes, the libc.so in RHL8.0 has symbol versions all the way back to GLIBC_2.0.
In particular, there are both fclose@GLIBC_2.0 and fclose@@GLIBC_2.1.
The whole purpose of symbol versions is "forward compatibility": preserve
today's semantics in the face of changing standards, "bug fixes,"
new features, etc.

>
> If so that is a *really* neat system! Which leads to my next question.
> When I do an nm -a and grep for my own shared library functions, they
> all show up as just plain old functions with versioning. How can I apply
> the same versioning system that glibc uses so that I can also build
> portable shared libraries so that we can better support future binary
> compatibility with our shared libs?

$ info ld
* Scripts:: Linker Scripts
* VERSION:: VERSION Command

David Konerding

unread,
Feb 19, 2003, 8:25:04 PM2/19/03
to
In article <%MR4a.1687$gz4...@newssvr19.news.prodigy.com>, Kendall Bennett wrote:
> Paul Pluzhnikov wrote:
>
>> Wrong. Unless your program is extremely low-level, you could link
>> it against e.g. RedHat-6.2's glibc-2.1, and it will work on 99.9%
>> of installed systems.
>
> Ok, that is good information to know. I was getting worried about
> compatibility ;-)
>
>> The easiest solution is to build on the lowest OS level you plan
>> to support. A slightly more complicated solution is to replicate
>> that "lowest level" environment on a more modern box.
>
> What would be a good 'lowest OS level' to build and support with? I am
> building with Red Hat 8.0 now, but perhaps I should go back to Red Hat
> 6.2 or something earlier? What would you recommend?

Empirically, I found building on Red Hat 7.3 got a good level of compatibility
across distributions. But you could get a very similar result by installing the compat-*
compiler and libraries on a 8.x system and back-build a 7.3 app that way.

Dave

Paul Pluzhnikov

unread,
Feb 20, 2003, 1:05:20 AM2/20/03
to
Kendall Bennett <Kend...@scitechsoft.com> writes:

> Paul Pluzhnikov wrote:
>
> > The easiest solution is to build on the lowest OS level you plan
> > to support.
>

> What would be a good 'lowest OS level' to build and support with?

I have not seen any problems related to our building on an RH 6.2
box within last 3 years. This also depends on your audience,
I think ... Larger customer organizations may have a tendency to
lag behind. I would be very surprized to find anybody running
releases before RH 7.3, but YMMV.

I recently visited a telephone call center, that runs 50+ operators
on an ancient (1993) DECsystem with 64MB of RAM and 1GB disk.
The system is no longer supported, the HW manufacturer has been
subsumed twice, the software writers are nowhere to be found,
but the system just keeps on ticking (or rather ringing the
phones ;-)

Kendall Bennett

unread,
Feb 20, 2003, 5:58:42 PM2/20/03
to
John Reiser wrote:

> "-Wl,-Bstatic -lstdc++ -lg++ -Wl,-Bdynamic" somewhere towards the end of
> the link command (after all of the app's *.o, *.a, etc.) "-Wl," passes
> loader-specific commands through gcc/g++. See "info ld" for -B.

Ok thanks, I will try doing that and see what happens.

What about X11 libraries and so on. What do people do for maintaining
backwards compatbility with X programs? The next project involves an X11
binary, so I will need to solve that next ;-)

> > I assume the glibc 2.1 stuff should be OK (and I don't think I want to
> > stop using fopen/fclose!!), but what platforms will this work on?
>
> Any platform which has symbol version GLIBC_2.1 in libc.so. This is
> roughly
> the class which includes RedHat Linux 6.2, approximately spring 2000,
> nearly three years ago; and/or any subsequent glibc.

Awesome, that sounds good enough for me ;-) The full source to our
shared library will be available anyway (and for most of the programs
actually), so people should be able to recompile nearly everything
anyway if they really need to.

> > But how about the 2.3 stuff above? These are coming from the use of
> > <ctype.h> in my code, which is all basic ANSI C stuff. I can't exactly
> > not use this, unless I want to write my own portable ctype.h
> > implementation (which I could probably do if necessary). Any suggestions
> > on how to fix this?
>
> Look at <ctype.h>, compile a few test routines, and figure out how
> "tolower(c)" [etc.] got implemented as something involving
> __ctype_tlower_loc
> [which is a function, by the way.] It looks like it has something to do
> with __OPTIMIZE__, __NO_CTYPE, __cplusplus, etc. This is an example of
> an area where the C standard and the glibc implementation are changing
> under the feet of existing code. For instance, character classes
> can be locale-dependent, and each thread can have its own locale!
> However, the plain-vanilla, un-optimized example that I tried produced
> a reference to tolower@@GLIBC_2.0 . Your app must be doing something else.

Ok. So you are saying it could be something related to building with
optimisations on? We always build with -02 for optimized builds, and I
don't think we are doing anything especially complicated with the
ctype.h stuff we are using (just convering to lowercase etc). I will
play around with the code and see what I can figure out.

> Yes, the libc.so in RHL8.0 has symbol versions all the way back to
> GLIBC_2.0.
> In particular, there are both fclose@GLIBC_2.0 and fclose@@GLIBC_2.1.
> The whole purpose of symbol versions is "forward compatibility": preserve
> today's semantics in the face of changing standards, "bug fixes,"
> new features, etc.

Very neat!

Kendall Bennett

unread,
Feb 20, 2003, 5:59:27 PM2/20/03
to
David Konerding wrote:

>>What would be a good 'lowest OS level' to build and support with? I am
>>building with Red Hat 8.0 now, but perhaps I should go back to Red Hat
>>6.2 or something earlier? What would you recommend?
>
> Empirically, I found building on Red Hat 7.3 got a good level of compatibility
> across distributions. But you could get a very similar result by installing the compat-*
> compiler and libraries on a 8.x system and back-build a 7.3 app that way.

Ok. So it should be possible to install RH 7.3 compatible libraries,
headers and compiler onto my RH8.0 system? Are they on the RH8.0 CD's?
Or do I need to download and build this stuff myself?

David Konerding

unread,
Feb 21, 2003, 10:41:03 AM2/21/03
to
In article <j5d5a.1180$nd5...@newssvr16.news.prodigy.com>, Kendall Bennett wrote:
> David Konerding wrote:
>
>>>What would be a good 'lowest OS level' to build and support with? I am
>>>building with Red Hat 8.0 now, but perhaps I should go back to Red Hat
>>>6.2 or something earlier? What would you recommend?
>>
>> Empirically, I found building on Red Hat 7.3 got a good level of compatibility
>> across distributions. But you could get a very similar result by installing the compat-*
>> compiler and libraries on a 8.x system and back-build a 7.3 app that way.
>
> Ok. So it should be possible to install RH 7.3 compatible libraries,
> headers and compiler onto my RH8.0 system? Are they on the RH8.0 CD's?
> Or do I need to download and build this stuff myself?
>

Yeah, they are there.

compat-gcc-7.3-2.96.110.i386.rpm
compat-gcc-c++-7.3-2.96.110.i386.rpm
compat-libstdc++-7.3-2.96.110.i386.rpm
compat-libstdc++-devel-7.3-2.96.110.i386.rpm

When you compile such an app, it should in principle produce an app that
runs compatibly on 7.3. 7.3 even had 6.2 compat libs, you could use a
hosting 7.3 system to build 7.3 and 6.2 binaries, both of which should
also in principle run fairly compatibly on an 8.0 system.

We ended up just building 6.2, 7.3, and 8.0 systems in VMware partitions, and
built executables in the partitions. It's easier and cheaper than dedicating hardware,
especially when you want to test on a fresh install- just use the nonpersistent
disk configuration.

Kendall Bennett

unread,
Mar 20, 2003, 6:17:01 PM3/20/03
to
David Konerding wrote:

>>Ok. So it should be possible to install RH 7.3 compatible libraries,
>>headers and compiler onto my RH8.0 system? Are they on the RH8.0 CD's?
>>Or do I need to download and build this stuff myself?
>
> Yeah, they are there.
>
> compat-gcc-7.3-2.96.110.i386.rpm
> compat-gcc-c++-7.3-2.96.110.i386.rpm
> compat-libstdc++-7.3-2.96.110.i386.rpm
> compat-libstdc++-devel-7.3-2.96.110.i386.rpm

I have installed all the above and all I end up with is a gcc296 install
which allows me to build with the back level compiler. The resulting
executeables will *not* run on Red Hat 7.3 because they are still using
the glibc 2.3 version that comes with Red Hat 8.0. Hence I need to know
if there is a package that can be installed to install the glibc version
from Red Hat 7.3 for building 7.3 compatible code from Red Hat 8.0.

To me this must be pretty obvious, since without the 7.3 libs you can't
build compatible code! However I can't seem to find any documentation
about this anywhere on the Red Hat web site.

Thanks!

David Konerding

unread,
Mar 20, 2003, 8:13:46 PM3/20/03
to
In article <NZrea.3963$5L6.27...@newssvr15.news.prodigy.com>, Kendall Bennett wrote:
> David Konerding wrote:
>
>>>Ok. So it should be possible to install RH 7.3 compatible libraries,
>>>headers and compiler onto my RH8.0 system? Are they on the RH8.0 CD's?
>>>Or do I need to download and build this stuff myself?
> >
>> Yeah, they are there.
>>
>> compat-gcc-7.3-2.96.110.i386.rpm
>> compat-gcc-c++-7.3-2.96.110.i386.rpm
>> compat-libstdc++-7.3-2.96.110.i386.rpm
>> compat-libstdc++-devel-7.3-2.96.110.i386.rpm
>
> I have installed all the above and all I end up with is a gcc296 install
> which allows me to build with the back level compiler. The resulting
> executeables will *not* run on Red Hat 7.3 because they are still using
> the glibc 2.3 version that comes with Red Hat 8.0. Hence I need to know
> if there is a package that can be installed to install the glibc version
> from Red Hat 7.3 for building 7.3 compatible code from Red Hat 8.0.
>
> To me this must be pretty obvious, since without the 7.3 libs you can't
> build compatible code! However I can't seem to find any documentation
> about this anywhere on the Red Hat web site.

It actually worked just fine for me for "Hello World" cases. I wrote test.c and test.C:

dek@master:~
:cat test.c
#include <stdio.h>
int main(void) {
printf("Hello world\n");
exit(0);
}

dek@master:~
:cat test.C
#include <iostream.h>
int main(void) {
cout << "Hello world" << endl;
exit(0);
}


and then compiled them:
1004 /usr/bin/i386-redhat-linux7-gcc test.c -o testc
1016 /usr/bin/i386-redhat-linux7-g++ test.C -o testC

then copied them to a 7.3 box and they ran just fine.


Can you confirm that at least these simple test cases work OK on your system?
On mine, the testc app is dynamically linked against libc.so.6

One possibility, which should be dealt with using the compat rpms, is
symbols which are multiply versioned in the newer library- the versions
compatible with the RH73 libs should be linked in.

You're not actually trying to link statically are you? Then, you'd have
to make sure you have a copy of the static library you were linking in.
Also, any other libraries that you wanted to link in, such as jpeg,
tiff, etc, would have to be the appropriate 7.3 versions, not 8.0


Problems like this are why some of us always use VMware :-)

Dave

Kendall Bennett

unread,
Mar 20, 2003, 8:22:19 PM3/20/03
to
David Konerding wrote:

> It actually worked just fine for me for "Hello World" cases. I wrote test.c and test.C:

Yes, Hello World works just fine. As I have discovered, all of the
problems actually turn out to be problems with <ctype.h>. I don't think
RedHat realised that the <ctype.h> in their glibc 2.2.93 thinks that it
should be using the GLIBC_2.3 interaces which are not backwards
compatible with earlier versions of glibc. Since they shipped 2.2.5 on
RedHat 7.3, they probably figured they should be compatible (which they
appear to be, except for <ctype.h>).

My solution (after not being able to get 6.2 compat libraries working
either!) was simply to steal the <ctype.h> header file from a RedHat 7.3
install. Once I did that, my Red Hat 8.0 compiled binaries run just fine
on nearly all systems I have tested.

But still, it doesn't solve the problem that for *real* backwards
compatibility they should have created a glibc 7.3 compatibility library
like they did for 6.2 libraries on 7.3.

David Konerding

unread,
Mar 21, 2003, 1:31:38 PM3/21/03
to
In article <fPtea.3991$_E7.274...@newssvr15.news.prodigy.com>, Kendall Bennett wrote:
> David Konerding wrote:
>
>> It actually worked just fine for me for "Hello World" cases. I wrote test.c and test.C:
>
> Yes, Hello World works just fine. As I have discovered, all of the
> problems actually turn out to be problems with <ctype.h>. I don't think
> RedHat realised that the <ctype.h> in their glibc 2.2.93 thinks that it
> should be using the GLIBC_2.3 interaces which are not backwards
> compatible with earlier versions of glibc. Since they shipped 2.2.5 on
> RedHat 7.3, they probably figured they should be compatible (which they
> appear to be, except for <ctype.h>).
>
> My solution (after not being able to get 6.2 compat libraries working
> either!) was simply to steal the <ctype.h> header file from a RedHat 7.3
> install. Once I did that, my Red Hat 8.0 compiled binaries run just fine
> on nearly all systems I have tested.
>
> But still, it doesn't solve the problem that for *real* backwards
> compatibility they should have created a glibc 7.3 compatibility library
> like they did for 6.2 libraries on 7.3.
>

That's probably correct and I think they did do that for RH73->RH62 compat
(there is a compat-glibc package).

Dave

Reply all
Reply to author
Forward
0 new messages