Compiling objective c on Linux - objective-c

I am trying to compile the following example from http://www.otierney.net/objective-c.html. It consists of three files:
Fraction.h
#import <Foundation/NSObject.h>
#interface Fraction: NSObject {
int numerator;
int denominator;
}
-(void) print;
-(void) setNumerator;
-(void) setDenominator;
-(int) numerator;
-(int) denominator;
#end
Fraction.m
#import <stdio.h>
#implementation Fraction
-(void) print {
printf("%i/%i", numerator, denominator);
}
-(void) setNumerator: (int) n {
numerator = n;
}
-(void) setDenominator: (int) d {
denominator = d;
}
-(int) denominator {
return denominator;
}
-(int) numerator {
return numerator;
}
#end
main.m
#import <stdio.h>
#import "Fraction.h"
int
main(int argc, char **argv)
{
//Create a new instance
Fraction *frac = [[Fraction alloc] init];
//set the values
[frac setNumerator: 1];
[frac setDenominator: 3];
//print it
printf("The fraction is: ");
[frac print];
printf("\n");
//Frac memory
[frac release];
return 0;
}
Using to following to compile
$ gcc `gnustep-config --objc-flags` -lobjc -lgnustep-base main.m -o main
This produces a main.d file, that is just ascii
$ cat main.d
main: main.m Fraction.h /usr/include/GNUstep/Foundation/NSObject.h \
/usr/include/GNUstep/Foundation/NSObjCRuntime.h \
/usr/include/GNUstep/GNUstepBase/GSVersionMacros.h \
/usr/include/GNUstep/GNUstepBase/GSConfig.h \
/usr/include/GNUstep/GNUstepBase/preface.h \
/usr/include/GNUstep/GNUstepBase/GSObjCRuntime.h \
/usr/include/GNUstep/ObjectiveC2/runtime.h \
/usr/include/GNUstep/ObjectiveC2/Availability.h \
/usr/include/GNUstep/Foundation/NSZone.h \
/usr/include/GNUstep/GNUstepBase/GNUstep.h \
/usr/include/GNUstep/Foundation/NSDate.h \
/usr/include/GNUstep/GNUstepBase/NSObject+GNUstepBase.h
Fraction.h:
/usr/include/GNUstep/Foundation/NSObject.h:
/usr/include/GNUstep/Foundation/NSObjCRuntime.h:
/usr/include/GNUstep/GNUstepBase/GSVersionMacros.h:
/usr/include/GNUstep/GNUstepBase/GSConfig.h:
/usr/include/GNUstep/GNUstepBase/preface.h:
/usr/include/GNUstep/GNUstepBase/GSObjCRuntime.h:
/usr/include/GNUstep/ObjectiveC2/runtime.h:
/usr/include/GNUstep/ObjectiveC2/Availability.h:
/usr/include/GNUstep/Foundation/NSZone.h:
/usr/include/GNUstep/GNUstepBase/GNUstep.h:
/usr/include/GNUstep/Foundation/NSDate.h:
/usr/include/GNUstep/GNUstepBase/NSObject+GNUstepBase.h:

I have an answer for you. Here is what you need:
1. Setup GNUstep just like on this site: http://camelek.wikidot.com/wprowadzenie-do-objective-c
2. Create GNUmakefile with that content:
include $(GNUSTEP_MAKEFILES)/common.make
TOOL_NAME = Fraction
$(TOOL_NAME)_OBJC_FILES = main.m Fraction.m
include $(GNUSTEP_MAKEFILES)/tool.make
Here is how your compilation will look like, and how works your new program:
camelek#debian:~/.../Fraction$ gs_make
This is gnustep-make 2.6.2. Type 'make print-gnustep-make-help' for help.
Making all for tool Fraction...
Compiling file main.m ...
Compiling file Fraction.m ...
Linking tool Fraction ...
camelek#debian:~/.../Fraction$ file ./obj/Fraction
./obj/Fraction: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=0xd25682721d14fd4e0fb48bb999797da28d4f8940, not stripped
camelek#debian:~/.../Fraction$ ./obj/Fraction
The fraction is: 1/3
camelek#debian:~/.../Fraction$
I am using Debian Wheezy 7.1

Related

GCC Undefined Reference to xxx

