Compilar seu software para rodar em quase qualquer lugar, sem nunca usar o root

Bem … nem sempre , acho que se você ainda usou soluções de hospedagem compartilhada com provedores que oferecem apenas uma conta FTP para trabalhar – isso não é para você. Esta dica profissional compartilha as informações que permitirão a alguém, em particular aquelas configurações sem raiz que requerem tal abordagem, usar GNU autotools dentro da pasta pessoal do usuário e reconstruir sua própria /usrhierarquia local de bibliotecas de software para usar, como possivelmente ter outro software depende e é construído. Em particular, qualquer pessoa atualmente usando, LD_LIBRARY_PATHpor exemplo, ~/.bashrcou ~/.zshrcpode se beneficiar desta dica profissional. Já que não assumimos nenhum acesso root, acho que não tenho que avisar / aconselhar contra a compilação de pacotes do código-fonte como root (NUNCA, NUNCA, FAÇA, ISSO).

Público

Ou o “para quem é isso?”. Bem, vamos ver se consigo imaginar um bom perfil de quem pode se beneficiar com essa dica profissional. Você pode já estar procurando por algo nesta ordem, mas provavelmente não sabe o que procurar. Vamos ver. Você tem horas de combate no ambiente do terminal de linha de comando * nix e, na verdade, tem um ou mais ambientes nos quais você trabalha, acesso não-root mais ou menos ‘não supervisionado’ por meio de uma conexão SSH. Você não tem acesso normal ao gerenciador de pacotes Debian ou RPM / Yum (provavelmente sem os comandos por completo) e não pode escrever em /usrou /usr/local. Você ainda deseja executar seu próprio software personalizado, como fazê-lo?

Um exemplo de caso de uso do mundo real

Provedores de hospedagem, como nosso provedor de hospedagem dedicada Magento, podem oferecer acesso não-root ‘não gerenciado’ a ambientes presos / protegidos e redes corporativas. Portanto, no caso de nosso host Magento, eles rodam o parque de servidores web (Apache / nginx) e banco de dados (escravos MySQL / MariaDb) que são otimizados para hospedagem Magento e, no caso de banco de dados não sem importância, a manutenção de freqüentes ajustes de toda a coisa. Mas o acesso para os usuários é limitado a um painel de controle baseado na web que controla as coisas que você pode ajustar sozinho. Isso tem um SLA e garante um certo tempo de atividade e tempo de recuperação de, erh, na maioria desenvolvedores Magento inexperientes, eu acho – e você estragou muito no início, eu prometo – mas a máquina shell (presa, compartilhada por 10 contas) obviamente não tem SLA. Qual é bom,qualquer coisa que possamos gerenciar sem realmente quebrar ou quebrar os sistemas de segurança (se você for essa elite, bom para você), mas sem SLA significa apenas sem suporte (como treiná-los no suporte de operações de linha de comando? não é realmente possível cobrir todo o terreno ) De qualquer forma, o principal motivo que eles dão a você é um lugar de 6 GB para hospedar os arquivos Magento de possivelmente várias pastas e mídias duplicadas e … seu próprio armazenamento memcache. As restrições se aplicam basicamente apenas à leitura / vazamento de coisas que as outras 9 contas estão usando no meu caso.

aviso Legal

Uma palavra de advertência com antecedência. O proprietário da máquina pode tentar fazer isso, pode ter uma política de uso corporativa em vigor que o proíba de fazer isso. Certifique-se de que o que você está prestes a fazer, a compilação do software da fonte, é realmente permitido. Nada é mais fácil do que contrabandear um ou dois arquivos de texto, compile-os na máquina e de repente você terá uma ferramenta de cracking. Portanto, um bom administrador de sistema terá removido quaisquer compiladores ou impedido o acesso a eles por usuários regulares, após qualquer configuração de provisionamento ter sido feita (se for usado gcc, pode ser necessário durante a configuração de máquinas). Além disso, você deve sempre conhecer sua máquina , tanto o hardware quanto o software. Não serei responsabilizado (moral ou legalmente) por nenhuma máquina fraturada ou BOFH irritado portanto, aja com responsabilidade e não mantenha o dedo no gatilho se não tiver certeza absoluta de que deseja puxá-lo.

Linha de base

Neste exemplo, vou mostrar os comandos que usei para compilar o meu próprio zshno host do provedor, uma vez que o único sh oferecido (ba) deles aborrece o bazinga de mim. Sinto falta das funções familiares, o zle, zparseopts e outras coisas legais que vão com o funcionamento do melhor dos dois ( ).zsh > bash

