I'm getting include not found compile error in XCode. I have an iOS app project that i use Objective-c and c++ as mix.
Initially, i created one .h file and one .cpp file in my ios project. Then, I renamed the .cpp file to .mm file.
Here is my .h file;
TestLog.h
#ifndef CalculatorDemo_TestLog_h
#define CalculatorDemo_TestLog_h
#include <string>
using namespace std;
class TestLog
{
private:
string logString;
public:
void Log(string logMessage);
};
#endif
TestLog.mm
#include "TestLog.h"
void TestLog::Log(string logMessage)
{
//this->logString->append(logMessage);
}
What am I missing? Do I need to add std c++ library to my targetS? Something related to Search Header Paths?
I just need to use string type.
Thanks much for in advance
select project -> build setting -> apple LLVM compiler 5.1 -> language
In Compile Sources As change to Objective-C++
There's a quirk in XCode. I noticed it in 7.3. Most projects recognize .mm files and the STL, while one project I had did not. The fix was that I had to click on the top-left project icon, then click Targets > Build Phases > Link Binary with Libraries > and add in AppKit.framework. Next, I had to click Targets > Build Settings > search on "Compile Sources", and set it to "Objective C++" on all possible columns. Then, do a Clean and then a Build from the Product menu. This compiled properly then. Then, go back to that Compile Sources again and set it back to "According to File Type" on all possible columns. Then, click Build from the Product menu again. At that point, it compiled properly and allowed me to utilize the "according to file type" option, which I like better.
Oh, and if doing Cocoa stuff, don't forget to add the following header in your files:
#import <Cocoa/Cocoa.h>
And if doing command line stuff, don't forget to add the following instead of the Cocoa header:
#import <Foundation/Foundation.h>
i believe you need to include the whole path to the library. similarly to say "foundation" & "uiview" frameworks.
#import <Foundation/Foundation.h>
or
#import <UIKit/UIKit.h>
and yes, make sure you add the library to your target.
So I was having this issue with the Cocoapods library Bypass and none of these solutions did anything. The problem was with a file which Cocoapods creates called an umbrella header. This is located in <POD_NAME>/Support Files/<POD_NAME>-umbrella.h. Delete it, and it should build just fine.
Now for the explanation of why this is necessary: the umbrella header is mixing both C++ and Objective-C code directly in a header which is a big no-no apparently and ends up completely breaking the C++ imports. By removing it (which seems to have no effect?) this conflicting import which Cocoapods unknowingly created will go away.
Ran into this with xcode 12.4 with a project that is objective-c, but where I need one C++ modul. Solution: wrap the contents of the .h file in:
#if defined __cplusplus
declarations
#endif
Apparently xcode is not good at detecting a mix of sources.
see Expected ; after top level declarator, error in xcode
This often happens when Xcode doesn't understand that a C++ header file you've imported into Objective-C is actually for C++ code.
So you can solve this problem by finding the Objective-C file that imports C++ code, and simply change its extension from .m to .mm
Related
I'm trying to create a bundle application using Xcode 10.3.
The main code is going to live inside a C++ file, which I added to the bundle project, and I also need to use some Cocoa related stuff.
and here is the catch, anytime I include
#include <Cocoa/Cocoa.h>
I immediately get like 20 errors
which are rather strange. Is there anything else to be added or set in Xcode so I can include Cocoa headers inside a CPP file?
Looks like the solution was easier than expected, you just have to change the compilation type for the cpp file from C++ Source to Objective-C++ Source and then everything compiles as needed.
In an iOS Swift project I'm including a set of libraries built using C++ (HikVision/hcnetsdk.h) and while I've managed to get the frameworks to build, the header file won't compile and Xcode is giving me multiple 'C does not support default arguments'.
For example on this line:
NET_DVR_API BOOL __stdcall NET_DVR_SetConnectTime(DWORD dwWaitTime = 3000, DWORD dwTryTimes = 3);
I've checked the build settings of the project and as far as I can tell everything is set to use C++, so I'm confused as to why Swift is compiling this as C, and complaining about default arguments.
My bridging header file is as follows:
#import "ldapTest.h"
#import "hcnetsdk.h"
#import "HikDec.h"
I'm fairly sure it's a build setting somewhere but which one I don't know.
So it turns out you can't include a C++ header file which contains C++ specific keywords into a Swift bridging header file.
What I did manage to do for my specific situation was find a "C" replacement of the "C++" header which worked with a few minor tweaks.
This is the "C" header file for the HikVision HCNetSDK.h which I found online:
https://github.com/shulianghe/new-project/blob/master/pro/hcSrc/incCn/HCNetSDK.h
If anyone has a similar problem with other C++ header files, you can copy some of the #ifdef __cplusplus statements in the link above to see how it's done.
I want to make an app in Swift that simply record via the mic of the iPhone and then play the sound recorded.
For that, I'd like to use the lib Superpowered that is a static library with header files.
For that, I tried to drag and drop the .a and headers files in my project (Xcode create for me a bridging header file), add the .a in "Linked Frameworks and Libraries" in Xcode > Target > General (and so in Xcode > Target > Build phases > "Link Binary With Libraries" too) and index the .h files path in Xcode > Target > Build Settings > Search Paths > Library Search Paths.
But with that I have the error "ld: symbol(s) not found for architecture arm64"
Exactly the same as here XCode: Undefined symbols for architecture arm64 error and I tried all the solutions that I found on the web for that, still no way to compile.
SO !
Superpowered gives us a sample app to show how to mix Objective-C++ and use their lib within a Swift project (Here's a link to the git if you want https://github.com/superpoweredSDK/Low-Latency-Android-Audio-iOS-Audio-Engine).
Here is some screenshots of the sample project with what I understand and what I don't :
The Bridging-Header-File with the prototypes of the methods of the lib that I want to use within my Swift code (I don't like this but if it's the only way...).
The viewController file where the code in Swift is, and where I can create a Superpowered object thank's to the Bridging-Header-File, and call the methods that I've put in it.
And wtf I don't even understand why this Objective-C++ file is here and what it contains. It comes out from nowhere, not even their lib files.
So with this sample project in mind, I've created my own project, here is some screenshots :
The same Bridging-Header-File that in the sample project except that I include SuperpoweredIOSAudioIO.h so I can use SuperpoweredIOSAudioIODelegate.
My viewController file where the code in Swift is, and where I can create a Superpowered object thank's to the Bridging-Header-File, and call the methods that I've put in it.
Until here, it's great, except that I can't for exemple create a SuperpoweredRecorder object. If I try to include the SuperpoweredRecorder.h file in my Bridging-Header-File I have these errors :
So I saw that it is because SuperpoweredRecorder.h includes some .cpp files and I have to create a wrapper for cpp (a little bit like I did with the bridging header, no ?) but that includes a .h and a .mm file and I don't know what I have to put in that .mm file (the code of SuperpoweredRecorder.cpp ? But I don't have access to it)
So yes, I'm a little bit confused with all that stuff, can you help me to understand how can I use all the Superpowered lib in my Swift project please ?
As I said in comment to #OmniProg, I had a little conversation with the CTO of Superpowered that helped me a lot to find the solution below.
So, as Swift cannot interact directly with C++ but can with Objective-C, I had to create objects in Objective-C++ (.mm file, a mix between C++ and Objective-C) that wrap C++ classes of the lib Superpowered.
Here is an example with the SuperpoweredRecorder object from the lib :
Here I create a .h file where I prototype my wrapper with the name SuperpoweredRecorderWrapped, and I also prototype in it all the methods of the SuperpoweredRecorder of the lib that I want to use.
Then I create a new .m file that I rename .mm and I implement SuperpoweredRecorderWrapped on it.
I import both SuperpoweredRecorderWrapped.h and SuperpoweredRecorder.h.
I create a SuperpoweredRecorder object as property named _wrapped and in my methods, I call the corresponding method of the _wrapped object.
With that, when I'll call start of a SuperpoweredRecorderWrapped in my Swift code, this one will call start of _wrapped, a SuperpoweredRecorder object. See the trick ?
And finally I include all the wrapped classes in my Bridging-Header, like that I can instantiate my wrapped objects from Swift.
NOTE: All the C++ code HAVE to be in .mm files, that's why I make my #include of .h that contains C++ code in my .mm file and not in my .h file.
I haven't programmed in Objective-C++, but I do have experience with C, C++, Objective-C, and Swift, so here are some observations and ideas based on looking at the Superpowered SDK and sample code.
A bridging header lets Swift interface directly with Objective-C, and since Objective-C is a strict superset of C, this implies interfacing with C as well. However, you cannot interface directly with C++, and that's where Objective-C++ comes to the rescue. From what I'm seeing you can mix Objective-C and C++ code in Objective-C++, which allows Objective-C to use C++ classes.
Now on to some specifics.
The bridging header in the SuperpoweredFrequencies example that you looked at introduces a new Objective-C class, Superpowered, which is not part of the library, but of the example, and is implemented in Superpowered.mm. It is an Objective-C++ file, because Superpowered calls some C++ code.
Looking at Superpowered.mm, you will see that it imports Objective-C headers:
#import "SuperpoweredFrequencies-Bridging-Header.h"
#import "SuperpoweredIOSAudioIO.h"
as well as C and C++ headers:
#include "SuperpoweredBandpassFilterbank.h"
#include "SuperpoweredSimple.h"
We could have used import instead of include for C++ code, too, but they are probably using include just to emphasize that it is C++ code. Looking at SuperpoweredBandpassFilterbank.h, we see that SuperpoweredBandpassFilterbank is a C++ class. It is used in Superpowered.mm by the Superpowered Objective-C++ class, see the filters member, which is a pointer to a SuperpoweredBandpassFilterbank object.
In the project you attempted to build, I see where the Superpowered interface is declared in the bridging header, but I don't see an implementation. The failure to #import SuperpoweredRecorder.h is due to SuperpoweredRecorder.h being a C++ header. The #include should be in your Objective-C++ (.mm) file, it's useless in the bridging header, since Swift can't make sense of C++ anyhow.
Hopefully this is helpful. Welcome to the world of C++.
I'm a bit surprised that you would have to provide prototypes of method.
I used Objective C libraries in my Swift project before and I only had to add the header files in my bridging header.
See example from my project. The bridging header contains just that:
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "QTouchposeApplication.h"
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#import <VungleSDK/VungleSDK.h>
I've been using a C++ library without problems on projects built with Xcode 3, but I'm now getting build problems on projects built with Xcode 4.
Drop the library into the Xcode 4 project and it builds fine, but as soon as I #include it, I get a "Lexical or Preprocessor Issue" error, more specifically " 'string' file not found, on line 4 of its main header file.
On closer inspection, the error specifies that 'string' file not found in ~/my project's directory/include/mainheader.h
I've tried the solutions listed here, but none worked.
So it thinks that header file is in my project directory, but it's obviously a C/C++ header… How can I tell Xcode to look for these C/C++ headers?
The problematic #include was at the top of my ViewController.mm, which I had already turned into Objective-C++ by giving it .mm as its extension. But ViewController.mm gets eventually imported by AppDelegate.m, which is Objective-C by default – and I had forgotten to make it Objective-C++, hence the problem.
So renaming AppDelegate.m to AppDelegate.mm solved the problem.
I think #include is a c++ class template..so you need to used using namespace std in your header file and also rename your source file .m format to .mm format.
it works for me :) try this...
I'm beginning to tear my hair out over this, so it's time to post here!
I have a C++ project in XCode, built as a Command Line Tool. All .cpp files have been renamed as .mm, there is one .hh and a few .h headers. I've specified 'Compile Sources As -> Objective-C++' in Build Settings.
I have another XCode project for an iOS app. This is set to 'Compile Sources As -> According to File Type'. I can't set it to compile everything as Objective-C++ since some parts of the project won't compile as Obj-C++.
There is one class in the iOS app where I wish to utilise my C++ project, and it consists of files MyClass.hh, MyClass.mm; they were simply .h and .m but I renamed them in the hope of remedying this problem.
I dragged my cpp project into the iOS project. I then added a Target Dependency in the iOS Build Phases to point to the cpp CLI application.
In MyClass.hh I have
#include "../path/to/CppProject/ImportAll.h"
..which is a header file that successively 'include's all headers from the cpp project. I then go about my business, creating one property within MyClass.hh which is a pointer to a cpp object, and various references within MyClass.mm to cpp classes.
The darn thing just won't compile though - I get a ton of messages relating to my cpp classes like this:
MyCPPFile.h:10: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
Is the compiler not recognising that MyClass.hh is Objective-C++ not Objective-C? Should I have a target dependency which is a library instead of pointing to this CLI app, perhaps?
I've googled around for a while trying to solve the problem. I've seen references to people using
#ifdef __cplusplus
or else having to rename files to .mm to get things working, but in other cases people simply say they drag and drop projects across with no issues.
Can someone please enlighten me, and explain what key steps I should be performing to make this work? I'd be very grateful! Thank you.
Thanks to everyone who gave me suggestions.
Having created my projects anew from scratch, I fiddled and logic-ed my way to the solution. Note that - at least in my case - no use of #ifdef __cplusplus was required, nor any other preprocessor directive. Only file suffix changing is essential (as detailed below).
Here's the process:
Create C++ Static Library and Include/Link with Objective-C Library (e.g. iOS app) in XCode 4:
In XCode 4 create a New Project of type Cocoa Touch Static Library. Hereafter we shall refer to this project as 'CProj'.
In CProj workspace create/import as many C++ classes as required. No special suffix for filenames is necessary - all my files are .h and .cpp.
In XCode create/open any Objective-C project e.g. iOS app. Hereafter we shall refer to this project as 'ObjProj'.
Find CProj.xcodeproj in Finder (typically /Documents/CProj/CProj.xcodeproj), drag it onto the visible ObjProj project icon at the top of your XCode Project Navigator (visible file/folder hierarchy on left side in XCode). This now places CProj as a nested project within ObjProj.
Left click ObjProj project icon in Project Navigator, a new pane emerges to the right, left click Build Phases in this pane.
Under Target Dependencies click '+' icon and select CProj library icon below listed CProj project. Click OK.
Under Link Binary With Libraries click '+' icon and select CProj library icon from within Workspace collapsible folder at top of window presented.
File Renaming Rules
Where including a CProj header in ObjProj, use path backtracking to identify import, e.g. #include "../../MyProj/MyImport.h" to step 2 dirs backwards then step into MyProj folder.
Any ObjProj implementation file including a CProj header must be renamed from .m to .mm . Any ObjProj header file including a CProj header must be renamed from .h to .hh .
Any ObjProj file including a file whose suffix is now .hh (consequence of step above) must be renamed in the same manner.
An example:
Consider you have files A.h, A.m, B.h, B.m.
A.m imports B.h, and B.h includes one or more CProj headers. B.m includes type references, using CProj classes included via B.h .
First renaming is B.h -> B.hh since it contains includes.
Then B.m -> B.mm since it contains type references to CProj (no includes necessary since B.h has already done them).
Then A.m -> A.mm since A.m which contained an include for B.h now has an include for the renamed file, B.hh .
P.S. Note that the C++ library doesn't like to auto-rebuild when it should - I often have to 'Clean' then 'Build' in ObjProj after updating CProj from within it.
It sounds like the crux of your problem is this:
Is the compiler not recognising that MyClass.hh is Objective-C++ not
Objective-C?
The compiler is not recognizing that MyClass.hh is Objective-C++ code. Or any other code; the compiler never sees MyClass.hh (in all likelyhood).
By convention, header files are never passed to the compiler by default. Only the source files (.cpp, .m, et cetera) are -- the preprocessor that is run on those files results a translation unit that contains the original source file plus all the included headers and resolved macros.
So the problem is that you probably have a .mm source file that imports MyClass.hh, which in turn includes the C++ header file. But the compiler is trying to compile the resulting translation unit as Objective-C++ and encountering some C++-specific stuff in that header. In fact, I suspect that this problem has nothing at all to do with the additional target dependencies and such that you've got set up: I think you could reproduce it minimally with a very simple Objective-C++ application that includes the header. You should try that and see, it will either confirm my theory (after all I'm just speculating since you haven't shown enough source for me to know for sure) or indicate that the problem is elsewhere.
The solution is probably to use preprocessor guards like #ifdef __cplusplus (there's a useful catalog of predefined symbols here) to hide the C++-specific code from the Objective-C++ compiler (or the other way around in some cases). Note that this may be difficult to impossible to do based on the actual content of the header.