| 1 | Title: Metrowerks w/ configure HOWTO |
| 2 | Author: David Elliott |
| 3 | Id: $Id$ |
| 4 | |
| 5 | === Introduction to Metrowerks command line tools === |
| 6 | |
| 7 | Since CodeWarrior version 8, Metrowerks has provided command-line compilers |
| 8 | hosted on OS X. There are three available targets. |
| 9 | |
| 10 | 1) Mac OS X/PPC |
| 11 | Compiler: mwcc |
| 12 | Linker: mwld |
| 13 | -- File formats -- |
| 14 | Executable: Mach-O |
| 15 | Shared Library: Mach-O (bundle, dylib, etc.) |
| 16 | Static Library: CodeWarrior |
| 17 | Object: CodeWarrior |
| 18 | |
| 19 | 2) Mach-O/PPC |
| 20 | Compiler: mwccppc |
| 21 | Linker: mwldppc |
| 22 | -- File formats -- |
| 23 | Executable: Mach-O |
| 24 | Shared Library: Mach-O (bundle, dylib, etc.) |
| 25 | Static Library: Archived (ar) Mach-O (.a files) |
| 26 | Object: Mach-O .o files |
| 27 | |
| 28 | 3) Mac/PPC |
| 29 | Compiler: mwpefcc |
| 30 | Linker: mwpefld |
| 31 | -- File formats -- |
| 32 | Executable: PEF |
| 33 | Shared Library: PEF ("code fragments") |
| 34 | Static Library: CodeWarrior |
| 35 | Object: CodeWarrior |
| 36 | |
| 37 | As you can see, only one of these targets produces Mach-O .o files that |
| 38 | normal ar and ranlib could hope to handle. It's no matter though, |
| 39 | really all that ar and ranlib do is create a static library (.a) from a |
| 40 | collection of .o files. This can be emulated by a shell script which |
| 41 | calls the appropriate mwld. I've provided one called mwar which does this. |
| 42 | For ranlib simply use true since mwar does all of the work. |
| 43 | |
| 44 | === Metrowerks Environment Variables === |
| 45 | |
| 46 | In order for any of these programs to work some environment variables |
| 47 | must be set. The compiler must know where to look for headers (CIncludes). |
| 48 | The linker needs to know where to look for libraries (Libraries) such as |
| 49 | those specified on the commandline with -l as well as crt1.o (or sometimes |
| 50 | mwcrt1.o) for OS X. The linker also needs to know if any additional |
| 51 | libraries should be linked into executables (LibraryFiles). Finally, |
| 52 | on OS X the linker needs to know where to look for Frameworks (FrameworkPaths). |
| 53 | These are controlled by the following environment variables: |
| 54 | |
| 55 | 1) Mac OS X/PPC |
| 56 | CIncludes: MWCMacOSXPPCIncludes |
| 57 | Libraries: MWMacOSXPPCLibraries |
| 58 | LibraryFiles: MWMacOSXPPCLibraryFiles |
| 59 | FrameworkPaths: MWFrameworkPaths |
| 60 | |
| 61 | 2) Mach-O/PPC |
| 62 | CIncludes: MWCMachPPCIncludes |
| 63 | Libraries: MWMachPPCLibraries |
| 64 | LibraryFiles: MWMachPPCLibraryFiles |
| 65 | FrameworkPaths: MWFrameworkPaths |
| 66 | |
| 67 | 3) Mac/PPC |
| 68 | CIncludes: MWPEFCIncludes |
| 69 | Libraries: MWPEFLibraries |
| 70 | LibraryFiles: MWPEFLibraryFiles |
| 71 | FrameworkPaths: (N/A) |
| 72 | Notes (mwldppc 3.0.3 build 343): |
| 73 | The environment variables (including MWPEFLibraries) aren't read until after |
| 74 | the command line options have been parsed! The command line option parser |
| 75 | actually tries to do the linking from within the parser and thus -l options |
| 76 | which don't have a -L specifying where to look for the library do not work. |
| 77 | Yes, this means that MWPEFLibraries is essentially useless AFAICT. |
| 78 | |
| 79 | I have provided an example mwvars.sh. It's what I use with CW 8.3. YMMV. |
| 80 | |
| 81 | === Compiling wxWidgets targetting Mac OS X with Metrowerks === |
| 82 | |
| 83 | With recent wxWidgets (2.5.5) it is possible to compile using the |
| 84 | Metrowerks tools with minimal effort. You may use either mwcc/mwld |
| 85 | or mwccppc/mwldppc. Ideally you will have the tools on your path |
| 86 | on your path as well as the mwar script I've provided. You will also |
| 87 | have had to source mwvars.sh (either yourself or by sourcing it from |
| 88 | your .profile or .bash_profile). |
| 89 | |
| 90 | Before beginning I strongly recommend you write a simple C++ hello world |
| 91 | program. I recommend #include <iostream> and cout << "Hello World" << endl;. |
| 92 | This will ensure your C++ standard library is working. Note that |
| 93 | you can compile this using mwcc hello.cpp. You will find a hello.cpp.o |
| 94 | file as well as an a.out file if the compiler and linker were successful. |
| 95 | Assuming your compiler can produce a.out you're ready to begin. |
| 96 | |
| 97 | As per usual, I recommend building outside the source tree. |
| 98 | From the source tree (workingDirectory$ is the prompt) |
| 99 | |
| 100 | wxWidgets$ mkdir ../BUILD_MACd_CW8 |
| 101 | wxWidgets$ cd ../BUILD_MACd_CW8 |
| 102 | BUILD_MACd_CW8$ ../wxWidgets/configure --enable-debug --disable-shared CC=mwcc CXX=mwcc LD=mwld AR=mwar RANLIB=true |
| 103 | [ configure hopefully succeeds ] |
| 104 | BUILD_MACd_CW8$ make |
| 105 | [ make hopefully succeeds ] |
| 106 | BUILD_MACd_CW8$ make -C samples/minimal |
| 107 | [ minimal make succeeds ] |
| 108 | BUILD_MACd_CW8$ ./samples/minimal/minimal.app/Contents/MacOS/minimal |
| 109 | [ minimal runs and your prompt will return when you Quit the app ] |
| 110 | |
| 111 | The important options are CC=mwcc CXX=mwcc LD=mwld AR=mwar RANLIB=true |
| 112 | Right now you also need --disable-shared. Eventually I hope to add the |
| 113 | ability to created shared libraries. |
| 114 | |
| 115 | If you wish to use the Mach-O compilers instead of the Mac OS X compilers |
| 116 | then use CC=mwccppc CXX=mwccppc LD=mwldppc. You don't need a special |
| 117 | AR or RANLIB with this compiler. |
| 118 | |
| 119 | At the moment, precompiled headers aren't supported though you don't need |
| 120 | to pass --disable-precomp-headers since the Makefiles know they can't do PCH. |
| 121 | I hope to add this soon. |
| 122 | |
| 123 | As you can see, this is not wildly different from compiling using any |
| 124 | other compiler (for instance GCC). The same files that would be compiled |
| 125 | by gcc are now compiled by mwcc. The same files that would be linked |
| 126 | by the combination of ar and ranlib are now linked using the mwar shell |
| 127 | script that calls mwld to do the work and using true in place of ranlib. |
| 128 | The same files that would be linked using ld (i.e. the executable sample) |
| 129 | are linked using mwld. |
| 130 | |
| 131 | |
| 132 | === Compiling wxWidgets targetting Mac OS (Carbon) with Metrowerks === |
| 133 | |
| 134 | Compiling for Mac OS PEF Carbon is not really more or less difficult |
| 135 | than compiling for OS X. However, there is still some work left to do. |
| 136 | |
| 137 | In particular, the -lCarbonLib and -lQuickTimeLib options to the linker don't |
| 138 | work because of the aforementioned bug in mwpefld. To fix this you can add |
| 139 | -L/path/to/Universal/Libraries/StubLibraries to LDFLAGS. Unfortunately |
| 140 | because autoconf (2.59) doesn't always use eval appropriately you cannot |
| 141 | have spaces in the path. What I recommend is to make a symlink from |
| 142 | /Applications/Metrowerks CodeWarrior 8.0/Metrowerks CodeWarrior/MacOS Support to some path which can be accessed without using spaces. |
| 143 | Something like this: |
| 144 | ~$ ln -snf "/Applications/Metrowerks CodeWarrior 8.0/Metrowerks CodeWarrior/MacOS Support" MW_MacOS |
| 145 | |
| 146 | There is also a problem with the samples Makefiles. Currently they clear |
| 147 | the resource fork of the executable rather than append to it. This |
| 148 | can be remedied by adding the -a option to Rez before making in that |
| 149 | sample's directory. I hope to fix this soon. |
| 150 | |
| 151 | Assuming you work around these it's pretty straightforward: |
| 152 | |
| 153 | wxWidgets$ mkdir ../BUILD_MACCARBONd_CW8 |
| 154 | wxWidgets$ cd ../BUILD_MACCARBONd_CW8 |
| 155 | BUILD_MACCARBONd_CW8$ ../wxWidgets/configure --host=powerpc-apple-macos --enable-debug --disable-shared CC=mwpefcc CXX=mwpefcc LD=mwpefld AR=mwpefar RANLIB=true LDFLAGS=-L/Users/yourname/MW_MacOS/Universal/Libraries/StubLibraries |
| 156 | [ configure hopefully succeeds ] |
| 157 | BUILD_MACd_CW8$ make |
| 158 | [ make hopefully succeeds ] |
| 159 | BUILD_MACd_CW8$ make -C samples/minimal |
| 160 | [ minimal make succeeds ] |
| 161 | BUILD_MACd_CW8$ /System/Library/Frameworks/Carbon.framework/Versions/A/Support/LaunchCFMApp ./samples/minimal/minimal |
| 162 | [ minimal runs and your prompt will return when you Quit the app ] |
| 163 | |
| 164 | Unlike the OS X case not many people compile wxMac Carbon PEF using configure. |
| 165 | From time to time there may be minor problems. Please report these using |
| 166 | the sourceforge bug tracker. |
| 167 | |
| 168 | === Other Metrowerks notes === |
| 169 | --- Object file extension --- |
| 170 | By default, the mw compilers when used with the -c option will append .o |
| 171 | to the source filename (following symlinks even). This is in contrast to |
| 172 | normal compilers which replace the files extension with .o. To get the |
| 173 | normal behavior you must add -ext o to the compiler options. The wxWidgets |
| 174 | configure script does this and the macros to check for this are part of |
| 175 | Bakefile (bakefile.sourceforge.net). |
| 176 | |
| 177 | --- Static library extension --- |
| 178 | The CodeWarrior IDE typically uses the .lib extension for CodeWarrior static |
| 179 | libraries and .a for Mach-O static libraries (ar/ranlib archives). The |
| 180 | wxWidgets makefiles always use .a. This isn't really a problem just be |
| 181 | aware that the .a files aren't really ar/ranlib archives and aren't useable |
| 182 | by anything other than CodeWarrior itself. |
| 183 | |
| 184 | --- IDE --- |
| 185 | As far as I know it should be possible to use libraries created by |
| 186 | the command line tools from the IDE. For instance, you could compile |
| 187 | wxWidgets using this method but continue to use the IDE for your application. |
| 188 | Personally, I prefer sticking with the command line so I haven't tried this. |
| 189 | |
| 190 | --- OS X SDKs --- |
| 191 | Before CodeWarrior 9.3 the usage of SDKs (those in /Developer/SDKs) is |
| 192 | impossible. You might think that it would work simply be prefacing any |
| 193 | /System or /usr paths with the SDK path when setting the environment variables. |
| 194 | Unfortunately, the libraries and frameworks inside these SDKs contain absolute |
| 195 | paths to libraries and frameworks which they depend on. Thus, the linker |
| 196 | attempts to load the non-SDK version to satisfy the dependency. |
| 197 | |
| 198 | To ensure an app will work correctly on previous versions of the OS you |
| 199 | can use Apple's availability macros. |
| 200 | |
| 201 | --- CodeWarrior 8.3 and Panther --- |
| 202 | CodeWarrior 8.3 has some problems running on Panther. When using the IDE |
| 203 | version it is typical to change the OS X directory to the 10.2 SDK. |
| 204 | Unfortunately, this is impossible with the command line compiler due to |
| 205 | the aforementioned bug. Thus, the only solution is to allow CodeWarrior |
| 206 | 8.3 to work with Panther's headers. Fortunately, this isn't as hard |
| 207 | as some people (particularly those at Metrowerks) would make you think. |
| 208 | |
| 209 | First of all, there are issues with Apple's headers declaring conflicting |
| 210 | types. Particularly with respect to wchar_t. Now, I'm sure you're |
| 211 | aware of the "(wchar_t Support fix)" directory. What you need to do |
| 212 | is create another one called "(wchar_t Support Panther fix)" using the |
| 213 | provided machine/ansi.h file which contains some minor changes from |
| 214 | the Metrowerks version. |
| 215 | |
| 216 | Secondly, there is an issue with crt1.o. Apple's position is that |
| 217 | /usr/lib/crt1.o is intended to be used only with Apple's GCC. |
| 218 | Metrowerks does provide an mwcrt1.o and when you're using the IDE you |
| 219 | can perfectly well use it instead of Apple's crt1.o. Unfortunately, |
| 220 | when you are using mwld it has crt1.o hardcoded. Very fortunately, it |
| 221 | has only the filename encoded and it searches the libraries path! |
| 222 | What I do is symlink "Mac OS X Support/Libraries/Startup/mwcrt1.o" to |
| 223 | crt1.o in the same directory. |
| 224 | |
| 225 | --- MSL on OS X --- |
| 226 | In mwvar.sh for the Mac OS X/PPC toolchain I've used MSL C++ with the |
| 227 | BSD CRT. To do this I used the .a files. Earlier I used the .lib files |
| 228 | but these also require the MSL C .lib. AFAIK using this would cause |
| 229 | the MSL CRT to be used and I think I don't want that unless I'm using |
| 230 | the MSL CRT headers. It did work although I never tested it with |
| 231 | anything too complex. I suspect it would have failed although I'm |
| 232 | wondering how it works with the CW projects because I think they do |
| 233 | link with the MSL_C libs. This is probably very wrong. |
| 234 | |
| 235 | If you do decide to use the MSL_C libs you'll need to add |
| 236 | "MSL/MSL_C/MSL_MacOS/Src/console_OS_X.c". Unfortunately, |
| 237 | mwld is a linker and doesn't understand C source code. Thus you must |
| 238 | compile this file and use the compiled version. |
| 239 | |
| 240 | What I did was simply run mwcc -c console_OS_X.c to generate a |
| 241 | console_OS_X.c.o object file. This file must be in MWMacOSXPPCLibraryFiles. |
| 242 | |