As bibliotecas estáticas C são desaprovadas? [fechadas]

11

Existem 2 argumentos para ter bibliotecas compartilhadas:

  1. Ajuda a reduzir o espaço em disco.
  2. Quando uma biblioteca compartilhada é atualizada, todos os binários, dependendo dela, recebem a atualização.

Existe principalmente uma desvantagem para bibliotecas compartilhadas:

  • Eles (podem) introduzir o inferno da dependência.

Em computadores de mesa, a primeira vantagem não é mais válida. A perda de espaço em disco não é um problema nos dias de hoje.

Ter binários estáticos nos permitiria obter melhores gerenciadores de pacotes - quero dizer, o inferno da dependência seria uma coisa do passado. Adicionar um programa seria apenas adicionar um binário; eventualmente uma pasta para permitir que ele lide com seus arquivos. Excluir um programa seria simplesmente excluir este arquivo. Dependências? Se foi.

A segunda vantagem ainda permanece, mas acho que a vantagem dos binários estáticos em computadores desktop a supera. Quero dizer, mesmo novas linguagens como Go compilam todos os seus binários, apesar das vantagens das bibliotecas compartilhadas, devido à conveniência.


Como uma das principais vantagens das bibliotecas compartilhadas não é mais um grande problema, as bibliotecas estáticas C ainda são desaprovadas? Se sim, por quê?

Florian Margaine
fonte
4
O principal motivo pelo qual C é mais usado é especificamente porque você não está trabalhando em computadores desktop modernos.
Telastyn 28/08/2014
18
@Telastyn me desculpe? A maioria do software instalado em meus computadores de mesa está escrito em C.
Florian Margaine
6
Side bit - uma leitura fora do local sobre o assunto - Link dinâmico considerado nocivo
6
Um benefício das bibliotecas dinâmicas é que as pessoas ainda podem atualizar as bibliotecas para solucionar bugs, falhas de segurança ou problemas de hardware em seu jogo de código fechado de 15 anos que há muito tempo parou de receber atualizações. É um caso de nicho, mas como bons jogos não são mercadorias, "basta usar outro programa" não ajuda. Também é importante cumprir a LGPL sem fornecer código-fonte aberto.
Doval
4
Você esqueceu duas outras vantagens das bibliotecas compartilhadas: 1) elas também são compartilhadas na memória; 2) todos os vinculadores são péssimos, e vincular um binário enorme é altamente desagradável. Dividir um binário em várias entidades menores torna todo o processo muito mais tolerável.
SK-logic

Respostas:

9

A premissa da sua pergunta é falha. O que é desaprovado é aderir a doutrinários e absolutos sem entender a base por trás deles (Programação de Cult de Carga?).

A resposta do SO vinculada é um estudo interessante nesse mesmo tópico - a pergunta era sobre por que uma opção compilar com - estática não estava funcionando, a resposta à qual você vinculou nada mais era do que um discurso retórico sobre não usar vinculação estática. Se não discute por que está ruim, e exige que o OP use a vinculação dinâmica. É lamentável que esteja marcada como a resposta correta (a resposta a seguir tem o dobro de votos e a resposta correta à pergunta do OP) porque, embora a resposta correta esteja lá, ela está profundamente escondida entre uma opinião dogmática.

A verdadeira questão é quais são os prós e os contras da vinculação estática versus dinâmica e quando um seria preferido em relação ao outro.

mattnz
fonte
2
A resposta de Basile faz dizer-lhe exatamente por que ele recomenda o uso de bibliotecas compartilhadas: ? "Por que você deseja vincular estaticamente a sua aplicação . Em geral, é um erro (porque você não fazer lucro de atualizações para as bibliotecas dinâmicas do sistema) Em particular interruptor de serviço de nome instalações da libc querem bibliotecas dinâmicas. " Não é um" discurso retórico "só porque você discorda.
Cody Gray
@Cody A resposta vinculada foi editada desde que eu a chamei de discurso retórico. A única opinião que tenho sobre a vinculação estática versus dinâmica é usar a que é mais apropriada para suas necessidades e entender os pontos fortes e fracos da escolha, em vez de cair na doutrina de programação de cultos de carga, porque "alguém disse isso".
mattnz
Sim, a parte "Em particular ..." foi adicionada. Não tenho certeza de como isso afeta seu status de discurso retórico. Claro que não estou defendendo programação de cultos de carga. É justamente que os defensores da vinculação estática (na minha experiência) geralmente ignoram ou subestimam as preocupações de segurança. A vinculação estática pode ser muito apropriada para utilitários únicos, tornando o aplicativo independente e, portanto, a distribuição muito mais fácil. Mas qualquer aplicativo que será amplamente implantado ou usado para produção deve realmente vincular-se a uma biblioteca compartilhada. Não há desvantagens reais: nesse nível de aplicativo, você já precisa de um processo de implantação.
Cody Gray
1
Um bom exemplo de onde a vinculação estática é apropriada é onde eu trabalho - sistemas grandes e complexos de vida crítica. Depois que um módulo crítico é testado e aprovado para operação, seu comportamento não deve mudar sem passar pelo 'processo'. No entanto, nenhuma parte operacional e não vital do sistema (cobrança e relatório) precisa de um controle menos robusto e usa ligação dinâmica.
mattnz
7

