I'm trying to build hello world on Objective-C on Linux (Ubuntu).
main.c
#import <Foundation/Foundation.h>
int main(void)
{
NSLog(#"asdasd");
return 0;
}
I don't think there is the error here. Then i'd created Makefile:
GNUSTEP_MAKEFILES = /usr/share/GNUstep/Makefiles
include $(GNUSTEP_MAKEFILES)/common.make
TOOL_NAME = main
main_OBJC_FILES = main.m
include $(GNUSTEP_MAKEFILES)/tool.make
And then i run "make":
This is gnustep-make 2.2.0. Type 'make print-gnustep-make-help' for help.
Making all for tool main...
make[1]: GNUmakefile: no such file or directory
How can i fix it ?
Installing the GNUstep libraries and tools on an Ubuntu system is simple, just sudo apt-get install gnustep gnustep-devel and you're all set (seriously, Apt is, as far as I know, the easiest way to install software - as long as it's in the repositories).
Turns out I had named it GNUMakefile, while I should have named it GNUmakefile.
source.m:
#import <Foundation/Foundation.h>
int main(void)
{
NSLog(#"asdasd");
return 0;
}
GNUmakefile:
GNUSTEP_MAKEFILES = /usr/share/GNUstep/Makefiles
include $(GNUSTEP_MAKEFILES)/common.make
TOOL_NAME = app
app_OBJC_FILES = source.m
include $(GNUSTEP_MAKEFILES)/tool.make
And I can run it.
us#com:~/ObjectiveC$ make
This is gnustep-make 2.6.0. Type 'make print-gnustep-make-help' for help.
Making all for tool app...
Compiling file source.m ...
Linking tool app ...
us#com:~/ObjectiveC$ ./obj/app
2011-11-22 18:01:21.285 app[8042] asdasd
Related
I am puzzled how a mere g++ -o testpoco testpoco.cpp -lPocoFoundation was able to compile successfully in my Cygwin environment. The complete C++ code is below:
#include <Poco/File.h>
int main (int argc, char *argv[])
{
Poco::File f("/tmp/test.log");
if (f.exists()) {
return 1;
}
return 0;
}
I installed the cygwin Poco development headers and libraries and I verified they are in:
/usr/include/Poco/ (the header files)
/usr/lib/ (the libraries)
But without specifying those include and library path in g++ how did it was able to compile and produce the exe? I checked the output of g++ -v and did not see any routes to Poco.
The compiler has default search paths for include files and for libraries. (Actually the latter applies to the linker, not the compiler, but the g++ command invokes both.)
/usr/include and /usr/lib are in those default search paths.
You specified #include <Poco/File.h>, so the compiler found /usr/include/Poco/File.h.
You specified -lPocoFoundation, so the linker found /usr/lib/libPocoFoundation.dll.a, the file that contains the code implementing the PocoFoundation library under Cygwin.
I checked the output of g++ -v and did not see any routes to Poco
The command g++ -v will just print out some version information about GCC, and how it was configured. Adding the -v option to your real commands used for compiling and/or linking will show the search paths for headers and libraries.
In other words, instead of just g++ -v you should try:
g++ -o testpoco testpoco.cpp -lPocoFoundation -v
This will show the search paths that Keith Thompson refers to in his answer.
I am trying to compile a simple hello world program written in objective c from ubuntu but I am getting an error as
gcc: error: unrecognized command line option ‘-fobjc-nonfragile-abi’
To compile I am using the command
gcc gnustep-config --objc-flags -lgnustep-base hello.m -o hello
Can you please help me out with this. I am not getting any solution in google too.
The best way to compile gnustep code is with makefiles. It avoids all this faff with GCC:
make a file called GNUmakefile
Make the content:
include $(GNUSTEP_MAKEFILES)/common.make
TOOL_NAME=hello
hello_OBJC_FILES=hello.m
include $(GNUSTEP_MAKEFILES)/tool.make
just type:
make
to compile, the output is in the obj/ dir
I would give this a read
http://www.gnustep.it/nicola/Tutorials/WritingMakefiles/
Now a problem I always have is it can't find the gnustep makefiles.
The long term fix is to add it to path, the quick fix is every session, type:
export GNUSTEP_MAKEFILES=/usr/share/GNUstep/Makefiles
/usr/share/GNUstep/Makefiles is my gnustep makefile dir, YOURS MAY BE DIFFERENT! but I assume that this is the dir if you installed gnustep like this:
apt-get install gnustep gnustep-devel
it may be worth making sure you have the gnustep-devel package!
Good luck!
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.
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
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.