Guia do Cross-Compiling para Principiantes

Iniciado por Nosferatu Arucard, 12 de Dezembro de 2013, 16:38

tópico anterior - próximo tópico

Nosferatu Arucard

O Cross-Compiling é o nome genérico para um conjunto de ferramentas de programação destinadas para criar programas que funcionem numa máquina diferente do computador do programador. (Genericamente, é classificado de SDK).
A dificuldade de criar ferramentas num modo universalmente genérico faz que somente para quem tenha paciência para compilar compiladores cruzados (cross-compilers), ou arranjar bibliotecas para linkagem torna o procedimento um bocado assustador para quem tenha alguns conhecimentos de programação.

O exemplo mais comum, é querer portar um software Linux que foi desenvolvido para sistemas x86 e contenha os makefiles para compilar, mas o destino final é um tablet ARM com Android ou uma versão Linux que seja compatível com os toolkits do programa.
Em determinadas plataformas (Android), a Google já lança um SDK completo que instala os compiladores cruzados e optimiza as configurações, especialmente se a máquina-alvo for ARM (se usar MIPS, ou PowerPC então teria que compilar tudo à unha  :P).

Para desanuviar potenciais cenários assustadores, vamos concentrar no método mais simples de querer recompilar software Linux para um sistema Linux ARM que use processadores ARMv7l (conhecidos por armhf, por ter um co-processador matemático por hardware, ao contrário do ARMv6 e anteriores que exige uma biblioteca de emulação, e por isso é conhecido por armel).
Para evitar complicações do que seria a criação de um toolchain compiler (que é compilar nativamente em x86, os compiladores para ARM), vamos usar um truque proporcionado pelos softwares chroot e qemu.  :)

Neste cenário bem mais acessível e amigável a um programador amador (que mal conseguiria recompilar sem mexer no código-fonte), só temos que montar um file-system root virtual (chroot) para o nosso sistema operativo Linux ARM, e usar o qemu para emular um processador ARM (o que torna o procedimento um bocado lento  ;D.)
A vantagem dos cross-compilers é a compilação ser feito em compiladores nativos do nosso sistema x86, mas perde pela dificuldade em compilar bibliotecas em ARM, pois os makefiles não são uniformizados para o cross-compiling

Resumindo, são precisos 7 passos simples e conseguirá em menos de uma hora instalar e correr um sistema ARM numa máquina x86!  :o

1. Abra o Terminal e instale primeiro as seguintes dependências...
sudo apt-get install binfmt-support debootstrap qemu qemu-user-static schroot
(É necessário o Qemu User Mode compilado estaticamente, pois este deve ser um programa auto-suficiente, ou daria problemas!)

2. Crie uma pasta para montar o filesystem virtual. Pode usar a pasta do utilizador, se assim o pretender.
sudo mkdir -p saucy_armhf

3. Ultrapassado essa etapa, vamos usar o comando debootstrap para gerar um chroot Ubuntu Saucy 13.10 (pode usar qualquer versão ou arquitectura, pois basta mudar os parâmetros relevantes)
sudo debootstrap --arch=armhf --foreign saucy ~/saucy_armhf/ http://ports.ubuntu.com

Este passo demora poucos minutos e utiliza até esse momento, ferramentas nativas (x86) do nosso sistema. Como é óbvio, um sistema ARM não vai correr numa máquina x86  :(
Para ultrapassar este obstáculo, basta...

4. Copie o emulador Qemu User Mode Static correcto para o filesystem ARM (para outras arquitecturas é só adaptar correctamente)
sudo cp /usr/bin/qemu-arm-static ~/saucy_armhf/usr/bin/

A única limitação real desta configuração é que um ambiente ARM chrooted não permite a compilação de módulos de kernel ARM nativos, pois somente com um cross-toolchain é possível criar um kernel ARM. Além disso, o nosso sistema ARM virtual nem utiliza um kernel ARM, usa o mesmo kernel x86 do sistema Ubuntu, e o qemu irá traduzir o código ARM para x86 e redireccionar as chamadas de sistema (syscalls) adequadamente. Felizmente, este ambiente é perfeitamente adequado para compilar programas, o que é mais plausível para um programador amador que queira portar alguns programas para outro hardware.  ;)

5. A partir daí, é invocado a emulação ARM (pois aí a execução pode ser entre 5 a 15 vezes mais lenta do que a velocidade nativa do processador x86 nativo), ao configurar o sistema base do Ubuntu ARM:
sudo chroot ~/saucy_armhf/ /debootstrap/debootstrap --second-stage exit
(A seguinte linha diz-nos para montar o sistema ARM e correr o segundo estágio de configuração, finalizando-o logo após a sua conclusão)
A maioria dos pacotes é configurada em alguns segundos, embora um deles (make-dev) leve uns dois ou três minutos...

