Qual é a fonte da mentalidade “compile você mesmo” no linux [fechado]

11

Eu usei o Linux um pouco na faculdade e estou familiarizado com os termos. Eu desenvolvo em linguagens .NET regularmente, por isso não sou analfabeto do computador.

Dito isto, eu realmente não posso dizer que entendo a mentalidade "compile você mesmo" [CIY] que existe nos círculos * nix. Eu sei que está indo embora, mas ainda ouço de vez em quando. Como desenvolvedor, sei que configurar compiladores e dependências necessárias é um problema, então sinto que os fluxos de trabalho da CIY ajudaram a tornar o * nix muito menos acessível.

Quais fatores sociais ou técnicos levaram ao surgimento da mentalidade do CIY?

Sidney
fonte
12
Você ouve nos círculos Linux ou UNIX ? Há uma enorme diferença.
terdon
2
O Linux tem tantas distribuições diferentes que não é nenhuma surpresa. Agora que algumas distros estão surgindo como líderes, existem versões compiladas, mas costumava ser uma web que não era prática.
Centimane
8
E para constar, "configurar compiladores e dependências necessárias" em um sistema Linux não é tão difícil assim. Alguns podem até dizer fácil.
Deathgrip
6
@ Darren - É o contrário, hoje em dia a maioria dos tarballs de código aberto segue um padrão que não existia anos atrás. Baixe tarball, extraia tarball, cd para o diretório, execute ./configure <options>e faça e instale. Eu cortei meus dentes há 30 anos nos servidores AT&T 3B2 executando o AT&T SysV Unix e o ferro Gould executando o UTX. As coisas estavam muito mais difíceis naquela época. Alguns tiveram o início do configureprocesso, a maioria dos quais você teve que editar manualmente makefile(s)para seu sistema específico.
Deathgrip
1
@ Deathgrip De fato, você já tentou configurar um ambiente de desenvolvimento do Windows para programação de sistemas sem o Visual Studio? Quase no impossível, eu te digo.
gato

Respostas:

27

Muito simplesmente, durante grande parte da história do * nix, não havia outra escolha. Os programas foram distribuídos como tarballs de origem e a única maneira de usá-los era compilar a partir do código-fonte. Portanto, não é tanto uma mentalidade, mas um mal necessário.

Dito isso, existem boas razões para compilar as coisas você mesmo, pois elas serão compiladas especificamente para o seu hardware, você pode escolher quais opções ativar ou não e, portanto, pode acabar com um executável ajustado da maneira que desejar. . Isso, no entanto, obviamente é apenas algo que faz sentido para usuários experientes e não para pessoas que desejam apenas uma máquina em funcionamento para ler seus e-mails.

Agora, no mundo Linux, as principais distribuições se afastaram disso há muitos anos. Atualmente, você muito, muito raramente precisa compilar qualquer coisa, a menos que esteja usando uma distribuição projetada especificamente para pessoas que gostam de fazer isso como o Gentoo. Para a grande maioria das distribuições, no entanto, o usuário médio nunca precisará compilar nada, pois praticamente tudo o que eles precisam está presente e compilado nos repositórios da distribuição.

Portanto, essa mentalidade CIY, como você chama, desapareceu essencialmente. Pode ainda estar vivo e chutando no mundo UNIX, não tenho experiência lá, mas no Linux, se você estiver usando uma distribuição popular com um repositório decente, quase nunca precisará compilar nada.

