Cross-compiling tools package guidelines (Português)
32-bit – CLR – CMake – Cross – DKMS – Eclipse – Electron – Fonte – Free Pascal – GNOME – Go – Haskell – Java – KDE – Kernel – Lisp – Meson – MinGW – Node.js – Nonfree – OCaml – Perl – PHP – Python – R – Ruby – Rust – VCS – Web – Wine
Essa página descreve como criar pacotes para cadeias de ferramentas de compilador cruzado. Outro método para compilação cruzada, faz uso de distcc em arquiteturas misturadas. Consulte Distcc#Cross compiling with distcc.
Nota importante
Esta página descreve a nova maneira de fazer as coisas, inspirada nos seguintes pacotes:
-
mingw-w64-gcc e outros pacotes da série
mingw-w64-*
-
arm-none-eabi-gcc e outros pacotes da série
arm-none-eabi-*
- E outros pacotes da série
arm-wince-cegcc-*
Compatibilidade de versão
As seguintes estratégias permitem que você selecione versões compatíveis do gcc, binutils, kernel e biblioteca C:
- Regras gerais:
- existe uma correlação entre as versões gcc e binutils, use versões lançadas simultaneamente;
- é melhor usar os cabeçalhos mais recentes do kernel para compilar a libc, mas use o opção
--enable-kernel
(específica da glibc, outras bibliotecas C podem usar convenções diferentes) para reforçar o funcionamento em kernels mais antigos;
- Repositórios oficiais: talvez seja necessário aplicar correções adicionais e hacks, mas as versões usadas pelo Arch Linux (ou seus forks específicos de arquitetura) provavelmente podem funcionar juntas;
- Documentação de software: todo software GNU tem arquivos
README
eNEWS
, documentando coisas como versões mínimas exigidas de dependências; - Outras distribuições: elas também fazem compilação cruzada;
- https://clfs.org cobre etapas necessárias para compilação de compilador cruzado e menciona versões um pouco atualizadas de dependências.
Compilando um compilador cruzado
A abordagem geral para construir um compilador cruzado é:
- binutils: Compile um cross-binutils, que vincula e processa para a arquitetura de destino
- cabeçalhos: Instale um conjunto de bibliotecas C e cabeçalhos de kernel para a arquitetura de destino
- use linux-api-headers como referência e pesse
ARCH=target-architecture
para o make - crie um pacote de cabeçalhos libc (o processo para Glibc é descrito aqui)
- use linux-api-headers como referência e pesse
- gcc-stage-1: Compile um compilador cruzado gcc básico (estágio 1). Isso será usado para compilar a biblioteca C. Ele não conseguirá compilar quase nada mais (porque ele não consegue se vincular à biblioteca C que ele não tem).
- libc: Compile a biblioteca C "cross-compilada" (usando o compilador cruzado do estágio 1).
- gcc-stage-2: Compile um compilador cruzado C completo (estágio 2)
O fonte dos cabeçalhos e libc podem variar conforme a plataforma.
--with-build-sysroot=/
para o configure
.Nomenclatura de pacote
O nome do pacote não deve ser prefixado com a palavra cross-
(foi proposto anteriormente, mas não foi adotado em pacotes oficiais, provavelmente devido ao comprimento adicional de nomes), e consistirá do nome do pacote, prefixado por trio GNU sem campo de fornecedor ou com "desconhecido" no campo do fornecedor; exemplo: arm-linux-gnueabihf-gcc
. Se houver uma convenção de nomenclatura mais curta (por exemplo, mips-gcc
), ela poderá ser usada, mas isso não é recomendado.
Colocação de arquivos
As versões mais recentes do gcc e do binutils usam caminhos não conflitantes para sysroot e bibliotecas. Os executáveis devem ser colocados em /usr/bin/
, para evitar conflitos aqui, prefixar todos eles com o nome da arquitetura.
Geralmente, ./configure
teria pelo menos os seguintes parâmetros:
_target=seu_alvo _sysroot=/usr/lib/${_target} ... ./configure \ --prefix=${_sysroot} \ --sysroot=${_sysroot} \ --bindir=/usr/bin
sendo que seu_alvo
pode ser, p. ex., "i686-pc-mingw32"
Exemplo
Esse é o PKGBUILD do binutils para MinGW. Coisas interessantes de se observar são:
- especificar o diretório raiz do ambiente cruzado
- o uso de variáveis
${_pkgname}
,${_target}
e${_sysroot}
para fazer o código mais legível - remoção de arquivos duplicados/conflitantes
# Maintainer: Allan McRae <allan@archlinux.org> # cross toolchain build order: binutils, headers, gcc (pass 1), w32api, mingwrt, gcc (pass 2) _target=i686-pc-mingw32 _sysroot=/usr/lib/${_target} pkgname=${_target}-binutils _pkgname=binutils pkgver=2.19.1 pkgrel=1 pkgdesc="MinGW Windows binutils" arch=('i686' 'x86_64') url="http://www.gnu.org/software/binutils/" license=('GPL') depends=('glibc>=2.10.1' 'zlib') options=('!libtool' '!distcc' '!ccache') source=(http://ftp.gnu.org/gnu/${_pkgname}/${_pkgname}-${pkgver}.tar.bz2) md5sums=('09a8c5821a2dfdbb20665bc0bd680791') build() { cd ${srcdir}/${_pkgname}-${pkgver} mkdir binutils-build && cd binutils-build ../configure --prefix=${_sysroot} --bindir=/usr/bin \ --with-sysroot=${_sysroot} \ --build=$CHOST --host=$CHOST --target=${_target} \ --with-gcc --with-gnu-as --with-gnu-ld \ --enable-shared --without-included-gettext \ --disable-nls --disable-debug --disable-win32-registry make make DESTDIR=${pkgdir}/ install # clean-up cross compiler root rm -r ${pkgdir}/${_sysroot}/{info,man} }
configure
e make a partir do diretório dedicado (chamada compilação fora da árvore) e remova todo o diretório src
após a menor mudar em PKGBUILD.Comos e por ques
Por que não instalar em /opt
?
Dois motivos:
- Primeiro, de acordo com o File Hierarchy Standard, esses arquivos pertencem apenas a um lugar no
/usr
. - Em segundo lugar, a instalação em
/opt
é a última medida quando não há outra opção.
O que é o negócio de out-of-path executables?
Essa coisa estranha facilita a compilação cruzada. Às vezes, os Makefiles do projeto não usam CC
e outras variáveis e, em vez disso, usam 'gcc' diretamente. Se você quiser apenas tentar compilar esse projeto, a edição do Makefile pode ser uma operação muito demorada. No entanto, alterar o $PATH
para usar "nossos" executáveis primeiro é uma solução muito rápida. Você então executaria PATH=/usr/arch/bin/:$PATH make
em vez de make
.
Solução de problemas
O que fazer se a compilação falhar sem uma mensagem clara?
Para um erro ocorrido durante a execução do configure
, leia $srcdir/pkgname-build/config.log
. Para erro ocorrido durante compilação, role o log do console ou pesquise pela palavra "error".
O que esse erro [error message] significa?
Muito provavelmente você fez algum dos erros não óbvios:
- Muitos ou poucos sinalizadores de configuração. Tente usar um conjunto já comprovadamente correto de sinalizadores.
- As dependências estão corrompidas. Por exemplo, arquivos de binutils perdidos ou colocados no lugar errado podem resultar em erros ocultos durante a configuração do gcc.
- Você não adicionou
export CFLAGS=""
à sua funçãobuild()
(veja bug 25672 no Bugzilla do GCC). - Algumas combinações
--prefix
/--with-sysroot
podem exigir que diretórios sejam graváveis (não óbvias em guias de clfs). - sysroot ainda não tem cabeçalhos de kernel/libc.
- Se google-fu não ajudar, abandone imediatamente sua configuração atual e tente uma mais estável e de funcionamento confirmado.
Por que os arquivos são instalados em lugares errados?
Vários métodos de execução da linha genérica make install
acabam em resultados diferentes. Por exemplo, alguns destinos de make podem não fornecer suporte a DESTDIR
e, em vez disso, requerem o uso de install_root
. O mesmo para tooldir
, prefix
e outros argumentos semelhantes. Às vezes, fornecendo parâmetros como argumentos em vez de variáveis de ambiente, p. ex.
./configure CC=arm-elf-gcc
em vez de
CC=arm-elf-gcc ./configure
e vice-versa pode resultar em resultados diferentes (geralmente causados por auto-invocação recursiva de configure/make).