Aprendendo a compilar coisas da fonte (no Unix / Linux / OSX)

47

Enquanto instalo o software a partir de pacotes (MacPorts / apt-get) sempre que possível, muitas vezes me vejo precisando compilar pacotes a partir da fonte. ./configure && make && sudo make installgeralmente é suficiente, mas às vezes não funciona - e quando não funciona, frequentemente fico preso. Isso quase sempre se refere a outras dependências da biblioteca de alguma maneira.

Gostaria de aprender o seguinte:

  • Como faço para descobrir para quais argumentos passar ./configure?
  • Como as bibliotecas compartilhadas funcionam no OS X / Linux - onde vivem no sistema de arquivos, como as ./configure && makeencontram, o que realmente acontece quando estão vinculadas
  • Quais são as diferenças reais entre uma biblioteca compartilhada e uma biblioteca vinculada estaticamente? Por que não posso vincular estaticamente tudo (a RAM e o espaço em disco são baratos hoje em dia) e, portanto, evitar conflitos estranhos na versão da biblioteca?
  • Como posso saber quais bibliotecas eu instalei e quais versões?
  • Como posso instalar mais de uma versão de uma biblioteca sem interromper meu sistema normal?
  • Se estou instalando coisas da fonte em um sistema gerenciado usando pacotes, qual é a maneira mais limpa de fazer isso?
  • Supondo que eu consiga compilar algo complicado da fonte, como posso empacotá-lo para que outras pessoas não precisem pular os mesmos bastidores? Particularmente no OS X ....
  • Quais são as ferramentas de linha de comando que eu preciso dominar para ficar bom nisso? Coisas como otool, pkg-config etc.

Estou disposto a investir bastante tempo e esforço aqui - não necessariamente quero respostas diretas para as perguntas acima; prefiro obter recomendações sobre livros / tutoriais / perguntas frequentes que posso ler, o que me dará a conhecimento eu preciso entender o que realmente está acontecendo e, portanto, descobrir problemas sozinho.

Simon Willison
fonte

Respostas:

40

Peço desculpas por responder diretamente a tudo, mas não conheço tutoriais, FAQs, etc. Basicamente, o que se segue são 8 anos de criação de aplicativos para desktop (que eu ajudo a distribuir), frustração e pesquisa no Google:

1. Como faço para descobrir quais argumentos passar para ./configure?

Pratique realmente. Autotools é fácil o suficiente, pois é consistente. Mas há muitas coisas por aí usando cmake, ou scripts de construção personalizados. Geralmente, você não precisa passar nada para configurar; ele deve descobrir se o seu sistema pode criar ou não uma ferramenta de foo.

As ferramentas Configure e GNU procuram em /, / usr e / usr / local por dependências. Se você instalar algo em qualquer outro lugar (o que torna as coisas dolorosas se a dependência foi instalada pelo MacPorts ou Fink), você terá que passar um sinalizador para configurar ou modificar o ambiente do shell para ajudar as ferramentas GNU a encontrar essas dependências.

2. Como as bibliotecas compartilhadas funcionam no OS X / Linux - onde vivem no sistema de arquivos, como ./configure && make as encontra, o que realmente acontece quando estão vinculadas

No Linux, eles precisam ser instalados em um caminho que o vinculador dinâmico possa encontrar, isso é definido pela LD_LIBRARY_PATHvariável de ambiente e pelo conteúdo do /etc/ld.conf. No Mac, é o mesmo para a maioria dos softwares de código aberto quase sempre (a menos que seja um projeto Xcode). Exceto que a variável env é DYLD_LIBRARY_PATHalternativa.

Há um caminho padrão que o vinculador procura por bibliotecas. É / lib: / usr / lib: / usr / local / lib

Você pode complementar isso usando a variável CPATH, ou CFLAGS ou qualquer número de outras variáveis ​​de ambiente realmente (convenientemente complicado). Sugiro CFLAGS assim:

exportar CFLAGS = "$ CFLAGS -L / novo / caminho"

O parâmetro -L é adicionado ao caminho do link.

Coisas modernas usam a ferramenta pkg-config. O material moderno que você instala também instala um arquivo .pc que descreve a biblioteca, onde está e como vincular a ela. Isso pode facilitar a vida. Mas como ele não vem com o OS X 10.5, você também precisará instalá-lo. Também muitos deps básicos não o suportam.

O ato de vincular é apenas "resolver esta função em tempo de execução", na verdade é uma grande tabela de strings.

3. Quais são as diferenças reais entre uma biblioteca compartilhada e uma biblioteca vinculada estaticamente? Por que não posso vincular estaticamente tudo (a RAM e o espaço em disco são baratos hoje em dia) e, portanto, evitar conflitos estranhos na versão da biblioteca?

