- How to Compile 32-bit Apps on 64-bit Ubuntu?
- 3 Answers 3
- Как запустить 32-битное приложение на 64-битном Linux
- Как запустить 32-битное приложение на 64-битном Linux
- 1. Добавьте архитектуру i386
- 2. Установите необходимые библиотеки пакетов
- 3. Выполните 32-битную программу
- Заключение
- Похожие записи:
- Блог начинающего сисадмина
How to Compile 32-bit Apps on 64-bit Ubuntu?
I’m trying to compile a 32-bit C application on Ubuntu Server 12.04 LTS 64-bit using gcc 4.8. I’m getting linker error messages about incompatible libraries and skipping -lgcc . What do I need to do to get 32 bit apps compiled and linked?
3 Answers 3
This is known to work on Ubuntu 16.04 through 22.04:
sudo apt install gcc-multilib g++-multilib
Then a minimal hello world:
compiles without warning with:
gcc -m32 -ggdb3 -O0 -pedantic-errors -std=c89 \ -Wall -Wextra -pedantic -o main.out main.c
main.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=87c87a83878ce7e7d23b6236e4286bf1daf59033, not stripped
but fails on an x86_64 executable with:
./main.out: Invalid ELF image for this architecture
It is a shame that this package conflicts with the cross compilers like gcc-arm-linux-gnueabihf https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211
Running versions of the question:
We are able to run 32-bit programs directly on 64-bit Ubuntu because the Ubuntu kernel is configured with:
grep CONFIG_IA32_EMULATION "/boot/config-$(uname -r)"
Include code to run legacy 32-bit programs under a 64-bit kernel. You should likely turn this on, unless you're 100% sure that you don't have any 32-bit programs left.
This is in turn possible because x86 64 bit CPUs have a mode to run 32-bit programs that the Linux kernel uses.
TODO: what options does gcc-multilib get compiled differently than gcc ?
Doesn’t work in podman/docker container with Ubuntu 18.04. As a matter of fact, I don’t see why would it ever work, because the mentioned gcc-multilib packages barely has any files, and certainly it has no libraries in them.
So, what helped for me in a docker/podman container with Ubuntu, is to install lib32gcc-10-dev (worth noting, the 10 version in my case is from PPA; without PPA it would be a lower version).
To get Ubuntu Server 12.04 LTS 64-bit to compile gcc 4.8 32-bit programs, you’ll need to do two things.
- Make sure all the 32-bit gcc 4.8 development tools are completely installed: sudo apt-get install lib32gcc-4.8-dev
- Compile programs using the -m32 flag gcc pgm.c -m32 -o pgm
Note that the -m32 flag is specific to 32-bit x86. You need different flags to compile for 32-bit ARM, RISC-V, etc.
Multiarch installation is supported by adding the architecture information to the package names you want to install (instead of installing these packages using alternative names, which might or might not be available).
See this answer for more information on (modern) multiarch installations.
In your case you’d be better off installing the 32bit gcc and libc:
sudo apt-get install libc6-dev:i386 gcc:i386
It will install the 32-bit libc development and gcc packages, and all depending packages (all 32bit versions), next to your 64-bit installation without breaking it.
Как запустить 32-битное приложение на 64-битном Linux
Почти каждая система Linux имеет как 32-битную, так и 64-битную архитектуру. Но проблема в том, что по умолчанию приложение, написанное для работы на 32-битной системе, не будет работать на 64-битной системе и наоборот. Это может быть очень неприятно, поскольку никто не хочет разрабатывать два исходных кода для одного и того же приложения или поддерживать два отдельных бинарных файла для разных архитектур. Вы можете решить эту проблему, сделав так, чтобы 32-битная программа могла работать на 64-битной архитектуре. В этой статье мы узнаем, как запустить 32-битное приложение на 64-битном Linux.
Как запустить 32-битное приложение на 64-битном Linux
Ниже описаны шаги для запуска 32-битных приложений в 64-битной системе Linux. Чтобы иметь возможность запускать 32-битные программы на 64-битной системе Linux, такой как Ubuntu, необходимо добавить архитектуру i386 и установить 3 библиотечных пакета libc6:i386, libncurses5:i386 и libstdc++6:i386.
1. Добавьте архитектуру i386
Откройте терминал и выполните следующую команду.
sudo dpkg --add-architecture i386
2. Установите необходимые библиотеки пакетов
Затем выполните следующую команду для установки 3 библиотек пакета.
sudo apt-get update sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386
Если вышеуказанная команда не сработала, выполните следующую команду.
sudo apt-get install multiarch-support
3. Выполните 32-битную программу
Теперь вы должны иметь возможность запустить 32-битную программу на 64-битной системе. Замените приведенное ниже sample32bitprogram на имя файла бинарного файла вашей программы.
Если вы используете несовместимую версию gcc на вашей системе Ubuntu, вы можете получить ошибку при выполнении вышеуказанных команд, вам может потребоваться обновить gcc с помощью следующей команды.
sudo apt-get install gcc-multilib
Заключение
В этой статье мы узнали, как запускать 32-битные программы на 64-битных, не создавая отдельные бинарные файлы как для 32-битных, так и для 64-битных систем.
Похожие записи:
Блог начинающего сисадмина
На сегодняшний день все выпускаемые процессоры так или иначе поддерживают 64-битную архитектуру. В связи с тем, что 32-битные процессоры могут адресовать 232 бита данных, они не могут работать с памятью более 4 Гб, однако процессоры на архитектуре x86-64, могут работать с гораздо более большим объемом памяти. Отличительными особенностями новых процессоров является поддержка 64-битных регистров общего назначения (РОН), арифметических и логических операций над целыми числами и поддержкой 64-битных виртуальных адресов.
В GNU Linux для того чтобы узнать разрядность процессора, существует команда lscpu :
$ lscpu | grep Architecture
Architecture: x86_64
Поле Architecture отображает разрядность процессора ( x86_64 ), в случае 32-битного процессора значение этого поля было бы i686 ( i386 ).
Для того, чтобы узнать разрядность операционной системы, существует команда arch :
$ arch
x86_64
В довольно редких случае необходимо запускать программы, написанные под 32х-битную ОС когда-то давно на новых операционных системах. Существует несколько способов запуска 32-битных программ на 64-битной системе:
— с использованием нативной поддержки (multiarch)
— с использованием технологий ядра Linux: chroot, Docker, OpenVZ
— с использованием виртуальных машин
Multiarch
В то время, как 64-битные программы не могут работать в 32-битных операционных системах, 32-битные программы могут работать в 64-битных операционных системах, однако они нуждаются в соответствующих 32-битных библиотеках. Со времен появления дистрибутивов Ubuntu 11.04 (Natty) и Debian 7.0 (Wheezy) было объявлено о поддержке multiarch, где 32-битные и 64-битные библиотеки могут сосуществовать вместе в одной системе. Пакет под названием ia32-libs включает в себя множество версий разделяемых библиотек.
Пример установки 32-битной программы в Debian/Ubuntu:
# dpkg —add-architecture i386
# apt update
# apt install -y ia32-libs
# apt install package-name:i386
chroot
С помощью технологии chroot, поддержку которой имеет ядро Linux, возможно организовать запуск 32-битных программ в изолированном окружении (песочнице) в уже имеющейся 64-битной операционной системе. Идея состоит в том, чтобы установить необходимое окружение в поддереве каталогов и запустить приложения из под него. В основном chroot используется для тестирования различных приложений, в том числе для 32- и 64-битных архитектур.
Команда chroot и одноименный системный вызов запускают процессы, с учетом того, что на самом деле запускаемое окружение является всего лишь системным подкаталогом.
Для организации удобного управления подобным окружением существует утилита schroot :
# apt update
# apt install -y schroot debootstrap dbus
Утилита debootstrap позволяет установить базовую систему Debian в необходимый подкаталог. Пакет dbus позволяет некоторым приложениям в операционной системе общаться друг с другом.
Пример установки 32-битного окружения в chroot:
# mkdir /chroot
# debootstrap —arch=i386 stable /chroot http://deb.debian.org/debian/
После создания окружения, создаем конфигурационный файл для его запуска:
# vim /etc/schroot/chroot.d/test
[test]
description=Installing 32-bit env
aliases=test
type=directory
directory=/chroot
users=root
root-groups=root
profile=desktop
personality=linux
preserve-environment=true
Заходим в окружение chroot:
# schroot -c test
(test)[email protected]:~#
После этого можно устанавливать необходимые программы в данное окружение chroot.
Технология chroot является полезной, однако распространение таких технологий как OpenVZ и Docker позволяют не только изолировать окружения в каталогах, но и изолировать ресурсы для каждого контейнера. В данный момент множество людей во всем мире использую Docker для запуска множества контейнеров, в основном для тестирования различных версий ПО.
К примеру команда:
# docker run -i -t ubuntu:12.04 /bin/bash
запускает контейнер с операционной системой Ubuntu 12.04.
Аналогично для OpenVZ 7:
# prlctl create ct1 —ostemplate debian-8.0-x86_64 —vmtype=ct
У Docker и OpenVZ есть один недостаток, так как это технология виртуализации уровня операционной системы, то он может запускать только приложения, поддерживающие ядро хост-системы. Например Вы не сможете запустить Windows или FreeBSD на ядре Linux.
KVM / VirtualBox / Hyper-V / ESXi
Для того, чтобы запустить любые операционные системы существуют технологии полной виртуализации, такие как KVM, VirtualBox и другие. С помощью KVM можно запускать любую x64-совместимую операционную систему поверх Linux, поэтому любую 32-битную систему можно установить в гостевую виртуальную машину без использования multiarch, chroot и Docker, достаточно лишь скачать необходимый образ операционной системы и установить ее на виртуальную машину.
Пример установки дистрибутива Linux Mint в виртуальную машину KVM.
Создадим виртуальный жесткий диск размером 10 Гб:
$ dd if=/dev/zero of=/vdisk_qemu bs=10000000 count=1000
Запуск виртуальной машины:
$ kvm -k ru -cdrom /linuxmint-32bit.iso -hda /vdisk_qemu -m 1024 -boot d -name TEST32
где:
-cdrom указывает путь к iso-образу операционной системы
-hda /vdisk_qemu путь к виртуальному жесткому диску
-m 1024 оперативная память указанная в мегабайтах
-boot d порядок загрузки оборудования (с cdrom)
-name TEST32 имя виртуальной машины
После установки операционной системы, можно отключить виртуальную машину и запустить ее с виртуального жесткого диска.
$ kvm -hda /vdisk_qemu -m 1024