Cross compile for iPhone on a mac? - macos

How would I go about setting everything up to cross compile from my OSX 10.7 Macbook pro to my jailbroken 4th generation iPod touch. I'm mainly aiming to be able to port open source libraries to iphone. I can't seem to find any good/recent articles on cross compiling for iOS 4.

After some attempt, I found out that it's possible to use ./configure and force it to build for arm-apple-darwin11. You have to use these flags directly after the ./configure --some-flags:
CPP="cpp" CXXCPP="cpp"
CXX="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-llvm-g++-4.2" CXXFLAGS="-O -arch armv6 -arch armv7 -isysroot $SDK_ROOT/SDKs/iPhoneOS5.0.sdk"
CC="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2" CFLAGS="-O -arch armv6 -arch armv7 -isysroot $SDK_ROOT/SDKs/iPhoneOS5.0.sdk"
AR="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar"
AS="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/as"
LD="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ld"
LDFLAGS="-lstdc++ -arch armv6 -arch armv7 -isysroot $SDK_ROOT/SDKs/iPhoneOS5.0.sdk"
LIBTOOL="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/libtool"
STRIP="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/strip"
RANLIB="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib"
CPP and CXXCPP are the preprocessor required (the default one); CC and CXX are the path to the c and c++ compiler for arm that comes with Xcode, the other are flags the compiler gets or macros that defines the path to the most common tools used when compiling. I cannot grant everything will work, but this is a good idea of what you should do.
I'd suggest to add to ./configure these flags:
--prefix=/tmp/build --host=arm-apple-darwin11
what they do is to help create a makefile that will send libs and programs in a folder under /tmp/build.

Neither did I. All the toolchain I tried ended up in not working or creating x86_64 binaries, which won't work on iOS.
I'm currently trying to build apr directly on my iPad as I have installed from Cydia all the required things, yet I'm stuck kqueue.c not compiling properly. I have already ported lua and some other software, so I can say it generally works this way. The main reason for building on a native platform rather than cross compiling is that some programs rely on other programs (example: apr-util on apr) so some of them must be run. However, it's not possible to run arm on intel (at least without emulation, and iPhone Simulator uses i386 binaries).
Anyone who's interested in using/building UNIX tools on iOS has to keep these points in mind:
You might find what you wanted, but it's not said it'll work as expected (this is intended especially for developers. Example: apr is shipped in Cydia, but it's not a complete package, so it's useless to build apr-util).
You have to use a jailbroken device. This may become a problem if you break the OS and need to restore. Be always sure to save SHSH so that you're able to restore to a jailbreakable iOS.
If you don't find what you were searching, things will get pretty messy. Most software, although thought to work on generic UNIX system, might have problems on iOS, which is near OS X in structure and way to work, but has differences especially under the net-related sections.
Plus you'll probably have to (fake)code sign any software you build.
Even software without build problems may hold unwanted surprises: I had successfully build apache2 for iOS, but when I run I got stuck with SIGSYS, without much more explanation.
So, beware and brace yourself, because things are not easy usually.
About the fact of Mac being without a toolchain (except the one provided by Apple), this may hold an explanation as you don't need to have a mac to download Xcode, while a mac cost usually more than devs are willing to spend. This means there aren't much people doing the same thing you do, despite the boom mac hardware has had recently. Toolchains have been more or less successfully built for Linux based OSes, such as Ubuntu. You can always try to use a VM.

Related

gcc, cross-compilation, sysroot and glibc nightmare