Quando você vincula a um arquivo de biblioteca estática, o código se torna parte do seu aplicativo. Seria como se houvesse um arquivo .c gigante para essa biblioteca e você o compilasse em seu aplicativo.

As bibliotecas dinâmicas têm o mesmo código, mas quando o aplicativo é executado, o código é carregado no aplicativo em tempo de execução (explicação simplificada).

Você pode vincular estaticamente a tudo, no entanto, infelizmente, quase nenhum sistema de compilação facilita isso. Você precisaria editar os arquivos do sistema de compilação manualmente (por exemplo, Makefile.am ou CMakeLists.txt). No entanto, provavelmente vale a pena aprender se você instalar regularmente coisas que exijam versões diferentes de bibliotecas e estiver achando difícil instalar paralelamente dependências.

O truque é alterar a linha de link de -lfoo para -l / path / para / static / foo.a

Você provavelmente pode encontrar e substituir. Depois, verifique se a ferramenta não está vinculada ao .so ou dylib usando ldd foo ou otool -L foo

Outro problema é que nem todas as bibliotecas são compiladas em bibliotecas estáticas. Muitos fazem. Mas então o MacPorts ou o Debian podem ter decidido não enviá-lo.

4. Como posso saber quais bibliotecas eu instalei e quais versões?

Se você possui arquivos pkg-config para essas bibliotecas, é fácil:

pkg-config --list-all

Caso contrário, muitas vezes você não pode facilmente. O dylib pode ter um soname (ou seja, foo.0.1.dylib, o soname é 0.1) igual à versão da biblioteca. No entanto, isso não é necessário. O soname é um recurso de computabilidade binária; você deve esbarrar na maior parte do soname se alterar o formato das funções na biblioteca. Então você pode obter, por exemplo. versão 14.0.5 soname para uma biblioteca 2.0. Embora isso não seja comum.

Fiquei frustrado com esse tipo de coisa e desenvolvi uma solução para isso no Mac, e vou falar sobre isso a seguir.

5. Como posso instalar mais de uma versão de uma biblioteca sem interromper meu sistema normal?

Minha solução para isso está aqui: http://github.com/mxcl/homebrew/

Eu gosto de instalar a partir do código-fonte e queria uma ferramenta que facilitasse, mas com algum gerenciamento de pacotes. Então, com Homebrew eu construo, por exemplo. wget-me da fonte, mas certifique-se de instalar em um prefixo especial:

/usr/local/Cellar/wget/1.1.4

Em seguida, uso a ferramenta homebrew para vincular tudo isso a / usr / local, então ainda tenho / usr / local / bin / wget e /usr/local/lib/libwget.dylib

Posteriormente, se eu precisar de uma versão diferente do wget, posso instalá-lo em paralelo e apenas alterar a versão vinculada à árvore / usr / local.

6. Se estou instalando coisas da fonte em um sistema que de outra forma é gerenciado usando pacotes, qual é a maneira mais limpa de fazer isso?

Eu acredito que a maneira Homebrew é a mais limpa, então use-a ou faça o equivalente. Instale em / usr / local / pkgs / name / version e faça o link simbólico ou vincule o restante.

Use / usr / local. Toda ferramenta de compilação existente procura por dependências e cabeçalhos. Sua vida será muito mais fácil.

7. Supondo que eu consiga compilar algo complicado da fonte, como posso empacotá-lo para que outras pessoas não precisem pular os mesmos bastidores? Particularmente no OS X ....

Se não houver dependências, você pode tar o diretório build e entregá-lo a outra pessoa que pode fazer "make install". No entanto, você só pode fazer isso de maneira confiável nas mesmas versões exatas do OS X. No Linux, provavelmente funcionará para Linux semelhante (por exemplo, Ubuntu) com a mesma versão do Kernel e a versão secundária da libc.

A razão pela qual não é fácil distribuir binários no Unix é devido à compatibilidade binária. O pessoal do GNU e todos os outros alteram suas interfaces binárias frequentemente.

Basicamente, não distribua binários. As coisas provavelmente vão quebrar de maneiras muito estranhas.

No Mac, a melhor opção é criar um pacote de macports. Todo mundo usa macports. No Linux, existem tantos sistemas e combinações de construção diferentes, que não acho melhor aconselhar do que escrever uma entrada de blog sobre como você conseguiu criar a ferramenta x em uma configuração estranha.

