readline in objective-c program throwing Mach-O Linker (Id) Error - objective-c

When I try to run the following code, xcode throws the following error. What is causing this?
#import <Foundation/Foundation.h>
#include <readline/readline.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSLog(#"What number would you like to count down by three from?");
const char *countFrom = readline(NULL);
NSString *result = [NSString stringWithUTF8String:countFrom];
NSLog(#"Counting down from %#", result);
}
return 0;
}
Undefined symbols for architecture x86_64:
"_readline", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Figured it out. Had to go into the Link Binary With Libraries section in the Build Phases section of project settings and include libreadline.dylib.

Related

extern function with macro

Im having a linker problem in Objective C when i attempt to do a marco with a extern function. Any idea why?
Header file
To assist in doing comparison with the device version
extern NSString* getOperatingSystemVerisonCode();
#if TARGET_OS_IPHONE // iOS
#define DEVICE_SYSTEM_VERSION [[UIDevice currentDevice] systemVersion]
#else // Mac
#define DEVICE_SYSTEM_VERSION getOperatingSystemVerisonCode()
#endif
#define COMPARE_DEVICE_SYSTEM_VERSION(v) [DEVICE_SYSTEM_VERSION compare:v options:NSNumericSearch]
#define SYSTEM_VERSION_EQUAL_TO(v) (COMPARE_DEVICE_SYSTEM_VERSION(v) == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) (COMPARE_DEVICE_SYSTEM_VERSION(v) == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) (COMPARE_DEVICE_SYSTEM_VERSION(v) != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) (COMPARE_DEVICE_SYSTEM_VERSION(v) == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) (COMPARE_DEVICE_SYSTEM_VERSION(v) != NSOrderedDescending)
.mm file
NSString* getOperatingSystemVerisonCode()
{
/*
[[NSProcessInfo processInfo] operatingSystemVersionString]
*/
NSDictionary *systemVersionDictionary =
[NSDictionary dictionaryWithContentsOfFile:
#"/System/Library/CoreServices/SystemVersion.plist"];
NSString *systemVersion =
[systemVersionDictionary objectForKey:#"ProductVersion"];
return systemVersion;
}
Linker Error:
Undefined symbols for architecture x86_64:
"_getOperatingSystemVerisonCode", referenced from:
-[Manager isFeatureAvailable] in Manager.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 problem is not caused by the macro definition.
The getOperatingSystemVerisonCode() function is defined in a ".mm" file and therefore
compiled as Objective-C++. In particular, the function name is mangled as a C++ function.
But when referenced from (Objective-)C sources, the unmangled name is expected.
You have two options to solve the problem:
Rename the ".mm" file to ".m", so that it is compiled as an Objective-C file.
In the header file where the function is declared, add the extern "C" declaration to enforce C linkage even in an (Objective-)C++ file:
#ifdef __cplusplus
extern "C" {
#endif
NSString* getOperatingSystemVerisonCode();
#ifdef __cplusplus
}
#endif
For more information about mixing C and C++, see for example
Combining C++ and C - how does #ifdef __cplusplus work?

Apple Mach-0 linker error duplicate

I have written a straight forward program, but getting duplicate symbol linker error (error below) There is nothing additional in the .h file excepting for the #interface Fraction : NSObject #end
I am rather new to xcode.
//SAMPLE CODE
#import "JTViewController.h"
#interface Fraction ()
-(void) print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
#end
#implementation Fraction
{
int numerator;
int denominator;
}
-(void) print
{
NSLog (#"%i/%i", numerator, denominator);
}
-(void) setNumerator:(int)n
{
numerator = n;
}
-(void) setDenominator:(int)d
{
denominator = d;
}
#end
int main (int argc, char * argv[])
{
#autoreleasepool {
// Create an instance of Fraction and initialise it
Fraction *myFraction = [[Fraction alloc] init];
//Set Fraction to 1/3
[myFraction setNumerator: 1];
[myFraction setDenominator: 3];
//Display the fraction using the print method
[myFraction print];
}
return 0;
}
This is the error
Ld /Users/jamesmurray/Library/Developer/Xcode/DerivedData/BrandNew-akqlirretjwoeuaqkrwlbqmlqxlc/Build/Products/Debug-iphonesimulator/BrandNew.app/BrandNew normal i386
cd /Users/jamesmurray/AppsDev/BrandNew
setenv IPHONEOS_DEPLOYMENT_TARGET 6.1
setenv PATH "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch i386 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk -L/Users/jamesmurray/Library/Developer/Xcode/DerivedData/BrandNew-akqlirretjwoeuaqkrwlbqmlqxlc/Build/Products/Debug-iphonesimulator -F/Users/jamesmurray/Library/Developer/Xcode/DerivedData/BrandNew-akqlirretjwoeuaqkrwlbqmlqxlc/Build/Products/Debug-iphonesimulator -filelist /Users/jamesmurray/Library/Developer/Xcode/DerivedData/BrandNew-akqlirretjwoeuaqkrwlbqmlqxlc/Build/Intermediates/BrandNew.build/Debug-iphonesimulator/BrandNew.build/Objects-normal/i386/BrandNew.LinkFileList -Xlinker -objc_abi_version -Xlinker 2 -fobjc-arc -fobjc-link-runtime -Xlinker -no_implicit_dylibs -mios-simulator-version-min=6.1 -framework UIKit -framework Foundation -framework CoreGraphics -o /Users/jamesmurray/Library/Developer/Xcode/DerivedData/BrandNew-akqlirretjwoeuaqkrwlbqmlqxlc/Build/Products/Debug-iphonesimulator/BrandNew.app/BrandNew
duplicate symbol _main in:
/Users/jamesmurray/Library/Developer/Xcode/DerivedData/BrandNew-akqlirretjwoeuaqkrwlbqmlqxlc/Build/Intermediates/BrandNew.build/Debug-iphonesimulator/BrandNew.build/Objects-normal/i386/main.o
/Users/jamesmurray/Library/Developer/Xcode/DerivedData/BrandNew-akqlirretjwoeuaqkrwlbqmlqxlc/Build/Intermediates/BrandNew.build/Debug-iphonesimulator/BrandNew.build/Objects-normal/i386/JTViewController.o
ld: 1 duplicate symbol for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I have no idea where it came from. Any assistance would be appreciated.
Like the linker error says, you have two main() functions; one in main.m and one in JTViewController.m.
Remove the one in JTViewController.m (move the functionality into main.m).
There is nothing special about main here. You can only have one globally visible non-common symbol in your object files. Non-static functions are globally visible and non-common symbols, hence you can only have a function with a specific name defined only once. For example:
a.c:
int func() { ... }
b.c:
void func(int arg) { ... }
When both files are compiled, it creates two globally visible symbols with the name of func (with whatever decoration the compiler might apply to the symbol), despite the difference in the argument lists and the return types. As the linker tries to resolve all symbol references in order to produce the final executable, it faces the hard choice of selecting the right version of func, so it takes the most direct approach - simply gives you an error about duplicate symbol definition and bails out.
This is not a requirement unique to the C language (and Objective-C is basically a runtime extension of C) as it is imposed by the system linker. It also translates to many other languages like Objective-C, C++, Fortran, Pascal, etc. In C++ function symbols are decorated according to the namespace they live in and the list of their arguments (the former enables function overloading), but again one cannot have two functions with the same list of arguments in the same namespace defined in different source files.
Usually C and C++ functions are compiled to globally visible symbols unless the static modifier is applied:
a.c:
static int func() { ... }
b.c:
void func(int arg) { ... }
This would not result in a global symbol func in a.o clashing with the one in b.o and the linker would not complain. It would also work if rather func in b.c is given the static treatment or if both functions are static.

Can't compile Objective-C code with clang

I get following error with following Objective-C code, while trying to compile it with clang.
Obj-C Code:
// first program example
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
#autoreleasepool {
NSLog (#"Programming is fun!");
}
return 0;
}
Error message:
main.m:6:5: error: unexpected '#' in program
#autoreleasepool {
^
main.m:7:38: error: extraneous ')' before ';'
NSLog (#"Programming is fun!");
^
main.m:7:16: warning: expression result unused [-Wunused-value]
NSLog (#"Programming is fun!");
^~~~~~~~~~~~~~~~~~~~~~
main.m:9:5: error: expected identifier or '('
return 0;
^
main.m:10:1: error: expected external declaration
}
^
1 warning and 4 errors generated.
I can compile without error within XCode.
Clang info:
Apple clang version 2.1 (tags/Apple/clang-163.7.1) (based on LLVM 3.0svn)
Target: x86_64-apple-darwin11.3.0
Thread model: posix
You need clang v3.0 or greater to use #autoreleasepool.
Supposing you have clang 3.0 on your system path you can compile your code with:
clang -Wall -framework Foundation prog_name.m -o prog_name
You'll need to upgrade your Clang; the #autoreleasepool{} directive was released at the same time as ARC, and requires v3.0 or greater.

Is possible to use CATextLayer in a c struct?

I need to associate a tag with a CATextLayer so I thought this:
.h
#import <QuartzCore/QuartzCore.h>
#import <CoreText/CoreText.h>
typedef struct textLayerWithTag
{
CATextLayer *textLayer;
int tag;
}textLayerWithTag;
.m`
textLayerWithTag textLayer1;
textLayer1.tag = 0;
textLayer1.textLayer = [[CATextLayer alloc] init];
textLayer1.textLayer.string = #"aaaa";
textLayer1.textLayer.frame = CGRectMake(0.f, 10.f, 320.f, 32.f);
[self.view.layer addSublayer:textLayer1.textLayer];`
But when I try to build it I have this error:
"_OBJC_CLASS_$_CATextLayer", referenced from:
objc-class-ref-to-CATextLayer in StructViewController.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
Any ideas? :/
You probably aren't linking the QuartzCore and CoreText Frameworks to your project. Right click on the Frameworks Group in XCode and then do add->Existing Frameworks... Select QuartzCore and CoreText and you should be good to go!

Why does backtrace not contain Objective-C symbols regardless of -rdynamic?

Update: I'm working with the GNU-runtime on Linux. The problem does not occur on MacOS with the Apple-runtime.
Update 2: I compiled the GNU-runtime on MacOS and build the example with it. The error does not occur on MacOS with the GNU-runtime. I would say the problem is the glibc (since backtrace and backtrace_symbols are glibc extensions).
When printing a backtrace in a GCC compiled Objective-C app using backtraceand backtrace_symbols, I don't get any Objective-C symbols. Only the filenames, addresses and C-symbols appear.
I compiled with -g and linked with -rdynamic.
My test app:
void _printTrace()
{
void *addr[1024];
int aCount = backtrace(addr, 1024);
char **frameStrings = backtrace_symbols(addr, aCount);
for (int i = 0; i < aCount; i++) {
printf("%s\n", frameStrings[i]);
}
free(frameStrings);
}
#interface TheObject
+ (void)_printTrace;
+ (void)printTrace;
#end
#implementation TheObject
+ (void)_printTrace
{
_printTrace();
}
+ (void)printTrace
{
[self _printTrace];
}
#end
void printTrace()
{
[TheObject printTrace];
}
int main(int argc, char **argv)
{
printTrace();
return 0;
}
and it's output:
./test.bin(_printTrace+0x1f) [0x8048e05]
./test.bin() [0x8048e60]
./test.bin() [0x8048e8b]
./test.bin(printTrace+0x34) [0x8048ec5]
./test.bin(main+0xf) [0x8048eda]
/lib/libc.so.6(__libc_start_main+0xe5) [0xb7643bb5]
./test.bin() [0x8048b51]
Is there a way to let the Objective-C symbols appear in this backtrace?
dladdr() only reports global and weak symbols. But all Objective-C function symbols are local:
$ readelf -s so_backtrace
Symbol table '.dynsym' contains 29 entries:
…
Symbol table '.symtab' contains 121 entries:
Num: Value Size Type Bind Vis Ndx Name
…
49: 08048a01 13 FUNC LOCAL DEFAULT 14 _c_TheObject___printTrace
50: 08048a0e 47 FUNC LOCAL DEFAULT 14 _c_TheObject__printTrace
…
You can verify that local symbols are never returned by looking at the GNU libc source code yourself. backtrace_symbols() is defined in sysdeps/generic/elf/backtracesyms.c. It relies on _dl_addr(), which is defined in elf/dl-addr.c, to provide it with the symbol names. That ultimately calls determine_info(). If it can, it uses the the GNU hash table, which does not include local symbols by design:
49 /* We look at all symbol table entries referenced by the hash
50 table. */
…
60 /* The hash table never references local symbols so
61 we can omit that test here. */
If the GNU hash table isn't present, it falls back to standard hash table. This includes all the symbols, but the determine_info() code filters out all but the global symbols and weak symbols:
90 if ((ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
91 || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
To symbolicate the Objective-C function addresses, you would have to perform the look-up yourself and not filter out the local function symbols. Further, you would have to demangle the Objective-C function symbols to restore _c_TheObject___printTrace to +[TheObject _printTrace].
GNUstep's NSException implementation doesn't use backtrace, instead it uses libbfd (binary file descriptor). I think the function that actually does the work is called static void find_address, which you can view here. Using this trivial example, I get the results that follow.
#include <Foundation/Foundation.h>
#interface Test : NSObject {}
+ (void) test;
#end
#implementation Test
+ (void) test
{
Class GSStackTrace = objc_getClass("GSStackTrace");
id stack = [GSStackTrace currentStack];
for (int i = 0; i < [stack frameCount]; i++)
{
NSLog (#"%#", [[stack frameAt:i] function]);
}
}
#end
int main(int argc, char **argv)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[Test test];
[pool release];
return 0;
}
Output (when compiled with debug symbols):
2010-10-18 14:14:46.188 a.out[29091] +[GSStackTrace currentStack]
2010-10-18 14:14:46.190 a.out[29091] +[Test test]
2010-10-18 14:14:46.190 a.out[29091] main
2010-10-18 14:14:46.190 a.out[29091] __libc_start_main
You may be able to pick apart GSStackTrace. It is a “private” class (that's why I need to use objc_getClass, you'll also get lots of unrecognised selector warnings), but it seems to contain all the code necessary to read Objective-C class names.
Tested on Ubuntu 9.04 with GNUstep configured with --enable-debug (so that GSFunctionInfo is included in the build).
I expect you'll need to ask the ObjC run time about the addresses to get symbol information. The addresses returned from backtrace() could probably be passed to something like object_getClass() to get the class, for example. I haven't tried any of this but it's where I'd look next in this case.