terdon
fonte
5
No mundo Unix, ele difere novamente, dependendo do sistema operacional. Minha última posição envolveu um grande número de servidores Solaris (plataforma Sun Sparc) e eu executei o Solaris 10 x86 em casa como desktop por alguns anos. Não posso falar pelo HPUX ou AIX, mas você precisava fazer um pouco de CIY no Solaris. A Sun distribuiu vários utilitários OpenSource pré-empacotados para Solaris. Havia também sites como opencsw.org e unixpackages.com. Mas eu ainda compilei bastante a partir de tarballs de origem.
Deathgrip
"durante grande parte da história do * nix, não havia outra escolha. os programas foram distribuídos como tarballs de origem". - mas isso é por causa da mentalidade do CIY, certo?
Woodrow Barlow
2
@ Woodrow não é realmente. Não havia outra opção disponível. Não esqueça que * nix é antigo . Além disso, a maioria dos programas foi distribuída entre colegas que já eram especialistas e por que você se incomodaria em inventar algo tão complexo quanto um instalador ou gerenciador de pacotes para as outras 8 pessoas que usariam seu código? Quando essas ferramentas foram inventadas, o pessoal do * nix começou a usá-las como todos os outros.
terdon
@WoodrowBarlow Não, você está trocando causa e efeito. Os programas foram distribuídos como fonte, porque havia muitas plataformas diferentes (arquiteturas de hardware diferentes, sistemas operacionais diferentes, conjuntos diferentes de bibliotecas); portanto, o autor do programa precisaria distribuir centenas ou milhares de binários para cobrir todas elas. O CIY ainda existe para pessoas que executam plataformas "exóticas", mas a grande maioria executa plataformas "tradicionais", onde os binários estão prontamente disponíveis nas distribuições.
Gilles 'SO- stop be evil'
@terdon ok, entendo. Gostaria apenas de salientar, porém, que esse parágrafo é um pouco tautológico. em um certo nível, o OP perguntou "por que os desenvolvedores * nix distribuem código-fonte em vez de binários compilados?" e seu primeiro parágrafo diz "porque * os desenvolvedores do nix distribuem o código-fonte em vez dos binários compilados". Sim, percebo que estou simplificando, mas acho que sua resposta seria mais clara se você adicionar os argumentos do seu comentário ao texto da resposta.
Woodrow Barlow
13

Existem algumas causas para essa mentalidade, de usuários finais, mantenedores de distribuição e grupos de fornecedores / desenvolvedores / projetos de código, e cada um deles é perfeitamente válido.

O aspecto de código aberto

Há quem goste de saber que está usando o software livre e o valida escolhendo compilar a partir do código-fonte. É aí que entram coisas como o projeto / howto / guia / livro do Linux From Scratch.

O aspecto de otimização e opções

Deseja compilar coisas com otimizações específicas para sua arquitetura de CPU específica? Talvez haja uma opção de tempo de compilação (ou correção para criar uma) para ativar ou desativar um recurso específico que você precisa. Exemplos disso podem ser o patchfix do patchfix para ter a capacidade de gerenciar cotas, ou usar uma distribuição como o Gentoo, na qual você pode optar por não usar o systemd ou, especificamente, oferecer suporte ao ogg / theora / vorbis / Whatever e NOT mp3 devido a problemas de licenciamento como queiras.

O aspecto da arquitetura da CPU

Seu local de trabalho usa máquinas de ponta não-x86 / amd64? O pacote que você precisa / deseja pode não estar disponível pré-compilado para sua arquitetura de CPU, muito menos em qualquer distribuição que você esteja executando. É verdade que a maioria dos locais que executam esse tipo de hardware também é suportada pela IBM etc., e não instala / compila coisas à vontade. Mas e se você escolher um de uma venda excedente, desenterrar um antigo iMac com processador PPC, etc.?

O aspecto Distribuição

"Famílias" de distribuição - isto é, Debian com Ubuntu, Mint, et al e RedHat com CentOS, Whitebox, Fedora, et al - usam formatos de pacotes diferentes. E cada versão é fornecida com diferentes versões da biblioteca, etc. Mesmo para um simples script de shell de arquivo único, a configuração de um arquivo Debian .deb adequado leva tempo e esforço. Se você escreveu algum software para coçar um pouco de coceira e queria torná-lo gratuito e publicá-lo no gitlab, seu próprio servidor web, o que seja, você prefere publicar um arquivo .tar.gz genérico da fonte com instruções de construção ou prefere empacote versões para 2 versões do Debian (stable e testing, talvez oldstable), várias versões do Redhat e Fedora como RPMs, um TGZ para Slackware, um perfil ebuild para o Gentoo, etc. etc. etc.