Se você criar uma descrição do pacote (para macports ou homebrew), qualquer pessoa poderá instalar esse pacote e resolverá também os problemas de dependência. No entanto, isso geralmente não é fácil e também não é fácil incluir sua receita de macports na árvore principal de macports. Além disso, o macports não suporta tipos de instalação exóticos, eles oferecem uma opção para todos os pacotes.

Um dos meus objetivos futuros com o Homebrew é possibilitar o clique em um link em um site (por exemplo, homebrew: // blah e ele fará o download do script Ruby, instalará os deps para esse pacote e criará o aplicativo. ainda não concluído, mas não muito complicado, considerando o design que escolhi.

8. Quais são as ferramentas de linha de comando que eu preciso dominar para ficar bom nisso? Coisas como otool, pkg-config etc.

otool é realmente útil apenas depois. Ele informa a que os binários construídos são vinculados. Quando você está descobrindo as dependências de uma ferramenta que precisa construir, é inútil. O mesmo se aplica ao pkg-config, pois você já instalou a dependência antes de poder usá-la.

Minha cadeia de ferramentas é, leia os arquivos README e INSTALL e faça uma configuração --help. Observe a saída da compilação para verificar se está correta. Analise os erros de construção. Talvez no futuro, pergunte no serverfault :)

Max Howell
fonte
2
Interessante, o Homebrew parece muito com o Portage (o gerenciador de pacotes do Gentoo Linux). Parece um bom trabalho.
317 David Z
12

Este é um tópico importante, então, vamos começar com as bibliotecas compartilhadas no Linux (ELF no Linux e Mach-O no OS X). Ulrich Drepper tem uma boa introdução à criação de DSOs (objetos dinâmicos compartilhados), que abrangem um histórico de bibliotecas compartilhadas no Linux disponível aqui, incluindo por que eles são importantes

Ulrich também descreve por que a vinculação estática é considerada prejudicial. Um dos pontos principais aqui são as atualizações de segurança. Estouros de buffer em uma biblioteca comum (por exemplo, zlib) que está extensamente vinculada estaticamente pode causar uma enorme sobrecarga para distribuições - isso ocorreu com o zlib 1.1.3 ( aviso da Red Hat )

DUENDE

Página de manual do linker ld.so

man ld.so 

explica os caminhos e arquivos básicos envolvidos na vinculação dinâmica do tempo de execução. Nos sistemas Linux modernos, você verá caminhos adicionais adicionados via /etc/ld.so.conf.d/ adicionados geralmente através de uma inclusão global no /etc/ld.so.conf.

Se você quiser ver o que está disponível dinamicamente através da sua configuração ld.so, você pode executar

ldconfig -v -N -X

A leitura do tutorial do DSO deve fornecer um bom nível básico de conhecimento para entender como esses princípios se aplicam ao Mach-O no OS X.

Mach-O

No OS X, o formato binário é Mach-O. A documentação do sistema local para o vinculador é

man dyld

A documentação do formato Mach está disponível na Apple

Ferramentas de Construção UNIX

O comum configure, make, make installprocesso é geralmente fornecida pelo GNU autotools que tem um livro on-line que abrange alguns da história do configure divisão / build e o conjunto de ferramentas GNU. O Autoconf usa testes para determinar a disponibilidade do recurso no sistema de construção de destino, usa a linguagem de macro M4 para fazer isso. Automake é basicamente um método de modelagem para Makefiles, o modelo geralmente chamado Makefile.am que gera um Makefile.in em que a saída do autoconf (o script de configuração) se converte em um Makefile.

O programa hello da GNU funciona como um bom exemplo para entender a cadeia de ferramentas GNU - e o manual inclui a documentação de ferramentas automáticas.


fonte
10

Simon! Eu sei como você se sente; Também lutei com essa parte do aprendizado do Linux. Com base em minhas próprias experiências, escrevi um tutorial sobre alguns dos itens que você aborda (principalmente como referência para mim!): Http://easyaspy.blogspot.com/2008/12/buildinginstalling-application-from.html . Acho que você apreciará minha observação sobre como os aplicativos Python são simples de construir / instalar. :)

Espero que isso ajude! E feliz compilando.

Tim Jones


Construindo / instalando um aplicativo a partir da fonte no Ubuntu Linux

Enquanto os repositórios do Ubuntu estão repletos de ótimas aplicações, em um momento ou outro você é obrigado a encontrar a ferramenta "imprescindível" que não está nos repositórios (ou não possui um pacote Debian) ou você precisa de um versão mais recente que nos repositórios. O que você faz? Bem, você precisa criar o aplicativo a partir da fonte! Não se preocupe, não é realmente tão complicado quanto parece. Aqui estão algumas dicas, com base nas minhas experiências de deixar de ser um amador! (Enquanto estou usando o Ubuntu neste exemplo, os conceitos gerais devem ser aplicáveis ​​à maioria das distribuições Unix / Linux, como o Fedora, e até a plataforma Cygwin no Windows.)

