Xcode compilation errors with external library (OSX program) - objective-c

I have a simple "Hello world" type program in Xcode and I'm trying to use an external library in that, but I'm getting compilation errors. The library is the Magtek edynamo macOS sdk:
https://www.magtek.com/Content/SoftwarePackages/1000004036.zip
(parent page is https://www.magtek.com/support/edynamo?tab=software; download is the macOS SCRA SDK)
This is my code:
#import "MTSCRA.h"
int main (int argc, const char * argv[])
{
MTSCRA* mtSCRALib = [[MTSCRA alloc] init];
return 0;
}
So basically I'm just importing the library and trying to instantiate one of its classes. Xcode doesn't show any inline compile errors anywhere, but when I try to build and run, it results in a variety of undefined symbol errors such as this:
Undefined symbols for architecture x86_64:
"_NSApplicationWillTerminateNotification", referenced from:
-[HIDManager init] in libMTSCRAOSX.a(HIDManager.o)
and warnings such as this:
ld: warning: object file (/path/HelloWorld/libMTSCRAOSX.a(MTSCRA.o)) was built for newer OSX version (10.12) than being linked (10.11)
(If I comment out the MTSCRA* mtSCRALib = [[MTSCRA alloc] init]; line, it runs fine.)
These are the steps I took to include the library in my Xcode project:
I dropped the MTSCRA.h and libMTSCRAOSX.a into my project directory.
From Build phases -> Link binary, I added libMTSCRAOSX.a.
Build Settings -> Library search paths is set to "$(inherited)" and "$(PROJECT_DIR)/HelloWorld"
This is my environment:
Macbook Pro 64-bit
OSX El Capitan 10.11.5
Xcode V8.2.1
Tried all the google solutions; nothing worked. Any help...can anyone else successfully import and use this library?

Solved this. Not sure if these are rookie mistakes, but I had two issues:
1) I also needed to include the library /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.‌​platform/Developer/S‌​DKs/MacOSX.sdk/usr/l‌​ib/libstdc++.6.0.9.t‌​bd
2) I also had to import #import <Cocoa/Cocoa.h>. So:
#import "MTSCRA.h"
#import <Cocoa/Cocoa.h>
int main (int argc, const char * argv[])
{
MTSCRA* mtSCRALib = [[MTSCRA alloc] init];
return 0;
}

Related

Sublime Text: Is it possible to build a simple - headless - objective-c app?

So, think the classic beginner C programming right of passage: hello world. But written in Objective-C.
For reasons I prefer not to get into, I don't want to use XCode but rather my new love, Sublime Text.
Can it be done?
Paste the following into Sublime and save the file as main.m
#import <Foundation/Foundation.h>
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSLog(#"Hello, World!");
[pool drain];
return 0;
}
Then in the terminal navigate to the file with cd and type:
gcc -framework Foundation main.m -o NAME_OF_YOUR_APP
And run the app by typing:
./NAME_OF_YOUR_APP
I did a bit of digging and found this which lets me build and run entirely within Sublime Text which is what I need. Still testing: https://gist.github.com/chendo/4398077

Object created inside scope deallocated even when used outside of scope