Do ponto de vista do desenvolvedor, o vínculo dinâmico geralmente pode acelerar consideravelmente o loop de compilação / link / teste.

Do ponto de vista do gerenciamento de pacotes, considere a libGL, por exemplo. Eu tenho aproximadamente uma dúzia de implementações diferentes disponíveis no meu gerenciador de pacotes, algumas genéricas e outras direcionadas para placas gráficas específicas. Se não estivesse vinculado dinamicamente, haveria uma dúzia de versões de cada programa vinculado ao libGL, ou então seria necessário criar uma camada adicional de abstração que não seja tão eficiente quanto uma chamada de função.

Pense em um problema de segurança em uma biblioteca popular como o Qt. Com o vínculo dinâmico, posso apenas atualizar esse pacote, em vez de precisar identificar, recompilar e implantar todos os pacotes vinculados no Qt.

O link estático pode ter vantagens em aplicativos de código fechado implantados independentemente, mas no gerenciamento de pacotes de código aberto isso prejudica mais do que ajuda.

Karl Bielefeldt
fonte
2
Isso é verdade (acelerando o desenvolvimento), mas é realmente frustrante que ele entre em produção. O exemplo canônico é o Firefox. A quantidade de esforços de engenharia (na forma de hackers hediondos) que foram usados ​​para acelerar a resolução dinâmica de símbolos de vinculação, de forma que o Firefox carrega em tempo razoável, é totalmente louco. Um desempenho muito melhor poderia ter sido alcançado com muito menos custo de engenharia se eles estivessem dispostos a vincular estática todo o seu código no projeto (enquanto ainda vinculam bibliotecas e plug-ins de sistema dinâmicos, se desejado).
R .. GitHub Pare de ajudar o gelo
5

Bibliotecas compartilhadas são fortemente preferidas pelos mantenedores de distribuição do Linux, basicamente pelo seu motivo nº 2. É realmente importante para eles que, por exemplo, quando alguém encontra um bug de segurança no zlib , ele não precisa recompilar todos os programas que usam o zlib - isso não apenas lhes custaria mais ciclos de CPU para fazer o recompilando, todo mundo que usa a distribuição precisa baixar novamente todos esses programas. Enquanto isso, dentro do conjunto de pacotes fornecidos por uma distribuição, o inferno das dependências não é um problema, porque tudo é testado para funcionar com esse conjunto de bibliotecas.

Se você estiver criando software de terceiros que precisa de bibliotecas que não estão na sua distribuição, vincular estaticamente essas bibliotecas pode ser menos incômodo do que a alternativa, e isso é bom.

A outra coisa importante a saber é que o GNU libce o GCC libstdc++possuem componentes que não funcionam de maneira confiável se a biblioteca estiver vinculada estaticamente. O problema mais comum é com dlopen, porque qualquer módulo com o qual você carrega dlopené vinculado dinamicamentelibc.so.6 . Portanto, isso significa que agora você tem duas cópias da biblioteca C em seu espaço de endereço, e a hilaridade ocorre quando eles não concordam com qual cópia da mallocestrutura de dados interna (por exemplo) é autoritativa. Fica pior: várias funções que parecem não ter nada a ver com dlopen, como gethostbynamee iconvusamdlopeninternamente (para que seu comportamento seja configurável em tempo de execução). Felizmente, a ABI para libc e libstdc ++ é muito estável, portanto, é improvável que você encontre problemas vinculando-os dinamicamente.

zwol
fonte
2

Eu concordo com o último ponto de mattnz: esta questão é uma pergunta carregada. Ele pressupõe que a vinculação estática seja ruim. Posso pensar em duas razões pelas quais esse não é o caso:

  • A vinculação estática é segura: se uma biblioteca compartilhada for atualizada de forma que um aplicativo use a nova (talvez a nova substitua a antiga ou a antiga seja removida), isso poderá gerar riscos de que a nova versão interrompa o aplicativo. Esta é uma alteração de código fora do escopo de uma atualização oficial para o aplicativo. Pode não ter sido testado. A vinculação estática evita isso, não compartilhando bibliotecas externamente. Considero que isso é uma desvantagem para as bibliotecas compartilhadas devido a esse risco. E se uma nova versão de uma biblioteca compartilhada introduzir um novo bug que quebre alguns aplicativos mais antigos?

  • A vinculação estática garante que um aplicativo seja mais independente. Embora as bibliotecas compartilhadas possam ser colocadas com o executável principal, geralmente elas são depositadas em locais compartilhados. Aplicativos vinculados estaticamente são mais fáceis de garantir "portáteis" no sentido de "não exigir alterações em arquivos, diretórios ou configurações pertencentes ao sistema operacional" (pense no diretório, registro do Windows, / etc).


