Compiling 32-bit OS X binaries on a 64-bit environment - macos

What is involved in compiling 32-bit Intel OS X binaries on a 64-bit command-line environment? Is it as simple as adding a -m32 flag? I'm not using Xcode, but could use it to install libraries that gcc could use, if needed. Thanks for your advice.

If you're compiling on a Macintosh computer using Apple's implementation of GCC, one of the extra options you can pass along is the "-arch" parameter.
The man page says this:
-arch arch
Compile for the specified target architecture arch.
The allowable values are i386, x86_64, ppc and ppc64.
Multiple options work, and direct the compiler to produce "universal"
binaries including object code for each architecture specified with -arch.
This option only works if assembler and libraries are available
for each architecture specified. (APPLE ONLY)

Related

Assembly armv8 on mac os

I would like to assemble Aarch64 armv8 Assembly on my mac and eventually run it with qemu and maybe on a real device like a raspberry pi 2 or 4 later on. I don't know how to assemble the code I'm going to write, gcc, llvm-gcc and clang don't seem to support the -arch=armv8 flag or anything similar. So I can't build for the targeted architecture, how could I achieve this?
I'm running mac os 10.14.5. I wouldn't mind finding a solution that works on a recent ubuntu version either since I have a VM for linux development.
The clang version that ships with Xcode supports -arch arm64. (Or armv7 for 32bit.)
Note that if you want to use any libraries though, they'll have to be arm64 as well. If you want, you can invoke the iOS toolchain with xcrun -sdk iphoneos clang -arch arm64 [...], but then you'll also have to pull the libraries you want off of some IPSW and stuff them into qemu.
Also note that the above will give you a Mach-O binary. For your Raspberry Pi, you'll probably want an ELF, and you'll probably want gcc rather than clang. You should be able to build both gcc and GNU binutils from source with --target as either aarch64-linux-gnu or aarch64-none-elf, depending on your goals. Yet another note: since macOS silently aliases gcc to clang and many tools depend on that, you'll probably also want to build this toolchain with something like --program-prefix=aarch64-.

Building 32bit binary for ARM on 64bit CentOS

It seems that gcc doesn't accept -m32 option for ARM target. I am not sure how gcc behaves on 64bit Linux, but does it automatically generate 32bit binaries if gcc is of ELF32 running on 64bit Linux?
If so, is there any workaround?
Thanks in advance.
You need to use a cross-compiler to compile for ARM from your host running either x86 or x86_64, the reason being your host and target are 2 totally independent architectures.
The cross compiler would usually be configured to output only a 32-bit or 64-bit binary for ARM (not both). Most ARM device applications make use of only 32-bit and so using an arm cross-compiler without any extra arguments would build 32-bit binaries.
Toolchains have other -m flags to specify machine type such as armv7, arm cortex a-8, etc. for further optimization. You need to look at the documentation of the ARM cross compiler.
As for getting the correct toolchain which works for your target and runs under CentOS, it is better to start at the website of the vendor of the target device.
The -m32 option provided by the x86_64 version of gcc makes gcc compile 32-bit binaries instead of 64-bit since the x86 instruction set and the x86_64 (AMD64 or Intel EMT64) are quite similar. Especially the fact that it allows executing 32-bit instructions in 64-bit mode quite easily.

How to specify win32 or Windows 64 target with cross compiler i686-w64-mingw32-gcc

I have recently downloaded the mingw-w64 package under Fedora Linux in order to be able to cross compile targetting both win32 and "Windows 64". But I fail to understand how to specify what target I want to use. What flags do I need to supply to gcc and to the linker in order to choose my target architecture?
W32 and W64 are two different architectures, so you distinguish by compiler name. The debian mingw-w64 calls them i686-w64-mingw32-gcc for Win32 and x86_64-w64-mingw32-gcc for Win64.

How to compile universal libraries on Mac OS X?