6. O Ubuntu ARM está agora instalado, mas necessita de algumas configurações adicionais. Usando o Terminal no modo x86, use o nano (x86, que é o habitual...) em root e abra o ficheiro das apt-lists:
sudo nano ~/saucy_armhf/etc/apt/sources.list

Dentro do editor, copie as seguintes linhas do repositório (se quiser, pode acrescentar mais algumas que sejam necessárias, se bem que a arquitectura ARM não seja propriamente a mais vulgar para encontrar software em pacotes em repositórios de terceiros):
deb http://ports.ubuntu.com/ saucy main restricted universe multiverse
deb-src http://ports.ubuntu.com/ saucy main restricted universe multiverse

Salve o ficheiro (Ctrl + O) e saia do nano (Ctrl + X).

7. Só falta configurar um perfil de emulação para terminar a instalação, use o nano (normalmente) e abra o seguinte ficheiro (no nosso sistema x86 familiar):
sudo nano  /etc/schroot/schroot.conf

E acrescente no final a seguinte configuração:
[Ubuntu Saucy ARM]
description=ARM Cross-Compiler
aliases=saucy_armhf
type=directory
directory=/home/nosferatu/saucy_armhf
users=nosferatu
root-groups=root

Guarde e salve o ficheiro da mesma forma que no passo anterior... E já está!  :D

Para arrancar o sistema ARM, basta abrir uma janela de terminal e executar o comando:
schroot -c saucy_armhf

Após um ou dois segundos (para inicializar o qemu) aparece o prompt do Linux ARM virtual!  :)
Teste o sistema executando os seguintes comandos:
sudo apt-get clean
sudo apt-get update
sudo apt-get upgrade

Actualize se for necessário (não se esqueça que a execução é entre 5 a 15 vezes mais lenta do que está habituado!), e pronto!
Agora, pode instalar o gcc, instalar os runtimes GTK e Qt, compilar algum software do Ubuntu x86 que gosta para um tablet Linux ARM, da mesma forma que faria numa máquina x86, sem se preocupar com toolchains, cross-scripts, ARCH=armel e outros problemas chatos!  ;D



Tota

Ola

De onde tirou isto?

O texto é de sua lavra?

É que fiquei com muitas dúvidas. Pelo que entendi um cross-compiling é um sdk.

Se for assim, o sdk da oracle cria uma maquina java e é possivel fazer cross-compiling nela?

Ou sdk significa "software development kit" e algum sdk (como o do google citado) é que permite compilacão cruzada?
CitarA dificuldade de criar ferramentas num modo universalmente genérico faz que somente para quem tenha paciência para compilar compiladores cruzados (cross-compilers)

Também não entendi como "compilar compiladores cruzados"

Compilar não exige um compilador?

[]'s

Nosferatu Arucard

O texto é da minha autoria, baseando em pelo menos três fontes dispersas...
Se houve possível mal-entendido, o cross-compiling (compilação cruzada) é uma ferramenta de compilação destinada a outra arquitectura.
Normalmente os cross-compilers são distribuídos em SDK para eliminar os problemas de compatibilidade.
Podemos compilar de raíz dos cross-compilers e formar um SDK a nosso gosto, do qual é o método mais "correcto" para compilar software para hardware diferente, mas exige uma grande paciência com as bibliotecas.

A respeito deste texto, o uso do chroot para correr uma distro ARM numa máquina x86 é uma forma de montar um sistema para cross-compiling, com a vantagem de ser mais flexível e testar directamente os executáveis da mesma forma que se faria numa máquina x86.
Tem a vantagem adicional de ser mais simples de usar, do que criar cross-toolchains (gnutils) e compilar os cross-compilers.
O seu maior inconveniente é ser um processo lento, pois estamos a emular um sistema ARM completo, e todos os processos de compilação de software, depuração e execução será em média 10% da velocidade que seria obtido com um cross-compiler "convencional".

Ainda relativamente ao guia, um pequeno acrescento:
Se executar aplicações que usam o X Window Server, deverá explicitar a variável Display da seguinte forma:
Caso um programa se chame startlazarus, então dentro do ambiente chroot virtual deverá prefixar:
DISPLAY=:0.0 startlazarus

E programa deverá correr normalmente (mas um bocadinho devagar...  ;D)