Make 32 bit linux

How do I create a single makefile for both 32- and 64-bit?

I have a makefile that works transparently for Linux ( x86_64 ) and OS X Intel ( x86_64 ). This uses 64-bit specific GCC options. Is there a way to adjust the makefile so that I could build for 32-bit and 64-bit OS X PPC ( ppc , ppc64 ) without having to maintain separate, arch-specific makefiles — perhaps something like a pre-processor directive that can determine the architecture before building?

6 Answers 6

ARCH := $(shell getconf LONG_BIT) CPP_FLAGS_32 := -D32_BIT . Some 32 specific compiler flags . CPP_FLAGS_64 := -D64_BIT CPP_FLAGS := $(CPP_FLAGS_$(ARCH)) . all the other flags . 

Try file inclusion. This is not part of the standard Makefile syntax (the one in the Single Unix v3 specification) but is widely supported. With GNU make, this looks like this:

With this, you could have an x86 Makefile like this:

ARCHFLAGS = -m64 -mtune=core2 include common.mk 
ARCHFLAGS = -mcpu=g3 include common.mk 

and the bulk of your compilation rules will be in one file ( common.mk ), using $(ARCHFLAGS) where necessary.

This is very useful. There are a lot of different standards and relatively few operating systems seem to fully comply with each. do you have to read both the standards and the compliance information for each target OS, or is there an easier way to find out which systems support each feature? I’ve done well for myself with auto dependency generation, but that depends on ‘include’, and I thought that was universally supported.

I think that you would achieve your goals with less work (and pain) by employing some kind of a build system such as cmake or GNU autotools.

I would say if your project is small and you don’t have lots of library dependencies to handle on different platforms then stay the hell away from auto-tools because its hell to maintain. If its a small(ish) project and you have an idea of what the tragets will be like then you are just fine with some tuned makefiles.

I would say that even if your project is small, go with the autotools. It’s much better than CMake and modern automake with AM_SILENT_RULES looks almost as good. Hell to maintain? Not really.

Well, usability of computer programs has always been in the eye of the beholder 🙂 There is an another option which has a considerably gentler learning curve: tmake from Trolltech. Unsupported but works. Much simpler than the alternatives.

Источник

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:

Читайте также:  Vipnet client dst linux

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.

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.

Источник

The proper way of forcing a 32-bit compile using CMake

Sorry that there are many similar questions, but I do find that Googling for CMake queries always yields similar-but-not-the-same scenarios, conflicting CMake commands and so on! I need to force my project to build 32-bit binaries because I have to link with a library which is only available as 32-bit. I diagnosed this based on error messages such as:

/usr/bin/ld: i386 architecture of input file `*external-32bit-lib*' is incompatible with i386:x86-64 output 
/usr/bin/ld: i386 architecture of input file `*project-output-lib*' is incompatible with i386:x86-64 output 

AND still get the same errors for the external library too. I think this is because the -m32 made gcc generate 32-bit binaries, but ld is still trying for 64-bit output? Further Googling for this problem didn’t give any success, so if anyone could verify that I am right and give the correct way of doing this, I would be very grateful! Many thanks!

Читайте также:  Linux mint моя сборка

6 Answers 6

If you want to compile and link for 32 bit using cmake use this for creating libraries and binaries:

add_library(mylib SHARED my_source.c) set_target_properties(mylib PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32") 
add_executable(mybin sources.c) set_target_properties(mybin PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32") 

Even if this seems like extra works, I believe a proper solution is to use toolchain file in this case. Something like:

# the name of the target operating system set(CMAKE_SYSTEM_NAME Linux) # which compilers to use for C and C++ set(CMAKE_C_COMPILER gcc) set(CMAKE_C_FLAGS -m32) set(CMAKE_CXX_COMPILER g++) set(CMAKE_CXX_FLAGS -m32) # here is the target environment located set(CMAKE_FIND_ROOT_PATH /usr/i486-linux-gnu ) # adjust the default behaviour of the FIND_XXX() commands: # search headers and libraries in the target environment, search # programs in the host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 
$ cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake /path/to/source 

The important part here is that one is now able to specify a root dir path ( CMAKE_FIND_ROOT_PATH ) which should be used to search for third party lib. Indeed your compiler may not be smart enough to know where to search for an x86 Qt library on an x86_64 system.

Having a toolchain file allows one to specify a different one on a par compiler basis, and you should be able to tweak the option when compiling in 32bits from a windows environement.

Nowadays this is extra works since compiling 32bits from an x86_64 Linux OS is pretty much trivial, but this solution will work for other more exotic setup.

For more information on toolchain file, one can check for example:

Источник

Compiling to 32-bit using make

I am trying to compile a very simple program using the -m32 flag.
If I try to do this using gcc -m32 it works just fine(I have the needed libs)
Yet, when I add this flag to my flags in a makefile, I get a weird error
This is the makefile that I have

CC=gcc CFLAGS=-m32 -O1 -W -Wall -pedantic -std=c99 all: main.o $(CC) -o main main.o rm main.o clean: rm main 
gcc -o main main.o /usr/bin/ld: i386 architecture of input file `main.o' is incompatible with i386:x86-64 output collect2: ld returned 1 exit status make: *** [all] Error 1 

Can someone please tell me what does this mean? and how can I fix it? As for the code, the code does NOTHING except printing ‘hello world’ I am using GCC 4.4.3 under Linux 2.6.35 64-bits

Since you are relying on the implicit rule to make main.o , why not also use the implicit rule to make main ? You are not passing $(CFLAGS) , but the implicit rule would do so. Use the implicit rule.

@zakkak If neither rule is explicitly given, the single suffix rule .c will be used, which uses both: $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $

2 Answers 2

Your mistake is that you don’t pass -m32 to the linker.

You actually need to change your Makefile to look like this:

CC=gcc CFLAGS=-m32 -O1 -W -Wall -pedantic -std=c99 LDFLAGS = -m32 all: main.o $(CC) $(LDFLAGS) -o main main.o rm main.o clean: rm main 

An even better approach would be the following Makefile :

CC=gcc CFLAGS=-m32 -O1 -W -Wall -pedantic -std=c99 LDFLAGS=-m32 .INTERMEDIATE: main.o all: main main: main.o clean: -rm main 

In the later you just say that main depends on main.o and GNU Make will invoke the linker with the LDFLAGS as arguments for you as it invokes the compiler with the CFLAGS as arguments for the main.o

Читайте также:  Linux add user with sudo

«The targets which .INTERMEDIATE depends on are treated as intermediate files. See section Chains of Implicit Rules. .INTERMEDIATE with no dependencies marks all file targets mentioned in the makefile as intermediate.» Special Built-in Target Names

Источник

Build 32bit on 64 bit Linux using an automake configure script?

I’m using a 64bit system but want a set of 32bit binaries. What options must I pass to a configure script to generate a 32bit/x86 makefile?

Plus one. I’m trying to build Git for Solaris. uname -m returns i86pc . All but one of the 10 or so dependent libraries misdetected the platform. Only OpenSSL correctly identified it as x86_64.

5 Answers 5

Passing the following argument to configure script allowed me to build the 32bit library on 64bit Linux

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

It didn’t work for me when trying to build a library. It gave me the message configure: error: C++ compiler cannot create executables .

This answer is incomplete, which is why sometimes you can get the «compiler cannot create executables» error. See my answer in this same thread

Jack’s answer is incomplete.

You need compiler/libc support for 32-bit compilation. In some distros like Ubuntu, what you need to do is install packages gcc-multilib and/or g++-multilib :

sudo apt-get install gcc-multilib g++-multilib 

Then you can call configure as you said, specifyiong a 32-bit host and passing 32-bit compilation flags:

./configure --host=i686-linux-gnu "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32" 

If you do not have multilib installed, you will get an error like configure: error: C compiler cannot create executables when passing the -m32 flag.

Some programs compile 32-bit on amd64 by default (eg. wine,) possibly in addition to 64-bit and should be able to find multilib if installed. Doesn’t seem to be the case for OP. Also, Jack was right about one thing — it should be —build , not —host . —host should be used if and only if you are building a compiler. It still works because there is plenty of people who don’t RTFM and write scripts that use —host instead of —build , and the autotools people have broken enough things already.

I still see g++-multilib in Debian Stretch. As well as that, you will need to enable 32-bit runtime libraries, as documented at wiki.debian.org/Multiarch/HOWTO. The commands at the bottom of that page dpkg —add-architecture i386; apt-get install libstdc++6:i386 libgcc1:i386 zlib1g:i386 libncurses5:i386 are a good starting point. You can install extra libraries as needed now, for example to build something that requires SSL, you can apt-get install libssl-dev:i386 .

@JonathanBaldwin ./configure —help says (for a script generated by autoconf): System types: —build=BUILD configure for building on BUILD [guessed] —host=HOST cross-compile to build programs to run on HOST [BUILD]

Источник

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