Cet exemple se compose de plusieurs fichiers:Force un agent de liaison à l'échec d'une erreur multiple de définition, même si, y compris --whole-archives
// baz.cxx
int wat = 0;
int counter = ++wat;
// foo.cxx (empty)
// bar.cxx (empty)
// main.cxx
#include <iostream>
extern int wat;
int main() {
std::cout << wat << '\n';
}
// makefile
run : main.cxx foo.so bar.so
g++ -std=c++11 $^ -o [email protected]
baz.a : baz.cxx
g++ -std=c++11 -c $^ -o baz.o -fPIC
ar rcs [email protected] baz.o
%.so : %.cxx baz.a
g++ -std=c++11 $< -Wl,--whole-archive baz.a -Wl,--no-whole-archive -o [email protected] -shared -fPIC
En l'état, si vous exécutez simplement make && LD_LIBRARY_PATH=. ./run
, tout avec compiler, construire, lier, exécuter et afficher 2
. En effet, les deux foo.so
et bar.so
fournissent wat
et l'initialisation pour counter
est exécutée deux fois.
Y at-il un moyen de forcer en quelque sorte run
à ne pas faire le lien avec une erreur multiple de définition dans ce cas, tout en veillant à ce que les deux foo.so
et bar.so
ont une définition pour wat
?
Pas vraiment une solution mais peut-être pourriez-vous mettre le code d'initialisation dans un constructeur pour une classe statique qui vérifie si elle a déjà été initialisée et ne l'initialise pas à nouveau? – Curious
@Curious Ouais, c'est une option. Cela semble plutôt affreux cependant et j'aimerais vraiment beaucoup ne pas le faire. Le laisser en dernier recours. – Barry
La sortie est '1', pour moi, avec g ++ 4.9.2, 5.4.1, 6.2.0, 6.3.0, 7.0.1, GNU ld 2.26.1, 2.28, ubuntu 16.04, 17.04. –