Is it possible to build objective c code correctly with GCC under cygwin.
I have the following application that should work on a Mac environment, but can't get the most basic stuff to work with gcc. Are there more libraries I need to have.
#import "HelloWorldApp.h"
int main(int argc, char *argv[]) {
return 0;
} // End of the //
#interface Car
{
int test;
}
//The registration is a read-only field, set by copy
#property int (readonly, copy) test;
//the driver is a weak reference (no retain), and can be modified
//#property Person* (assign) driver;
#end
CC=gcc
CXX=gcc-g++
LD=$(CC)
CFLAGS=
LDFLAGS=-lobjc
all: HelloWorld
HelloWorld: HelloWorld.o
$(LD) $(LDFLAGS) -o $# $^
%.o: %.m
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $#
clean:
rm -rvf *.o HelloWorld HelloWorld.exe
Error:
gcc -c HelloWorld.m -o HelloWorld.o
In file included from HelloWorld.m:6:
HelloWorldApp.h:19: error: stray '#' in program
HelloWorldApp.h:19: error: parse error before "int"
make: *** [HelloWorld.o] Error 1
I think it's because you're using Objective-C 2.0, which is a private extension that Apple developed and that they did not contribute back to the "standard", FSF GCC. Thus, your mingw compiler (which is not based on Apple's, but on the FSF's) does not understand new syntax like properties.
# Malaxeur - you hit the nail right on the head. I've just been bashing about with ObjC on a PC and had that exact problem - my path was pointing to a v3.x gcc compiler. I switched to the 4.x version and voila!
It's also worth noting that the "stray '#'" error also pops up if you spell 'implementation' wrong, which is a little misleading.
Anyway, thanks for the help.
Have you tried running the gcc commands directly from command line rather than via makefile?
Found this reference:
Taken directly from http://www.cs.indiana.edu/classes/c304/ObjCompile.html
Compiling Objective-C
Objective-C code can be compiled using the GNU C compiler gcc. Objective-C interface files usually marked by the extension .h as in List.h. Implementation files are usually marked by the extension .m as in List.m. The implementation file should #import its corresponding interface file. Your main program should also #import the interface files of all of the classes it uses.
Usually, you will want to compile the files which implement your classes separately. For instance, to compile List.m, use the following command:
gcc -c -Wno-import List.m
The -c switch tells the compiler to produce an object file, List.o, which can then later be linked into your program. Do this for each of your implementation files, and your main program.
The -Wno-import switch tells the compiler not to give a warning if you have a #import statement in your code. For some reason, Richard Stallman (the GNU Project founder) doesn't like the #import construction.
When you are ready to compile your program, you can link all of the implementations of your classes using gcc again. For example, to compile the files List.o, and main.o you could use the following command:
gcc -o prog -Wno-import List.o main.o -lobjc
The -o prog tells gcc to create an executable program with the name prog (if you do not specify this, it will default to a.out.
Note that when linking Objective-C with gcc, you need to specify the Objective-C library by using the -lobjc switch. If gcc reports an error, contact your system administrator to make sure that the Objective-C library and header files (objc/Object.h) were installed when gcc was built.
Related
I'm trying to compile a program in Objective C on Ubuntu, I have installed GNUstep, set all the GNUSTEP_* environment variables, and installed clang, because I read that gcc can't compile Objective-C code with blocks (Objective-C 'anonymous' functions, just to be clear: ^ { }).
What I get when I run this command:
clang hello.m -o hello
Is:
hello.m:1:9: fatal error: 'Foundation/Foundation.h' file not found
#import <Foundation/Foundation.h>
^
1 error generated.
I tried this also:
clang -L '/usr/include/GNUstep/Foundation/Foundation.h' hello.m -o hello
Where /usr/include/... is the path to the Foundation.h file on my system; but I still get the same result.
How can I link those header files automatically and compile Objective-C?
Thanks!
You can use gnustep-config:
clang `gnustep-config --objc-flags` `gnustep-config --objc-libs` hello.m -o hello
I am new to LLVM. I built LLVM and Clang on windows by GnuStep yesterday.
LLVM+CLang:3.2
GCC:4.6.1(GnuStep)
OS:Win7 64
I can compile Objective-c source file to both bitcode and exe. The exe works, but when I tried to execute the bitcode, I got this error:
LLVM ERROR: Could not resolve external global address:
_OBJC_CLASS_NSConstantString
Questions:
How can I load dll or lib files in llvm?
How can I link lib files(ex: libobjc.dll.a) to bitcode? Is that possible?
hello.m
#import <Foundation/Foundation.h>
int main(int argc, char**argv)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSLog(#"Hello Objective-C\n");
[pool release];
return 0;
}
Makefile
CC=gcc
CCFLAGS=-fconstant-string-class=NSConstantString -ID:/GNUstep/GNUstep/System/Library/Headers
LDFLAGS=-LD:/GNUstep/GNUstep/System/Library/Libraries/ -lobjc -lgnustep-base
CLANG=clang
CLANG_FLAG=-c -fobjc-runtime=gcc -emit-llvm
LLC=llc
LLI=lli
LLI_FLAG=-load=D:\GNUstep\GNUstep\System\Tools\objc-4.dll -load=D:\GNUstep\GNUstep\System\Tools\gnustep-base-1_24.dll
#LLI_FLAG=-load=D:\GNUstep\GNUstep\System\Library\Libraries\libgnustep-base.dll.a -load=D:\GNUstep\GNUstep\System\Library\Libraries\libobjc.dll.a
all:hello.obj hello1.exe
hello.exe: hello.o
$(CC) -o hello.exe hello.o $(LDFLAGS)
hello.obj: hello.bc
$(LLC) -filetype=obj hello.bc
hello.bc:hello.m
$(CLANG) -o hello.bc hello.m $(CLANG_FLAG) $(CCFLAGS)
hello1.exe: hello.m
$(CLANG) hello.m -o hello1.exe $(CCFLAGS) $(LDFLAGS)
run:
#Err
$(LLI) $(LLI_FLAG) -force-interpreter=false hello.bc
#OK
hello.exe
#OK
hello1.exe
clean:
rm *.o
rm *.exe
rm *.bc
You likely need at least one hard, static reference to a symbol in each DLL. In your main(), try adding [NSConstantString class]; (add a declaration, if needed).
The windows dynamic linker is quite proactive about not loading DLLs without a hard symbol reference. This conflicts with Objective-C's dynamic lookup.
(This is a guess based on experience. Been a decade since I've done ObjC on Windows, but seemingly little has changed.)
I'm learning Objective-C language. Since I don't have a Mac, I'm compiling and running my code within Ubuntu 11.04 platform.
Until now, I was using gcc to compile. I've installed GNUStep and all was working. But then I started to try some Objective-C 2.0 features, like #property and #synthesize, that gcc does not allow.
So I tried to compile the code with Clang, but it seems that it is not correctly linking my code with the GNUStep libraries, not even with a simple Hello world program.
For example, if I compile the following code:
#import <Foundation/Foundation.h>
int main(void) {
NSLog(#"Hello world!");
return 0;
}
The output of the compiler is:
/tmp/cc-dHZIp1.o: In function `main':
test.m:(.text+0x1f): undefined reference to `NSLog'
/tmp/cc-dHZIp1.o: In function `.objc_load_function':
test.m:(.text+0x3c): undefined reference to `__objc_exec_class'
collect2: ld returned 1 exit status
clang: error: linker (via gcc) command failed with exit code 1 (use -v to see invocation)
The command I'm using to compile is
clang -I /usr/include/GNUstep/ test.m -o test
with the -I directive to include the GNUStep libraries (otherwise, Clang is not able to find Foundation.h).
I've googled my problem, and visited both GNUStep and Clang web pages, but I haven't found a solution to it. So any help will be appreciated.
Thanks!
The problem was that the library gnustep-base was not being used by the linker. So the solution to this was using the option -Xlinker, that sends arguments to the linker used by clang:
clang -I /usr/include/GNUstep/ -Xlinker -lgnustep-base test.m -o test
The statement "-X linker -lgnustep-base" made the magic. However, I had problems with this command related to the class that represents a string in Objective-C:
./test: Uncaught exception NSInvalidArgumentException, reason: GSFFIInvocation:
Class 'NXConstantString'(instance) does not respond to forwardInvocation: for
'hasSuffix:'
I could solve it adding the argument "-fconstant-string-class=NSConstantString":
clang -I /usr/include/GNUstep/ -fconstant-string-class=NSConstantString \
-Xlinker -lgnustep-base test.m -o test
In addition, I've tried with some Objective-C 2.0 pieces of code and it seems to work.
Thank you for the help!
You can try gcc compiler:
First of all install GNU Objective-C Runtime: sudo apt-get install gobjc
then compile: gcc -o hello hello.m -Wall -lobjc
You are not able to use ObjC 2.0 features because you're missing a ObjC-runtime supporting those. GCC's runtime is old and outdated, it doesn't support ObjC 2.0. Clang/LLVM doesn't have a acompanied runtime, you need to install the ObjC2-runtime from GNUstep (which can be found here: https://github.com/gnustep/libobjc2 ) and reinstall GNUstep using this runtime.
Here are some bash scripts for different Ubuntu versions, that do everything for you:
http://wiki.gnustep.org/index.php/GNUstep_under_Ubuntu_Linux
And please don't try to reinvent GNUstep make, instead, use it:
http://www.gnustep.org/resources/documentation/Developer/Make/Manual/gnustep-make_1.html
If you really don't think so, here is some excerpt from there:
1.2 Structure of a Makefile
Here is an example makefile (named GNUmakefile to emphasis the fact that it relies on special features of the GNU make program).
#
# An example GNUmakefile
#
# Include the common variables defined by the Makefile Package
include $(GNUSTEP_MAKEFILES)/common.make
# Build a simple Objective-C program
TOOL_NAME = simple
# The Objective-C files to compile
simple_OBJC_FILES = simple.m
-include GNUmakefile.preamble
# Include in the rules for making GNUstep command-line programs
include $(GNUSTEP_MAKEFILES)/tool.make
-include GNUmakefile.postamble
This is all that is necessary to define the project.
In your case replace all occurrences of simple with test and you're done
1.3 Running Make
Normally to compile a package which uses the Makefile Package it is purely a matter of typing make from the top-level directory of the package, and the package is compiled without any additional interaction.
Assuming you have your .h and .m ready on a Linux server, which command would you issue to GCC to have it compiled?
The relevant parts:
gcc -c -Wno-import List.m
gcc -o prog -Wno-import List.o main.o -lobjc
. . . make sure that the Objective-C library and header files (objc/Object.h) were installed when gcc was built.
Note that when linking Objective-C with gcc, you need to specify the Objective-C library by using the -lobjc switch.
See this link for more information.
Additional link with possible solution to the missing compiler issue:
Try installing either gobjc++ or gobjc
sudo apt-get install gobjc++
gcc -x objective-c file.m -o out
Google is your friend
I am exploring with compiling an application with GNUstep on Windows. This is my main.m file:
#import <???/???.h>
int main(int argc, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[NSApplication sharedApplication];
[pool release];
}
I realize this is an incomplete fragment to say the least and it obviously won't do anything. I have tried several different import statements including Cocoa/Cocoa.h, GNUstepGUI/GMAppKit.h, etc. But I always run into errors with compiling that I can't seem to find help with online.
This is my compile command, which I am running from the mingw shell:
gcc -o test main.m -I /GNUstep/System/Library/Headers/ \
-L /GNUstep/System/Library/Libraries/ -lobjc -lgnustep-base \
-fconstant-string-class=NSConstantString -enable-auto-import
These are the errors I get:
c:/WINDOWS/TEMP/ccHxKZG2.o:main.m(.data+0x390): undefined reference to
'___objc_class_name_NSApplication'
collect2:ld returned 1 exit status
Any ideas on what I need to #import, or what needs fixing in my compile command?
Thanks!
Thanks to Peter Hosey I was able to Google myself to the page with the answer:
http://psurobotics.org/wiki/index.php?title=Objective-C
Unlike OS X development, you need a "makefile":
Put this into a file called "GNUmakefile" in the same directory as your source:
include $(GNUSTEP_MAKEFILES)/common.make
APP_NAME = MyAppName
MyAppName_HEADERS =
MyAppName_OBJC_FILES = main.m
MyAppName_RESOURCE_FILES =
include $(GNUSTEP_MAKEFILES)/application.make
Then execute make
The page says to execute openapp ./MyAppName.app but the .exe file within the .app folder appears to run on its own.
That's a linker error. #import is a preprocessor directive; it won't solve an error in linking, and you wouldn't have gotten as far as linking if you'd had a preprocessor error, anyway.
You need to link against Foundation and AppKit (especially the latter, for NSApplication), or whatever GNUstep's equivalents are.
Under Linux, you can compile with gcc :
gcc ``gnustep-config --objc-flags --gui-libs`` -o main main.m -L /usr/include/GNUstep/ -lobjc -lgnustep-base -lgnustep-gui