
Fabien Sanglard's non-blog
Build Doom3 on MacOSX with XCode4.
November, 25th 2011
Introduction
The source code of Doom3 has been released three days ago :) ! I have started to read it and I will probably write a code review if enough people are interested.
According to the README.txt the source code is building well with Visual Studio 2010 but it is not building at all on Mac OS X with XCode 4.0 ( it is actually very broken :( !).
Here are the instructions to get it to run.
Note : If you do not want to redo all of this and just want to download Doom3 source code for Xcode 4,
a fork of the original release is available:
github repo with Xcode 4.0 support.
Edit : This post describes the entire process for educational purpose only. If fixing the PowerPC intrinsic sheader was trivial ; Fixing linker's ld: bad codegen or ld: illegal text-relocoation were
more difficult and I hope some will learn something in the process.
Edit : Thanks to John Carmack for tweeting about my website .
1. Fix Architecture and Target SDK.
Open the project in neo/sys/osx/Doom3.xcodeproject:
You should see this:
The first thing to notice is that all the Target SDK are missing:
In all 5 projects:
- Change "Architectures" from "ppc i386" to "32-bit Intel"
- Change baseSDK value to "Latest MacOSX"
Note: There are two targets in the idlib project, make sure you update the architecture and target SDK in both.
2. Fix all broken framework references.
Redefine the broken OpenGL.framework reference in the idlib's two targets:
You should now have something that look like:
Now is time to fix the missing Carbon.framework, IOKit.framework, OpenGL.framework, CoreAudio.framework references in Doom3 project:
3. Fix ppc_intrinsics.h.
Since PowerPC are a thing of the past we need to remove all references:
Try to build Doom3 Project:
The build will fail. It is because PPC_INTRINSICS is automatically defined if MACOS_X is defined (old times when all Macs were PowerPC). The fix is to be more subtle in neo/idlib/math/Simd_AltiVec.h
#define PPC_INTRINSICS
to
#if defined(MACOS_X) && defined(__ppc__)
#define PPC_INTRINSICS
#endif
Tip : Double click on the error, it will take you right to the line you need to comment.
4. Fix ld linker options.
Try to build: It will fail again with this cryptic error message:
ld: bad codegen, pointer diff in __ZN10idAnimator11CreateFrameEib to global weak symbol __ZN6idCVarD1Ev for architecture i386
Command /Developer/usr/bin/clang++ failed with exit code 1
For some reason the five projects don't have the same linker flags and this is confusing ld:
For all five projects, make sure:
- Inline Methods Hidden are set to "No".
- Symbols Hidden by Default are set to "No".
5. Fix C++ code.
Let's try to compile again. Surprise it still doesn't work:
/Users/fabiensanglard/raid/dev/TTimo-doom3.gpl-
1559777/neo/sys/osx/../../tools/compilers/aas/../../../idlib/containers/VectorSet.h:151:2: error:
use of undeclared identifier 'Append' [3]
The template code is not liked by LLVM, you need to change VectorSet.h:
Append( v );
to
this->Append( v );
6. Fix more C++ code.
Try to fail at building again: Yea !!!
This time it is a bunch of miscast and impossible implicit conversion from
long to GLint:
First batch:
/Users/fabiensanglard/raid/dev/TTimo-doom3.gpl-1559777/neo/sys/osx/macosx_glimp.mm:412:26:{412:26-412:54}:
error: cannot initialize a parameter of type 'GLint *' (aka 'int *') with an rvalue of type 'long *' [3]
/Users/fabiensanglard/raid/dev/TTimo-doom3.gpl-1559777/neo/sys/osx/macosx_glimp.mm:413:26:{413:26-413:54}:
error: cannot initialize a parameter of type 'GLint *' (aka 'int *') with an rvalue of type 'long *' [3]
/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/AppKit.framework/Headers/NSOpenGL.h:117:28:
note: passing argument to parameter 'vals' here [3]
Change macosx_glimp.mm:
[pixelFormat getValues: (long *) &glConfig.colorBits forAttribute: NSOpenGLPFAColorSize forVirtualScreen: 0]; [pixelFormat getValues: (long *) &glConfig.depthBits forAttribute: NSOpenGLPFADepthSize forVirtualScreen: 0]; [pixelFormat getValues: (long *) &glConfig.stencilBits forAttribute: NSOpenGLPFAStencilSize forVirtualScreen: 0];
to
[pixelFormat getValues: (int *) &glConfig.colorBits forAttribute: NSOpenGLPFAColorSize forVirtualScreen: 0]; [pixelFormat getValues: (int *) &glConfig.depthBits forAttribute: NSOpenGLPFADepthSize forVirtualScreen: 0]; [pixelFormat getValues: (int *) &glConfig.stencilBits forAttribute: NSOpenGLPFAStencilSize forVirtualScreen: 0];
More errors:
/Users/fabiensanglard/raid/dev/TTimo-doom3.gpl-1559777/neo/sys/osx/macosx_glimp.mm:1271:8:{1271:8-1271:28}:
error: no matching function for call to 'CGLQueryRendererInfo' [3]
/Users/fabiensanglard/raid/dev/TTimo-doom3.gpl-1559777/neo/sys/osx/macosx_glimp.mm:1283:9:{1283:9-1283:28}:
error: no matching function for call to 'CGLDescribeRenderer' [3]
/Users/fabiensanglard/raid/dev/TTimo-doom3.gpl-1559777/neo/sys/osx/macosx_glimp.mm:1295:10:{1295:10-1295:29}:
error: no matching function for call to 'CGLDescribeRenderer' [3]
/Users/fabiensanglard/raid/dev/TTimo-doom3.gpl-1559777/neo/sys/osx/macosx_glimp.mm:1303:10:{1303:10-1303:29}:
error: no matching function for call to 'CGLDescribeRenderer' [3]
/Users/fabiensanglard/raid/dev/TTimo-doom3.gpl-1559777/neo/sys/osx/macosx_glimp.mm:1313:10:{1313:10-1313:29}:
error: no matching function for call to 'CGLDescribeRenderer' [3]
Change macosx_glimp.mm:
long rendererInfoIndex, rendererInfoCount = MAX_RENDERER_INFO_COUNT;
long rendererIndex, rendererCount;
long maxVRAM = 0, vram = 0;
long accelerated;
long rendererID;
long totalRenderers = 0;
to
long rendererInfoIndex;
GLint rendererInfoCount = MAX_RENDERER_INFO_COUNT;
long rendererIndex;
GLint rendererCount;
long maxVRAM = 0;
GLint vram = 0;
GLint accelerated;
GLint rendererID;
long totalRenderers = 0;
Some more errors:
/Developer/SDKs/MacOSX10.6.sdk/usr/include/ucontext.h:42:2: error: #error ucontext routines are deprecated, and require _XOPEN_SOURCE to be defined [2]
Change DoomController.mm:
#import <ucontext.h>
to
#import <sys/ucontext.h>
Still more errors:
/Users/fabiensanglard/raid/dev/TTimo-doom3.gpl-1559777/neo/sys/osx/DOOMController.mm:474:8:{474:11-474:121}:
error: assigning to 'cpuid_t' from incompatible type 'int' [3]
Change DOOMController.mm:
cpuid_t Sys_GetProcessorId( void )
{
cpuid_t cpuid = CPUID_GENERIC;
#if defined(__ppc__)
cpuid |= CPUID_ALTIVEC;
#elif defined(__i386__)
cpuid |= CPUID_INTEL | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_SSE3 | CPUID_HTT | CPUID_CMOV | CPUID_FTZ | CPUID_DAZ;
#endif
return cpuid;
}
to
cpuid_t Sys_GetProcessorId( void )
{
int cpuid = CPUID_GENERIC;
#if defined(__ppc__)
cpuid |= CPUID_ALTIVEC;
#elif defined(__i386__)
cpuid |= CPUID_INTEL | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_SSE3 | CPUID_HTT | CPUID_CMOV | CPUID_FTZ | CPUID_DAZ;
#endif
return static_cast<cpuid_t>(cpuid);
}
Finally
Change macosx_glimp.mm:
common->Printf( "%8d kB total OpenAL audio memory used\n", ( alGetInteger( alGetEnumValue( (ALubyte*) "AL_EAX_RAM_SIZE" ) ) - alGetInteger( alGetEnumValue( (ALubyte*)"AL_EAX_RAM_FREE" ) ) ) >> 10 );
to
common->Printf( "%8d kB total OpenAL audio memory used\n", ( alGetInteger( alGetEnumValue( "AL_EAX_RAM_SIZE" ) ) - alGetInteger( alGetEnumValue( "AL_EAX_RAM_FREE" ) ) ) >> 10 );
7. Fix the compiler.
Try to build: Fail.
ld: illegal text-relocoation (direct reference) to (global,weak) __ZN6idMatX11InverseSelfEv in
/Users/fabiensanglard/TTimo-doom3.gpl-1559777/neo/sys/osx/build/Debug/libidlib_nopic.a(Matrix.o)
from __ZN6idMatX11InverseSelfEv in /Users/fabiensanglard/TTimo-doom3.gpl-1559777/neo/sys/osx/build/Debug/libidlib_nopic.a(Matrix.o)
for architecture i386
It seems all the projects did not use the same compiler, some defaulted to Apple LLVM compiler 3.0 while some other did default to LLVM GCC 4.2. Set them all to LLVM GCC 4.2 (don't forget there are two target in the idlib project: idlib_pic and idlib_nopic).
8. Fix the OpenAL weak reference.
The Doom3 project features a weak framework reference:
-weak_framework OpenAL
Remove this flag and add the OpenAL.framework instead.
9. Remove the old curl lib reference.
Delete the curl project reference and add libcurl.dylib to the list of framework in Doom3 project. This will make the build process much faster.
10. Don't build unused architectures.
Optional: For all projects: Set "Build active Architecture only" to Yes.
11. Add libraries to linker.
The build will still fail at this point since the linker is missing the game.dylib and the libidklib_pic.a libraries. Add them to the project:
12. Get the assets.
Dust out your Doom3 CDs:
If you haven't bought it yet: it is available on Steam ;) ! Place the
base folder just next to Doom3 executable. Copy base/defaut.cfg from the source release to the base folder from Steam.
13. Link game.dylib.
If you try to launch the game now it will crash at startup:
Dyld Error Message: Library not loaded: /usr/local/lib/game.dylib Referenced from: /Users/dev/TTimo-doom3.gpl-1559777/neo/sys/osx/build/Debug/Doom 3.app/Contents/MacOS/Doom 3 Reason: image not found
Two solutions possible:
- Copy
game.dylibto/usr/local/lib/(or even better, create a symbolic link). - Set "Dynamic Library Install Name" to "", this will make Doom3 search for the dylib locally.
14. Enjoy !
Let's try one last time:

Happy Hacking guys ;) !
Add a comment
Comments (64)
Alfredo
Just an comment for step 12.
You can copy the game.dylib to Doom 3.app/Contents/Frameworks and then
install_name_tool -change /usr/local/lib/game.dylib @executable_path/../Frameworks/game.dylib Doom 3.app/Contents/MacOS/Doom 3
it will change the reference relative to the app bundle so you have a self contained app (no need to copy game.dylib anywhere on the system).
Other than that, a great fix, thanks.
Usually id release the source code and stop maintaining it. Your approach would have been valid if we had some guaranty that someone on the master GIT will actually make sure the fork doesn't break anything on the other platforms builds and actually merge it back.
If not, the fork will remain buried as a Pull Request with no visibility at all.
IMHO it is already too late, the source code is all over the web and I don't think the gitHub one will be monitored in order to achieve a figure of authority.
Fabien
For OS X Lion with Xcode 4.2.1, I started from your project but then also had to:
1. Set the SDK to 10.6 because a bunch of deprecated Carbon era graphics code has been stripped from the 10.7 SDK.
2. Change the Deployment Target for all the projects to 10.4
And curiously, I didn't have the problem with it trying to load game.dylib from /usr/local/lib.
Yeah, interested !
... And thanks for the fix.
I'm interested, please !!!
Thanks for theses tips ;)
Can't wait for your next tutorial: How to build Doom 3 for iOS. :)
I'm also interested in the review ;)
https://github.com/badsector/Doom3-for-MacOSX-
Also a DMG with precompiled "release" binary is available in the Downloads tab :-).
There are two bugs: fullscreen mode doesn't seem to work and due to a linking problem (similar to the one mentioned above, but apparently not due to the same reasons since all projects do use the same compiler) the UI interpolations are disabled (i commented out the code that caused the issue). When i find some time i'll try to fix these - unless someone else beats me to it, of course :-P. Whatever the case, i'll try to update the DMG when these two are fixed :-).
I don't understand why all the media isn't included?
Do I have to buy doom 3. Then how is that open source?
This is standard procedure for id software now: The source code is open but the assets remain proprietary.
>>Do I have to buy doom 3. Then how is that open source?
This way we can play and learn from the technology while id is free to keep on commercially exploiting their creation.
>>Can you upload the base folder as well?
This is still the property of id software, this would be illegal. It is only 10$ on steam.
Fabien
When I saw the Doom 3 sources online I immediately opened your page to see if there's the source review. I loved the Quake 2 rasterizer analysis and can't wait to see what you can explain us about the D3 engine!
Thanks and nice article.
Would love a code review!
Second I would point out that your guide does not mention how one can upgrade the Doom 3 assets taken from one's old install CDs. I'm still confused as to how to do it from OS X. From your instructions it appears that you simply use the non-updated assets from the original retail release of the game without applying any updates, which seems like the wrong thing to do (the source code readme even specifically mentions this, ie. the game should be updated to the latest version).
(Quick semi-related rant: I love id Software but I think they're being total douches for having never bothered to update any of their games on Steam to be Mac-compatible. Even those that are just DOSBox-contained DOS games, I mean how hard can that be?)
I do have one question, have you by chance figured out how to get any game.dylib working with Doom 3 without having to link it to the executable its self?
This is something that's kinda baffled me; without linking the game's dylib with the executable, the game will certainly get to the title screen, but trying to actually load a game seems to cause it to crash completely.
Any ideas?
Keep the good work ;)
Please count me among those interested in a code review!
Thanks
I just updated the page: In order to avoid linking issue you can set "Dynamic Library Install Name" to "" in the "game" projects, this will make Doom3 search for the dylib locally
>>How does it feel to be tweeted by John Carmack ?
I am going to print and frame the tweet :) !
I used the OpenAL fix, the game.dylib fix (which would lead into my own fix), and the CGL fixes (which weren't necessary for me under LLVM GCC 4.2, but were necessary to get it compiling with Clang).
Regarding the linking bits, I moreso mean getting it working to the point that you can just load any game.dylib (i.e., one from a mod) without having the game crash on loading a map. I've done a little bit of investigation into why it crashes between vanilla Doom 3 and Doom 3 RoE, but I haven't found anything particularly useful yet.
on github there's a 404 error for your page,
there's some problem ?
All the changes are in the git fork, it is normal that you did not have to do anything.
With regard to the asset, you need to install the game with the 3 CDs. Then download the latest Doom3 patch (this will patch the assets as well). Then just copy past the "base" folder just next to the executable generated in the "build" folder.
Keep up the good work.
And pleaaaase, yes, a code review would be so great :)
Tip2: When you got the Windows CDs like me, to patch the base folder to version 1.3.1 (necessary to play) , download the doom 3 linux patch and change the target folder to a temporary folder, then copy the files in the base folder of the temporary folder to your base folder.
I just discovered your website. Your reviews on ID software engines are very nice. I already check source of these engines long time ago but didnt know about your articles.
A doom 3 source review would be very nice. I already check it by myself and discover lot of stuff but i have to admit it takes times. i'd like to post what i have found somewhere but dont know what the best (create a blog ? use wikipedia?)
If you ever decide to create something here are some hints :
What would be very interesting is to know is general architecture (how engine is designed, different main parts). This would help to understand main code structure and know where to go. Some parts could be more described in details (like the renderer (especially those shadows), event/entities system, networking or the virtual machine. Would be also good to know if engine differ a lot from previous id software engines (especially idtech3)
Would be nice if you can review the Doom 3 source code
thanks for this great How-To. I could fix many problems, but I still cannot completely compile the sources. I'm running Mac OS X 10.8.2 with the latest Xcode 4.5. With the Apple LLVM Compiler 4.1 I get 3 Errors in the glext.h at lines 2786, 2787 and 2793. When I use the LLVM GCC 4.2 Compiler, there are about 50 more errors. I'm not that experienced in C++ and OpenGL, so I have no clue how to fix these errors. I think I have done all the steps in your How-To. I hope you have a hint.
Thank you very much! :)









