GNU/Linux >> Znalost Linux >  >> Linux

32bitová podpora životnosti:Křížová kompilace s GCC

Pokud jste vývojář vytvářející binární balíčky, jako je RPM, DEB, Flatpak nebo Snap, musíte zkompilovat kód pro různé cílové platformy. Mezi typické cíle patří 32bitové a 64bitové x86 a ARM. Můžete vytvářet své buildy na různých fyzických nebo virtuálních strojích, ale to znamená udržovat několik systémů. Místo toho můžete ke křížové kompilaci použít GNU Compiler Collection (GCC) a vytvořit tak binární soubory pro několik různých architektur z jednoho sestavení.

Předpokládejme, že máte jednoduchou hru na házení kostkami, kterou chcete křížově zkompilovat. Něco napsaného v C je na většině systémů relativně snadné, takže abych to přidal na složitosti kvůli realističnosti, napsal jsem tento příklad v C++, takže program závisí na něčem, co v C není (iostream , konkrétně).

#include <iostream>
#include <cstdlib>

using namespace std;

void lose (int c);
void win (int c);
void draw ();

int main() {
  int i;
    do {
      cout << "Pick a number between 1 and 20: \n";
      cin >> i;
      int c = rand ( ) % 21;
      if (i > 20) lose (c);
      else if (i < c ) lose (c);
      else if (i > c ) win (c);
      else draw ();
      }
      while (1==1);
      }

void lose (int c )
  {
    cout << "You lose! Computer rolled " << c << "\n";
  }

void win (int c )
  {
    cout << "You win!! Computer rolled " << c << "\n";
   }

void draw ( )
   {
     cout << "What are the chances. You tied. Try again, I dare you! \n";
   }

Zkompilujte jej ve svém systému pomocí g++ příkaz:

$ g++ dice.cpp -o dice

Poté jej spusťte a potvrďte, že funguje:

$ ./dice
Pick a number between 1 and 20:
[...]

Pomocí souboru můžete vidět, jaký druh binárního souboru jste právě vytvořili příkaz:

$ file ./dice
dice: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically
linked (uses shared libs), for GNU/Linux 5.1.15, not stripped

A stejně tak důležité je, na jaké knihovny odkazuje pomocí ldd :

