[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Compiling GNUstep vs. Cocoa?
From: |
David Chisnall |
Subject: |
Re: Compiling GNUstep vs. Cocoa? |
Date: |
Tue, 18 May 2010 23:23:41 +0100 |
On 18 May 2010, at 20:37, Fred Kiefer wrote:
> For a really nerdy answer you will have to wait until David Chisnall
> replies.
I'm not sure if I should be offended by that or complimented...
> He will be able to explain the details of the different linker
> format perhaps plus some trick how to cheat around these when building a
> fat application.
I actually had replied already, but I forgot to mention linker formats and to
CC the list. Mac OS X uses Mach-O binaries (you can spot the Apple people,
because they pronounce this macho, while everyone pronounces it Mac... Oh),
while all sane platforms use ELF and Windows uses PE/COFF. This means that the
run time loader won't understand the formats. This is not a huge problem, for
example WINE provides a loader than can load PE binaries on *NIX.
As Fred says, you can cheat. Both GNUstep and OS X use bundles for
applications. The formats are very slightly different, but it's pretty easy to
produce a bundle that contains both OS X binaries, Linux binaries, Windows
binaries, and so on, but shares all of the resources between them.
>> From me you get only the much simple reply that the GNUstep and Cocoa
> classes are not binary compatible. This means subclasses of any Cocoa
> class will have different sizes in the different environments and at the
> moment this would break application code, even when linked differently.
Actually, with the non-fragile ABI, it's class sizes are not such an issue. I
am, of course, completely biased in suggesting that everyone should use the
non-fragile ABI, but now that I've rewritten the dtable stuff in libobjc2
Gorm's memory usage has dropped by 50%, so I think I'm more or less able to
justify it...
Part of the problem is the non-Cocoa stuff. For example, if you #include
<ctype.h> in your application (to use things like isalpha()) then this file
includes a load of inline functions, which refer to libc functions. The same
libc functions exist on FreeBSD, but not on GNU/Linux.
On 18 May 2010, at 21:18, Jay Phelps wrote:
> Thanks David for chiming in. I know you likely get asked this quite a lot,
> but what sort of undertaking would it be to implement either a compatibility
> layer (like Wine) or even true binary compatibility on a distro of Linux?
> This sort of question probably demonstrates my lack of fundamental
> understanding, obviously, but I can only know if I learn so I apologize!
A compatibility layer to provide Mac compatibility to Linux would be very
difficult. Mac applications have an irritating habit of using a lot of stuff
outside of Cocoa, including Mach and BSD stuff (even if they grab it from
headers implicitly). NetBSD has a Darwin compatibility layer that implements
some of this stuff. You could possibly extend it to work with GNUstep, but it
would be a lot of effort.
You'd also need some shims, because Linux uses a completely brain-dead calling
convention on x86 (for example, if you return a union of a pointer and a
pointer-sized integer, OS X and FreeBSD return it in %eax, Linux passes a
pointer to a pointer-sized region of stack memory into the function and then
returns the value by writing it into the address - apparently someone thought
this was sensible). You'd need shims for all of the libc functions that a
Cocoa program might call, translating these conventions.
You'd need a Mach-O loader to start with. You'd then need to implement a
compatibility layer for the Mac Objective-C runtime. This wouldn't necessarily
be difficult - the current code in libobjc2 is not really very much like the
old GNU runtime - it basically comes with a compatibility layer that makes it
pretend to be like the old GNU ABI (which was possibly designed with the aid of
illicit substances). Unfortunately, the Mac runtime is distressingly primitive
in many ways, so supporting code compiled for it would be forced to disable a
lot of the nice features of libobjc2. You'd also have to implement
objc_msgSend(), which is a completely horrible function that is impossible to
implement in C and requires some custom assembly for each target architecture
and set of calling conventions.
Basically, it's not worth it. Unlike Windows, few people have a large backlog
of legacy OS X applications that they need to run on another platform.
Source-level ports are often useful, but running binary-only apps is not. And,
if you've used WINE, you'll know that, while it's a technically impressive
achievement, it's a usability disaster. Cross platform user interfaces are a
terrible idea - when you move an app from one platform to another, you should
make sure that it conforms to the target platform's user interface guidelines,
or people will hate it.
David