0

On Windows this can be done (though not recommended since pass c standard library object between different c library instances can have problem), like this:

Every executable image (EXE or DLL) can have its own statically linked CRT, or can dynamically link to a CRT. The version of the CRT statically included in or dynamically loaded by a particular image depends on the version of the tools and libraries it was built with. A single process may load multiple EXE and DLL images, each with its own CRT

Can this be done on Linux?

Does this mean false? But a general system like Linux should not have such restrictions right? For example, what if codebase A and codebase B really need different version of libc to work well and suppose they both have very simple C style API for the clients (i.e. no pointer parameter in those APIs)?

If it is not possible, then there is no need to read the following.

As a first step toward this goal, when I tried to build a shared library with static linked libc:

 g++ -fPIC -Wall -fexceptions -g  -c main.cpp -o main.o
 g++ -shared -static  main.o  -o libtestCppSharedLib.so
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginT.o: relocation R_X86_64_32 against hidden symbol `__TMC_END__' can not be used when making a shared object
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
jw_
  • 1,663
  • 18
  • 32
  • Statically linked libraries are included in the resulting binary, so there is no problem with two binaries statically linked to different libraries. Interesting is the case that (as you linked) such a statically linked library has a reference to a dynamic library. AFAIK such references include the version number of the dynamic library such that the required interface is satisfied. Multiple versions of a dynamic library can exist on a Linux system. – the busybee Apr 08 '21 at 06:03
  • @thebusybee But the lib considered here is a very special lib: libc. Libc have relations with the loading/initialization/syscall process, so the problem for libc may be not trivial – jw_ Apr 08 '21 at 07:17
  • Sure, but if multiple versions of libc exist and work on the specific system, why should an application with references to them not work? For example, if the application references a newer version of libc and a statically linked library references an older version of libc? – the busybee Apr 08 '21 at 07:25
  • 1
    I can think of some special case that needs a specific sequence of systems calls made by the application and the statically linked library, which might not work because the different referenced versions of libc are not compatible. In this case you need to dynamically link the application to the libc that the library references, I think. – the busybee Apr 08 '21 at 07:25
  • Please tell why you want to do so. It is against every usual Linux practice. Read Drepper's paper [*How to write shared libraries*](https://www.akkadia.org/drepper/dsohowto.pdf) – Basile Starynkevitch Apr 08 '21 at 17:04
  • @thebusybee "I can think of ... not compatible" Can you give some more detailed example (no need to be real)? – jw_ Apr 23 '21 at 01:07
  • @BasileStarynkevitch For now it is do some "bare metal experiments" to learn about the linking process and their limitations. – jw_ Apr 23 '21 at 01:30
  • For example, your application requests a resource of the system with the first libc, which executes some specific system calls. But the application uses or frees this resource by a function of the statically linked library with the second libc, which works in a incompatible way and executes more, less, or other system calls than the first libc. – the busybee Apr 23 '21 at 05:34
  • @thebusybee If the client code use libc in a way that libc resources (e.g. FILE* and pointers returned by malloc/new operator) are not shared between libc instances (as mentioned in OP), can this still happen? – jw_ Apr 23 '21 at 10:00
  • Do you know `errno`? It is a static variable, but I'm not sure if it is shared between all loaded libc instances of one application. For example, if the application calls a function in the static library linked to one libc and this fails and sets `errno`, and your application then reads `errno`, but it is retrieved from its version of libc, are you sure both are the same variable? It's not especially a question of pointers, it could be anything. -- To bring this to an end: I have no personal experience with such scenarios, just wanted to say "be careful, expect any problem". – the busybee Apr 23 '21 at 12:18
  • @thebusybee That's still the case that I mentioned, errno is a libc resource which should be used only in one libc instance. If some code in the app use some function in a libc instance, the code that check errno for the result should use the same instance of libc, e.g. they are in the same shared library that is linked to some version of libc. – jw_ Apr 23 '21 at 13:42

1 Answers1

3

Can this be done on Linux?

In theory: yes. In practice: no.

None of libc versions available on Linux are designed to support having multiple copies of the library in a single process.

In addition, UNIX and Linux use very different linking model, compared to Windows DLLs.

Under Windows, a DLL is a self-contained unit -- only functions and variables explicitly exported from it are visible from outside, and calling a function defined in the DLL will always result in calling that function (no symbol interpositioning).

Under the UNIX model, everything in a shared library is exported by default, and calling a function defined in the same library may or may not resolve to that function at runtime.

what if codebase A and codebase B really need different version of libc to work well a

The libc provides a standard interface. If A requires a specific version of libc to work well, it's broken. The UNIX philosophy is that you should fix A or B (or both).

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • The conclusion may be true which I will verify later, but there may be some problem in the reasoning: (1) "None of libc ..." Commonly a library need not to be designed to work in this way to work in this way, they just work in this way in most case. They only break down on some special case - but what are the special cases for gcc - do they exist? – jw_ Apr 23 '21 at 01:24
  • 1
    (2) "Under the UNIX model, everything in a shared library is exported", the visibility flags and attributes can solve the problem, for libc to be statically linked, the libc instances only serve clients in the shared library it is linked to and won't export the symbols, and the the clients in shared libraries with statically linked libc will use that libc, there is no dynamic linking problems for those clients. And the clients in the main executable and shared libraies without libc will use the shared version of libc with dynamic linking. – jw_ Apr 23 '21 at 01:28