First off I just want to say congratulations to you guys - I've been
watching the project (LLVM & clang) for a couple of years now, and I
can't say loudly enough what a great job you guys have done and what a
potentially fantastic project something like this is!
I've recently pulled down the latest LLVM build on windows and built
it successfully with Visual Studio 2008. Woot.
What I'd like to do is some Objective C programming without *any* use
or dependance on GCC. I tried a few simple tests, which clang was able
to emit apparently valid bitcode for. When I try and run them with
lli, I get an error
"LLVM ERROR: Program used external function '__objc_exec_class' which
could not be resolved!"
Not surprising, it doesn't know where the runtime is. Apple provides
the source, plus Visual Studio projects, for their objcrt, and after a
few tweaks I was able to build it successfully, and ended up with
objc.dll, and a whole bunch of runtime functions.
Now my question is: how do I get LLVM to use this? I'm not interested
in Cocoa whatsoever, I'd just be curious to use bare bones objective
C, and even build my own framework if I get really ambitious. I notice
that there are two files in clang, CGObjCGNU.cpp, and CGObjCMac.cpp -
would I need something like CGObjCWin32.cpp that implements the
appropriate code? Is there something else involved? Has anyone else
tried this, or even interested in this?
Thanks
Jim
It depends on what you're trying to do. If you're trying to JIT code, you can load it with the 'lli -load foo.dll' command line option. However, LLI doesn't know enough about objc metadata to register the classes etc with the runtime, so you'd have to add this.
If you want to statically compile code, just linking to the dll you built should be enough. I'm not an objc or windows guru though.
-Chris
This sounds like you are generating code for the GNU runtime. __objc_exec_class() is the GNU Objective-C function that loads the Objective-C data within a compilation unit. To emit code that invokes Apple runtime, instead of GNU runtime, functions you will need to specify -fnext-runtime. This is not the default on any platform other than Darwin because the Apple runtime is not supported on any other platforms (although Apple uses it on Windows, and it may possibly work for you too).
David
OK thanks. I can see that clang is responding to "-fnext-runtime", I
presume I just need to get llvm-ld to work now and I'm almost there.
Can llvm generate an exe directly or does it always have to go from
llvm bitcode to C code to native c compiler?
Cheers
Jim
David,
Thanks! do I use "-fnext-runtime" when I compile with clang or when I use lli?
It needs to be when you run clang. You almost certainly won't be able to use the resulting code with lli though. lli interprets the bitcode. The NeXT runtime uses special segment types to register Objective-C structures. The segment types and the loader callbacks do not exist in interpreted or JIT-compiled code, so the runtime does not have any way of getting at them. The interaction between the loader and the NeXT runtime is quite complex. In contrast, the GNU runtime just expects __objc_exec_class() to be called once per compilation unit, which is done via the same mechanism C++ uses for static initalisers and gcc uses for __attribute__((constructor)) functions in C.
If you want to JIT compile or interpret Objective-C code for the NeXT runtime then you will need to make calls to objc_allocateClassPair() and so on in your own code.
Is there a sensible reason why you chose to use the NeXT runtime, by the way?
Actually all I really want, ideally, is to be able to use clang/llvm
to generate an exe or dll based on ObjectiveC. I'd rather not use the
GNU runtime, especially since the Apple one is publicly available, and
I'm guessing it's better than the GNU one, plus as a general rule I
try to avoid any of the GNU stuff for windows related programming. I
don't care about using Cocoa per se, I'd be perfectly happy with just
the basic Objective C runtime.
Thanks
Jim
The current Apple’s objc runtime is maybe better than the old GNU one, but I don’t think it will give you more than the GNU objc2 runtime but troubles.
Trying to use the Apple runtime outside of the Apple world is not recommended and not supported at all. The ObjC runtime is Open source but it heavily relies on Foundation to set it up.
Without the Apple’s Foundation, critical part of the runtime will not work properly.
– Jean-Daniel
As the maintainer of the GNU objc2 runtime, please note that it still hasn't yet had an official release and, although I am using it on a daily basis, it may still contain serious bugs (I fixed one just an hour ago) and I reserve the right to break the new ABI in fun and exciting ways at any point between now and the official release (so, until then, make sure you use the latest svn with the latest svn of clang if you use -fobjc-nonfragile-abi).
That said, more testing is welcome, and please send me bug reports...
David
-- Sent from my Apple II
The current Apple's objc runtime is maybe better than the old GNU one, but I
don't think it will give you more than the GNU objc2 runtime but troubles.
Trying to use the Apple runtime outside of the Apple world is not
recommended and not supported at all. The ObjC runtime is Open source but it
heavily relies on Foundation to set it up.
Without the Apple's Foundation, critical part of the runtime will not work
properly.
-- Jean-Daniel
Well all I want is just the minimal bare bones Objective C language
support. I have no interest in using Apple's Foundation, AppKit, or
any other Cocoa frameworks. I just wanted a basic Objective C
implementation that can be compiled and used with a Microsoft
toolchain. The rest I'd be more than happy to build myself, again more
as an interesting exercise than anything practical.
Cheers
Jim
Yes, it depends what you mean by minimal.
It should be fine if you don't plan to use Block, Exception, Forwarding , synchronize, etc…
-- Jean-Daniel
Yes, it depends what you mean by minimal.
It should be fine if you don't plan to use Block, Exception, Forwarding , synchronize, etc…
So are those things part of the Objective C, or just some extension?
Are you saying exception handling is fundamentally dependent on the
Foundation kit? Oh well, maybe it's just not worth the bother then.
Cheers
Jim
The Apple runtime is design to be used with (Apple) Foundation framework.
See for example the comment in objc-exception.m
// quick and dirty exception handling code
// default implementation - mostly a toy for use outside/before Foundation
// provides its implementation
// Perhaps the default implementation should just complain loudly and quit
You can probably rewrite some part to replace Foundation.
I don’t know which runtime Cocotron uses, but as it is design for Windows, you may have a look at it.
http://code.google.com/p/cocotron/
– Jean-Daniel
I am not sure about that but I think he tries to say that using Apple
runtime
is not a good option.
I suppose it should be possible to do some simple objective-C by using
compiler and
GNUStep objc runtime.
For the GNU runtime (the same is mostly true for the Apple runtime):
Throwing and catching exceptions is handled by the personality function in the runtime. It just checks the isa pointers of the thrown object. In OpenStep code it is common to only throw or catch NSException objects - and some code depends on this behaviour - but it's not required by the runtime. With the old Apple runtime, and until a few years ago with the GNU runtime, exceptions were all implemented in terms of setjmp()/longjmp() in Foundation and were completely outside the runtime.
Blocks are not supported by the old GNU runtime. The GNU objc2 runtime has a blocks implementation that has been tested on FreeBSD and Linux and has been in use by various people for about a year. The Apple runtime delegates this to the blocks runtime (a separate library). The implementation used on OS X is in CompilerRT, but I don't know if anyone has used this on non-Darwin platforms. Last time I looked it was full of Darwinisms, but it might have been tidied up by now.
Forwarding is mainly done by the Foundation framework. When an object does not respond to a message, the runtime calls a function in Foundation which constructs an NSInvocation object. With GNUstep, this uses either libffi or ffcall. I'm not sure what Apple uses. As NSInvocation is part of Foundation, this can't be in the runtime. In 'classic' Objective-C, forwarding is done via the forward:: method, which is responsible for deconstructing the stack frame itself. I think the GNU runtime falls back to doing this if no callback function is registered, but it's so horrible to use I don't think anyone does.
@synchronize() must create a recursive mutex for each object. This calls functions that weren't present in the old GNU runtime. They are provided by both GNUstep and the GNU objc2 runtime, and I think the ones in Apple's libobjc don't depend on Foundation.
You should be aware, however, that Foundation is usually regarded as the Objective-C standard library. It implements all of the core stuff that most programs will need, like collections, interfaces with the runtime system, and so on. Using Objective-C without Foundation is possible (obviously, as that's effectively what the authors of a Foundation implementation had to do), but it's a lot of work. You will find that GNUstep-base and libFoundation both provide implementations of Foundation that work on Windows. Cocotron might too, but they seem better at PR than writing code.
David
-- Sent from my Apple II
If we want to migrate ObjectiveC to windows platform, at least need to
support windows api. Considerating mingw to support windows sdk is not
always up to date. If we can direct using windows sdk headers is the
best choice:) and also ms provide the *.lib files, if we can direct
support pecoff files, then we can linkage to these files directly:)