Is Windows Safari using Objective-C 2.0?
November 12th, 2009If you look at the Safari installation directory on Windows you probably noticed the objc.dll file. Are you curious if Windows Safari is using Objective-C version 1.0 or 2.0? I was, and this is my little adventure on trying to find that out. The short answer is NO. Safari on Windows still uses Objective-C 1.0. In this article I’m going to build the Objective-C DLL and show you why I don’t think Safari for Windows is using version 2.0.

The Objective-C Runtime Environment
In my last article I showed you how to build a bare bones Objective-C program in Windows with Cygwin. In that case, the Objective-C runtime used was installed with Cygwin. You can execute the following command to take a peek at the Objective-C header and library files that Cygwin uses.
find /lib/gcc | grep objc
This is not the same Objective-C runtime that Apple uses when compiling Safari for Windows. In fact there are three Objective-C runtime environments that I know of:
- Cygwin
- Apple
- GnuStep
We used Cygwin in the last article and now we’re going to build Apple’s implementation on Windows. I may discuss GnuStep at a later date.
Let’s Start Building Something
The first thing we need to do is get the latest source.
http://www.opensource.apple.com/tarballs/objc4/objc4-437.tar.gz
Once you unpack the tarball it’s time to find out how to build this sucker. You won’t find a Makefile but you will find objc.vcproj. This is a Microsoft Visual Studio project file.
If you don’t have Visual Studio installed you can download the free version here. Why Microsoft insists on on continuing to charge for an IDE is beyond me. Must be a cultural thing. What you want is Visual C++ Expression Edition 2008. It may or may not work with the new 2010 Beta; I have no idea. I ran 2008 so I’m telling you to do the same.
Once you have Visual Studio installed, open up the project file and choose build –> build solution. You’re going to get some errors about AvailablityMacros.h and TargetConditionals.h not being found.
Did you really think it was going to be that easy?
Error #1 TargetConditionals.h
If you have XCode installed on a Mac you can easily find TargetConditionals.h. However, that file doesn’t support the Microsoft compiler. This is evident by the comment at the top of the file. It’s good to read the source no?
So with a little Googly magic you’ll find the TargetConditionals.h that you’re looking for here under Universal Interfaces 3.4.2. Of course, a *.img.bin file isn’t much help on a Windows operating system so you’re going to have to extract the files on a Mac and then copy them to the Windows Machine.
Oh, and the files are going to have those classic Mac line breaks instead of Unix line breaks so you’re going to have to convert them.
for file in `ls *.h` do tr '\r' '\n' < $file > tempfile.txt mv tempfile.txt $file done
Put those UniversalHeaders files you worked so hard to get somewhere logical, and include the header files in your project search path. What’s that? You can’t figure out where to do that? Confusing Microsoft UI got you down?
Then set the “Show directories for” combo box to “Include files”.

If you do another build then you’ll notice there are no complaints about TargetConditionals.h but Visual Studio still can’t find AvailabilityMacros.h.
Error #2 AvailabilityMacros.h
To get rid of the AvailabilityMacros.h error grab all the header files in the latest SDK you installed on your Mac. We are trying to compile the version of Objective-C that is compiled on Snow Leopard so you should probably get the 10.6 *.h files.
Create another directory for some extra includes. I called mine
/cygdrive/c/Dev/usr/include/VisualStudio, but you can call it what you like. Now copy these three files to that new directory, and add the directory to the list of include directories in Visual Studio.
- Availability.h
- AvailabilityInternal.h
- AvailabilityMacros.h
Error #3 stdint.h
Stdint.h is used for making C code more portable and you need a copy.
Download a copy and put it in that new include directory you created.
http://msinttypes.googlecode.com/svn/trunk/stdint.h
Error #4 _unmap_image_nolock
Next you will see a link error about some functions in the file objc-runtime-old.m. There is some information about this issue here:
http://lists.apple.com/…/msg00075.html
http://lists.apple.com/…/msg00076.html
Basically you need to comment out three functions so that it will compile. The explanation on the mailing list is that the source is out of sync which means nobody at Apple has probably tried to build objc on Windows for a while.
- unmap_image
- map_images
- load_images
Add #if !TARGET_OS_WIN32 … #endif around those three functions.
Error #5 SRCROOT & DSTROOT
We’ve almost got this DLL built, we just need to do one last thing. Several places in the project properties the variables $(SRCROOT) and $(DSTROOT) are referenced.

Created a batch file to define those variables right before opening up the Visual Studio Project file.
set DSTROOT=c:\Dev\builds\ObjC\ set SRCROOT=c:\Dev\sourceRoot\ObjC\ C:\cygwin\bin\cygstart.exe objc.vcproj
Now you should be able to successfully build the objc.dll library. It can be found under $DSTROOT\AppleInternal\bin\objc.dll.
Attempt to Build Objective-C 2.0
So far you’ve built Objective-C 1.0. Now let’s try to build version 2.0. If you look at the source code you see __OBJC2__ littered all over the kode. To build version 2.0 you need to define it.
Add /D “__OBJC2__” to the C/C++ command line arguments in the project properties and do a build. You will get lots of errors.
If you’re building on 32-bit windows like myself you’ll get an error about an unknown preprocessor command in objc-runtime-new.m. Apparently the Microsoft C++ compiler does not recognize the #warning directive, must be a cultural thing.
430 431 432 433 434 435 436 | #if defined(__x86_64__) uint16_t *p = (uint16_t *)(dst + vtable_prototype_index_offset + 3); if (*p != 0x7fff) _objc_fatal("vtable_prototype busted"); *p = index * 8; #else # warning unknown architecture #endif |
I didn’t try too hard to build Objective-C 2.0 because I bumped into the following nugget when perusing objc-confg.h.
28 29 30 | #if TARGET_OS_EMBEDDED || TARGET_OS_WIN32 # define NO_GC 1 #endif |
Conclusion
If Objective-C 2.0 can be built on 32-bit Windows I don’t know how to do it. Garbage collection is one of the staple features of Objective-C 2.0 (properties and fast enumeration are just syntactic sugar) and if it’s not supported, is there really any point of building it? Therefore we can firmly conclude that Safari for Windows is not using Objective-C 2.0, at least the 32-bit version anyway.
Keep on Koding on!
References
A Quick Objective-C 2.0 Tutorial



