compile-time error when including ArcGIS SDK into Xcode project with other c++ code

3471
4
Jump to solution
10-22-2012 03:59 PM
DanaMaher
Occasional Contributor
I am unable to use the ArcGIS SDK for iOS in an XCode project that uses c++ code. If I create a new project in XCode, add an empty c++ file, and then link to the ArcGIS SDK for iOS, I get a series of errors under the header "undefined symbols for architecture i386." See attached text file for the complete error log.

If I pull out the c++ class, I can proceed to write an app that leverages the ArcGIS SDK for iOS. If I pull out the SDK, I can proceed to write an app that uses some c++ code. However, I need the ArcGIS SDK and an iOS build of the OpenCV library to play nicely within the same project. Previously, I have had no issues including c++ code in my XCode projects using the rules outlined here.

Typically, I see "undefined symbol..." errors when I forget to include a library or framework needed by some code in my project. For instance, if I set up an XCode project to use the ArcGIS SDK and I forgot to include libstdc++, I get a longer list of "undefined symbols for architecture i386" errors. In fact, the errors I am currently seeing are a subset of the errors resulting from not including libstdc++.

My guess is that when LLVM compiles a project that includes c++ code, it adjusts itself in a way that breaks the ArcGIS SDK's linkage with libstdc++. Or libstdc++ gets ignored for some other c++ library that is not quite equivalent. I base this guess on the observation that the errors I am seeing are a subset of the errors I get by not including libstdc++ and the observation that when building with c++ code in the project, I see an additional -stdlib=libc++ flag in the link phase of the compile. A -lstdc++ flag is also present since I am linking to libstdc++ in order to use the ArcGIS for iOS SDK.

Am I on track? If so, can I adjust the compiler settings to get around this?
0 Kudos
1 Solution

Accepted Solutions
DanaMaher
Occasional Contributor
Additional option: Wrap c++ code in the project using this method. This compartmentalizes the c++, removes the need to use Objective-C++ except for in wrapper classes, and prevents the compile-time error I was seeing.

View solution in original post

0 Kudos
4 Replies
EricIto
New Contributor III
Looking at your linker flags: I think the problem is the stdlib being libc++, it should be libstdc++. Can you retry with that as your stdlib?

    /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.0.sdk -L/Users/dcmaher/Library/Developer/Xcode/DerivedData/IG_ImageTracker-ctpdysoeefapnhaunikodxdioslg/Build/Products/Debug-iphonesimulator -F/Users/dcmaher/Library/Developer/Xcode/DerivedData/IG_ImageTracker-ctpdysoeefapnhaunikodxdioslg/Build/Products/Debug-iphonesimulator -F/Users/dcmaher/Library/SDKs/ArcGIS -filelist /Users/dcmaher/Library/Developer/Xcode/DerivedData/IG_ImageTracker-ctpdysoeefapnhaunikodxdioslg/Build/Intermediates/IG_ImageTracker.build/Debug-iphonesimulator/IG_ImageTracker.build/Objects-normal/i386/IG_ImageTracker.LinkFileList -Xlinker -objc_abi_version -Xlinker 2 -ObjC -all_load -framework ArcGIS -fobjc-arc -fobjc-link-runtime -Xlinker -no_implicit_dylibs -stdlib=libc++ -mios-simulator-version-min=6.0 -lstdc++ -framework CoreLocation -framework CoreText -lz -framework MediaPlayer -framework MobileCoreServices -framework QuartzCore -framework Security -framework Foundation -framework UIKit -framework CoreGraphics -o /Users/dcmaher/Library/Developer/Xcode/DerivedData/IG_ImageTracker-ctpdysoeefapnhaunikodxdioslg/Build/Products/Debug-iphonesimulator/IG_ImageTracker.app/IG_ImageTracker
0 Kudos
DanaMaher
Occasional Contributor
Looking at your linker flags: I think the problem is the stdlib being libc++, it should be libstdc++. Can you retry with that as your stdlib?


Eric, the compiler adds that particular flag when it finds c++ code in a project. I am not setting it anywhere. As you can see, the libstdc++ flag that must be explicitly added to compile the ArcGIS SDK is also present. I think you and I are in agreement about the basic problem.

I am not sure where in the build settings panel I would tell the compiler not to include the libc++ flag and I believe libc++ is needed to build c++ code in the project. I know that Apple's LLVM compiler switched from libstdc++ to libc++ a while back and that the two libraries are mangled differently by the compiler, so removing libc++ seems like it might solve the ArcGIS SDK issue but prevent my c++ code from compiling.
0 Kudos
DanaMaher
Occasional Contributor
Fixed! Two options:

1) If I move my linkage to the ArcGIS SDK from my target settings to my project settings, I can build. Targets using the ArcGIS SDK will need an $(inherited) flag in the Framework Search Paths field. I typically do all my framework/library linkage in the target settings on the general principle that my project might end up with multiple targets using different components, and I have never had an issue with this before.

I do not understand *why* this makes a difference; the build looks exactly the same (same linker flags, etc.) and my understanding is that target level settings simply add to or override project level settings *before* everything is fed into the compiler.

2) If I switch the default c++ library to libstdc++, I can build without doing 1). This is accomplished via the c++ standard library field in the project or target settings and I should have seen it right away. Changing that field will prevent LLVM from adding the -stdlib=libc++ flag, as per eric5320's suggestion. However, my understanding is that libc++ offers some substantial advantages over libstdc++. Having to make a project-wide change like that to accommodate one framework is unfortunate.
0 Kudos
DanaMaher
Occasional Contributor
Additional option: Wrap c++ code in the project using this method. This compartmentalizes the c++, removes the need to use Objective-C++ except for in wrapper classes, and prevents the compile-time error I was seeing.
0 Kudos