Undefined Symbols for custom C++ classes in Xcode 4.6.3. Works in Xcode 4.5.2 - objective-c++

I have an iOS app that works fine in Xcode 4.5.2 but in Xcode 4.6.3 i get undefined symbols for my custom c++ classes.
SomeClass.hpp
class SomeClass{
public:
SomeClass();
void doStuff();
}
SomeClass.cpp
#include "SomeClass.hpp"
SomeClass::SomeClass(){
// ra ra ra
}
SomeClass::doStuff() {
// ra ra ra
}
CallingClass.mm
#include "SomeClass.hpp"
#implementation CallingClass
-(void) execute{
SomeClass someObject;
someObject.doStuff();
}
#end
Error
Undefined Symbols for arm7:
SomeClass::SomeClass() referenced from:
-[CallingClass execute:] in CallingClass.o
The .hpp files are set to C++ Headers, the .cpp files are set to C++ Source, and the .mm files are set to Objective-C++ Source.
Each of the .cpp files are present in Build Phases/Compiled Sources.
libc++.dylib is included in the project for a library that i'm using.
The 4.6.3 C Language Dialect is c11 while in 4.5.2 its C99[-std=c99]. The C++ Language Dialect and C++ Standard Library are set to Compiler Default in both version of Xcode.
The compiler is Apple LLVM 4.2 in Xcode 4.6.3 while its LLVM 4.1 in 4.5.2.
Any guidance would be highly appreciated.
Cheers