I'm developing and building applications for a various amount of platforms (linux x86, x86_64, arm, aarch64, sparc64, mips, powerpc, macos x86_64, freebsd x86_64, solaris x86_64 and of course Windows) and I was using a very old linux box (2014 Ubuntu) for all this cross-compilation.
I've recently decided that it was more than time to move to a more updated build environment as many tools were obsolete and could not be updated, so I've moved everything to a Ubuntu 22.04. All worked fine but then I hit the "glibc version hell" when I tried to run that on other boxes as glibc on that buildbox is 2.35.
So I've tried to get older glibc to compile and link against these as I'd really like to avoid linking everything static. But now, all the gcc that are build with Ubuntu have been with a "--with-sysroot=/" which, AFAII means I can't do anything. The --sysroot option is ignored by gcc which uses / for sysroot, no matter what.
I've seen a few answers saying "use old box to build" and that seems really insane to me. On my Mac or Windows, I can chose minimum (old) target platform, even if I build on W11 or Monterey. And obviously, the reason WHY I move to a new buildbox is to NOT use an old one and be stuck with obsolete tools :-).
I can probably use again ct-ng and rebuild all compilers, including native ones, but that seems really an overkill. Anybody with a better solution?
Thanks!
Seems that there is really no solution for what I'm looking for. I ended up almost re-inventing the wheel while trying to manually installing glibc. It was a faster option to use ct-ng and install cross-compilers from there, not using the stock ones provides with my distro.

Is it possible to create a MingW / MSYS based Windows toolchain to compile Glibc dependent applications for Linux?

I was following instructions here and here to build a toolchain which would work on Windows and compile applications for Linux and different hardware platforms. At first I tried to create cross-compiler for i686-linux to test it on a generic Debian 8 system.
Binutils and GCC compiled fine, but I got stuck at Glibc. It told me:
*** The GNU C library is currently not available for this platform.
I see that Sysprogs toolchains are using Newlib instead of Glibc but I haven't found any explanations except that Newlib is a good choice for embedded devices.
Does it mean that Newlib is actually the only choice for Windows -> Linux and that there is no way to compile software which depends on Glibc? Maybe there are "cheats", like copying pre-built Glibc from the target platform or some other workaround?
In theory, I don't even need Glibc built on Windows, I need just some "Glibc compatible stub" built for the target architecture to link (only dynamically, of course) against while compiling for the target platform and OS. Or am I totally wrong here and GCC cannot link to a different C library than GCC itself was linked to?
Or should I forget it and accept the fact that it is impossible (and, most probably, never will be possible) to achieve full Glibc and Linux kernel compatible C/C++ cross-compiling from Windows to GNU/Linux?
I will accept the answer which explains how GCC and Glibc are related and whether it is possible or not to link against Glibc different from C library used when GCC itself was built, and provide some insight about why it is / is not possible.
my guess is you're using --target when building glibc when you really need to use --host (which is different from how newlib is configured -- best to not ask why).
that said, the glibc build system requires a case-sensitive file system as it creates files like foo.oS and foo.os which are very different things. on a system like Windows, that means the build will be corrupted and fail since foo.oS and foo.os refer to the same file. there are patches out there to hack around this, but really you'd be better off booting a VM and doing the toolchain build inside of that.
NB: i'm not saying you need the VM to do all your development. you just need the VM to build the cross-compiler which you'd then run under Windows. this would be a canadian cross build.
rather than do all this yourself by hand, please check out crosstool-ng. it handles/patches/fixes a lot of common errors people make when trying to create cross-compilers.

how do I build a universal binary with xcode 3.2.6?

I am using XCode 3.2.6 on an Intel Mac running OS X 10.6, to build a fairly simple app that needs to be able to run under OS 10.4 on a PPC-based Mac, in addition to modern Intel-based Macs.
Under the project settings, I only see options for 32-bit Intel, 64-bit Intel, and Standard (32/64 Intel). Should I be seeing a "Universal Binary" entry here?
I don't have any problem running it under 10.4 on an Intel Mac. I was careful not to use features that don't work under 10.4, and I think I set the project settings correctly to allow it to be backward-compatible to 10.4. It's just that I can't figure out how to get it to compile for PPC.
I'm flailing around, trying to figure out how to build a universal binary, and I think I'm probably just missing something obvious. Any help would be greatly appreciated.
You don't have to choose one of the predefined settings for the Architectures build setting. You can choose "Other..." and then explicitly enter a list of architectures like ppc, i386, x86_64.
By the way, there are extra tricks if you need to run on G3s: You must use GCC 4.0 and the 10.4 SDK.

