Undefined symbols for architecture x86_64 in hello world - objective-c

Today I'm learning Objective-C without Xcode following this Guide
Here's the hello world:
makclass.m
#import "makclass.h"
#import <stdio.h>
#implementation MakClass
-(void) age {
printf("Age is %d", age);
}
-(void) setAge: (int) a {
age = a;
}
+(void) say {
printf("Haha");
}
#end
makclass.h
#import <Foundation/NSObject.h>
#interface MakClass: NSObject {
int age;
}
-(void) age;
-(void) setAge: (int) a;
+(void) say;
#end
helloworld.m
#import <stdio.h>
#import "makclass.h"
int main(void) {
printf("Hello World");
MakClass *makclass = [[MakClass alloc] init];
[makclass setAge: 1];
[makclass age];
[MakClass say];
[makclass release];
return 0;
}
And clang helloworld.m give me the following errors:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_MakClass", referenced from:
objc-class-ref in helloworld-XEijke.o
"_objc_msgSend", referenced from:
_main in helloworld-XEijke.o
"_objc_msgSend_fixup", referenced from:
l_objc_msgSend_fixup_alloc in helloworld-XEijke.o
l_objc_msgSend_fixup_release in helloworld-XEijke.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

You need to make sure you pass in the framework and all the files as well:
clang -framework Foundation -o helloworld helloworld.m makclass.m

Welcome to Objective-C!
When you compile, you need to specify all of the implementation files that helloworld.m requires. Just because the header files are included does not mean that the implementation files will be included as well.
Additionally, since this is Objective-C, make sure you also include the -lObjC flag to include the Objective-C libraries.
So, the command that you should run will look like clang -lObjC helloworld.m makclass.m.
clang will then spit out a program called a.out, which you can run. If you want to change the name from a.out to, say, helloworld, you can specify that with the -o flag. For example:
clang -lObjc -o helloworld helloworld.m makclass.m
Hope this helps!

Related

Referencing macOS SDK header is not resolving when compiling with clang

I'm trying to link my Rust library with a macOS SDK. When trying to include a header from a macOS SDK in an .m file and compiling, the linker returns an error.
Code example:
#import <Foundation/Foundation.h>
#import <IOKit/KextManager.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSLog(#"Something");
}
return 0;
}
Error:
main.m:11:9: fatal error: 'IOKit/KextManager.h' file not found
#import <IOKit/KextManager.h>
^~~~~~~~~~~~~~~~~~~~~ 1 error generated.
When I reference the full path, the header gets included but I get other linker errors for some classes not found:
Code example:
#import <Foundation/Foundation.h>
#import "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/IOKit.framework/Headers/kext/KextManager.h"
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSLog(#"Something");
}
return 0;
}
Error I'm getting:
Undefined symbols for architecture x86_64: "_NSLog", referenced
from:
_main in main-891267.o "___CFConstantStringClassReference", referenced from:
CFString in main-891267.o "_objc_autoreleasePoolPop", referenced from:
_main in main-891267.o "_objc_autoreleasePoolPush", referenced from:
_main in main-891267.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to
see invocation)
I suspect this is because other headers are not resolved properly.
How to make headers resolving to work properly so all includes work not only from Xcode?
This code compiles and runs directly from Xcode without any additional references but is not compiling from terminal:
#import <Foundation/Foundation.h>
#import "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/IOKit.framework/Headers/kext/KextManager.h"
//#import <IOKit/KextManager.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
CFDictionaryRef result = KextManagerCopyLoadedKextInfo(NULL, NULL);
NSLog(#"%#", result);
}
return 0;
}
Getting same linker error:
ld: warning: URGENT: building for OSX, but linking against dylib
(/usr/lib/libSystem.dylib) built for (unknown). Note: This will be an
error in the future. Undefined symbols for architecture x86_64:
"_KextManagerCopyLoadedKextInfo", referenced from:
_main in main-abff3c.o "_NSLog", referenced from:
_main in main-abff3c.o "___CFConstantStringClassReference", referenced from:
CFString in main-abff3c.o "_objc_autoreleasePoolPop", referenced from:
_main in main-abff3c.o "_objc_autoreleasePoolPush", referenced from:
_main in main-abff3c.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to
see invocation)
Update 2:
Compiler command:
clang -framework IOKit -framework Foundation main.m -o main
Works with full path to header, but does not for #include <IOKit/KextManager.h>
The solution is to link Xcode included frameworks into include folder.
For stable release:
ln -s /Applications/Xcode.app/Contents/Frameworks/ /usr/local/include/
And for Xcode beta:
ln -s /Applications/Xcode-beta.app/Contents/Frameworks/
/usr/local/include/
Then KextManager imported like this:
#import <IOKit/kext/KextManager.h>

Why clang doesn't find .h file in #include "" in the same directory?