I'm making a simple test to see if I can run Objective-C on Linux without GNUStep, so I followed an example here on SO to get it running, here's my code:
//WSObject.h
#include <objc/runtime.h>
#include <stdio.h>
#interface WSObject
+ (id) alloc;
- (void) dealloc;
- (void) hello;
#end
//WSObject.m
#include "WSObject.h"
#implementation WSObject
+ (id) alloc {
return class_createInstance(self, 0);
}
+ (void) dealloc {
object_dispose(self);
}
+ (void) hello {
puts("Hello, world");
}
#end
//test.m
#include "WSObject.h"
int main(int argc, const char *argv[]) {
WSObject *obj = [WSObject alloc];
[obj hello];
[obj dealloc];
return 0;
}
When I then try to compile it with gcc test.m -o test -lobjc
I get the following error:
/tmp/ccDzvsol.o:(.data+0x80): undefined reference to `__objc_class_name_WSObject'
collect2: error: ld returned 1 exit status
Any help?

How to run a simple objective-c in linux

EDITED
I have been trying to start coding in Objective-c. Its just a simple program to try getter and setter methods. Also print Hello World. THe following is my code:
#import <objc/Object.h>
#interface Car:Object{
int wheel: 5;
}
- (int)wheel;
- (void)setWheel: (int)newWheel;
#end
#include <stdio.h>
#implementation Car
- (int)wheel{
return wheel;
}
- (void)setWheel: (int)newWheel{
wheel = newWheel;
}
#end
#include <stdlib.h>
int main(void){
printf("Hello World");
}
I now get garbage
/tmp/cc3UC6jY.o: In function `__objc_gnu_init':
hello.m:(.text+0x6d): undefined reference to `__objc_exec_class'
/tmp/cc3UC6jY.o:(.data+0x1c0): undefined reference to `__objc_class_name_Object'
collect2: error: ld returned 1 exit status
I used the the command gcc -o hello hello.m -lobjc
I have spent hours googling this answer.
The following variation of your code compiled and ran for me:
#import <objc/Object.h>
#interface Car : Object {
int wheel;
}
- (int)wheel;
- (void)setWheel: (int)newWheel;
#end
#implementation Car
- init {
wheel = 5;
return self;
}
- (int)wheel {
return wheel;
}
- (void)setWheel: (int) newWheel {
wheel = newWheel;
}
#end
#include <stdio.h>
int main(void){
printf("Hello World\n");
id myCar = [[Car alloc] init];
printf("Wheel value is %d\n", [myCar wheel]);
return 0;
}

Compiling objective-c programs without gnustep on ubuntu

is there any way to compile objective c programs on ubuntu without the use of GNUStep? I want to use the default C standard libraries and all but with Objective-C's OOB syntax. The problem I am having now is once I have all the methods up, I need a way to call them. In Mac I would just alloc and init it but on Linux when I try to compile this, clang just gives me an error.
#include <stdio.h> // C standard IO library (for printf)
#include <stdlib.h> // C standard library
// Interface
#interface test
-(void)sayHello :(char *)message;
#end
// Implementation
#implementation test
-(void)sayHello :(char *)message {
printf("%s", message);
}
int main(int argc, char *argv[]) {
test *test = [[test alloc] init];
[test sayHello:"Hello world"];
}
You can compile objective-c with gcc, but remember to use the -lobjc switch so the compiler knows what language you're using.
You'll also need to include the following header:
#import <objc/Object.h>
...and extend Object from your interface. See the hello world example for objective-c here:
http://en.m.wikipedia.org/wiki/List_of_Hello_world_program_examples#O
Good question - it got me to dig into the matters myself, since I want to rewrite several old Python projects in a normal language (C/ObjC), so I aim both to stay away from Crap++ and avoid GNUstep overhead. Here goes my try-and-test solution:
Foo.h:
#import <objc/Object.h>
#interface Foo: Object
{
#private
int
bar;
}
+ (id) alloc;
+ (id) new;
- (id) init;
- (id) set_bar: (int)value;
- (int) get_bar;
#end
Foo.m:
#import <stdio.h>
#import <objc/runtime.h>
#import "Foo.h"
#implementation Foo
+ (id) alloc
{
puts(__func__);
return class_createInstance(self, 0);
}
+ (id) new
{
return [[self alloc] init];
}
- (id) init
{
puts(__func__);
bar = 31;
return self;
}
- (id) set_bar: (int)value
{
puts(__func__);
bar = value;
return self;
}
- (int) get_bar
{
puts(__func__);
return bar;
}
#end
main.m:
#import <stdio.h>
#import "Foo.h"
int
main
()
{
id
foo = [Foo new];
printf("old bar: %i\n", [foo get_bar]);
[foo set_bar: 10];
printf("new bar: %i\n", [foo get_bar]);
return 0;
}
Makefile:
run: main.o Foo.o
gcc $^ -o $# -lobjc
main.o: main.m Foo.h
gcc -c $< -o $#
Foo.o: Foo.m Foo.h
gcc -c $< -o $#
The output I've got:
+[Foo alloc]
-[Foo init]
-[Foo get_bar]
old bar: 31
-[Foo set:bar:]
-[Foo get_bar]
new bar: 10
Looks like it works!

Why do I get a "parse error before '#' token" when I try to build this simple XCode project?

