Declaring extern NSString causes linker error

11,323

Solution 1

Thanks for your help guys

I added

NSString *kPlaySoundPrefsKey = @"playSoundKey";

[[NSUserDefaults standardUserDefaults] registerDefaults:defaultDict];

to app delegate. That fixed it

Solution 2

When you declaring something as extern you are telling the compiler the type AND that you will define it somewhere else. In your case you never define your variable.

So in your .h you would have:

extern NSString* kPlaySoundPrefsKey;

But in some .m you must also have

NSString* kPlaySoundPrefsKey = @"play_sounds"; // or some value

Since in your case these are constants you can also specify:

extern NSString* const kPlaySoundPrefsKey;

and

NSString* const kPlaySoundPrefsKey = @"play_sounds"; 

The addition of the const qualifier will cause a compiler error if someone ever writes something like

kPlaySoundPrefsKey = @"some_other_value";

Solution 3

I am also got the same error even if I am properly declared and define the extern const string , The problem is, my constant file not in the compile source list .

Make sure that your .m file appears in the "Compile Sources" Build Phase for your build target. Sometimes, adding files to a project in Xcode doesn't add all implementation files to the appropriate targets.

Hope this will helpful for some people. Refe: linker-error-undefined-symbols-symbols-not-found

Solution 4

First, ensure it is defined:

// AppDelegate.h
extern NSString* const kPlaySoundPrefsKey; // << declaration

// AppDelegate.m
NSString * const kPlaySoundPrefsKey = @"kPlaySoundPrefsKey";  // << definition

see also:

"extern const" vs "extern" only

3 questions about extern used in an Objective-C project

Linker error using extern "C" in Objective-C code

Share:
11,323
JSA986
Author by

JSA986

Updated on June 17, 2022

Comments

  • JSA986
    JSA986 almost 2 years

    This is ridiculous, im trying to create a sound bool to turn of in app sounds. I keep getting

    Undefined symbols for architecture i386:
    "_kPlaySoundPrefsKey", referenced from:
      -[AppDelegate application:didFinishLaunchingWithOptions:] in AppDelegate.o
    ld: symbol(s) not found for architecture i386
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    I have checked that all my files are linked in build phases, I have deleted the appdelegate .m where im getting the error before I even get to call the bool in any of my view controllers, and re imported it in build phases. Checked I have relevant framweworks in place. I have even checked a previous app I made with same code and the code it appears to be exactly the same with no error (built with previous version of xcode). Taking it right back to basics I get the error as soon as I add the following code to my App Delegate,

    .h

    #import <UIKit/UIKit.h>
    extern NSString *kPlaySoundPrefsKey;
    
    @interface AppDelegate : UIResponder <UIApplicationDelegate>
    
    @property (strong, nonatomic) UIWindow *window;
    
    @end
    

    .m

    #import "AppDelegate.h"
    #import <AudioToolbox/AudioToolbox.h> 
    
    @implementation AppDelegate
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:    (NSDictionary *)launchOptions
     {
    
    NSDictionary *defaultDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
     forKey:kPlaySoundPrefsKey];
    
    return YES;
    }
    

    If I change extern NSString *kPlaySoundPrefsKey; to NSString *kPlaySoundPrefsKey; it builds then crashes...Im out of ideas now

  • idz
    idz over 11 years
    I down voted the original answer because it did not address the root cause of the OP's problem; he was never defining the variable. Once you edited it to address this I removed it.
  • justin
    justin over 11 years
    @idz alright. i received two separate anon downvotes (which have both been undone now), one of which came after the update which mentioned the absence definition. so, i found it a bit unusual. thank you for the explanation.
  • JeremyP
    JeremyP over 11 years
    Does C++ name mangle variables? I thought it only did that with functions.
  • justin
    justin over 11 years
    @JeremyP in this case (toolchain+abi+etc.), the exported name is the same. will remove that part. cheers.
  • Daniel
    Daniel about 11 years
    Could you explain about the usage of extern here, it doesn't seem constant in the Apple header files to have this. Sometimes there is only NSString *const, other times extern NSString *const, and sometimes extern NSString *
  • justin
    justin about 11 years
    @Daniel a) could you provide an example header b+c) the only difference is that c may be assigned another string -- the string it 'points to' may be set during execution. for a pref key or notification name, it should be const
  • abbood
    abbood about 10 years
    ninja downvoters? lol! long time @justin it's good to see your answers again :)