Update: This was fixed in iOS 6.1 DP3 SDK.
I've tracked down a use-after-deallocated crash when building with ARC using the default release build configuration (debug seems to work fine). The problem occurs when creating an object inside an if-scope with a non-constant condition, assigning it to a variable from outside the scope and then only referencing the variable using Objective-C array or dictionary literals.
Here is the smallest reproducible case I've managed to find:
void test(BOOL arg)
{
id obj = nil;
if (arg) {
obj = [NSObject new];
}
// obj already deallocated here
#[obj];
// but using NSArray works
//[NSArray arrayWithObject:obj];
// #[obj] works if obj is referenced i.e. by NSLog print out
//NSLog(#"%#", obj);
}
int main(int argc, const char * argv[])
{
#autoreleasepool {
test(YES);
}
return 0;
}
When I build and run this with zombie objects enabled I get this error message:
-[NSObject retain]: message sent to deallocated instance 0x100109100
As I commented in the code it works fine if obj is referenced in some other way, like with NSLog or using NSArray instead. Have I misunderstood how objects are released with ARC and scopes or is this a optimization bug in LLVM or Clang?
I'm using Xcode 4.5.2 with clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn). I can reproduce it when building for x86 64 bit for iOS simulator and Mac OS X and I'm quite sure the same problem occurs when building for ARM as the issue was first found when running release build on an iPhone.
I have filed and bug report to Apple and created an open radar report.
What, if anything, am I missing?
Update, did some more experiments:
As Gabro pointed out the compiler translates #[] to a [NSArray arrayWithObjects:count:] statement so I did some tests:
// works
id a[] = {obj};
[NSArray arrayWithObjects:a count:1];
// does not work
const id *b = (id[]){obj};
[NSArray arrayWithObjects:b count:1];
// does not work
[NSArray arrayWithObjects:(id[]){obj} count:1];
So my guess is that this happens when combining ARC and anonymous C arrays.
You're not missing anything. It's a compiler bug.
I just tested the following code both building for OSX (x86 64) and iOS Simulator and I cannot reproduce the bug
void test(BOOL arg) {
id obj = nil;
if (arg) {
obj = [NSObject new];
}
#[obj];
NSLog(#"Hi there");
}
int main(int argc, const char * argv[]) {
#autoreleasepool {
test(YES);
}
return 0;
}
The above code simply prints Hi there in the console and returns.
My configuration is the same of yours: XCode 4.5.2 and Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn) as a compiler.
EDIT
I also tried to compile from command line (after adding #include <Foundation/Foundation.h>
at the beginning of the above example) using
clang -fobjc-arc -framework Foundation main.m
And the result was again
2012-12-03 12:47:45.647 a.out[39421:707] Hi there
EDIT 2
As pointed out in the comments it is possible to reproduce the bug increasing the optimization level over -O0. Summarizing:
clang -O0 -fobjc-arc -framework Foundation main.m
the program works as expected
clang -O1 -fobjc-arc -framework Foundation main.m
the bug presented in the question shows up. This is true with any optimization level over -O0
It's definitely a bug in the compiler.

Weird Error With Apple Script Bridge - iTunes