This is my first question on this site, so please be patient with me. I tried searching for an answer but couldn't find any relevant.
I have main.m, Person.h and Person.h files in a current directory. In main.m I include Person.h. Then I try to compile main.m, but it gives an error that Person object was not found.
Here is main.m:
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[])
{
#autoreleasepool {
// Create an instance of Person
Person *person = [[Person alloc] init];
[person setWeightInKilos:96];
[person setHeightInMeters:1.8];
float bmi = [person bodyMassIndex];
NSLog(#"person has a BMI of %f", bmi);
}
return 0;
}
Person.h:
#import <Foundation/Foundation.h>
#interface Person : NSObject
{
// 2 instance variables
float heightInMeters;
int weightInKilos;
}
// instance methods
- (void)setHeightInMeters:(float)h;
- (void)setWeightInKilos:(float)w;
- (float)bodyMassIndex;
#end
Person.m:
#import <Foundation/Foundation.h>
#implementation Person
- (void)setHeightInMeters:(float)h
{
heightInMeters = h;
}
- (void)setWeightInKilos:(float)w
{
weightInKilos = w;
}
- (float)bodyMassIndex
{
return weightInKilos / (heightInMeters * heightInMeters);
}
#end
Here is the error I get as I try to compile using 'cc main.m -framework Foundation':
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_Person", referenced from:
objc-class-ref in main-24c686.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I even tried adding the current directory in PATH, but it didn't help.
Thanks in advance for help.
That error is not about the include file "Person.h". The problem is that the Person
class it not found by the linker.
The reason is that you did not add the "Person.m" file to your command line:
cc main.m Person.m -framework Foundation

Objective-c subclassing gives linking error

I'm trying to port a game to iOS but I'm having a problem. I have a class called CKSprite with the following method:
- (id)initWithFile:(NSString *)fileName effect:(GLKBaseEffect *)effect
{
if ((self = [super init]))
{
//some stuff
}
return self;
}
I then have a subclass called CKPLayer (it has no other methods or properties at the moment other than what it inherits:
#property (strong) CKPlayer *player1;
But when I try to initialise it using the parent method:
self.player1 = [[CKPlayer alloc] initWithFile:#"Images/parrot.png" effect:self.effect];
I get this error:
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_CKPlayer", referenced from:
objc-class-ref in CKViewController.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
This is my first time trying to do anything like this so I've probably done something stupid.
Any help will be greatly appreciated.
#import "CKSprite.h"
#interface CKPlayer : CKSprite
#end
The linker is missing the implementation for the class CKPlayer. Maybe you just forgot to implement it since it has "no other methods or properties at the moment", in that case just add a file which should look like:
#import "CKPlayer.h"
#implementation CKPlayer
#end
and ld should be happy

GCDAsyncUdpSocket does not compile for iOS

I use this library: https://github.com/robbiehanson/CocoaAsyncSocket
There are examples for TCP on the iphone but not UDP. I think that everything should be just the same. Here is my code:
#import <UIKit/UIKit.h>
#class GCDAsyncUdpSocket;
#interface ThirdViewController : UIViewController
{
GCDAsyncUdpSocket *udpSocket;
}
.m:
#import "ThirdViewController.h"
#import "DDLog.h"
#import "DDTTYLogger.h"
#import "GCDAsyncUdpSocket.h"
static const int ddLogLevel = LOG_LEVEL_VERBOSE;
#implementation ThirdViewController
- (void)viewDidLoad
{
[DDLog addLogger:[DDTTYLogger sharedInstance]];
udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
}
But when compiling I get the errors:
Undefined symbols for architecture i386: "_OBJC_CLASS_$_DDLog",
referenced from:
objc-class-ref in ThirdViewController.o "_OBJC_CLASS_$_DDTTYLogger",
referenced from:
objc-class-ref in ThirdViewController.o "_OBJC_CLASS_$_GCDAsyncUdpSocket",
referenced from:
objc-class-ref in ThirdViewController.o ld: symbol(s) not found for architecture i386
What is wrong? Examples from the library compiled without errors.
You have to link CFNetwork.framework or if have it you're propably working on Automatic Reference Counter, turon off ARC for GCDAsyncUdpSocket using -fno-objc-arc
(Build Phases >> Link Binary With Libraries) Add CocoaLumberjack as optional dependency.

objective c gnustep - cannot separate interface and implementation files

I am using gnustep for objective-c on windows. If i keep interface and implementation files of a class together with main file, it compiles without error and gives expected output.
Following is the example:
// File "classA.h"
#import <Foundation/Foundation.h>
#interface classA: NSObject
{
int a;
}
-(void) print;
#end
// File "classA.m"
#import "classA.h"
#implementation classA
-(void) print
{
a = 10;
NSLog(#"a = %i", a);
}
#end
// File "test.m"
#import "classA.h"
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSLog(#"start");
classA *objA = [[classA alloc] init];
[objA print];
[objA release];
NSLog(#"done");
[pool drain];
return 0;
}
However, if i put the interface and implementation files separately, on compiling using following command
gcc `gnustep-config --objc-flags` -o program program.m -L /GNUstep/System/Library/Libraries -lobjc -lgnustep-base
i get following error
undefined reference to `__objc_class_name_myNewClass'
collect2: ld returned 1 exit status
How do i keep the files separate and still compile the program successfully
Thanks for help
Regards
You have a linker error here. Most likely, you are not including a required header file for myNewClass.
I know this is old, but double check the name of compiled files just in case the error is in a different file.
Reasons:
The class myNewClass is not referenced in the code above and there are no other imports other than Foundation.
The name of the file in the code comments and the file you appear to be compiling differ.
// File "test.m"
gcc `gnustep-config --objc-flags` -o program program.m
By the look of it, the given code should compile when split out.
Also, about the question "Also how do i included "Compiled files"?", assuming you mean a .o file, you just need to include the header file (.h) and make sure the compiler can find the matching .o file. Related: How do I link object files in C? Fails with "Undefined symbols for architecture x86_64"