what does macosx-version-min imply? - macos

When I pass compiler flag -mmacosx-version-min=10.5, what does it mean? I think it implies the result binary is x86, not ppc, but is it 32 bits or 64 bits? I'm compiling on snow leopard, so default output binary is 64 bits. I'm not passing -universal, it's not 32bit-64bit universal binary, I think.

This option will be used by the various availability macros placed into the headers. This means that you can require a minimum version of OS, even if you have a more recent SDK (i.e. target 10.5 with a 10.6 SDK). Using a 10.6 API while targetting 10.5 will trigger a warning and the API will be linked with a weak_import attribute.
Most Apple's API headers contains availability macros for each class, methods, functions or enumerations in order to declare for each of them:
The minimum OS supported
The deprecation
The unavailability
...
The macros look like:
AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER
AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED
...
As for the architecture, it only depends on the available architectures in the binaries of the SDK. For example with a 10.5 SDK, you can target four architectures (Intel/32bits, PowerPC/32bits, Intel/64bits, PowerPC 64bits), while with a 10.6 SDK, you can only target three architecture (Intel/32bits, PowerPC/32bits, Intel/64bits).
As you are using Snow Leopard, you can either target i386 (Intel/32bits), ppc (PowerPC/32bits) or x86_64 (Intel/64bits) very simply by passing an architecture option like this:
gcc -arch i386
or like this (for configure-based projects):
CFLAGS="-arch i386" LDFLAGS="-arch i386" ./configure

-mmacosx-version-min=... also influences the default choice of C++ STL implementation (GNU or LLVM), and in this regard, it is equally important for the compiler and the linker.

From my testing, it's also important that this option be passed to the link step (like -arch); so it does more than affect macros/preprocessing (as might be inferred from other answers).
When passed to compile step but not passed to the link step, I found that shared libraries built with 10.6 would not load under 10.5.

It triggers compiler warnings for methods that appeared after Mac OS X 10.5. Is has nothing to do with architecture.

Related

cross compiling Java JNI libraries for Windows / RPi from OS X / Linux

I have access to a 64 bit OS X environment, but I'd like to dramatically reduce the process for releasing native library builds for x86 / x86_64 / armv6 Linux and 32 / 64 bit Windows.
How can I cross compile JNI code from OS X (and failing that, from 64 bit Ubuntu Linux)? Which compilers must I install (I'm using macports) and from where can I install the foreign JDK environments that I must include and link against? What special compiler / linker flags are needed?
I'm using the maven-native-plugin so I can easily change the compiler, linker and JDK_HOME for every target. I have one module (i.e. pom.xml) per target platform.
The project, for those interested in details, is netlib-java/native_ref.
I've found out that various Linux cross-compilers come with macports in the form of
arm-elf-gcc
i386-elf-gcc
x86_64-elf-gcc
i386-mingw32-gcc
with 64 bit Windows cross-compile on its way.
Unfortunately, for my purposes I also need a Fortran compiler, so I'm asking for more help on that now on the macports mailing lists
EDIT: the current state of fortran cross-compilers (and mingw in general) on OS X is woeful. Best advice at the moment is to run a Linux box in VirtualBox and cross-compile all the targets from there. Two builds, not optimal, but better than all native.

Cross compile for iPhone on a mac?

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.

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..

kext for 10.4 - 10.6

I have a filter scheme driver with four binaries for 10.4 PPC, 10.4 i386, 10.5 & 10.6 i386 and 10.6 x86_64. I need to put them all into one kext. I don't think I can just lipo them together because of the two different i386 binaries.
How can I get them all into the same kext bundle?
See Apple's SimpleUserClient example: you can use sub-kexts for each OS revision.
Note that you may need to tweak the build settings a bit because later ld versions insert a load command that the earlier kernel linker doesn't understand; see this mailing list message (and the surrounding thread, if you need more context).
(Why on earth was this question marked "non programming related"?)
If you have four separate binaries, you cannot put them into the same kext bundle. You can put up to two binaries into a bundle by putting one bundle into the Plugins directory of the other bundle; the Plugin will match if the inital driver does not. However, if there are no API changes between your kexts, you may be able to use a kext compiled for 10.4 on 10.5 and 10.6, or one compiled for 10.5 on 10.6.

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