O processo básico de construção (compilação) da maioria dos aplicativos a partir da origem segue esta sequência: configure -> compile -> install. Os comandos típicos do Unix / Linux para fazer essas coisas são: config-> make-> make install. Em alguns casos, você encontrará páginas da web que mostram que tudo isso pode ser combinado em um único comando:

$ config && make && make install

Obviamente, este comando assume que não há problemas em nenhuma dessas etapas. É aqui que entra a diversão!

Começando

Se você não compilou um aplicativo da fonte no seu sistema antes, provavelmente precisará configurá-lo com algumas ferramentas gerais de desenvolvimento, como o gccconjunto do compilador, alguns arquivos de cabeçalho comuns (pense nisso como um código que já foi gravado). por outra pessoa usada pelo programa que você está instalando) e pela ferramenta make. Felizmente, no Ubuntu, existe um metapacote chamado build-essentialque será instalado. Para instalá-lo (ou apenas verifique se você já o possui!), Execute este comando no terminal:

$ sudo apt-get install build-essential

Agora que você possui a configuração básica, baixe os arquivos de origem do aplicativo e salve-os em um diretório para o qual você possui permissões de leitura / gravação, como o diretório "inicial". Normalmente, eles estarão em um arquivo compactado com extensão de arquivo .tar.gzou .tar.bz2. O .tarsimplesmente significa que ele é um "arquivo em fita", que é um agrupamento de arquivos que preserva a sua estrutura de diretório relativo. O .gzsignifica gzip (GNU zip), que é um popular formato de compactação Unix / Linux. Da mesma forma, .bz2significa bzip2, que é um formato de compactação mais recente que fornece uma compactação mais alta (tamanho menor do arquivo compactado) que o gzip.

Depois de baixar o arquivo de origem, abra uma janela do terminal (Terminal do sistema no menu Ubuntu) e mude para o diretório em que você salvou o arquivo. (Vou usar ~/downloadneste exemplo. Aqui, '~' é um atalho para o diretório "inicial".) Use o comando tar para extrair os arquivos do archive baixado:

Se o seu arquivo é um arquivo gzip (por exemplo, termina com .tar.gz), use o comando:

            $ tar -zxvf filename.tar.gz

Se o seu arquivo é um arquivo bzip2 (por exemplo, termina com .tar.bz2), use o comando:

            $ tar -jxvf filename.tar.gz

Dica: Se você não precisar se lembrar de todas as opções de linha de comando para extrair arquivos, recomendo adquirir um (ou ambos) desses utilitários: dtrx (meu favorito!) Ou deco (mais popular). Com um desses utilitários, basta digitar o nome do utilitário (dtrx ou deco) e o nome do arquivo, ele faz todo o resto. Ambos "sabem" como lidar com quase todos os formatos de arquivo que você provavelmente encontrará e eles têm um ótimo tratamento de erros.

Ao criar a partir da fonte, há dois tipos comuns de erros que você provavelmente encontrará:

  1. Os erros de configuração ocorrem quando você executa o script de configuração (geralmente denominado config ou configure) para criar um makefile específico para sua instalação.
  2. Os erros do compilador ocorrem quando você executa o comando make (após a geração do makefile) e o compilador não consegue encontrar o código necessário.

Examinaremos cada uma delas e discutiremos como resolvê-las.

Erros de configuração e configuração

Depois de extrair o arquivo de código-fonte, no terminal, você deve mudar para o diretório que contém os arquivos extraídos. Normalmente, esse nome de diretório será igual ao nome do arquivo (sem a extensão .tar.gzou .tar.bz2). No entanto, às vezes o nome do diretório é apenas o nome do aplicativo, sem nenhuma informação de versão.

No diretório de origem, procure um READMEarquivo e / ou um INSTALLarquivo (ou algo com nomes semelhantes). Esses arquivos normalmente contêm informações úteis sobre como criar / compilar o aplicativo e instalá-lo, incluindo informações sobre dependências. "Dependências" são apenas um nome sofisticado para outros componentes ou bibliotecas que são necessárias para compilar com êxito.

Depois de ler o arquivo READMEe / ou INSTALL(e, esperançosamente, examinar qualquer documentação on-line relevante para o aplicativo), procure um arquivo executável (com a permissão "x" definida no arquivo) chamado configou configure. Às vezes, o arquivo pode ter uma extensão, como .sh(por exemplo, config.sh). Geralmente, esse é um script de shell que executa alguns outros utilitários para confirmar que você possui um ambiente "saudável" para compilar. Em outras palavras, ele verificará se você tem tudo instalado que precisa.

