Essa postagem do blog é muito imprecisa.
Pelo que eu sei, mudanças no C ++ ABI foram introduzidas com cada versão principal do GCC (ou seja, aqueles com componentes de número de primeira ou segunda versão diferentes).
Não é verdade. As únicas alterações do C ++ ABI introduzidas desde o GCC 3.4 são compatíveis com versões anteriores, o que significa que o C ++ ABI está estável há quase nove anos.
Para piorar as coisas, a maioria das principais distribuições do Linux usa instantâneos do GCC e / ou corrige suas versões do GCC, tornando virtualmente impossível saber exatamente com quais versões do GCC você pode estar lidando ao distribuir binários.
As diferenças entre as versões corrigidas das distribuições do GCC são menores e não mudam o ABI, por exemplo, o 4.6.3 20120306 do Fedora (Red Hat 4.6.3-2) é ABI compatível com as versões upstream do FSF 4.6.x e quase certamente com qualquer 4.6. x de qualquer outra distro.
No GNU / Linux, as bibliotecas de tempo de execução do GCC usam a versão de símbolo ELF para que seja fácil verificar as versões de símbolo necessárias para objetos e bibliotecas, e se você tiver um libstdc++.so
que fornece esses símbolos ele funcionará, não importa se é uma versão com patch ligeiramente diferente de outra versão da sua distro.
mas nenhum código C ++ (ou qualquer código que use o suporte de tempo de execução C ++) pode ser vinculado dinamicamente se isso funcionar.
Isto também não é verdade.
Dito isso, vincular estaticamente a libstdc++.a
é uma opção para você.
O motivo pelo qual pode não funcionar se você carregar dinamicamente uma biblioteca (usando dlopen
) é que os símbolos libstdc ++ dos quais ela depende podem não ter sido necessários para seu aplicativo quando você o vinculou (estaticamente), portanto, esses símbolos não estarão presentes em seu executável. Isso pode ser resolvido vinculando dinamicamente a biblioteca compartilhada ao libstdc++.so
(o que é a coisa certa a se fazer de qualquer maneira se depender disso). A interposição de símbolo ELF significa que os símbolos que estão presentes em seu executável serão usados pela biblioteca compartilhada, mas outros não presente em seu executável será encontrado em qualquer libstdc++.so
link para o qual ele esteja vinculado. Se seu aplicativo não usadlopen
você não precisa se preocupar com isso.
Outra opção (e a que eu prefiro) é implantar o mais recente libstdc++.so
junto com seu aplicativo e garantir que ele seja encontrado antes do sistema padrão libstdc++.so
, o que pode ser feito forçando o vinculador dinâmico a procurar no lugar certo, usando $LD_LIBRARY_PATH
a variável de ambiente em run- tempo, ou definindo um RPATH
no executável no momento do link. Prefiro usar RPATH
, pois não depende do ambiente estar configurado corretamente para o aplicativo funcionar. Se você vincular seu aplicativo com '-Wl,-rpath,$ORIGIN'
(observe as aspas simples para evitar que o shell tente se expandir $ORIGIN
), o executável terá um RPATH
dos $ORIGIN
que informa ao vinculador dinâmico para procurar bibliotecas compartilhadas no mesmo diretório que o próprio executável. Se você colocar o mais recentelibstdc++.so
no mesmo diretório do executável ele será encontrado em tempo de execução, problema resolvido. (Outra opção é colocar o executável em /some/path/bin/
e o libstdc ++ mais recente. Assim, em/some/path/lib/
e vincular com '-Wl,-rpath,$ORIGIN/../lib'
ou qualquer outro local fixo em relação ao executável e definir o RPATH em relação a $ORIGIN
)
-static-libstdc++
opção, você simplesmente usaria-static