CodenameOne "Undefined symbols" error when adding native library - native

I am trying to add the Honeywell Captuvo iOS library to my CodenameOne project as a native library. I have been through the "Generate Native Access" process and placed the .a library in the native/ios directory. However when I send the app to be built it comes back with the error:
Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_EAAccessoryManager", referenced from:
objc-class-ref in libCaptuvoSDK.a(CaptuvoReal.o)
Many thanks

Rereading the error message it seems I missed a key detail. You need to add the ExternalAccessory.framework to your project. To do this you need to define the build hint: ios.add_libs=ExternalAccessory.framework
Original answer below:
Is the name of the .a library preceded with the lower case word lib and does it actually end with a .a. If not make sure to rename it so it abides by these constraints.
Assuming both are OK you will need to verify the library actually has the required architecture in this case arm64.
This is explained in this question: How to check if a static library is built for 64-bit?
I would just use the second suggestion: file libFileName.a
It should include arm64 among the list of supported architectures.

Related

Do not use -ObjC flag for linked library in XCode

I need to link two libraries in a project, Cordova and a library from a hardware manufacturer. The hardware manufacturer's library gives an error if you compile with -ObjC but Cordova requires -ObjC flag.
Is there a way to force the -ObjC flag for a library and not for the other (or vice-versa)?
Thanks!
Specific error: Undefined symbols for architecture armv7:
"_OBJC_CLASS_$_MPMusicPlayerController", referenced from:
objc-class-ref in libdtdev.a(AudioStream.o)
It looks like a posted the question just before I figured it out (like always). Instead of deleting the post, someone might want to know what the solution was...
If I keep the -ObjC flag in place and add the frameworks it's complaining about to the "Link Binary With Libraries" section (in my case "MediaPlayer.framework").

How to solve "Undefined symbols for architecture x86_64:"?

I've done hours and hours of searching and still no luck (read a lot of stackoverflow as well).
I am trying to implement FDTake via Cocoapods. When I try and run it I get the following:
undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_FDTakeController", referenced from:
objc-class-ref in VendeViewController.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 know there is many similar questions around SO but all their solutions don't seem to work for me.
From the logs I can assume that you would be using a static library which is not build for simulator(architecture x86_64).
The library is only compiled for device and it needs to be complied and build for simulator also. Then the two static files (one abc.a for device and one abc.a for simulator) needs to be fat file i.e these files should be merged together using lipo command on terminal to create a fat file. Now when you use this fat file it will work both for simulator as well as device.
But the important thing is that you should have the source to compile and build the static libraries for simulator and device. After which you merge these to create a fat file which will work on all the defined architectures.
In case you are using third party static library (SDK) then you need to contact the respected party.

ShareKit PKMultipartInputStream linker error

Recently I've updated ShareKit in my app via the git submodule method.
However, now it won't build anymore. I've gone through the installation Wiki again, seeing if I've missed any frameworks to include or something, but I can't find any I've missed.
Besides this, I've also changed the setting "Build active architecture only" to no, so it will always build all architectures. But to no avai.l
The error I'm getting is the following:
Undefined symbols for architecture armv7:
"_OBJC_CLASS_$_PKMultipartInputStream", referenced from:
objc-class-ref in libOAuth.a(NSMutableURLRequest+Parameters.o)
ld: symbol(s) not found for architecture armv7
Strange thing is, I also included ShareKit in another project and there it didn't give any errors. So I know I must be doing something wrong, but I can't figure out what. Do you guys have any hints of where to look? Or has one of you encountered the same error?
This can be solved by adding PKMultipartInputStream.m to the Compiled Sources in OAuth build settings inside ShareKit subproject
You probably have to add PKMultipartInputStream target to Target Dependencies and libPKMultipartInputStream to Link Binary With Libraries in your project.
It is better than making changes to external project.

Objective C Linker Error: Undefined Symbols

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!

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