Reputation: 121
This in in C++:
A static library "A" defines a global variable foo.
"B" and "C" are two dynamics libraries both depending on A hence linking (statically) with A.
Then B and C end up loaded in the same process (ex: Application loads B and C).
If we are in a windows environment, we will obtain two different instance of foo, one in B and one in C as clearly explained here:
Shared global variable in C++ static library
What about a Linux environment.
Context: We are currently porting a windows project to linux
Upvotes: 4
Views: 4616
Reputation: 9335
Each library will ship include a copy of A. However, at runtime only one will be used by all the components of the process.
// h.h
extern int a;
void b(void);
void c(void);
// a.c
#include "h.h"
int a = 0;
// b.c
#include <stdio.h>
#include "h.h"
void b(void)
{
printf("%i\n", a++);
}
// c.c
#include <stdio.h>
#include "h.h"
void c(void)
{
printf("%i\n", a++);
}
//main.c
#include <stdio.h>
#include "h.h"
int main()
{
b();
c();
}
#Makefile
main: libxc.so libxb.so
cc -o main main.c -L. -lxc -lxb
libxb.so:
cc -fPIC -shared a.c b.c -o libxb.so
libxc.so:
cc -fPIC -shared a.c c.c -o libxc.so
$make $ LD_LIBRARY_PATH=. ./main 0 1
Symbol table from libxa.so
:
53: 000000000020098c 4 OBJECT GLOBAL DEFAULT 24 a
From libxc.so
:
53: 000000000020098c 4 OBJECT GLOBAL DEFAULT 24 a
The default visibility is STV_DEFAULT
which according to LSB:
STV_DEFAULT
: The visibility of symbols with theSTV_DEFAULT
attribute is as specified by the symbol's binding type. That is, global and weak symbols are visible outside of their defining component (executable file or shared object). Local symbols are hidden, as described below. Global and weak symbols are also preemptable, that is, they may by preempted by definitions of the same name in another component.
man 5 elf
:
STV_DEFAULT
: Default symbol visibility rules. Globa and weak symbols are available to other modules; references in the local module can be interposed by definitions in other modules.
About the SysV ABI:
When resolving symbolic references, the dynamic linker examines the symbol tables with a breadth-first search. That is, it first looks at the symbol table of the executable program itself, then at the symbol tables of the
DT_NEEDED
entries (in order), then at the second level DT_NEEDED
entries, and so on.
If that's not what's expected, using STV_HIDDEN
on the symbol prevents it from behind visible outside of the shared object.
In contrast, on Windows a symbol is always imported from a given DLL and the symbols are not exported to other DLLs by default anyway.
Upvotes: 1