ivanivan
fonte
1
Outro motivo é que às vezes a fonte upstream corrige um erro não crítico para um recurso que funcionava em uma versão anterior, mas que foi quebrada desde então. No entanto, o pacote para uma distribuição mais estável pode não atualizar o pacote por semanas ou até meses. Essa é uma das razões pelas quais um usuário normal pode querer aprender como compilar algumas coisas da fonte. Além disso, até distros com reputação de software de ponta em seus repositórios, como o Arch, ficarão para trás em algum momento. Compilar a partir da fonte significa que posso ter tudo o que você mencionou, além de quaisquer novos recursos que possam ter sido introduzidos.
@ChronoKitsune Muito verdadeiro; compare as versões do pacote no Gentoo (uma distribuição CIY) com qualquer outra distribuição. Muito mais novo. Fazer instruções de compilação é mil vezes mais fácil do que criar um pacote binário que funcione em todas as arquiteturas. Isso significa que você pode usar novos recursos interessantes de software que outras pessoas não verão por um tempo.
dogoncouch
9

Como diz @terdon, hoje em dia a necessidade de compilar as coisas é muito pequena, especialmente para usuários domésticos.

No passado, no mundo Unix, eu era altamente dependente de compilar fontes, por exemplo, enquanto gerenciava os sistemas Solaris, AIX, Ultrix, Digital Ultrix e HP / UX que às vezes não eram mais mantidos pelo fornecedor ou quais implementações dos serviços comuns estavam muito atrás do que era comumente usado por outros Unixes, incluindo o Linux.

Ainda existem necessidades genuínas de compilar coisas no presente, para obter algum software mais obscuro ou obsoleto que não esteja nos repositórios ou usar uma versão mais recente de um pacote para o qual você não possui binários compatíveis ou quando você deseja adicionar funcionalidade extra ou raramente, se conseguir escrever um patch ou módulo para ele.

Eu também tive que compilar o software manualmente ao fazer a reengenharia de sistemas para portar para o Debian e / ou novas versões do Debian que tinham uma estrutura que não era mais suportada pelo sistema operacional.

Por exemplo, no passado, eu tive que compilar manualmente os daemons DHCP para ter suporte (até então recente) para alterações no protocolo do Windows ou para oferecer suporte a patches específicos para provisionamento no mundo das telecomunicações.

Eu ainda mantenho no meu repositório local as debs para versões do FreeRadius compiladas por mim no repositório dev git, pois havia uma série de versões estáveis ​​que apresentavam bugs (sérios) no Debian e, geralmente, os .debs correspondentes para o Debian / Ubuntu não foram adequado às nossas necessidades.

E nem é preciso dizer que, de vez em quando, também precisamos executar / ou compilar coisas escritas por nós mesmos.

Instalar as dependências hoje em dia não é tão difícil quanto no passado, e alguns softwares ainda têm arquivos de regras customizados para algumas distribuições comuns do Linux que nomeiam as dependências a serem compiladas e fazem o trabalho pesado de criar o arquivo de pacote com a lista de dependências incorporadas. Instalar um pacote desse tipo a partir de um repositório local não é muito diferente de instalar o mesmo pacote dos repositórios oficiais.

Rui F Ribeiro
fonte
4

Quais fatores sociais ou técnicos levaram ao surgimento da mentalidade do CIY?

A causa raiz é obviamente a razão técnica: a portabilidade binária é mais difícil que a portabilidade de origem . Fora dos pacotes de distribuição, a maioria dos softwares livres ainda está disponível apenas na forma de código-fonte, porque é muito mais conveniente para o (s) autor (es) / mantenedor (es).