I'm trying to create an ObjC application that will control iTunes. I need a method that will return an array of all the playlists in iTunes.
I'm getting the most bizarre, unhelpful error message ever... First the code:
#import "MusicControl.h"
#import "iTunes.h"
#implementation MusicControl
- (SBElementArray *) playlists {
// Create iTunes Object
iTunesApplication *iTunes = [SBApplication applicationWithBundleIdentifier:#"com.apple.iTunes"];
NSArray *sources = [iTunes sources];
iTunesSource *librarySource = nil;
for (iTunesSource *source in sources) {
if ([source kind] == iTunesESrcLibrary) {
librarySource = source;
break;
}
}
return [librarySource userPlaylists];
}
#end
I have no idea whether the array return is working or not because, after doing some debugging, I found that where this is bombing out is the very first line where I create the iTunes object, which was copied and pasted from Apple's website...
The error I'm getting is:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_SBApplication", referenced from:
objc-class-ref in MusicControl.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Any suggestion as the what the heck is going on?
This message (and similar ones) means that the linker is looking for some specific symbol, but can't find it. In your case it is SBApplication.
If you have not already done so, you should make sure that you have linked to the ScriptingBridge framework.
To add a framework, click on the project's icon at the top of the left hand bar in Xcode, then select Build Phases. If Link With Binary Libraries is not already expanded, do that and add the framework.
The same procedure can be used for plain libraries (a framework is really just a wrapper around a library, at least for the purpose of this discussion).

Link error while accessing NSSpeechSynthesizer

I'm trying to compile a trivial command-line tool with XCode:
#import <Cocoa/Cocoa.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//NSSpeechSynthesizer *speeker = [[NSSpeechSynthesizer alloc] initWithVoice: nil];
NSLog(#"%#", [NSSpeechSynthesizer availableVoices]);
NSLog(#"Hello, World!");
[pool drain];
return 0;
}
and even thought I'm importing Cocoa.h, I'm getting a link error:
Undefined symbols:
"_OBJC_CLASS_$_NSSpeechSynthesizer",
referenced from:
objc-class-ref-to-NSSpeechSynthesizer
in byc.o ld: symbol(s) not found
collect2: ld returned 1 exit status
Anybody knows what's going on???
You imported the header, so compilation worked, but linking failed because you didn't link against a framework that provides NSSpeechSynthesizer. You need to link against either the Application Kit framework (in addition to Foundation) or the Cocoa umbrella framework (instead of Foundation).
Whichever framework you choose, add it to your Linked Frameworks group in your project's group tree (by right-clicking on the group and choosing “Add Existing Framework”), and make sure you also add it to your target.

Symbol not found: _OBJC_CLASS_$_Article

I am working on an extension to Vienna to add the ability for third parties to write Objective-C plugins, but I am getting some runtime linker issues only when running in 64-bit mode (everything appears to work fine in 32-bit mode). My plugin, SynkPlugin, is loaded by the following code in Vienna.app:
NSArray * bundlePaths = [NSBundle pathsForResourcesOfType:#"bundle" inDirectory:[[Preferences standardPreferences] pluginsFolder]];
NSEnumerator * enumerator = [bundlePaths objectEnumerator];
NSString * bundlePath;
NSMutableArray * plugins = [NSMutableArray array];
while ( (bundlePath = [enumerator nextObject]) != nil )
{
NSBundle * pluginBundle = [NSBundle bundleWithPath:bundlePath];
Class principalClass = [pluginBundle principalClass];
id <ViennaPlugin, NSObject> plugin = [[principalClass alloc] init];
[plugins addObject:plugin];
[plugin release];
NSLog(#"Loaded plugin %# [main class: %#]", bundlePath, principalClass);
}
And in the console output, I get the following error message:
2010-07-09 08:55:40.128 Vienna[74065:a0f] Error loading /Users/dcrosta/Library/Application Support/Vienna/PlugIns/SynkPlugin.bundle/Contents/MacOS/SynkPlugin: dlopen(/Users/dcrosta/Library/Application Support/Vienna/PlugIns/SynkPlugin.bundle/Contents/MacOS/SynkPlugin, 265): Symbol not found: _OBJC_CLASS_$_Article
Referenced from: /Users/dcrosta/Library/Application Support/Vienna/PlugIns/SynkPlugin.bundle/Contents/MacOS/SynkPlugin
Expected in: flat namespace
in /Users/dcrosta/Library/Application Support/Vienna/PlugIns/SynkPlugin.bundle/Contents/MacOS/SynkPlugin
This error only happens when running in 64-bit mode, not 32-bit mode. Both Vienna and SynkPlugin are compiled with the "standard 32/64 universal" settings, and SynkPlugin has the additional linker flag "-undefined dynamic_lookup", which, it is my understanding, allows it to link to classes found in Vienna.app without having to compile code for those classes into its own binary.
The other references to this error on Stack Overflow have to do with UIKit differences between iPhone/iPod Touch and iPad -- in those cases, the frameworks are actually missing the classes on iPhone/iPod Touch. In my case, I'm certain that Vienna.app has the Article class within it somewhere, since it is built from identical code to the 32-bit version.
Has anyone seen an error like this before? Have any suggestions on where to look for more information? Thanks.
In the build settings of the Vienna target, under GCC 4.2 - Code Generation uncheck Symbols Hidden by Default (GCC_SYMBOLS_PRIVATE_EXTERN).