How do I build Universal binaries (ppc/i386) using Xcode 3.2.2 for OSX?

I am trying to build a universal binary for a project at work, but I can't seem to get Xcode set up properly to do so.
I am familiar with the Apple Documentation regarding this, but apparently I am not reading it correctly.
The Xcode build options in question seem to be:
Architectures
Base SDK
C/C++ Compiler Version
Mac OS X Deployment Target
In my settings I have the following Valid Architectures: i386 ppc ppc64 ppc7400 ppc970 x86_64.
If I use the following options, I get a binary with i386 and ppc970:
Architectures: i386 ppc
Base SDK: Mac OS X 10.5
C/C++ Compiler Version: GCC 4.0
Mac OS X Deployment Target: Mac OS X 10.5
I have several questions about this:
Why ppc970 and not ppc7400 (or simply ppc)?
What is the difference between the ppcs (ppc, ppc64, ppc7400, ppc970)?
How do I get a binary for any ppc?
Apparently, I need a binary with ppc7400 to work on the Mac Mini we have for testing. The Mini has a G4 and is running OSX 10.5.8. From what I can tell, a binary with ppc7400 works but not one with only ppc970.
I have tried several combinations of the above build options, including changing my Base SDK to 10.4u. The above configuration is the only one that even builds. Other builds fail, often because of not recognizing header files or clearly available #defines. For example, if I change my compiler to gcc 4.2, I get errors searching for stdarg.h because of the #include_next directive and no clear path to correct headers. If I drop my Base SDK to 4.0, #define FSIZE long long is no longer recognized despite not changing any includes.
I'd really appreciate any insight you can give me on this.
EDIT UPDATE
Thanks for the info. I understand the flags now. But I get a strange result.
These are my build flags now:
GCC_VERSION = 4.0
MACOSX_DEPLOYMENT_TARGET = 10.4
SDKROOT = macosx10.5
GCC_MODEL_TUNING = G3
This produces object file (.o) that have arch 'ppc' as shown by lipo. All the included libs and frameworks are either 'ppc' or 'ppc7400' (again as shown by lipo). But, the final build is 'ppc970'.
I have gone over this very carefully to ensure I got everything. Can anyone think of a reason for the ppc architecture differences?
I've even gone so far as to create a new project (Hello World) and link it to all the libs and frameworks of the first project. Hello builds as 'ppc' not 'ppc970'.
This just makes no sense to me.
ppc970 == G5. If you need to support as far back as the G4 then just build for ppc7400.
Rather than messing with individual architecture settings, though, you can just select 32-bit Universal (or Standard (32/64-bit Universal), if appropriate) from the popup menu, and that should give you what you need.
In target settings make below changes..
GCC_MODEL_PPC64 = NO
i.e., uncheck “Use 64-bit integer Math”.
Enabling will turn on 64 bit. So it will be G5 onwards..

Compiling for both Intel and PPC CPUs on OSX

I have a MacBook Pro with a 64-bit Intel Core 2 Duo processor, and I'm using gcc (i686-apple-darwin9-gcc-4.0.1) to compile executables which I can run ok on my own machine. Recently someone tried to run my application on a PowerBook G4 and got a 'Bad CPU type in executable' error, which I think is because their CPU is PPC rather than Intel (and also possibly 32 bit not 64 bit)
Is it possible for me to produce binaries that will work across all the various Mac architectures using gcc, and if so what options do I use?
Look at the -arch parameter for gcc Apple docs
You need to look into "Universal Binaries" this is the name given to an app file which runs, with no dynamic recompilation, on both ppc and i386 architectures. As you know .app files (Mac Executables), are in fact archives, which contain, within them, the actual binary application. These can be partitioned in such a way that both the i386 and ppc binaries are contained.
To save yourself and your users future headaches, you should bite the bullet and set up your project in Apple's Xcode. If you follow the defaults, Xcode can take care of all the details of building for multiple architectures, like using the proper -arch flags for gcc, using the correct SDK libraries, compatibility with previous OS X versions, etc etc.

Resources