Até as distribuições Linux começarem a empacotar a maioria das coisas que as pessoas comuns gostariam de usar, sua única opção era obter a fonte e compilá-la para seu próprio sistema. Os fornecedores comerciais do Unix geralmente não incluíam coisas que quase todo mundo queria (por exemplo, um bom shell como o GNU bashou similar), apenas sua própria implementação she / ou csh, então você precisava criar as coisas sozinho, se quisesse (como administrador de sistemas) para fornecer um ambiente Unix agradável aos seus usuários para uso interativo.

A situação agora, com a maioria das pessoas sendo o único administrador e o único usuário da máquina em sua área de trabalho, é muito diferente do modelo tradicional do Unix. Um administrador de sistema mantinha o software no sistema central e na área de trabalho de todos. (Muitas vezes, tendo as estações de trabalho das pessoas apenas montadas em NFS /opte a /usr/local/partir do servidor central e instalando coisas lá.)


Antes de coisas como .NET e Java, a verdadeira portabilidade binária em diferentes arquiteturas de CPU era impossível. A cultura Unix evoluiu com portabilidade de origem como padrão por esse motivo, com pouco esforço para tentar habilitar a portabilidade binária até esforços recentes do Linux como o LSB. Por exemplo, o POSIX ( o principal padrão Unix) tenta apenas padronizar a portabilidade de origem, mesmo em versões recentes.

Fator cultural relacionado: Os primeiros comerciais da AT&T Unix vieram com código-fonte (em fitas). Você não precisava criar o sistema a partir da fonte, ele estava lá para o caso de você querer ver como algo realmente funcionava quando os documentos não eram suficientes.

A Wikipedia diz :

"A política do Unix de extensa documentação on-line e (por muitos anos) acesso pronto a todo o código-fonte do sistema aumentou as expectativas dos programadores e contribuiu para o lançamento do movimento de software livre em 1983".

Não sei ao certo o que motivou essa decisão, já que é inédito nos dias de hoje oferecer aos clientes o código-fonte do software comercial. Existem claramente alguns preconceitos culturais nessa direção, mas talvez isso tenha surgido das raízes do Unix como um sistema operacional portátil escrito principalmente em C (não na linguagem assembly) que poderia ser compilado para diferentes hardwares. Eu acho que muitos sistemas operacionais anteriores tinham mais de seu código escrito em asm para uma CPU específica, portanto a portabilidade no nível da fonte foi um dos pontos fortes do Unix. (Eu posso estar errado sobre isso; não sou especialista no Unix inicial, mas Unix e C estão relacionados.)


A distribuição de software na forma de origem é, de longe, a maneira mais fácil de permitir que as pessoas o adaptem a qualquer sistema em que desejam que ele seja executado. (Usuários finais ou pessoas que o empacotam para uma distribuição Linux). Se o software já foi empacotado por / para uma distribuição, os usuários finais podem apenas usá-lo.

Mas é demais esperar que os autores da maioria dos pacotes façam binários para cada sistema possível. Alguns projetos importantes fornecem binários para alguns casos comuns (especialmente x86 / windows em que o sistema operacional não vem com um ambiente de construção e o fornecedor do sistema operacional enfatiza bastante a distribuição de instaladores apenas binários).

Conseguir que um software seja executado em um sistema diferente daquele usado pelo autor pode exigir algumas pequenas alterações, que são fáceis com a fonte . Um pequeno programa único que alguém escreveu para coçar sua própria coceira provavelmente nunca foi testado na maioria dos sistemas obscuros. Ter a fonte torna possível fazer essas alterações. O autor original pode ter esquecido algo ou intencionalmente escreveu um código menos portátil, porque economizou muito tempo. Mesmo grandes pacotes como o Info-ZIP não tinham testadores em todas as plataformas imediatamente e precisavam de pessoas para enviar seus patches de portabilidade à medida que os problemas fossem descobertos.