This may be a very silly question, but I'm new to developing on Macs and am having a hard time with the universal binaries.
I've got an application that I'm compiling in QT Creator, which according to lipo is producing i386 architecture outputs. As I understand it, that means it is producing Mac OS X 32 bit outputs.
The application depends on two external libraries. One of these libraries I'm compiling by calling ./config first, and then make. ./config states that it is "Configured for darwin-i386-cc". However, after running make, and calling lipo on the result, the architecture is reported as x86_64.
Similarly, I have another external library. That one has no configure script, and I compile it simply by calling make. The output from this one too is x86_64.
How can I compile these two external libraries so that they produce something compatible with my application's i386 output? Better yet, how can I compile these two external libraries to produce universal libraries so I can produce a universal binary from my application that works on both 32 and 64 bit?
Also, based on the current state of the Mac world, are there any other platforms that I should be expected to target to create a proper, user-friendly Mac OS X universal binary?
Finally got it working.
In order to control the architecture of the target, I manually went in and edited the Makefiles.
For one of them, I added to the end of the line that starts with CFLAGS: -arch i386 -arch x86_64 -arch ppc
This produced a universal binary.
For the other, when I did the same thing, the compile would error out. I had to cycle through and only put one arch at a time, and then after I produced all three, I called lipo on them with the -create flag to create a universal binary.
for ./configure, you can use this:
./configure CFLAGS="-arch i386 -arch x86_64" CXXFLAGS="-arch i386 -arch x86_64" LDFLAGS="-arch i386 -arch x86_64" --disable-dependency-tracking
--disable-dependency-tracking is important or gcc/g++ will refuse to compile code.
I can't answer the main part of your question, because I always use Xcode rather than make. But as for that last part, if you support OS versions earlier than 10.6, you may need to compile for PowerPC (arch. code "ppc") as well.

Mac OSX 10.6 compiler: a puzzling experience with 32 vs 64 bit

I have trouble understanding the gcc compiler provided by OSX 10.6 snow leopard, mainly because of my lack of experience with 64 bits environments.
$ cat >foo.c
main() {}
$ gcc foo.c -o foo
$ file foo
foo: Mach-O 64-bit executable x86_64
$ lipo -detailed_info foo
input file foo is not a fat file
Non-fat file: foo is architecture: x86_64
However, my architecture is seen as an intel i386 type (I have one of the latest Intel Core2 duo MacBook)
$ arch
i386
and the compiler targets i686-apple-darwin10
$ gcc --version
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646)
Of course, if I compile 32 bits I get a 32 bit executable.
$ gcc -m32 foo.c -o foo
$ file foo
foo: Mach-O executable i386
but I don't get the big picture. The default setup for the compiler is to produce x86_64 executables, even if I have arch saying I have a 32 bit machine (why? Core2 is 64); even if (I guess) I am running a 32 bit kernel; even if I have a compiler targeting the i686-apple-darwin platform. Why? How can they run ? Should I compile 64 or 32 ?
This question is due to my attempt to compile gcc 4.2.3 on the mac, but I am having a bunch of issues with gmp, mpfr and libiberty getting (in some cases) compiled for x86_64. Should I compile everything x86_64 ? If so, what's the target (not i686-apple-darwin10 I guess)?
Thanks for the help
The default compiler on Snow Leopard is gcc4.2, and its default architecture is x86_64. The typical way to build Mac software is to build multiple architectures in separate passes, then use lipo to combine the results. (lipo only compiles single-arch files into a multiple-arch file, or strips archs out of a multi-arch file. It has no utility on single-arch files, as you discovered.)
The bitness of the compiler has nothing to do with anything. You can build 32-bit binaries with a 64-bit compiler, and vice versa. (What you think is the "target" of the compiler is actually its executable, which is different.)
The bitness of the kernel has nothing to do with anything. You can build and run 64-bit binaries when booted on a 32-bit kernel, and vice versa.
What matters is when you link, whether you have the appropriate architectures for linking. You can't link 32-bit builds against 64-bit binaries or vice versa. So the important thing is to see what the architectures of your link libraries are, make sure they're coherent, then build your binary of the same architecture so you can link against the libraries you have.
i686-apple-darwin10.0.0 contains an x86_64 folder which is not understood by most versions of autotools. In other words, I'd say that the gcc compiler is unfortunately nothing short of a joke on Snow Leopard. Why you would bundle 32-bit and 64-bit libraries into i686-apple-darwin10.0.0 is beyond me.
$ ls /usr/lib/gcc
i686-apple-darwin10 powerpc-apple-darwin10
You need to change all your autotools configure files to handle looking in *86-darwin directories and then looking for 64-bit libraries I'd imagine.
As with your system, my mac mini says its i386 even though its obviously using a 64-bit platform, again another mistake since its distributed with 64-bit hardware.
$arch
i386
Apple toolchains support multiple architectures. If you want to create a fat binary that contains x86 and x86_64 code, then you have to pass the parameters -arch i386 -arch x86_64 to gcc. The compiler will compile your code twice for both platforms in one go.
Adding -arch i386 -arch x86_64 to CFLAGS may allow you to compile gmp, mpfr, and whatnot for multiple archs in one go. Building libusb that way worked for me.
This answer is wrong, but see comments below
The real question is... how did you get a 32-bit version of OSX? I wasn't aware that Snow Leopard had a 32-bit version, as all of Apple's Intel chips are Core 2 or Xeon, which support the x86_64 architecture.
Oh, and Snow Leopard only works on Intel chips.
Edit: Apparently Snow Leopard starts in 32-bit mode.

Resources