Dica: Se este é um aplicativo baseado em Python, em vez de um arquivo de configuração, você deve encontrar um arquivo chamado setup.py. Aplicativos Python geralmente são muito simples de instalar. Para instalar este aplicativo, como root (por exemplo, coloque o sudo na frente do seguinte comando no Ubuntu), execute este comando:

    $ python setup.py install

Isso deve ser tudo o que você precisa fazer. Você pode pular o restante deste tutorial e prosseguir diretamente para o uso e o aproveitamento do seu aplicativo.

Execute o script de configuração no terminal. Normalmente, você pode (e deve!) Executar seu script de configuração com sua conta de usuário comum.

$ ./config

O script exibirá algumas mensagens para lhe dar uma idéia do que está fazendo. Muitas vezes, o script fornece uma indicação sobre se foi bem-sucedido ou falhou e, se falhou, algumas informações sobre a causa da falha. Se você não receber nenhuma mensagem de erro, normalmente poderá assumir que tudo correu bem.

Se você não encontrar nenhum script que se pareça com um script de configuração, normalmente significa que o aplicativo é muito simples e é independente da plataforma. Isso significa que você pode simplesmente pular para a etapa de compilação / compilação abaixo, porque o fornecido Makefiledeve funcionar em qualquer sistema.

Um exemplo

Neste tutorial, vou usar o leitor de RSS baseado em texto chamado Newsbeuter como um exemplo para os tipos de erros que você pode encontrar ao criar seu aplicativo. Para Newsbeuter, o nome do script de configuração é config.sh. No meu sistema, quando executo config.sh, ocorrem os seguintes erros:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ ./config.sh
Checking for package sqlite3... not found

You need package sqlite3 in order to compile this program.
Please make sure it is installed.

Ao fazer algumas pesquisas, descobri que, de fato, o sqlite3aplicativo estava instalado. No entanto, como estou tentando criar a partir do código-fonte, esta é uma dica para a qual config.shrealmente procuramos as bibliotecas de desenvolvimento (cabeçalhos) sqlite3. No Ubuntu, a maioria dos pacotes possui um pacote de desenvolvimento associado que termina em -dev. (Outras plataformas, como o Fedora, costumam usar um sufixo de pacote -develpara os pacotes de desenvolvimento.)

Para encontrar o pacote apropriado para o sqlite3pacote de desenvolvimento, podemos usar o apt-cacheutilitário no Ubuntu (e, da mesma forma, o yumutilitário no Fedora):

tester@sitlabcpu22:~/download/newsbeuter-1.3$ sudo apt-cache search sqlite

Este comando retorna uma lista bastante grande de resultados, portanto, temos que fazer um pouco de trabalho de detetive para determinar qual é o pacote apropriado. Nesse caso, o pacote apropriado acaba sendo libsqlite3-dev. Observe que algumas vezes o pacote que estamos procurando terá o libprefixo, em vez de apenas o mesmo nome do pacote plus -dev. Isso ocorre porque, às vezes, estamos apenas procurando uma biblioteca compartilhada que possa ser usada por muitos aplicativos diferentes. Para instalar libsqlite3-dev, execute o comando típico apt-get install no terminal:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ sudo apt-get install libsqlite3-dev

Agora, precisamos executar config.shnovamente para garantir que resolvemos esse problema de dependência e que não temos mais problemas de dependência. (Embora eu não o mostre aqui, no caso do Newsbeuter, também tive que instalar o libcurl4-openssl-devpacote.) Além disso, se você instalar um pacote de desenvolvimento (como libsqlite3-dev) e o pacote de aplicativos associado (por exemplo, sqlite3) não for já instalado, a maioria dos sistemas instalará automaticamente o pacote de aplicativos associado ao mesmo tempo.

Quando a configuração for executada com êxito, o resultado será que ela criará um ou mais arquivos de criação. Esses arquivos geralmente são nomeados Makefile(lembre-se de que o nome do arquivo é importante no Unix / Linux!). Se o pacote de compilação incluir subdiretórios, como src, etc., cada um desses subdiretórios também conterá um Makefile.

Erros de compilação e compilação

Agora, estamos prontos para realmente compilar o aplicativo. Isso geralmente é chamado de construção e o nome é emprestado do processo do mundo real de construção de algo. As várias "partes" do aplicativo, que geralmente são vários arquivos de código-fonte, são combinadas para formar o aplicativo geral. O utilitário make gerencia o processo de construção e chama outros aplicativos, como o compilador e o vinculador, para realmente executar o trabalho. Na maioria dos casos, você simplesmente executa o make (com sua conta de usuário comum) no diretório em que executou a configuração. (Em alguns casos, como compilar aplicativos escritos com a biblioteca Qt, você precisará executar outro aplicativo "wrapper" como o qmake. Novamente, sempre verifique os READMEe / ou INSTALLdocumentos para obter detalhes.)