I had faced similar problem, and here is what I did to solve:
1 - Specify -fobj-arc flag against respective mm file in Build Phases section (this is optional and may not work always)
2 - Ensure that wherever .mm (or it's .h file) is included, that source is also marked as Objective-C++ Source and vice versa. I know it's bit tricky to do trial and error, but the basic principle is to maintain same compilation options for the file tree being included.

Solved
I changed the .hpp files to .h and the .cpp files to .mm.

Related

Xcode 9.1 upgrade to Swift 4 breaks #ifdef

I've got a project written in Swift 3 that has a number of #if ... #elses scattered throughout; they just check for a certain variable (defined with the -D compiler flag) which is set by my xcode project to know if the project is being built in xcode or with the package manager and does some imports accordingly. For example,
#if XCODE_BUILD
// do some imports that work when built with xcode
#else
// do some imports that won't work when built with xcode
#endif
The code builds just fine via either method.
But, when I select the option to upgrade to Swift 4 (either of the options offered -- "Minimize inference" or "Match Swift 3 behavior"), the code fails to compile so the migration fails. It appears that the #ifs are not being respected or the XCODE_BUILD variable isn't being defined, since the failures occur in the imports that shouldn't happen when being built from Xcode.
Does Swift 4 do something different with #ifs? Does Xcode somehow not define the compiler flags while doing the migration?
You can use #if, #else and #endif, resulting in:
#if XCODE_BUILD
// do some imports that work when built with xcode
#else
// do some imports that won't work when built with xcode
#endif
Apple docs here.
Another answer with some additional details can be found here: https://stackoverflow.com/a/24152730/118091
Previously, I was using the 'Other Swift Flags' build setting in Xcode to pass '-DXCODE_BUILD'. Apparently that setting doesn't work for Swift 4. The new setting that does work is 'Active Compilation Conditions' (it should be set to include XCODE_BUILD, no need for the -D flag).

Xcode: I just got an Apple Mach-O Linker (Id) Error and don't know why

I'm new to iOS Development, I'm using the latest version of Xcode and just got an error that said Apple Mach-O Linker (Id) Error exit code 1 and I haven't got a clue why. I think this is relevant but I'm not sure what it means:
ld: duplicate symbol _OBJC_CLASS_$_Timing1ViewController in /Users/tomkenning/Library/Developer/Xcode/DerivedData/EggTimer-ciznfdheqrtybuavrtbbcxfywyyw/Build/Intermediates/EggTimer.build/Debug-iphonesimulator/EggTimer.build/Objects-normal/i386/Mediumhb.o and /Users/tomkenning/Library/Developer/Xcode/DerivedData/EggTimer-ciznfdheqrtybuavrtbbcxfywyyw/Build/Intermediates/EggTimer.build/Debug-iphonesimulator/EggTimer.build/Objects-normal/i386/Timing1ViewController.o for architecture i386
All I've done recently is initialise and set some integer values in a .m file and then link to them from .h file from another ViewController, using #import "suchandsuch.m", there's been no errors in the code, but is that not allowed?
Thanks in advance for any help you can offer!
Don't do this:
#import "suchandsuch.m"
Do this:
#import "suchandsuch.h"
You are probably compiling suchandsuch.m, which defines the class Timing1ViewController, normally (by including suchandsuch.m in your target's list of files to build). Then your #import "suchandsuch.m" causes that same code to be inserted into a different source file, which is compiled as well. The result: two different source files try to define Timing1ViewController.
To do your constants the right way -- by declaring them extern in suchandsuch.h and defining them in suchandsuch.m -- see this answer.
You probably have two Timing1ViewController classes with the same name. If you don't try to Product -> Clean and build again.

identically-named classes in app and lib cause issues *after* converting from Makefile to cmake

I'm trying to convert a program and its plugin from custom Makefiles to CMake, with minimal changes to the code.
Both the plugin and the app share some code; #ifdef ... #else ... #endif blocks are used where there are differences, and I'm certain the code is compiled with the correct defines. The shared code includes a class called ToolImage. When the code is compiled for the app, the ToolImage constructor uses a different resource path than when it is compiled for the plugin.
#ifdef THE_APP
ToolImage::ToolImage(const wxString& name, bool full_path_given):wxImage(full_path_given?name:
(wxGetApp().GetResFolder() + _T("/bitmaps/") + name + _T(".png")), wxBITMAP_TYPE_PNG)
#else
ToolImage::ToolImage(const wxString& name, bool full_path_given):wxImage(full_path_given?name:
(theApp.GetResFolder() + _T("/bitmaps/") + name + _T(".png")), wxBITMAP_TYPE_PNG)
#endif
{
...
}
When the program and its plugin have been compiled with the custom Makefiles, everything works as expected. When both have been compiled with CMake, using a series of CMakeLists.txt files I created, there is an issue: the plugin isn't able to load the bitmaps for its toolbar.
I tracked the problem to the ToolImage class. The line number given by gdb tells me that the plugin is using the wrong constructor. strace tells me the same thing (the plugin is looking for its bitmaps in the app's resource dir rather than in the plugin's resource dir). To ensure that I didn't have the defines screwed up, I put a #error in ToolImage.cpp, inside the part of the #ifdef that should only be compiled for the app - and the plugin still compiled without error. This tells me that the plugin is compiling with the correct code. Since it is using the wrong path, I think it is using the class and constructor compiled into the program instead of its own.
How do I ensure that the plugin uses its own ToolImage class instead of the one in the app?! I don't own the project and don't want to make massive changes merely to support building with a different build system.
Using the precompiler to create two versions of a class seems like a poor choice to me. If I must make changes to the code, do you have suggestions for a workaround?
For the sake of experiment, I'd add -fvisibility=hidden when building theapp, to all or maybe to some specific sources. This should hide application's ToolImage from the plugin.
It is not a universal method, as in many cases plugins do use different symbols from the main executable.
I fixed this by adding the linker flag -Wl,-Bsymbolic-functions in the CMakeLists.txt:
set_target_properties( heekscnc PROPERTIES LINK_FLAGS -Wl,-Bsymbolic-functions )

Typedef for STL Vector does not compile in XCode

I have some code written in C++ which I would like to use in my iPhone app. I added the source files to the XCode project, but I have problem with some parts of the source code, e.g. I have he following code:
#import <vector>
// (...) some other code
typedef std::vector<keypoint> keypointslist;
// (...) rest of the code
In the line with the typedef I'm getting:
Expected '=', ',', ';', 'asm' or 'attribute' before ':' token in
Exactly the same code was compiled with gcc on Linux machine, so I wonder why XCode has problem with it.
Any suggestions?
Are you sure, you told XCode to compile the file as C++ and not as C or Objective-C? Maybe you must use the file extension ".cpp".
It's called #include, not #import:
#include <vector>
+1 with Ludger,
youre adding that to an objective c app, you'll need to add a .cp/.mm/.cpp translation unit to the project to get that to compile - right click on project classes select add class make sure you add one from the cpp section.
If you include C++ code in a ".m" file you must rename the extension to ".mm" or ".M". this applies even if you reference a C++ class from an objective C one, the file must be renamed. Sometimes this renaming has a domino effect and so you end up with a lot of ".mm" files in your project.
Make sure you included <vector> header file before typedef. It looks like the compiler doesn't know std namespace.
You have to rename the ALL files that use the C++ code with .mm extension.
That includes your view controller files that could be importing the C++ class. eg. MyViewController.mm

'__glibcxx_requires_valid_range' was not declared in this scope (xcode)

I'm trying to use in an Xcode (iphone) static library, and can't figure out this error. Anyone else had this before?
It borks in the file stl_algobase.h at these places:
__glibcxx_requires_valid_range(__first, __last);
I've tried using GCC 4.0, but it always includes from here:
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.3.sdk/usr/include/c++/4.2.1/bits/stl_algobase.h:606:0 '__glibcxx_requires_valid_range' was not declared in this scope in /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.3.sdk/usr/include/c++/4.2.1/bits/stl_algobase.h
Andrew
It's likely that your project contains a header file that shadows a system header file.
If you have a header called "debug.h", try renaming it to something else and recompile your project.