$ uname -a
Linux ssh1 3.2.0-4-grsec-amd64 #1 SMP Debian 3.2.53-2grsec6 x86_64 GNU/Linux

Ok, então eu confirmei que estamos executando um grseckernel. Enquanto tentava compilar antes, zshdescobri que não tínhamos a ncursesbiblioteca instalada, então precisava obtê-la. Vamos baixar e descompactar estas fontes:

$ test -d ~/build || mkdir ~/build; cd $_
$ wget
-qO- http://sourceforge.net/projects/zsh/files/zsh/5.0.5/zsh-5.0.5.tar.gz/download | tar xzv
$ wget
-qO- http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.9.tar.gz | tar xzv

Decidi mostrar alguns pequenos truques apenas para um bônus adicional, você pode ou não querer investigá-los se não conhecer esses comandos.

A rotina normal (FALHA)

Normalmente, as ferramentas GNU autoconfe automakesoftware construído, e há muitos pacotes oferecidos dessa forma, permitirão que alguém faça, por exemplo, o seguinte para configurar, construir / compilar e instalar o software:

$ cd some-package-sources
$
./configure
$ make
&& make install

Se alguma biblioteca essencial (cabeçalhos) estiver faltando, você será informado durante a etapa de configuração ou durante a criação do software. Nesse caso, você precisa descobrir qual componente está faltando e esperar por uma árvore de dependência muito simples que se segue a partir dele ou ficará preso no inferno de dependências. Esta é realmente a maioria dos gerenciadores de pacotes de merda como aptitudeetc. tentam lidar com o seu: detecte automaticamente os pacotes dependentes e instale-os primeiro antes do que depende deles (essa e outras condições atômicas / de corrida principalmente mais, bem, eles são confortável de usar – coisas arcaicas como essas ferramentas não fazem com que muitas pessoas saibam como operá-las e, então, escrevam sobre isso)

De qualquer maneira, essa tentativa não funcionará principalmente porque comandos inalterados (sem argumentos para, por exemplo) geralmente tentarão instalar software e, lembre-se, não temos permissões de gravação para essa pasta. Algumas equipes de desenvolvimento, mais ativas, na verdade configuram para oferecer um melhor suporte pronto para as pastas graváveis ​​pelo usuário, mas muitas vezes esse é apenas o caso para a configuração de um único usuário ou um ambiente onde, talvez, uma equipe de desenvolvimento pudesse receber uma parte (por exemplo ) permissões de gravação de arquivos e pastas, mas muitos ainda não o fazem../configure/usr/usr/localsetfacl/usr/local

Sempre há um local gravável para nós praticamente garantido: mas qualquer administrador de sistema que valha seu dinheiro não permitirá a execução de executáveis ​​compilados neles. Não. Existe um lugar melhor para fazer isso, é por isso que fizemos a pasta, não só para baixar, mas também para construir. Mas onde instalar?/tmp~/build

Instalando na casa do usuário (AGAIN FAIL)

O fantástico $HOMEoferece o resultado. É um lugar que, se você tiver acesso ao terminal, pode confiar que será total e verdadeiramente seu em todos os aspectos. É o lugar perfeito para configurar nossa hierarquia de sistema de arquivos ‘imitar’ de bibliotecas e pacotes ausentes. A prática comum fornece mais ou menos a localização para nós, mas isso não é obrigatório para a pasta, obviamente. Você poderia, mas provavelmente não deveria, nomear os diretórios de outra forma.

$ mkdir ~/local

Perfeito. Com isso no lugar, podemos adicionar nosso primeiro argumento ao script de configuração:

$ ./configure --prefix=$HOME/local

Muitas vezes, eu descobri, é tão simples e muitos fontes compilarão muito bem dessa maneira. No entanto, se você precisar de bibliotecas dinâmicas compiladas personalizadas para vincular (como eu faço com ncurses), você terá problemas.

Uma maneira que tradicionalmente usei para lidar com isso foi por meio de um afixo no comando como:./configure

$ env CPPFLAGS='-I/home/myuser/local/include' 
> LDFLAGS='-L/home/myuser/local/lib/' ./configure