Como no script de configuração acima, quando você executa o make (ou o utilitário semelhante) no terminal, ele exibe algumas mensagens sobre o que está sendo executado e quaisquer avisos e erros. Normalmente, você pode ignorar avisos, pois eles são principalmente para os desenvolvedores do aplicativo e estão dizendo a eles que existem algumas práticas padrão que estão sendo violadas. Geralmente, esses avisos não afetam a função do aplicativo. Por outro lado, os erros do compilador devem ser tratados. Com o Newsbeuter, quando eu corri make, as coisas correram bem por um tempo, mas então eu recebi um erro:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ make
...
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/configparser.o -c src/configparser.cpp
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/colormanager.o -c src/colormanager.cpp
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:5:18: error: stfl.h: No such file or directory
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:33: error: ISO C++ forbids declaration of \u2018stfl_form\u2019 with no type
./include/stflpp.h:33: error: expected \u2018;\u2019 before \u2018*\u2019 token
./include/stflpp.h:34: error: ISO C++ forbids declaration of \u2018stfl_ipool\u2019 with no type
./include/stflpp.h:34: error: expected \u2018;\u2019 before \u2018*\u2019 token
make: *** [src/colormanager.o] Error 1

O processo de criação será interrompido assim que o primeiro erro for encontrado. O tratamento de erros do compilador às vezes pode ser um negócio complicado. Você precisa procurar nos erros algumas dicas sobre o problema. Normalmente, o problema é que alguns arquivos de cabeçalho, que geralmente têm extensão de .hou .hpp, estão ausentes. No caso do erro acima, é (ou deve ser!) Claro que o problema é que o stfl.harquivo de cabeçalho não pode ser encontrado. Como mostra este exemplo, você deseja examinar as primeiras linhas da mensagem de erro e descer o caminho para encontrar a causa subjacente do problema.

Depois de examinar a documentação do Newsbeuter (o que eu deveria ter feito antes de começar, mas essa parte do tutorial não seria muito significativa!), Descobri que ela requer uma biblioteca de terceiros chamada STFL. Então, o que fazemos neste caso? Bem, basicamente repetimos exatamente o mesmo processo para a biblioteca necessária: obtenha a biblioteca e execute o processo configure-build-install para ela e, em seguida, retome a construção do aplicativo desejado. Por exemplo, no caso do STFL, eu tive que instalar o libncursesw5-devpacote para que ele fosse criado corretamente. (Geralmente, não é necessário refazer a etapa de configuração em nosso aplicativo original depois de instalar outro aplicativo necessário, mas isso também não prejudica.)

Após a instalação bem-sucedida do kit de ferramentas STFL, o processo de criação do Newsbeuter foi executado com êxito. O processo de criação normalmente começa de onde parou (no ponto do erro). Portanto, todos os arquivos que já foram compilados com êxito não serão recompilados. Se você deseja recompilar tudo, é possível executar o make clean all para remover todos os objetos compilados e, em seguida, executar o make novamente.

Instalando

Após a conclusão do processo de compilação, você estará pronto para instalar o aplicativo. Na maioria dos casos, para instalar o aplicativo nas áreas comuns do sistema de arquivos (por exemplo, /usr/binou /usr/share/binetc.), você precisará executar a instalação como root. A instalação é realmente a etapa mais simples de todo o processo. Para instalar, no terminal, execute:

$ make install

Verifique a saída deste processo quanto a erros. Se tudo foi bem-sucedido, você poderá executar o nome do comando no terminal e ele será iniciado. (Anexe e no final da linha de comando, se for um aplicativo da GUI, ou você não poderá usar a sessão do terminal até que o aplicativo termine a execução.)

Quando você cria um aplicativo a partir da fonte, ele normalmente não adiciona um ícone ou atalho aos menus da GUI no Ubuntu. Você precisará adicionar isso manualmente.

E esse é basicamente o processo, embora potencialmente iterativo, para criar e instalar um aplicativo a partir da fonte no Ubuntu. Depois de fazer isso apenas algumas vezes, isso se tornará uma segunda natureza para você!

Tim Jones
fonte
Tim, eu gostaria de ler o seu tutorial, mas o link que você postou não funciona.
Gareth_bowles 04/10/2009
6

