This question already has answers here:
Duplicate symbol error — global constant
(3 answers)
Closed 8 years ago.
I have a BConstants.h file where I put all the constants for my project. The file is the following:
#ifndef asdf_BConstants_h
#define asdf_BConstants_h
typedef NS_ENUM(NSUInteger, BTheme) {
kField
};
typedef NS_ENUM(NSUInteger, BItem) {
kBox
};
typedef NS_ENUM(NSUInteger, BMovementState) {
kTouchUp,
kTouchDown
};
#endif
When I add the following three lines to this file, I receive the subsequent errors when the file is #imported to another .m file
...
NSString * const kHero = #"Hero";
NSString * const kCount = #"Count";
#endif
Errors:
duplicate symbol _kHero in:
...list of .o files
duplicate symbol kCount in:
...list of .o files
2 duplicate symbols for architecture arm64
I have looked at questions already post on SO that state I may have duplicate files in my compile sources of the application target, but I checked and I found no duplicate files. Where else can this problem stem from, is it the inclusion of those 2 NSString constants in the BConstants.h file?
There are 2 other possibilities for this error besides duplicate files
You may importing .m file instead of .h by mistake
Constants kHero and kCount already defined in some other files. As
you are defining those constants in constant file then just import
that file in Prefix.pch file and remove from everywhere else.
Related
Currently writing a C extension for Python,
I successfully compiled and use the numpy C-API within the main/loader file of the module extension.
I am now trying to move the logic into a different C file.
Following the documented procedure, I set up the following declarations.
Inside the module loader file:
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#define PY_ARRAY_UNIQUE_SYMBOL CCMAP_ARRAY_API
#include "numpy/arrayobject.h"
Inside the file carrying the interactions with the numpy API
#define NO_IMPORT_ARRAY
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#define PY_ARRAY_UNIQUE_SYMBOL CCMAP_ARRAY_API
#include <Python.h>
#include "numpy/arrayobject.h"
The compilation breaks on the file carrying the interactions w/ the numpy API
In file included from ccmap/src/molecular_object.c:1:
In file included from ccmap/include/molecular_object.h:25:
In file included from /Users/MYNAME/Library/Caches/pypoetry/virtualenvs/pcmap-zIv2c8Xw-py3.9/lib/python3.9/site-packages/numpy/core/include/numpy/arrayobject.h:5:
In file included from /Users/MYNAME/Library/Caches/pypoetry/virtualenvs/pcmap-zIv2c8Xw-py3.9/lib/python3.9/site-packages/numpy/core/include/numpy/npy_interrupt.h:23:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/signal.h:69:42: error: use of undeclared identifier 'NSIG'
extern __const char *__const sys_signame[NSIG];
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/signal.h:70:42: error: use of undeclared identifier 'NSIG'
extern __const char *__const sys_siglist[NSIG];
^
2 errors generated.
error: command '/usr/bin/clang' failed with exit code 1
Under MacOS 11.6, I am missing a point here. Should I change/adapt my toolchain for such a seemingly minor change in file organization ?
Noob build question.
When I change this;
#define NOTIFICATION_PLAYBACK_STATE_CHANGED #"SC_NOTIFICATION_PLAYBACK_STATE_CHANGED"
to this;
NSString * const NOTIFICATION_PLAYBACK_STATE_CHANGED = #"SC_NOTIFICATION_PLAYBACK_STATE_CHANGED";
I get this:
ld: 752 duplicate symbols for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Sample of the 752 duplicates:
duplicate symbol _NOTIFICATION_PLAYBACK_STATE_CHANGED in:
/Users/myname/Library/Developer/Xcode/DerivedData/MyApp-hazegevzmypmbtbnalpiwebrhaea/Build/Intermediates/MyApp.build/Debug-iphoneos/MyApp.build/Objects-normal/armv7/SCRemoteRecordManager.o
/Users/myname/Library/Developer/Xcode/DerivedData/MyApp-hazegevzmypmbtbnalpiwebrhaea/Build/Intermediates/MyApp.build/Debug-iphoneos/MyApp.build/Objects-normal/armv7/SCRegisterAcceptTermsViewController.o
duplicate symbol _NOTIFICATION_PLAYBACK_STATE_CHANGED in:
/Users/myname/Library/Developer/Xcode/DerivedData/MyApp-hazegevzmypmbtbnalpiwebrhaea/Build/Intermediates/MyApp.build/Debug-iphoneos/MyApp.build/Objects-normal/armv7/SCRemoteRecordManager.o
/Users/myname/Library/Developer/Xcode/DerivedData/MyApp-hazegevzmypmbtbnalpiwebrhaea/Build/Intermediates/MyApp.build/Debug-iphoneos/MyApp.build/Objects-normal/armv7/SCStreamingVideoViewController.o
(A search for this particular duplicate symbol returns nothing outside of the class's own .h and .m files.)
There are many other places in the code where I have replaced such a #define with a constant without objections during the build.
Can someone take a guess at what's happening here (or advise me what information I would need to post for a guess to be possible)?
Is trawling through the code replacing #defines where they have been used to create constants (leaving stuff like debug/release defs untouched) a dumb thing to do, i.e. should I be doing this differently (if at all)?
You seem to have these constants defined in a header file. The header file is imported into multiple other files; the definition is thus repeated across all those files. Multiple definitions using the same name are not allowed.
What you want to do instead is to declare the constant in the header:
extern NSString * const NOTIFICATION_PLAYBACK_STATE_CHANGED;
extern indicates to the compiler "this is a name I'm going to use, but the storage and definition for it is elsewhere; let the linker handle that".
Then, in a file that imports the header, but is not itself imported anywhere, you define the string:
NSString * const NOTIFICATION_PLAYBACK_STATE_CHANGED = #"SC_NOTIFICATION_PLAYBACK_STATE_CHANGED";
The linker will find this definition, and all the copies of the extern declarations, and tie them together to be the same thing.
(It may interest you to see what errors you get if you omit each of these pieces in turn. You'll get a compiler error in one case, and a linker error in the other.)
I added the Scintilla framework successfully to my XCode project (i.e. it finds the header files correctly), but because it is written in Objective-C++ it doesn't compile. I get 8 syntax errors because of ::s. I already found you can't include Objective-C++ from a pure Objective-C file, so I changed the file extension to mm. It still gives me the same 8 errors.
I also changed the file type (of the importing file) to sourcecode.cpp.objcpp.
The relevant lines of code (with the errors in comments - the line numbers are from the original file, so without the errors in the comments):
ScintillaView.h
// Line 47-49
#protocol ScintillaNotificationProtocol
- (void)notification: (Scintilla::SCNotification*)notification; // 4 errors on this line:
// 1. expected type-specifier
// 2. expected ')'
// 3. expected identifier
// 4. expected ';'
#end
// [snip]
// Line 131
- (void) notification: (Scintilla::SCNotification*) notification; // The exact same errors.
When copying this code I noticed the :: operator is used a few more times in the file, so somehow the parser is only able to match it succesfully in certain places.
Once more, this code is not mine, but taken from the Scintilla Cocoa Library.
(See here for more info: http://www.scintilla.org/)
XCode 3.2.6, Mac OS X 10.6.8
Adding
typedef tdSCNotification Scintilla::SCNotification
Before the first offending line revealed that there was no type called SCNotification in that namespace. So I searched through the included header files (which, luckily, count only three) for namespace Scintilla {. It was in the first included header file, Scintilla.h. But it looked like this:
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
and
#ifdef SCI_NAMESPACE
}
#endif
So I assumed SCI_NAMESPACE wasn't defined. I added #define SCI_NAMESPACE to Scintilla.h somewhere online 45 and it worked. Almost. I got another error message:
Framework not found Scintilla
Command /Developer/usr/bin/llvm-g++-4.2 failed with exit code 1
I think this has to do with how I added the framework to my project, so it should be a separate question.
I have a really simply LESS file which for now just imports Bootstrap. I'm using grunt and grunt-contrib-less#0.9.0 to compile the LESS files on save (less#1.6.3).
My file looks like this:
#charset "utf-8";
/**
* This is the root style file for the app
* to include styles in your html, you only need to include either:
* dist/styles.dev.css (for development)
* dist/styles.css (for production)
*/
// Libraries
#import "../lib/bootstrap/less/bootstrap"
// Our own files
and I'm getting the following error whenever I try to run my less:dev task.
Running "less:dev" (less) task
>> ParseError: Unrecognised input in style/styles.less on line 10, column 1:
>> 9 // Libraries
>> 10 #import "../lib/bootstrap/less/bootstrap"
>> 11
I've tried removing everything from the file except the import line and it still fails, so something weird is going on with the #import directive.
Any ideas?
Use semi-colon after #import
#import "../lib/bootstrap/less/bootstrap";
I have a project containing a mixture of Objective c and c files. In one of the c header files I am trying to import complex.h. Xcode generates 13 compilation errors connected to NSObjRuntime.h:
NSObjRuntime.h
Parse Issue
Expected identifier or '('
Parse Issue
Unknown type name 'NSString'...
More compilation errors are produced from NSZone.h.
It looks to me like the errors are coming from Objective C code being unrecognized in a .c file. Should I convert my c files to objective c in order to import complex.h or is there a more elegant solution?
It looks to me like the errors are coming from Objective C code being unrecognized in a .c file.
exactly.
Should I convert my c files to objective c in order to import complex.h or is there a more elegant solution?
there is no need to use objc in this example. therefore, there is no need to compile it as objc. complex.h does not require or include objc headers.
you simply do not include objc headers in your c translations.
if this include is coming from the prefix header, you can use:
#if defined(__OBJC__)
#import <Foundation/Foundation.h>
#endif
if it's imported via another header you have included, you will have to consider your include dependencies. sometimes there are unnecessary includes, sometimes you can get away using #if defined(__OBJC__).