I'm trying to understand how Objective-C works, and the simplest example I found so far is from https://codeseekah.com/2012/09/12/compiling-objective-c-without-a-gui/ ; unfortunately, I cannot quite get it to compile (actually, link).
First of all, I use Ubuntu 14.04 (64-bit), and here I've installed:
sudo apt-get install clang-3.5 libobjc-4.8-dev
Then, I have the (slightly modified) files from the referenced page in this gist, so you can just do:
cd /tmp
git clone https://gist.github.com/dc0b573ae8ef2424aaeb043a6014b7fd.git testobjc
cd testobjc
make
The Makefile
there is modified to use the currently installed clang-3.5
.
The first problem I had, was:
main.m:45:26: error: class method '+new' not found (return type defaults to 'id') [-Werror,-Wobjc-method-access]
Person *brad = [Person new];
I found Unable to compile Objective-C code on Ubuntu :
+(id)new is a function of the NSObject class. However, you are subclassing a runtime Object. To use most of the Apple methods you're used to using in OS X, you'll need to subclass NSObject instead.
You can still use the Foundation framework while using the GNU runtime. It should be available. There is a reference you can use here: blog.lyxite.com/2008/01/…
That last is a dead link, but copy on http://www.cnblogs.com/jack204/archive/2012/03/21/2410095.html :
To Compile Objective-C Programs on Linux, GNUstep needs to be installed
Then I found How to instantiate a class in Objective-C that don't inherit from NSObject :
You absolutely can do so. Your class simply needs to implement +alloc itself, the way that NSObject does. At base, this just means using malloc() to grab a chunk of memory big enough to fit the structure defining an instance of your class.
So this is what I don't get:
- If GNUstep provides Foundation Objective-C framework on GNU/Linux, then what is the role of
libobjc
?!
Since none of these zoneAlloc
functions (needed for init
/alloc
) etc are available with the install of the above two packages, I did grep -r " id" //usr/lib/gcc/x86_64-linux-gnu/4.8/include/objc
, and found there is a function class_createInstance
that returns an id
, and so by defining a new
method that uses it, the compiler does not generate error messages in the compilation step anymore.
But then, it fails in the linking step - the full build log is also in the gist (as make.log
) - with:
/usr/bin/ld: cannot find -lobjc
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [all] Error 1
Well, first of all, libobjc.so
is in the directory /usr/lib/x86_64-linux-gnu
:
$ ls -la /usr/lib/x86_64-linux-gnu/libobjc*
lrwxrwxrwx 1 root root 19 May 7 2016 /usr/lib/x86_64-linux-gnu/libobjc_gc.so.4 -> libobjc_gc.so.4.0.0
-rw-r--r-- 1 root root 267552 May 7 2016 /usr/lib/x86_64-linux-gnu/libobjc_gc.so.4.0.0
lrwxrwxrwx 1 root root 16 May 7 2016 /usr/lib/x86_64-linux-gnu/libobjc.so.4 -> libobjc.so.4.0.0
-rw-r--r-- 1 root root 112536 May 7 2016 /usr/lib/x86_64-linux-gnu/libobjc.so.4.0.0
... and in the Makefile, I've tried running the clang
command by setting both LD_LIBRARY_PATH
and LIBRARY_PATH
to /usr/lib/x86_64-linux-gnu
- and I've also specified it with the "additional library paths" switch -L
(in LDFLAGS
). All of this seems to be ignored by the time the linker command "/usr/bin/ld"
runs, but that doesn't matter, because the linker command itself has this in its arguments:
... -L/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu ...
... and this path does indeed expand to /usr/lib/x86_64-linux-gnu
(checked it with readlink -f
), which is where libobjc.so.*
are. But still the linker command fails ?!
So my second question is:
- Why doesn't
ld
findlibobjc.so.*
, even if/usr/lib/x86_64-linux-gnu
where it is located is specified on its command line arguments via-L
-- and what do I need to do, to get this program to link?