Objective C Linker Error: Undefined Symbols - objective-c

What does it mean to have undefined symbols?
There are no errors in the code files themselves and I am NOT using any external libraries.
I DID add a typedef NS_ENUM prior to this linker error occurring.
Where do I add this -v to see invocation?
Here is the error message:
Undefined symbols for architecture x86_64:
"_OBJC_IVAR_$_UIViewController._parentViewController", referenced from:
-[PEPI_LessonController setParentViewController:] in PEPI_LessonController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

"Undefined Symbols"
Building source code files to an executable file consist of at least two steps:
Compile the source code files to intermediate binary files (often called xyz.o).
Link the intermediate binary files to the final executable file.
The error message "undefined symbols" is a linker message. It may appear even though the compilation process was successful without notice. The linker organizes final memory address relations and it replaces symbols that the compiler had to assume they would be valid later, if all parts of the code would be available. Without this, no modularization would be possible at all.
-v to see invocation
If you build your application in Xcode, then Xcode calls all the compile and link commands for you (CompileC, Ln, Clang ...). But remember that a typical IDE runs only the commands you could run by yourself in the shell. Theoretically, you could develop big applications only in a text editor and a shell. So I suggest take some time and try to copy paste some commands listed in the Xcode build report to a shell :-) You'll learn a lot about the backgrounds. Therefore, in my opinion, -v to see invocation is used while invoking the command in the shell - or in the build settings, if you wish permanently more information.
"External libraries"
Finally, try to clarify "external libraries". To look at the most simple example: even if you write a simple C program and you want to know something trivial like the length of a string, you'll include <glibc.h>. Now this is an external library. It's external to your program code. Are you sure you haven't included external libraries?
Solving linker problems
Linker errors are often confusing and somehow difficult, because details of the linked modules tend to be out of sight. You may find many hints if you enter the error message in a search engine. For example, have a look at here:
Undefined symbols for architecture armv7: "_SCNetworkReachabilityCreateWithAddress"
Even if all components are found for linking, all paths are known etc, they may have the wrong version or else.

It means it can't find the property parentViewController and method setParentViewController when linking your object files files. The most common cause for these types of errors is not linking a library or framework in your projects target. UIViewController is part of UIKit so I'd be surprised if it's not already linked. Is this an OSX project and your trying to use UIViewcontroller instead of NSViewController?

In my case I had forgotten to add the .m file to all the same targets as the .h and that's what caused this issue. In case it helps anyone thought I'd mention here... double check your target memberships!

Related

Calling Objective-C from Swift class causing linker errors

