Cross-compiling tools package guidelines (Português)

From ArchWiki
Status de tradução: Esse artigo é uma tradução de Cross-compiling tools package guidelines. Data da última tradução: 2020-03-27. Você pode ajudar a sincronizar a tradução, se houver alterações na versão em inglês.
Diretrizes de pacotes do Arch

32-bitCLRCMakeCrossDKMSEclipseElectronFonteFree PascalGNOMEGoHaskellJavaKDEKernelLispMesonMinGWNode.jsNonfreeOCamlPerlPHPPythonRRubyRustVCSWebWine

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.

Dica: Como alternativa à criação de pacotes de compiladores cruzados, você poderia usar crosstool-ng e criar sua própria cadeia de ferramentas de maneira totalmente automatizada. crosstool-ng pode ser encontrado em crosstool-ngAUR.

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

Atenção: O uso de versões incompatíveis de pacotes para compilação da cadeia de ferramentas leva a falhas inevitáveis. Por padrão, considere todas versões incompatíveis.

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 e NEWS, 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 é:

  1. binutils: Compile um cross-binutils, que vincula e processa para a arquitetura de destino
  2. cabeçalhos: Instale um conjunto de bibliotecas C e cabeçalhos de kernel para a arquitetura de destino
    1. use linux-api-headers como referência e pesse ARCH=target-architecture para o make
    2. crie um pacote de cabeçalhos libc (o processo para Glibc é descrito aqui)
  3. 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).
  4. libc: Compile a biblioteca C "cross-compilada" (usando o compilador cruzado do estágio 1).
  5. gcc-stage-2: Compile um compilador cruzado C completo (estágio 2)

O fonte dos cabeçalhos e libc podem variar conforme a plataforma.

Dica: O procedimento exato varia muito, dependendo das suas necessidades. Por exemplo, se você quiser criar um "clone" de um sistema Arch Linux com as mesmas versões de kernel e glibc, você pode pular cabeçalhos de construção e passar --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 <[email protected]>

# 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}
}
Nota: Durante a compilação de cadeia de ferramentas cruzadas sempre execute os comandos 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:

  1. Primeiro, de acordo com o File Hierarchy Standard, esses arquivos pertencem apenas a um lugar no /usr.
  2. 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ção build() (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).

Veja também