fonte
Obrigado por melhorar as vantagens que eu quis mencionar. No entanto, se você vir a maioria dos pacotes fornecidos por distribuições Linux, por exemplo, eles não serão compilados estaticamente. Ele faz parecer que a compilação estática é desaprovada, pelo menos de um ponto de vista externo.
Florian Margaine
1
Atualmente, as bibliotecas dinâmicas em praticamente todos os sistemas operacionais são paginadas por demanda. Somente as páginas realmente usadas estão na memória. Se vários aplicativos estiverem usando a mesma funcionalidade, eles compartilharão a memória e usarão menos que o caso da biblioteca estática. Se vários aplicativos estiverem usando funcionalidades diferentes na mesma biblioteca, os dois conjuntos de funcionalidades serão paginados, tendo aproximadamente o mesmo impacto que a abordagem estática.
Alan Shutko
@ AlanShutko Eu lutei e redigitei essa parte de várias maneiras por causa do que você mencionou. Não há garantias reais de qualquer maneira, mesmo que os sistemas operacionais modernos ofereçam, na prática, a eficiência de bibliotecas compartilhadas com a sobrecarga da estática. Vou editar novamente.
@ Snowman: Acho que o ponto básico é que, em qualquer sistema operacional realista que forneça vínculo dinâmico (não conheço nenhum sistema operacional que use vínculo dinâmico, mas não exija paginação), seu segundo ponto não retém água: a memória não é realmente usada a menos que a função seja usada e a memória usada por uma biblioteca dinâmica possa ser compartilhada entre diferentes programas, tornando o uso de memória para a versão dinâmica mais eficiente e não menos. Suas primeira e terceira razões são válidas, mas eu simplesmente excluiria a segunda: com quaisquer suposições realistas, é apenas errado.
Jules
@Jules Concordo, é um ponto problemático e de validade duvidosa nos sistemas operacionais modernos. Eu removi isso.
1

Cada uma das bibliotecas estáticas e dinâmicas possui seus próprios usos. Olhando para um único aplicativo no escopo, temos uma idéia diferente sobre o que é necessário e o que não é.

A vinculação estática simplifica drasticamente a implantação do aplicativo. Não é necessário detectar e lidar com versões diferentes. Basta assar e implantar.

A vantagem óbvia das bibliotecas dinâmicas é a capacidade de aplicar atualizações independentemente.

Essa é uma das razões pelas quais detesto o maven e outros construtores de projetos de vinculação dinâmica semelhantes para java. Eles esperam que uma única versão da biblioteca esteja disponível em um determinado URL para todo o sempre. Não entendo o problema que ocorre em 10 anos, quando ninguém pode compilar o aplicativo porque toda a origem e os jarros se foram.

muitas batatas fritas
fonte
Existe alguma razão específica para que os programas que costumam FooLib1.8não possam incluir o código dessa biblioteca em seu pacote executável de maneira padrão, para permitir que um utilitário de atualização enviado o FooLib1.9atualize ou faça o downgrade? A maneira como o código era armazenado no Classic Macintosh tornaria isso muito fácil; existe alguma razão para os sistemas atuais não conseguirem fazer isso ainda melhor?
Supercat
@ supercat, você quer dizer que todas as versões de uma determinada biblioteca estariam disponíveis no sistema? Não tenho certeza se entendi a pergunta. A questão do OP foi direcionada mais para bibliotecas compartilhadas em todo o sistema versus bibliotecas estáticas que seriam empacotadas juntas.
lotes de batatas fritas
Meu argumento era que o fato de um pacote executável incluir todas as bibliotecas necessárias não deveria impedir a possibilidade de atualizar as bibliotecas contidas nele. Portanto, não sei se consideraria a capacidade de atualizar as coisas após a implantação como uma vantagem de não agrupar um aplicativo com suas bibliotecas.
Supercat
Se a licença de uma determinada biblioteca permitir que você a distribua com seu pacote, essa é sempre a maneira preferida de fazê-lo. Reduz o número de dependências externas. Como você distribuiria tudo, um mecânico de atualização ou correção operaria da mesma maneira com estática ou dinâmica. Patching geralmente baseado em deltas binários. Não haveria diferença.
lotes de batatas fritas