In order to compile a Cocoa based program for both Mac OS X and another OS using Cocotron in the same Xcode project you will need to create additional targets in the project.
The new targets will specify a CDT compiler and Cocotron/OS specific build settings.
The easiest way to do this is to duplicate an existing target and modify the settings.
Cross-compiling is as easy as using Xcode for an OS X project - you just have to set things up correctly. This primarily consists of creating a target for the desired platform and modifying the build rules and settings. These instructions are for native Xcode targets.
Step One, creating the cross-compilation target
The easiest way to do this is to just duplicate an existing OS X target and name it accordingly, e.g. duplicate the target MyApp and name it MyApp-Windows. If you need platform dependent source the easiest thing is to either exclude or include them in your platform specific targets.
Step Two, modify the Build settings
What you need to do here is remove all the OS X specific Customized Settings so that the defaults are used and then add the target specific settings for the particular platform. Overall these settings are similar across platforms but they do vary.
It is essential that the C and/or C++ compiler setting is set to the desire Cocotron compiler
Once these steps are complete you should be able to compile your new target for the desired platform.
This document describes those build options which inevitably have to be customized in a CDT based target and how to customize them. Customization is due to some combination of the compiler, specification or target type not providing a suitable default or an unsuitable initial value. There are also some build options which must be changed in order to stay organized with multiple platforms and architectures, The SCC encourages you to use the <platform>/<architecture>/ directory structure mentioned here for build products.
The Mac OS X gcc and linker supports a lot of options that the CDT does not, expect to play a game of trial and error if you want to use more customized settings.
The CDT + Xcode is known to build Applications, Command-line Tools, Frameworks and Bundles, these options refer to those types of targets. If you have success with other target types, please pass along what you set up and they'll be included here.
undefined symbols link error
If you get link errors, make sure all frameworks you want to link against are members of the target. This is typically caused by Foundation.framework and AppKit.framework not being members of the Windows target. By default Xcode only makes Cocoa.framework a member of your projects target. To fix this, Get Info on Foundation.framework and AppKit.framework in your projects Other Frameworks group, and make them members of the Windows target.
Architectures (ARCHS)
Xcode uses this value when determining which compiler to use. It can not contain multiple architectures as the CDT compilers do not understand multiple architectures.
i386 Windows/Linux
sparc Solaris
SDK Path (SDKROOT)
This should be set to the current OS, i.e. empty.
Build Products Path (SYMROOT)
Must include a platform specific directory e.g. build/Windows. If you don't do this the build products from targets with the same product name will clobber each other.
Compiler for C/C++/Objective-C (GCC_VERSION)
This must specify the Cocotron cross-compiler desired, e.g. Cocotron 1.0 Windows i386 gcc 4.3.1.
Frameworks Search Path (FRAMEWORK_SEARCH_PATHS)
Should include the search path for the target platform as /Developer/Cocotron/1.0/<platform>/<architecture>/Frameworks, e.g. /Developer/Cocotron/1.0/Windows/i386/Frameworks.
If you are building your own frameworks you should organize the final products with a <platform>/<architecture>/ directory structure, for example Cocotron places frameworks in:
Mach-O Type
Dynamic Library Bundle
The default value of Bundle generates options which the CDT compiler does not understand, Dynamic Library does the job.
Prebinding (PREBINDING)
Off
The CDT compilers do not understand it.
Other Linker Flags (OTHER_LDFLAGS)
-shared Frameworks Bundles
Specifies that a shared object is to be created
-Wl,--enable-auto-import Windows
Specifies that the linker automatically imports external references
-Wl,--export-all-symbols Windows Frameworks
Specifies that all symbols are exported, your alternative is to maintain export files which is a hassle.
-Wl,--out-implib,$TARGET_BUILD_DIR/$(PRODUCT_NAME).framework/lib$(PRODUCT_NAME).a Windows Frameworks
Specifies the path of the library file to create. Windows by convention uses a separate file to specify entry points in a DLL, this generates that file inside the framework directory.
-mwindows Windows Application
Specifies that this executable should run as a GUI application. By default executables are marked as console applications, you need to specify this if you want a GUI.
-mconsole Windows Application
Optional but must be used with -mwindows in an Application target. For some bizarre annoying historical reason Windows distinguishes between command line and GUI applications in the executable. An application built without -mconsole does not output on stderr/stdout even if launched from a console window, so you need to specify -mconsole to get the output, the problem with -mconsole is that if you don't have a console, one is created for the application by Windows. So, it is good for debugging, but looks bad for deployment.
-lm -ldl -lpthread Linux/Solaris Command-Line Tool
-lsocket -lnsl Solaris Command-Line Tool
AFAIK Linux and Solaris do not allow you to specify shared object dependencies while linking a shared object, this means that if you link against the Cocotron frameworks you need to specify which libraries it depends on. These are those libraries.
-Wl,-rpath=$ORIGIN Linux/Solaris Command-Line Tool
Optional. This embeds a link command in the executable which tells the dynamic loader to look in the current directory for shared objects. You may or may not want to do this but if you are distributing an executable and shared objects which it depends on, using rpath is by far the simplest way to do this. $ORIGIN specifies the executables location and you can also tack on a relative directory if you want, say $ORIGIN/../SharedObjects.
Product Name (PRODUCT_NAME)
No modification needed. This is not platform specific and should remain as the original.
Executable Prefix (EXECUTABLE_PREFIX)
lib Linux/Solaris Frameworks
Required for the linker.
Info.plist file (INFOPLIST_FILE)
No modification needed if you have one.
Installation Directory (INSTALL_PATH)
If you are building a framework you should probably use the Platform/architecture/ directory organization. For other targets this doesn't need to be changed.
Precompile Prefix Header (GCC_PRECOMPILE_PREFIX_HEADER)
Off
CDT compilers do not understand it.
Accelerated Objective-C Dispatch (GCC_FAST_OBJC_DISPATCH)
Off
Does not function with the CDT compilers
Fix & Continue (GCC_ENABLE_FIX_AND_CONTINUE)
Off
Does not function with the CDT compilers
Generate Position-Dependent Code (GCC_DYNAMIC_NO_PIC)
Off
CDT compilers do not understand -mdynamic-no-pic. This may or may not default to Off depending on target type, make sure it is Off.
Other C Flags
-fPIC Linux/Solaris Frameworks/Bundles
Generate position independent code.
Executable Folder Path (EXECUTABLE_FOLDER_PATH)
$(CONTENTS_FOLDER_PATH)/Windows Windows Application/Bundle
$(CONTENTS_FOLDER_PATH)/Linux Linux Bundle
$(CONTENTS_FOLDER_PATH)/Solaris Solaris Bundle
Well, you do want your application executable in MyApp.app/Contents/Windows/MyApp.exe don't you?
Executable Suffix (EXECUTABLE_SUFFIX)
.exe Windows Application/Command-Line Tool
.dll Windows Frameworks/Bundles
.so Linux/Solaris Frameworks/Bundles
You can also specify a version if you want, e.g. .1.2.exe or .3.1.dll. That works on Windows, not sure about Linux/Solaris yet, the linker may not like it.