I'm trying to use RFDuino Objective-C library in Swift. It all sounds simple, I have called Objective-C from Swift classes before, no problem. This time however I hit the brick wall.
Created header file. Added header files to it. Swift can see the classes no problem. Project compiles fine.
The problem during build appears just after I try to call any of Objective classes
for example:
override func viewDidLoad() {
super.viewDidLoad()
let rfDuinoManager: RFduinoManager = RFduinoManager.sharedRFduinoManager()
}
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_RFduinoManager", referenced from:
__TMaCSo14RFduinoManager in ViewController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Im not sure what Im missing here.
Link to the project here.
https://www.dropbox.com/s/rza1ce01g4q5lp6/SmartHomeHub-stackoverflow.zip?dl=0
Thanks in advance for help. Honestly loosing hope now and considering rewrite whole library to Swift
The problem is how the rfduino folder was added to the project. So
Remove rfduino folder (selecting rfduino folder in the project navigator panel on left and hit delete button, but when it asks to move it to the trash or just remove references, choose "remove references".
Your bridging header has an absolute path reference, I'd suggest removing that altogether by selecting it in build settings and hitting delete button:
Re-add rfduino files back to the project, this time, under "added folders" option, choose "create groups" rather than "create folder references". If you want it to prompt to create proper bridging header for you, don't select folder, but select the individual files:
Also make sure that SmartHomeHub is checked below.
If you do that properly it will ask you to create bridging header automatically:
Go to this new bridging header and add your import lines again:
This is a linker error, not a compiler error. Are you sure the RFduino class (source or library) is included in your project (open the project membership panel on the right in Xcode and make sure the box is checked to include the library in your target).
If it is included, make sure it has x86_64 code compiled into it. It might be an iOS library and is just compiled for ARM. You can check by finding the binary and running lipo on it from the command line.
lipo -info [name of RFduinolibrary.a(dylib,whatever)]
it should show x86_64 as an architecture, ala:
Architectures in the file are: i386 x86_64
"The OPN [Debug] target overrides the OTHER_LDFLAGS build setting". This was the main issue. After adding $(inherited) in new line in other linker flags solved my issue.
For me, Removing all the files in 'derived dir', removing reference to the frameworks in my project and connect again and etc didn't work anymore. Only worked to me is to set 'Build Active Architecture Only' to 'YES'.

Xcode5: unit test linking errors

I seem to get this strange issue when testing an XCTestCase. I created a unit testing bundle, and set my main app as the "target"; now I can write tests against my Core Data NSManagedObjects just fine, but if I include anything else in my app that isn't an NSManagedObject, I get linking errors:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_iCloudListener", referenced from:
objc-class-ref in SLTestToDoWithRepeatInterval.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
This only happens with non-NSManagedObjects. And iCloudListener is definitely in the Compiled Sources for the main app target. The problem is that though I can go and add this particular iCloudListener class into the test target -> Build Phases -> Compile Sources list, and that will make this particular linking error go away, but it introduces new ones since it starts giving linking errors about all the header files from the iCLoudListener class; and if I start adding those, they require more and more files, to the point where I have to include pretty much all of my code into the test target "Compile Sources" section.
Is there something I'm doing wrong here? Is there a setting which might be causing Xcode to ignore the non-NSManagedObject classes?
It's because the project inserted the core data's xcdatamodeld file in compile sources. Select your project -> Build Phases -> Compile Sources and delete projectName.xcdatamodeld file.
And also check if you have imported .m file instead of .h file, it also gives the same linker error.
Check all the #import codes.
And check if you have added core data frame work in library and imported core data .h file. Check for creation of NSManagedObject and import it's file.
Just try it and reply me if still any error.

Linking error when trying to use self-written Framework in Library of an App

I've build a Framework for an Objective-C App. I've tested it on minimalistic Programs where it worked. I was trying to use it in a real App now. Unfortunately the linker can't find the definition of my classes. =(
When I try to run it, I get the following Error Message:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_ClassInMyFramework", referenced from:
objc-class-ref in libMyLib.a(MyLib.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The Dependency:
App -> libMyLib.a -> MyFramework.framework
The usual suggestion for this error message is to add the framework into the "Link Binary with Library" Build Phase... I can assure you that this has happened ;)
My first thought is that something might be wrong with the Build Settings which results in this linking error.
On second thought It may have to do with the Project-Setup. Is it possible to statically link a framework into an '.a' library file?
Update:
I've linked the Framework into the App and now it's working. But I don't consider this a clean solution. Help still appriciated. =)
The short answer is no, you can't link the framework statically into your .a file. See this discussion.
The reason is, the static library doesn't include the object code (the definition) of classes from the dynamic framework. The static library links to object code in the framework the same way the app links to the framework code: at run-time.
From Apple's Framework Programming Guide: "Dynamic shared libraries have characteristics that set them apart from static linked shared libraries. For static linked shared libraries, the symbols in the library are checked at link time to make sure they exist. If they don’t exist, link errors occur. With dynamic shared libraries, the binding of undefined symbols is delayed until the execution of the program."
It depends on what you want to be able to do with your code. You could add a static "target" for your framework project, so your framework project outputs both a framework and a static library. You could include this static library into apps.
But, one benefit of frameworks is that you can include nibs, images, headers, etc. So, linking your framework into your apps directly is not a bad way to go. Otherwise, you need to include these assets directly into your project. If you want this framework to be distributed with your app, you'll need to package it inside the app wrapper.
It looks like some people create a "static framework" for inclusion into an iOS project, but this looks a bit hacky to me.
As an interesting exercise, you can explore the symbols in your object code. Let's say you are using a ClassInMyFramework (from your framework) somewhere in your static library, like:
ClassInMyFramework *myFramework = [[ClassInMyFramework alloc] init];
The static library will then include the _OBJC_CLASS_$_ClassInMyFramework symbol. You can see the list of symbols in your static library file at the command line:
$ nm /path/to/libMyLib.a
This will output a list of symbols, which will show that _OBJC_CLASS_$_ClassInMyFramework is undefined (note, the "U" designates that the class is undefined):
U _OBJC_CLASS_$_ClassInMyFramework
Whereas, if you were do to the nm command on your framework:
$ nm /path/to/MyFramework.framework/Versions/A/MyFramework
Your output would show that the symbol is defined in your framework (though the definition will still only linked at run-time), which would look something like this, showing an address of the definition:
0000000000001100 S _OBJC_CLASS_$_ClassInMyFramework

TouchJSON Fails on Compile (link error)

Undefined symbols for architecture x86_64:
"_objc_unretainedPointer", referenced from:
-[CJSONScanner scanJSONStringConstant:error:] in CJSONScanner.o
-[CJSONSerializer serializeNumber:error:] in CJSONSerializer.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Hey all. Trying to use TouchJSON to do some JSON-y stuff. I followed the read me for the library to the meter I think, but every time I try to compile I get this error. I don't know much about Xcode (I've only been learning Obj-C recently) so I'm clueless about this. Any ideas?
Try to remove "Experimental" folder (and files inside, of course).
README
Be aware that the code in the Experimental subdirectory of Source is
just that and may not have been extensively tested and/or have extra
dependencies
So it could be a problem about extra dependencies (but always make sure if your project already have linked all dependency libraries/framework)

RKJSONParserJSONKit not found

I'm trying to use JSON parsing from RestKit, but I'm receiving
the following compile time error:
Undefined symbols for architecture armv7:
"_OBJC_CLASS_$_RKJSONParserJSONKit", referenced from:
objc-class-ref in FloorMapLoaderViewController.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see
invocation)
RestKit works ok, this being the only error I've seen so far.
This is my import line:
#import <RestKit/Support/JSON/JSONKit/RKJSONParserJSONKit.h>
edit:
oddly, it fails to compile only if I try to create a parser like so:
RKJSONParserJSONKit *parser = [RKJSONParserJSONKit new];
Commenting out this line allows for compilation, but I do need to instance a parser.
How can I fix this error?
Thank you.
Importing means that your source code can see the API, so the IDE knows how to auto-complete and so that the compiler knows how to generate the right object code.
You have a linker error. Once your own code is compiled, it has to all be bundled together with all the code it is dependent on (not counting dynamically linked system libraries). Your linker is telling you that after bundled everything it can find together, not all of it is there.
What you need to do is go to the target you are building, select the Build Phases tab, and add the necessary library to the "Link Binary With Libraries" section.