$ ldd dice
linux-vdso.so.1 => (0x00007ffe0d1dc000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(0x00007fce8410e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
(0x00007fce83d4f000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6
(0x00007fce83a52000)
/lib64/ld-linux-x86-64.so.2 (0x00007fce84449000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1
(0x00007fce8383c000)

Z těchto testů jste potvrdili dvě věci:Binární soubor, který jste právě spustili, je 64bitový a je propojen s 64bitovými knihovnami.

To znamená, že pro křížovou kompilaci pro 32bitovou verzi musíte sdělit g++ komu:

  1. Vytvořte 32bitový binární soubor
  2. Odkaz na 32bitové knihovny namísto výchozích 64bitových knihoven

Nastavení prostředí pro vývojáře

Ke kompilaci do 32bitové verze potřebujete na vašem systému nainstalované 32bitové knihovny a hlavičky. Pokud provozujete čistě 64bitový systém, pak nemáte žádné 32bitové knihovny ani hlavičky a potřebujete nainstalovat základní sadu. Přinejmenším potřebujete knihovny C a C++ (glibc a libstdc++ ) spolu s 32bitovou verzí knihoven GCC (libgcc ). Názvy těchto balíčků se mohou lišit distribuci od distribuce. Na Slackware je čistá 64bitová distribuce s 32bitovou kompatibilitou dostupná z multilib balíčky poskytované Alien BOB. Na Fedoře, CentOS a RHEL:

$ yum install libstdc++-*.i686
$ yum install glibc-*.i686
$ yum install libgcc.i686

Bez ohledu na systém, který používáte, musíte také nainstalovat všechny 32bitové knihovny, které váš projekt používá. Pokud například zahrnete yaml-cpp ve svém projektu, musíte nainstalovat 32bitovou verzi yaml-cpp nebo na mnoha systémech vývojový balíček pro yaml-cpp (například yaml-cpp-devel na Fedoře) před jeho kompilací.

Jakmile se o to postaráte, je kompilace poměrně jednoduchá:

$ g++ -m32 dice.cpp -o dice32 -L /usr/lib -march=i686

-m32 flag říká GCC, aby kompiloval v 32bitovém režimu. -march=i686 volba dále definuje, jaký druh optimalizací se má použít (viz info gcc pro seznam možností). -L flag nastavuje cestu ke knihovnám, na které má GCC odkazovat. Obvykle je to /usr/lib pro 32bitovou verzi, i když v závislosti na nastavení vašeho systému to může být /usr/lib32 nebo dokonce /opt/usr/lib nebo jakékoli místo, o kterém víte, že máte své 32bitové knihovny.

Po zkompilování kódu se podívejte na důkaz vašeho sestavení:

$ file ./dice32
dice: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
dynamically linked (uses shared libs) [...]

A samozřejmě ldd ./dice32 ukazuje na vaše 32bitové knihovny.

Různé architektury

Linuxový terminál

  • 7 nejlepších emulátorů terminálu pro Linux
  • 10 nástrojů příkazového řádku pro analýzu dat v systému Linux
  • Stáhnout nyní:SSH cheat sheet
  • Cheat sheet pro pokročilé příkazy systému Linux
  • Výukové programy příkazového řádku systému Linux

Kompilace 32bitové na 64bitové verzi pro stejnou rodinu procesorů umožňuje GCC učinit mnoho předpokladů o kompilaci kódu. Pokud potřebujete kompilovat pro úplně jiný procesor, musíte nainstalovat příslušné nástroje GCC pro křížové sestavení. Který nástroj nainstalujete, závisí na tom, co kompilujete. Tento proces je o něco složitější než kompilace pro stejnou rodinu CPU.

Když provádíte křížovou kompilaci pro stejnou rodinu, můžete očekávat, že najdete stejnou sadu 32bitových knihoven jako 64bitové knihovny, protože vaše distribuce Linuxu zachovává obě. Při kompilaci pro zcela odlišnou architekturu možná budete muset hledat knihovny požadované vaším kódem. Verze, které potřebujete, nemusí být v úložištích vaší distribuce, protože vaše distribuce nemusí poskytovat balíčky pro váš cílový systém nebo nemusí zrcadlit všechny balíčky na vhodném místě. Pokud je kód, který kompilujete, váš, pak pravděpodobně máte dobrou představu o tom, jaké jsou jeho závislosti a případně kde je najít. Pokud je kód něco, co jste si stáhli a potřebujete zkompilovat, pravděpodobně nejste tak obeznámeni s jeho požadavky. V takovém případě prozkoumejte, co kód vyžaduje ke správnému sestavení (obvykle jsou uvedeny v souborech README nebo INSTALL a určitě i v samotném zdrojovém kódu), a poté shromážděte komponenty.

Pokud například potřebujete zkompilovat kód C pro ARM, musíte nejprve nainstalovat gcc-arm-linux-gnu (32bitový) nebo gcc-aarch64-linux-gnu (64bitový) na Fedoře nebo RHEL nebo arm-linux-gnueabi-gcc a binutils-arm-linux-gnueabi na Ubuntu. To poskytuje příkazy a knihovny, které potřebujete k sestavení (alespoň) jednoduchého programu C. Navíc potřebujete jakékoli knihovny, které váš kód používá. Soubory záhlaví můžete umístit do obvyklého umístění (/usr/include na většině systémů), nebo je můžete umístit do vámi zvoleného adresáře a nasměrovat na něj GCC pomocí -I možnost.

Při kompilaci nepoužívejte standardní gcc nebo g++ příkaz. Místo toho použijte nástroj GCC, který jste nainstalovali. Například:

$ arm-linux-gnu-g++ dice.cpp \
  -I/home/seth/src/crossbuild/arm/cpp \
  -o armdice.bin

Ověřte, co jste vytvořili:

$ file armdice.bin
armdice.bin: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV) [...]

Knihovny a dodávky

Toto byl jednoduchý příklad toho, jak používat křížovou kompilaci. V reálném životě může váš zdrojový kód produkovat více než jen jeden binární soubor. I když to můžete spravovat ručně, pravděpodobně k tomu není žádný dobrý důvod. Ve svém příštím článku předvedu GNU Autotools, které dělá většinu práce potřebné k tomu, aby byl váš kód přenositelný.


Linux
  1. BleachBit 4.1.1 vydán s podporou Cleaning Slack

  2. Vydán Mozilla Firefox 84.0 s nativní podporou Apple Silicon

  3. KeePassXC 2.6.4 Vydán s podporou Apple Silicon M1

  1. Ovladač tiskárny HP HPLIP 3.21.4 Vydán s podporou HP Envy 6400

  2. Kooha – Screen Recorder s podporou Wayland

  3. Jak se vyhnout útokům typu Stack Smashing pomocí GCC

  1. Vydání Kali Linux 1.0.8 s podporou spouštění EFI

  2. Jak zkompilovat 32bitový binární soubor na 64bitovém linuxovém stroji s gcc/cmake

  3. Můj bootloader nelze zkompilovat s gcc 4.6 a 4.7 ... pouze 4.5