Bem, ./configure --help fornecerá muitas informações, para as ferramentas automáticas do GNU geradas pelos arquivos de configuração. A maior parte se resume a --com / - sem ativar recursos (estes podem levar um parâmetro extra, como "compartilhado" para dizer onde encontrar a biblioteca).

Outros importantes são --prefix (cujo padrão é / usr / local / na maioria das vezes) para dizer para onde instalar (se você estiver construindo pacotes, normalmente deseja isso como --prefix = / usr ou talvez --prefix = / opt / YourPackage).

No Linux, / lib, / usr / lib e / usr / local / lib geralmente são pesquisados ​​no meu gcc, e incluídos na configuração padrão do ldconfig. A menos que você tenha um bom motivo, é aqui que você deseja suas bibliotecas. O /etc/ld.so.conf pode listar entradas extras, no entanto.

configure e faça encontrá-los apenas tentando executar "gcc -l" e verificando se há erros. Você pode adicionar "-L" ao seu parâmetro CFLAGS para adicionar caminhos extras à pesquisa.

Você pode ter várias versões instaladas, e o software vinculado a uma versão mais antiga permanecerá vinculado a ela (execute ldd para descobrir a ligação no Linux), mas as novas compilações geralmente visam a versão mais recente de uma biblioteca dinâmica em seu sistema.

A maioria dos softwares assume bibliotecas dinâmicas, especialmente se usar libtool, portanto, você pode achar que aplicativos não triviais não são construídos corretamente estaticamente.

ls -l é sua melhor aposta para encontrar bibliotecas instaladas.

E é aí que estou sem informação; como jogar bem com pacotes: não sei. Quando possível, tento agrupar as coisas em um pacote para evitar o problema.

Aaron Brady
fonte
4

"Como faço para descobrir quais argumentos passar para ./configure?"

normalmente: ./configure --help dirá o que você deseja lá.

"Como posso saber quais bibliotecas eu instalei e quais versões?"

Isso depende do sistema. Uma maneira é simplesmente fazer um find /|grep libname|lessarquivo de biblioteca como geralmente tem a versão no nome do arquivo.

"Como posso instalar mais de uma versão de uma biblioteca sem interromper meu sistema normal?"

Novamente, depende do sistema e da biblioteca. sudo make altinstallirá criar um nome de versão para você. Os arquivos da biblioteca geralmente se modificam. Tenha em mente, no entanto; como as versões geralmente criam links simbólicos para um nome "normalizado", isso pode quebrar as coisas.

"Se estou instalando coisas da fonte em um sistema gerenciado usando pacotes, qual é a maneira mais limpa de fazer isso?"

Usar os parâmetros --prefix em ./configure e colocá-los em algum lugar /opté uma boa prática a seguir.

Isenção de responsabilidade: não sou especialista, mas uso o Linux há mais de 5 anos na linha de cmd (slackware, CentOS, redhat, ubuntu, misc outros e OS X).

Phillip B Oldham
fonte
4

Para responder um pouco da sua pergunta, encontrei um bom caminho outro dia para ver quais bibliotecas você instalou e as versões (isto é no Linux Debian, portanto, também deve funcionar com outras versões).

dpkg --list

Você deve obter uma lista realmente longa com alguma saída como esta

ii  libssl0.9.8    0.9.8c-4etch5  SSL shared libraries
ii  libssp0        4.1.1-21       GCC stack smashing protection library
ii  libstdc++5     3.3.6-15       The GNU Standard C++ Library v3
ii  libstdc++5-3.3 3.3.6-15       The GNU Standard C++ Library v3 (development
ii  libstdc++6     4.1.1-21       The GNU Standard C++ Library v3
Mark Davidson
fonte
4

Simon,

1.) ./configure --help fornece uma boa quantidade de informações. Sugiro dar uma olhada. Geralmente, ele tem opções para compilar bibliotecas estáticas / dinamicamente vinculadas, quando apropriado.

2.) Os libertários vivem no caminho do vinculador dinâmico. Isso geralmente é definido em /etc/ld.so.conf. O vinculador procura as bibliotecas apropriadas, como a variável de ambiente PATH que corresponde à primeira encontrada.

3.) Isso geralmente gera problemas, pois você precisa recompilar tudo quando a versão da biblioteca é alterada. Se você pesquisar, provavelmente encontrará várias razões pelas quais vincular estaticamente é uma má idéia. Eu não faço isso há tanto tempo que não posso realmente elaborar aqui.

4.) Isso é um pouco difícil. Você precisa verificar o caminho da sua biblioteca para ter certeza absoluta. Geralmente, as bibliotecas possuem um link simbólico para a versão instalada.

