Linux gcc 32 bit on 64 bit

Force gcc to compile 32 bit programs on 64 bit platform

I’ve got a proprietary program that I’m trying to use on a 64 bit system. When I launch the setup it works ok, but after it tries to update itself and compile some modules and it fails to load them. I’m suspecting it’s because it’s using gcc and gcc tries to compile them for a 64 bit system and therefore this program cannot use these modules. Is there any way (some environmental variables or something like that) to force gcc to do everything for a 32 bit platform. Would a 32 bit chroot work?

3 Answers 3

You need to make GCC use the -m32 flag.

You could try writing a simple shell script to your $PATH and call it gcc (make sure you don’t overwrite the original gcc, and make sure the new script comes earlier in $PATH , and that it uses the full path to GCC.

I think the code you need is just something like /bin/gcc -m32 $* depending on your shell (the $* is there to include all arguments, although it might be something else – very important!)

You’ll also need the 32bit C library, as well as 32 bit versions of whatever external libraries the program links against in some cases.

You may get a 32-bit binary by applying Alan Pearce’s method, but you may also get errors as follows:

fatal error: bits/predefs.h: No such file or directory 

If this is the case and if you have apt-get, just install gcc-multilib

sudo apt-get install gcc-multilib 

For any code that you compile directly using gcc / g++ , you will need to add -m32 option to the compilation command line, simply edit your CFLAGS , CXXFLAGS and LDFLAGS variables in your Makefile .

For any 3rd party code you might be using you must make sure when you build it to configure it for cross compilation. Run ./configure —help and see which option are available. In most cases you can provide your CFLAGS , CXXFLAGS and LDFLAGS variables to the configure script. You also might need to add —build and —host to the configure script so you end up with something like

./configure CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32 --build=x86_64-pc-linux-gnu --host=i686-pc-linux-gnu 

If compilation fails this probably means that you need to install some 32 bit development packages on your 64 bit machine

Читайте также:  How to install packages in arch linux

Источник

How to compile 32-bit executable on 64 bit system

Note: I looked through some of the suggested «similar questions» and didn’t find anything that looked conclusive. Plus, it seems most of them are 6 years old (from 2014), so I’m hoping for something more up-to-date (and more likely to «just work»). I have a 64 bit Ubuntu system that works fine. I would like to be able to build a 32 bit version of, say, «hello, world». This is mostly an academic pursuit, but it would be convenient to get it working. It would be nice if compiling with «-m32» would «just work», but it doesn’t. Worse, my memory is that this used to «just work» (in an older version of 64 bit Linux), but no longer works. Observe:

$ cat hello.c #include int main() < puts("hello, world"); return 0; >$ gcc -m32 hello.c In file included from hello.c:1:0: /usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file or directory #include ^~~~~~~~~~~~~~~~~~~~~~~~~~ compilation terminated. $ 
apt-get install libc6-dev-i386-x32-cross 
The following NEW packages will be installed: libc6-dev-i386-x32-cross libc6-dev-x32-cross libc6-i386-x32-cross libc6-x32-cross linux-libc-dev-x32-cross 

After that, with a little bit of fudging, I was able to get it to compile, but not link. The link phase gives these error msgs:

/usr/bin/ld: cannot find Scrt1.o: No such file or directory /usr/bin/ld: cannot find crti.o: No such file or directory /usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/7/libgcc.a when searching for -lgcc /usr/bin/ld: cannot find -lgcc /usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/7/libgcc.a when searching for -lgcc /usr/bin/ld: cannot find -lgcc collect2: error: ld returned 1 exit status 

Источник

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?

Читайте также:  Linux show hide files

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.

  1. Make sure all the 32-bit gcc 4.8 development tools are completely installed: sudo apt-get install lib32gcc-4.8-dev
  2. 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.

Читайте также:  Find file arch linux

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.

Источник

How to compile a 32-bit binary on a 64-bit linux machine with gcc/cmake

Is it possible to compile a project in 32-bit with cmake and gcc on a 64-bit system? It probably is, but how do I do it? When I tried it the «ignorant» way, without setting any parameters/flags/etc, just setting LD_LIBRARY_PATH to find the linked libraries in ~/tools/lib it seems to ignore it and only look in subdirectories named lib64.

7 Answers 7

It should do. You could also modify the cmake script to create a 32 bit target — it would just add -m32 to the CFLAGS , probably by setting CMAKE_REQUIRED_FLAGS .

Well, the problem is that this is of course not necessarily enough. You may need to tweak the linker, too!

What does export mean? Where does it belong? Te header files? The makefile ? Nope, totally not an answer for me as a beginner.

@TomášZato: At the shell prompt, before invoking cmake (however in your case, if you have a Makefile, then you would be using make instead).

$ gcc test.c -o testc $ file testc testc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped $ ldd testc linux-vdso.so.1 => (0x00007fff227ff000) libc.so.6 => /lib64/libc.so.6 (0x000000391f000000) /lib64/ld-linux-x86-64.so.2 (0x000000391ec00000) $ gcc -m32 test.c -o testc $ file testc testc: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped $ ldd testc linux-gate.so.1 => (0x009aa000) libc.so.6 => /lib/libc.so.6 (0x00780000) /lib/ld-linux.so.2 (0x0075b000)

In short: use the -m32 flag to compile a 32-bit binary.

Also, make sure that you have the 32-bit versions of all required libraries installed (in my case all I needed on Fedora was glibc-devel.i386)

In later versions of CMake, one way to do it on each target is:

set_target_properties(MyTarget PROPERTIES COMPILE_FLAGS «-m32» LINK_FLAGS «-m32»)

I don’t know of a way to do it globally.

+1. I’m trying to build 32-bit taglib(developer.kde.org/~wheeler/taglib.html) on a 64-bit snow leopard. This works for me.

Источник

Оцените статью
Adblock
detector