Uma compilação cruzada (cross-compiling) permite que programas sejam compilados para execução em plataformas diferentes daquela na qual o compilador está sendo executado. É comum nos depararmos com a necessidade de realizar este tipo de compilação quando estamos trabalhando com equipamentos embarcados, que geralmente possuem poder de processamento e armazenamento mais limitados, fazendo com que uma compilação nativa seja mais lenta. Outro aspecto que deve ser considerado é que ferramentas como toolchains de compilação ocupam uma quantidade considerável de armazenamento. Como este é um recurso limitado em muitos dispositivos embarcados, é prática comum excluir estas ferramentas do sistema, mantendo somente o binário da aplicação. Isso também colabora para que o sistema seja mais seguro.
Existem diversas ferramentas que auxiliam no processo de cross-compilação. Entre essas ferramentas estão as IDEs, que além de fornecerem funcionalidades que auxiliam na construção do próprio software, também permitem realizar compilações cruzadas, fazendo com que os binários gerados possam ser executados em outras arquiteturas.
Neste artigo temos como objetivo criar e cross-compilar um programa em um computador com a arquitetura x86 utilizando a IDE Lazarus para que seja executado em um microprocessador com a arquitetura ARM.
Setup
Neste artigo utilizaremos um computador em módulo Arm Colibri iMX6DL da Toradex, que é baseado no SoC i.MX6 da NXP. Além dele, utilizaremos a placa base Aster conectada a um display de 7”, ambos também da Toradex.
Mãos à obra!
Em primeiro lugar instalaremos todas as dependências para instalarmos o FPC (Free Pascal Compiler). Como o nome mesmo diz, este é basicamente o compilador da linguagem que utilizaremos. Para o Lazarus, felizmente existe uma ferramenta chamada fpcupdeluxe que irá nos auxiliar na instalação dos itens mencionados acima. Trata-se de uma aplicação com interface gráfica de fácil utilização feita para instalar juntos o FPC e o Lazarus.
O primeiro passo é instalar os pré-requisitos para que a ferramenta consiga realizar o build de todos os componentes. Caso você esteja no Windows, a ferramenta irá fazer o download de todos os binários necessários. Caso esteja em um computador Linux, será necessário instalar as dependências com o seguinte comando, utilizado para Debian/Ubuntu:
1 2 |
$ sudo aptitude install make binutils build-essential gdb subversion zip unzip libx11-dev libgtk2.0- dev libgdk-pixbuf2.0-dev libcairo2-dev libpango1.0-dev |
Vamos então baixar a ferramenta e dar permissões de execução a ela:
1 2 |
$ wget https://github.com/LongDirtyAnimAlf/fpcupdeluxe/releases/download/1.6.2x/fpcupdeluxe-x86_64-linux $ chmod +x fpcupdeluxe-x86_64-linux |
Agora podemos executá-la através da linha de comando:
1 |
$ ./fpcupdeluxe-x86_64-linux |
Ao executar, a seguinte interface gráfica deve aparecer:
Deve-se então selecionar o caminho da instalação, a versão desejada, clicar em Install e pronto! A ferramenta irá fazer basicamente todo o trabalho para você. Caso tudo corra bem, você deve ter a seguinte saída:
O próximo passo é instalar o compilador. Para isso, selecione a aba Cross, então selecione a CPU arm e o OS linux como demonstrado na imagem abaixo, então clique em Install compiler.
Caso tudo corra bem, você deve receber uma saída conforme a figura abaixo:
Um executável deve ter sido criado no diretório home do seu computador. Vamos agora iniciá-lo:
1 2 |
$ cd ~ $ ./Lazarus_fpcupdeluxe |
Temos agora o ambiente do Lazarus sendo executado em nosso computador. Neste artigo irei executar um pequeno hello world que terá como função alterar o texto de um botão ao pressioná-lo.
Para iniciar um projeto, vamos em File → New … → Project → Application. Para criar um novo botão selecionamos TButton na aba Standard da barra de ferramentas e clicamos na janela Form1:
Agora acessamos a janela Object Inspection e selecionamos o botão criado anteriormente. Na aba Events, e damos um duplo clique na função OnClick. Você será redirecionado para uma parte do código onde deve ser adicionada a seguinte linha:
1 2 3 4 |
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction); begin Button1.Caption:='Olá Mundo'; end; |
Após termos o programa criado, devemos agora configurar o projeto para realizar a compilação cruzada para ARM, para isso acessamos Project → Project Options → Compiler Options → Config and Target e configuramos da seguinte forma:
Após termos o programa e as configurações feitas, podemos então compilar o programa clicando em Run → Build. É possível descobrir o diretório do binário gerado na aba Messages do Lazarus. No meu caso, o binário foi gerado em /home/daniel/fpcupdeluxe/projects/project1.
Agora que temos nosso binário gerado, podemos tentar executá-lo em nosso computador para verificar se realmente ele foi cross compilado corretamente. Se tudo correu bem, você deve receber a seguinte saída:
1 2 3 |
$ cd ~/fpcupdeluxe/projects $ ./project1 bash: ./project1: cannot execute binary file: Exec format error |
Além disso, podemos também utilizar o comando file para obtermos mais informações sobre o binário:
1 2 |
$ file project1 project1: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 2.0.0, not stripped |
Sabendo que o binário foi realmente compilado para Arm, basta agora enviá-lo para a nossa plaquinha e executá-lo:
1 2 3 |
$ scp project1 root@<ip-da-placa>:/home/root # cd ~ # ./project1 |
Aplicação sendo executada no módulo Colibri iMX6 da Toradex
Parabéns pelo artigo, ficou fenomenal… Como entro em contato contigo, para tirar umas dúvidas, Daniel?
Muito legal seu artigo,sobre o uso do lazarus, ha muito tempo não vejo algo assim.
Trabalho com ele, porem não conhecia esse aplicativo. Sempre fiz compilação no proprio equipamento.
O que notei é que alguns componentes não suportam em todas as plataformas, o que não acontece quando instalamos nativamente.
O Lazarus é promissor, pena que o mercado tem tanta restrição.
Uso o Lazarus desde 2007 (versão 0.9.23).Posso afirmar que o mercado deveria adota-lo.