Complete newbie question. I'm learning Objective-C from Kochan's book. When I try to build the following very simple project, I keep getting a
parse error before '#' token
referring to the #property int numerator, denominator; statement in the Fraction.h file.
Here is the Fraction.h file:
#import <Foundation/Foundation.h>
#interface Fraction : NSObject
{
int numerator;
int denominator;
}
#property int numerator, denominator;
-(void) print;
-(void) setTo: (int) n over: (int) d;
-(double) convertToNum;
#end
Here is the Fraction.m file:
#import "Fraction.h"
#implementation Fraction
#synthesize numerator, denominator;
-(void) print
{
NSLog(#"%i/%i", numerator, denominator);
}
-(void) setTo: (int) n over: (int) d
{
numerator = n;
denominator = d;
}
-(double) convertToNum
{
if (denominator != 0)
return (double) numerator/denominator;
else
return 1.0;
}
#end
Any help in understand why I am getting that parse error is much appreciated.
I found this on Objective-C 2.0 (but interestingly not in Kochan's book): "All Objective-C applications developed for Mac OS X that make use of the [above] improvements for Objective-C 2.0 are incompatible with all operating systems prior to 10.5 (Leopard)." So we've found the explanation. Thank you all.
Hello Scolfax
welcome
it seems your problem in
#property int numerator, denominator; and
NSLog(#"%i/%i", numerator, denominator);

Compiling Objective-C project on Linux (Ubuntu)

How to make an Objective-C project work on Ubuntu?
My files are:
Fraction.h
#import <Foundation/NSObject.h>
#interface Fraction: NSObject {
int numerator;
int denominator;
}
-(void) print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
-(int) numerator;
-(int) denominator;
#end
Fraction.m
#import "Fraction.h"
#import <stdio.h>
#implementation Fraction
-(void) print {
printf( "%i/%i", numerator, denominator );
}
-(void) setNumerator: (int) n {
numerator = n;
}
-(void) setDenominator: (int) d {
denominator = d;
}
-(int) denominator {
return denominator;
}
-(int) numerator {
return numerator;
}
#end
main.m
#import <stdio.h>
#import "Fraction.h"
int main( int argc, const char *argv[] ) {
// create a new instance
Fraction *frac = [[Fraction alloc] init];
// set the values
[frac setNumerator: 1];
[frac setDenominator: 3];
// print it
printf( "The fraction is: " );
[frac print];
printf( "\n" );
// free memory
[frac release];
return 0;
}
I've tried two approaches to compile it:
Pure gcc:
$ sudo apt-get install gobjc gnustep gnustep-devel
$ gcc `gnustep-config --objc-flags` -o main main.m -lobjc -lgnustep-base
/tmp/ccIQKhfH.o:(.data.rel+0x0): undefined reference to `__objc_class_name_Fraction'
I created a GNUmakefile Makefile:
include ${GNUSTEP_MAKEFILES}/common.make
TOOL_NAME = main
main_OBJC_FILES = main.m
include ${GNUSTEP_MAKEFILES}/tool.make
... and ran:
$ source /usr/share/GNUstep/Makefiles/GNUstep.sh
$ make
Making all for tool main...
Linking tool main ...
./obj/main.o:(.data.rel+0x0): undefined reference to `__objc_class_name_Fraction'
So in both cases compiler gets stuck at
undefined reference to `__objc_class_name_Fraction'
Do you have and idea how to resolve this issue?
It's right. In both cases you did not include Fraction.m in your list of files to be compiled, so it can't find the implementation of the class Fraction
From the comment, this command works
gcc `gnustep-config --objc-flags` -o main *.m -lobjc -lgnustep-base
I am not an expert at writing the make files like that, I find simply typing the following works on ubuntu quite well:
gcc -I /usr/include/GNUstep/ -I /usr/include/mysql -L /usr/lib/GNUstep/\
-lgnustep-base -lmysqlclient\
-g -ggdb\
-fconstant-string-class=NSConstantString -o test *.m
I am using it on this project:
http://github.com/uptecs/SmsgateDelivery/
If the above GCC command does not work you have not installed enough packages, use apt-cache to search for more gcc and objective c packages to install (I just installed more packages that looked relevant at random until it worked)
the make file:
include ${GNUSTEP_MAKEFILES}/common.make
APP_NAME=Fraction
Fraction_HEADERS = Fraction.h
Fraction_OBJC_FILES = main.m Fraction.m
include ${GNUSTEP_MAKEFILES}/application.make
The approach I just got working was (in Ubuntu, which is closely related to Debian):
Use Synaptic to install all likely-looking GnuStep packages;
Source ( . ) the GnuStep startup script, /usr/share/GNUstep/Makefiles/GNUstep.sh (this can go into .profile or .bashrc or something so you don't have to do it manually every time)
Create a GNUmakefile according to the instructions in A First Tool
This allowed me to successfully build command line programs.
Add Fraction.m in make file,
include ${GNUSTEP_MAKEFILES}/common.make
TOOL_NAME = main
main_OBJC_FILES = main.m Fraction.m
include ${GNUSTEP_MAKEFILES}/tool.make
and then make ^^
Just add Fraction.m in main.m instead to add Fraction.h in main.m. And this will work. The following is the main.m file i used :
#import <stdio.h>
#import "Fraction.m"
int main( int argc, const char *argv[] ) {
//create a new instance
Fraction *frac = [[Fraction alloc] init];
//set the values
[frac setNumerator: 1];
[frac setDenominator: 3];
//print it
printf("The fraction is : ");
[frac print];
printf("\n");
//free memory
[frac release];
return 0;
}