(Existem outros tipos de problemas de portabilidade de nível de fonte que só acontecem por causa de diferenças na construção env, e não são realmente relevantes para a questão aqui. Com Java-style portabilidade binária, auto-ferramentas ( autoconf/ auto-make) e coisas semelhantes, como cmakewouldn E não teríamos coisas que alguns sistemas exigem a inclusão de, em <netinet/in.h>vez de<arpa/inet.h> parantohl(3) (e talvez não tivéssemos ntohl()ou qualquer outra coisa de ordem de bytes em primeiro lugar!)


Eu desenvolvo em linguagens .NET regularmente, por isso não sou analfabeto do computador.

Compilar uma vez, executar em qualquer lugar é um dos principais objetivos do .NET e também do Java; portanto, é justo dizer que linguagens inteiras foram inventadas em um esforço para resolver esse problema , e sua experiência com o desenvolvedor é com uma delas. Com o .NET, seu binário é executado em um ambiente de tempo de execução portátil (CLR) . Java chama seu ambiente de tempo de execução de Java Virtual Machine . Você só precisa distribuir um binário que funcione em qualquer sistema (pelo menos, qualquer sistema em que alguém já tenha implementado uma JVM ou CLR). Você ainda pode ter problemas de portabilidade, como /vs \separadores de caminho, ou como imprimir, ou detalhes de layout da GUI, é claro.

Muitos softwares são escritos em idiomas totalmente compilados no código nativo . Não há .netbytecode ou java, apenas código de máquina nativo para a CPU em que será executado, armazenado em um formato de arquivo executável não portátil. C e C ++ são os principais exemplos disso, especialmente no mundo Unix. Obviamente, isso significa que um binário precisa ser compilado para uma arquitetura específica da CPU.

As versões da biblioteca são outro problema . As bibliotecas podem e muitas vezes mantêm a API no nível de origem estável ao alterar a ABI no nível binário. (Consulte Diferença entre API e ABI .) Por exemplo, adicionar outro membro a um opaco structainda muda de tamanho e requer uma recompilação com cabeçalhos para a nova versão da biblioteca para qualquer código que aloque espaço para essa estrutura, seja ela dinâmica (malloc ), estático (global) ou automático (local na pilha).

Os sistemas operacionais também são importantes . Um sabor diferente de Unix para a mesma arquitetura de CPU pode ter diferentes formatos de arquivos binários, a ABI diferente para fazer chamadas de sistema e valores numéricos diferentes para constantes como fopen(3)'s O_RDONLY, O_APPEND,O_TRUNC .

Observe que mesmo um binário vinculado dinamicamente ainda possui algum código de inicialização específico do SO que é executado anteriormente main(). No Windows, é isso crt0. Unix e Linux têm a mesma coisa, onde algum código de inicialização do C-Runtime está estaticamente vinculado a todos os binários. Eu acho que, em teoria, você poderia projetar um sistema em que esse código também fosse dinamicamente vinculado, e parte da libc ou do próprio vinculador dinâmico, mas não é assim que as coisas funcionam na prática em qualquer sistema operacional que eu conheça. Isso resolveria apenas o problema de ABI da chamada de sistema, não o problema de valores numéricos para constantes para funções de biblioteca padrão. (Normalmente, as chamadas do sistema são feitas através das funções do invólucro libc: Um binário x86-64 Linux normal para a fonte que usa mmap()não inclui a syscallinstrução, apenas umcall instruções para a função wrapper libc com o mesmo nome.

Isso é parte do motivo pelo qual você não pode simplesmente executar os binários do i386-FreeBSD no i386-Linux. (Por um tempo, o kernel do Linux tinha uma camada de compatibilidade de chamada do sistema. Acho que pelo menos um dos BSDs pode executar binários do Linux, com uma camada compatível semelhante, mas é claro que você precisa de bibliotecas do Linux.)


Se você quisesse distribuir binários, seria necessário criar um separado para cada combinação de CPU / OS-sabor + versão / versão-biblioteca-instalada .

Nos anos 80/90, havia muitos tipos diferentes de CPU em uso comum para sistemas Unix (MIPS, SPARC, POWER, PA-RISC, m68k etc.) e muitos tipos diferentes de Unix (IRIX, SunOS, Solaris, AIX, HP-UX, BSD etc.).
E isso é apenas sistemas Unix . Muitos pacotes de código-fonte também compilariam e funcionariam em outros sistemas, como VAX / VMS, MacOS (m68k e PPC), Amiga, PC / MS-DOS, Atari ST, etc.

Ainda existem muitas arquiteturas de CPU e sistemas operacionais, embora agora a grande maioria dos desktops esteja x86 executando um dos três principais sistemas operacionais.

Portanto, já há mais combinações de CPU / OS do que você pode imaginar, mesmo antes de começar a pensar nas dependências de bibliotecas de terceiros que podem estar em versões diferentes em sistemas diferentes. (Qualquer coisa que não seja fornecida pelo fornecedor do SO deve ser instalada manualmente.)

Todos os caminhos que são compilados no binário também são específicos do sistema. (Isso economiza RAM e tempo em comparação com a leitura de um arquivo de configuração na inicialização). Os sistemas Unix da velha escola geralmente tinham muitas coisas personalizadas à mão, então não há como você fazer suposições válidas sobre o que é onde.

A distribuição de binários era totalmente inviável para o Unix da velha escola, exceto para os principais projetos comerciais que podem se dar ao luxo de construir e testar todas as principais combinações .

Mesmo fazendo binários por apenas i386-linux-gnue amd64-linux-gnué difícil. Muito tempo e esforço foram gastos em coisas como a Linux Standard Base para possibilitar binários portáteis . Mesmo binários vinculados estaticamente não resolvem tudo. (por exemplo, como um programa de processamento de texto deve ser impresso em um sistema RedHat vs. um sistema Debian? Como a instalação deve adicionar um usuário ou grupo para um daemon e organizar seu script de inicialização após cada reinicialização?) exemplos, porque a recompilação a partir da fonte não os resolve.


Além de tudo isso, antigamente a memória era mais preciosa do que é agora. Deixar de lado os recursos opcionais em tempo de compilação pode criar binários menores (menos tamanho de código) que também usam menos memória para suas estruturas de dados. Se um recurso exigir um membro extra em todas as instâncias de um determinado item classou structrastrear algo, a desativação desse recurso reduzirá o objeto em 4 bytes (por exemplo), o que é bom se for um objeto ao qual o programa aloca 100k.

Atualmente, os recursos opcionais em tempo de compilação são usados ​​com mais frequência para tornar opcionais bibliotecas extras. por exemplo, você pode compilar ffmpegcom ou sem libx264, libx265, libvorbis, e muitas outras bibliotecas para vídeo específico / codificadores de áudio, a manipulação das legendas, etc. etc. Mais comumente, um monte de coisas podem ser compilados com ou sem libreadline: se estiver disponível quando você executa ./configure, o O binário resultante dependerá da biblioteca e fornecerá edição de linha sofisticada ao ler de um terminal. Caso contrário, o programa usará algum suporte de fallback para ler apenas linhas do stdin com fgets()algo assim.)

Alguns projetos ainda usam recursos opcionais para omitir códigos desnecessários por motivos de desempenho. por exemplo, o próprio kernel do Linux pode ser construído sem o suporte a SMP (por exemplo, para um sistema incorporado ou uma área de trabalho antiga); nesse caso, grande parte do bloqueio é mais simples. Ou com muitos outros recursos opcionais que afetam parte do código principal, não apenas deixando de fora os drivers ou outros recursos de hardware. (Embora as opções de configuração específicas do arco e do hardware sejam responsáveis ​​por grande parte do código fonte total. Consulte Por que o kernel do Linux tem mais de 15 milhões de linhas de código? )

Peter Cordes
fonte