por exemplo libssh2.so.1 -> libssh2.so.1.0.0

Geralmente as pessoas gerenciam as bibliotecas e programas que instalam rolando seus próprios pacotes debian ou usando alguma outra técnica. Eu gerencio o software instalado usando o stow ( http://www.gnu.org/software/stow/ ), que é muito simples e instala a biblioteca usando links simbólicos. Acho mais fácil, pois não preciso criar / instalar / testar um pacote deb / rpm.

5.) Diversas versões de bibliotecas podem ser instaladas normalmente em diretórios de bibliotecas. As bibliotecas vinculadas aos executáveis ​​permanecerão vinculadas às versões às quais foram vinculadas. executar o ldd em um executável informará a quais bibliotecas o executável está vinculado.

6.) Como mencionei anteriormente, rolar seus próprios pacotes debian ou usar stow é provavelmente a solução mais limpa.

7.) Eu realmente não posso falar pelo Mac OSX, mas para o Linux o sistema de empacotamento da distribuição é o melhor caminho.

8.) Provavelmente, muita frustração será resolvida usando o ldd e descobrindo em qual versão algo está vinculado ou em qual biblioteca vinculada a um executável não pode ser encontrada. O pkg-config o ajudará bastante, mas apenas no software que o utiliza. Ele não faz parte do sistema de criação de ferramentas automáticas padrão, embora seja popular atualmente.

Ian Lewis
fonte
4

Bibliotecas estáticas não são uma boa ideia - se você precisar atualizar a biblioteca (para corrigir um problema de segurança, por exemplo), precisará recompilar tudo com uma dependência dessa biblioteca.

Eu não gosto da idéia de "make install" potencialmente mexer com o meu sistema, mas como outros já disseram, geralmente é muito menos difícil instalar coisas em / usr / local em vez de usar --prefix para instalar em outro lugar. Então, eu cansei / usr / local para meu usuário comum (sem privilégios). Dessa forma, "make install" é praticamente garantido para não mexer com arquivos importantes do sistema. (Obviamente, isso não funcionará em sistemas multiusuário. É ótimo para servidores virtuais.)

ithinkihaveacat
fonte
4

Embora não esteja explicitamente na sua lista de perguntas, você menciona no seu prefácio:

./configure && make && sudo make install geralmente é suficiente, mas às vezes não funciona - e quando não funciona, frequentemente fico preso.

Quando eu ficar preso no Debian ou Ubuntu, usarei o auto-apt, que instalará automaticamente os pacotes que contêm os arquivos que configuram não podem ser encontrados.

Vejo:

Outra ferramenta que você pode achar útil é o CheckInstall, que adiciona aplicativos instalados make installà sua lista de pacotes instalados: https://help.ubuntu.com/community/CheckInstall

Swoogan
fonte
3

Para o OS X:

  • Como faço para descobrir quais argumentos passar para ./configure?

./configure --help

  • Quais são as diferenças reais entre uma biblioteca compartilhada e uma biblioteca vinculada estaticamente? Por que não posso vincular estaticamente tudo (a RAM e o espaço em disco são baratos hoje em dia) e, portanto, evitar conflitos estranhos na versão da biblioteca?

O uso de bibliotecas compartilhadas permite que você atualize a biblioteca sem recompilar tudo o que a utiliza.

  • Como as bibliotecas compartilhadas funcionam no OS X / Linux - onde vivem no sistema de arquivos, como ./configure && make as encontra, o que realmente acontece quando estão vinculadas

As bibliotecas do sistema estão em / usr / lib.

As bibliotecas que você compila vivem em / usr / local / lib (/ usr / local é o sinalizador --prefix padrão para ./configure).

As variáveis ​​de ambiente DYLD_FALLBACK_LIBRARY_PATH e LD_LIBRARY_PATH permitem especificar em quais pastas procurar, portanto, / usr / local / lib deve estar lá no início da lista.

  • Como posso instalar mais de uma versão de uma biblioteca sem interromper meu sistema normal?

Instale tudo em / usr / local - com as variáveis ​​de ambiente acima, a versão em / usr / local / lib tem precedência sobre a versão em / usr / lib em seu ambiente.

  • Se estou instalando coisas da fonte em um sistema gerenciado usando pacotes, qual é a maneira mais limpa de fazer isso?

Instale em / usr / local. No Ubuntu, tento usar o checkinstall primeiro, para criar um pacote deb.

  • Supondo que eu consiga compilar algo complicado da fonte, como posso empacotá-lo para que outras pessoas não precisem pular os mesmos bastidores? Particularmente no OS X ....

Documente as etapas de compilação em uma postagem no blog, eu diria.

Alf Eaton
fonte