Observe que GNU autoconf e autotools levam muitas, muitas opções de configuração e a documentação nem sempre pode ser facilmente encontrada ou totalmente compreendida. Felizmente, a maioria das variáveis ​​de ambiente e valores / sinalizadores são usados ​​automaticamente ou quase nunca são usados. Para sua referência, a documentação GNU é provavelmente um começo útil.

Sem entrar em detalhes sobre o que são exatamente CPPFLAGS(sinalizadores do compilador C ++) e LDFLAGS(sinalizadores do vinculador dinâmico), acredite que eles podem ser muito importantes e podem ser ajustados para corresponder à sua situação. Talvez seja importante notar que (menos i) acrescentará esses caminhos aos locais já conhecidos, como por exemplo ou . Portanto, os locais do sistema nativo não são esquecidos e podem ser usados ​​para fazer o link.-I/usr/include/usr/local/include

Resta uma Pièce de résistance final. E se você não souber o nome dele, será muito difícil pesquisar no Google o que você não sabe que está realmente procurando.

O evasivo (FTW!)config.site

Há um mecanismo integrado muito interessante para localizar as variáveis ​​de ambiente de que nossas ferramentas precisam. É chamado de e é tudo que você precisava e muito mais. Basicamente, ele permite que você ignore a configuração manual tediosa e demorada normalmente associada a esses comandos.config.site

  1. coloque um arquivo na pasta de localização, por exemploshare//home/myuser/local/share
  2. nomeie esse arquivo config.site
  3. faça com que seu conteúdo defina seus sinalizadores de compilação

A mais elegante das soluções permite uma configuração diversamente rica para usar como linha de base. Mais informações podem ser encontradas aqui . Por um lado, ele nos permite definir um sinalizador de compilação que venho sugerindo: o kernel grsec às vezes requer sinalizador. ncurses vai precisar dele e você pode ler sobre o que ele faz aqui .-fPic

Eu tenho o seguinte definido em ~/local/share/config.site

CHOST="x86_64-unknown-linux-gnu"

# util-linux and other programs might complain for libraries not in standard location
# this goes for a few header files `<ncurses.h>` and `<term.h>` which many libs/apps use
# the last addition `-I` to `/ncurses` fixes this since a component relies on this it fails all
CPPFLAGS
="-I/home/myuser/local/include -I/home/myuser/local/include/ncurses"
LDFLAGS
=-L/home/myuser/local/lib

# next line you may find the need to toggle or remove from -fPIC -fstack-protector
# for not everything may appreciate its use (glibc compile may fail for example)
CFLAGS
="-march=native -O2 -pipe -fPIC -fstack-protector"
CXXFLAGS
="$CFLAGS"

# the -j stands for the number of jobs to simultaneously run, principle is to simply
# set the -j value to the number of cores plus 1, or at least common in Gentoo/Arch.
MAKEFLAGS
="-j5"

# foreign function interface library: high level programming interface
# for one, it allows packages to compile without explicit use of pkg-config tool
LIBFFI_CFLAGS
=-I/home/myuser/local/lib/libffi-3.1/include
LIBFFI_LIBS
="-L/home/myuser/local/lib -lffi"

Você pode querer reservar algum tempo para ler e estudar cuidadosamente essas e outras variáveis ​​de ambiente que afetam o gcc . Muitos deles podem nunca ser usados ​​efetivamente, mas alguns são realmente úteis para configurar corretamente e irão ajustar e otimizar ainda mais seu processo de construção. Mas cuidado: certifique-se de que as estatísticas de hardware fornecidas estão corretas, por exemplo, não use mais sinalizadores do que sua máquina pode controlar e use em vez-j3core2nativepode otimizar um pouco sua produção, a última é mais freqüentemente a aposta mais segura em que você não pode errar! Você deve se informar sobre quaisquer culpados que possam se aplicar à sua situação antes de fazer qualquer coisa precipitada e estúpida (você já foi avisado o suficiente). Google as perguntas que você pode ter – apenas como uma observação geral – a documentação, referências, postagens de blog e outras fontes de informação tornam-se muito escassos em algum ponto conforme você se aprofunda na matriz: da área de usuário ao kernel e ao código de máquina, menos você será capaz de desenterrar fontes (obrigado, capitão, óbvio) com as quais você esteja acostumado e confortável. Incluindo a mim mesmo: de alguma forma, nunca vou aprender a amar os manuais Zsh, Apache ou GNU, mas a informação geralmente está lá e você só terá que fazer as perguntas certas, pesquisar com inteligência e obter essas informações. Ah – e bem-vindo ao mundo das listas de discussão, usenet e IRC, caso você ainda não tenha se familiarizado. Você verá muitos deles.

Agora, de volta ao caso de exemplo, devemos agora tentar construir a biblioteca de terminal ncurses e, dado o arquivo de exemplo mencionado acima , devemos (depois de estudar e ajustar os valores à sua situação pessoal) avançar:config.site

$ cd ~/build/ncurses-source-folder
$ mkdir build
&& cd build
$
./../configure --prefix=$HOME/local
$ make
&& make install

Graças à nossa nova ‘mágica’ encontrada, estamos de volta aos comandos de ‘corte limpo’ novamente, embora a configuração real para construir o software tenha alguma complexidade adicional na parte de trás, o resultado final na frente é muito mais desejável . No entanto, uma coisa a se ter em mente: nem todo pacote será tão tolerante e você pode ter que recorrer a mais pesquisas para descobrir quaisquer opções específicas de longo ou curto que você precisa fornecer. Felizmente, a saída de erro é freqüentemente uma dica boa o suficiente para resolver problemas rápido o suficiente e muito raramente alguém realmente precisa ‘ir fundo’ e alterar, por exemplo, arquivos autoconf, m4, libtool e outros. As opções podem se aplicar apenas a essa ferramenta e sua própria configuração específica, por isso é difícil ser específico, mas frequentemente também você pode incluir e excluir bibliotecas / módulos compilados com os binários resultantes.:versionmostra estes) não foi incluído? Interruptores de compilação.

O padrão se repete para a pasta de origem zsh. Nesse ponto, percebi uma violação anterior de uma prática recomendada: dei comandos para compilar diretamente no (agora corrigi isso, mas pensei que deveria compartilhar), mas é muito melhor não construir diretamente no código-fonte. Porém, uma subpasta é aceitável (pelo que me lembro), então como segundo comando na sequência abaixo, criamos a pasta e configuramos + make a partir dela:ncurses-source-folder/build/

$ cd ~/build/zsh-source-folder
$ mkdir build
&& cd build
$
./configure --prefix=$HOME/local
$ make
&& make install

Se algo der errado e você tiver que começar de novo de alguma forma, lembre-se:

$ make distclean

O padrão típico é make cleanremover todos os arquivos intermediários e make distcleandeixar a árvore do jeito que estava quando foi descompactada (ou algo bem parecido) incluindo a remoção de qualquer saída do script de configuração. E dependendo dos autores do pacote, outros comandos make podem estar disponíveis frequentemente: test, uninstall, dist e outros.

Acho que devo dar o exemplo de fechamento adequado, ou seja, amarrar as últimas pontas soltas porque ainda não chegamos a 100%. Era necessário pelo menos mais um passo para me reunir verdadeira e totalmente com um velho amigo em terras estrangeiras; bastante compreensível, mas sem o root, não é possível alterar o shell (usando com freqüência chsh) e modificar o arquivo para que no próximo login, possamos usar zsh imediatamente. Devido a essas restrições, é difícil recorrer ao que eu poderia chamar de uma carona nas costas fornecida pelo bash, um impulso para todo o trabalho. Bash e clib fornecem apenas o mecanismo para este ‘hack’, usando os arquivos auto-carregados do bash que podemos modificar (em nossa casa), sendo (não funcionou em meu host) ou , que funcionou:/etc/passwd~/.profile~/.bash_profile

# ~/.bash_profile
export PATH="$HOME/local/bin:$PATH" # ensure shebang #!/usr/bin/env zsh works
export SHELL=$HOME/local/bin/zsh # set the shell environment variable
exec $SHELL # do not spawn a new sub-shell / fork the process - rather replace altogether

A maioria das técnicas ilustradas neste exemplo deve fornecer material suficiente para trabalhar. Lembre-se de que a cadeia pode quebrar em dependências ausentes durante a configuração ou posteriormente ao fazer o software. Nesse caso, inspecione a saída e encontre o comando ausente, depois Google e veja a qual pacote esse comando pertence e tente encontrar o código-fonte para ele. Praticamente todo o GNU pode ser baixado como fonte, e muitas coisas também podem ser encontradas no GitHub .

Desfrute de mexer e usar seus novos poderes com sabedoria.

PS Eu adoraria ouvir de você. Comentários, acréscimos, erros, críticas ou apenas feedback simples são apreciados e se algo exigir elaboração ou esclarecimento, pergunte nos comentários.