How to make VS Code IntelliSense work with `.mm` file extentions? - c++

When I change the file extension from .cpp to .mm IntelliSense and Go to definition stops working. How can I set it up to with .mm files as well?

If all you want to do is association of .mm files with C++, you merely need to add this association in .vscode/settings.json file of your project:
{
...
"files.associations": {
"*.mm": "cpp",
...
},
}
Be advised that VSCode is actually able to differentiate Objective-C and Objective-C++ languages. And if you alter the default association, VSCode will drop (possible) support for the language. (however to my knowledge there is no a viable language-server extension for Objective-C/Objective-C++)

Related

vscode plugin for c++ auto add include header

I am looking for a visual studio code's plugin for c++ has feature that auto complete/add include header when writing code. Any suggestion?
Actually, there isn't any extension like what you exactly want, but you can create your own desired option without any extension and only using USER-SNIPPETS. To do this:
open visual studio code > File > Preferences > User Snippets : here you can create a new user snippets file or use an existing one, if you are new you might don't have any hence create a fresh one(make sure it is for c++), then put your desired snippets, here's mine as an example:
"Add iostream & string": {
"prefix": "#include",
"body": [
"#include <iostream>",
"#include <string>",
""
],
"description": "Add iostream & string"
}
after whenever you type #inc in a .cpp file a snippet will be shown for you and you can accept that.
but if you mean what Deepak Punjabi said, considering that c++ has a huge amount of libraries it isn't actually intellectual to do such a thing. searching a huge huge bunch of libraries to just include a header. the feature you are looking for somehow is a compiler feature which some languages like python meet the needs better.
Does not find any plugin that supports auto add #include header files. However , there's one plugin [Include What You Use][1] may help optimize the include files.
The main goal of include-what-you-use is to remove superfluous #includes. It does this both by figuring out what #includes are not actually needed for this file (for both .cc and .h files), and replacing #includes with forward-declares when possible.

How to use Superpowered lib in Swift project

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>

Xcode and C++ Headers

I have a question about using C++ header files in Objective-C++ modules in Xcode. Specifically, why can I #include them in source files but not header files?
Here is a specific example.
I'm using Xcode 7.2.1 and have two projects. The first is a C++ framework I package into "myFramework.framework". It exposes "myFramework.h", which in turn pulls in "myLib.h". At the top of "myLib.h" is an "#include <string>".
The second project is an Objective-C iOS app which consumes the above framework. In this project, "myViewController.mm" (Objective-C++ source) has "#import "myFramework/myFramework.h" at the top and makes reference to things defined in that header file.
At this point all is well and good. It builds and runs with no issues.
When I move the "#import myFramework/myFramework.h" line to "myViewController.h", the compile fails because it cannot locate the "" header dependency.
It doesn't matter if I change the file type for "myViewController.h" to Objective-C++ header from plain old "C Header". Either way, Xcode's header search paths don't look for standard C++ headers.
So my main question is why does it behave this way? Why is a #include/#import treated differently just because it's in a header file?
My second question is if there's some way to make Xcode treat the #include/#import the same when it's in the header file instead of the source file?
Thanks much!
Are you sure that you get the error while compiling the myViewController.mm file?
Check if myViewController.h is imported into some other, non ObjC++ file (and that that one is the file that fails to compile).
I suspect the issue with including C++ headers inside other headers is that an Objective-C source file gets to see the C++ header file, which upsets it.
If you have mixed C++/Objective-C++/Objective-C then you are probably better off only exposing a pure Objective-C interface to other modules in the project and include any C++ header files in the Objective-C++ source files only.
Alternatively make everything Objective-C++ and then you don't need to worry about it at all.
Hopefully this answers your second question as well.

Compiling .cpp file as Objective-C++ via binding.gyp when building Node.js/Node-webkit addons

I have an preexisting C++ static library that I am porting over to be compilable as an addon for Node.js / Node-webkit. To build this addon I am running node-gyp / nw-gyp on a binding.gyp file I have created. This static library is multiplatform, and compiles for Windows, Mac, and Linux via VisualStudio, Xcode and CMake, respectively. This static library is already used in a variety of applications (read, it is likely not going to be refactored just for this one case of addon compilation - which is still in the proof of concept phase).
All of the crossplatform C++ files have the .cpp file extension, even though some of them are actually compiled on Mac as Objective-C++ (so as to leverage some Cocoa niceties). In Xcode on Mac, I am able to compile such .cpp files as Objective-C++ by switching the 'type' for the file from 'Default - C++ Source' to 'Objective-C++ Source' in the 'File Inspector'. This is convenient as I am able to have the self-same file compile as C++ on Windows/Linux and Obj-C++ on Mac, regardless of the .cpp file extension. To build the addon, I am using the ObjectWrap paradigm. In order to wrap the Objective-C++ classes I must include their .h files, which forces the Objective-C++ scenario at the addon level.
I am rather new to using node-gyp and nw-gyp. Is there any additional qualifiers I can add to my binding.gyp file to explicitly denote that a given .cpp file should actually be compiled as Objective-C++, similar to the 'type' setting in Xcode I mentioned above? As an interim step while building out a proof of concept, I am successfully able to get .mm files to compile as Objective-C++. However as also alluded to above, many of these files are actually multiplatform and should compile as straight C++ on Windows/Linux once I move my proof of concept onto the other platforms, and so I would much prefer they keep the .cpp file extension.
To compile all .cpp files as Objective-C++ add the following to binding.gyp:
'conditions': [
['OS=="mac"', {
'xcode_settings': {
'OTHER_CFLAGS': [
'-ObjC++'
]
}
}]
]
If you need to compile only some .cpp files as Objective-C++ create a .mm file that only includes the .cpp files that should be compiled as Objective-C++. In binding.gyp use conditions to compile the .mm wrapper file or the .cpp files depending on the platform.
In file.mm:
#include "file.cpp"
In binding.gyp:
'conditions': [
['OS=="mac"', {
'sources': [
"file.mm"
]
}],
['OS=="win"', {
'sources': [
"file.cpp"
]
}]
]

cpp compilation issues in iOS project

I have added some objective C files and c++ files to an existing iOS project. When I import a .h file of a .mm file into a .h file with a corresponding .m file I get all kinds of errors.
When I change the .m file of the .h file importing the new code to .mm I then get the same previous errors but with new errors regarding the new .mm file.
Im not really sure how to fix this.
I am using ARC if this has any effect.
It complains about namespace (unknown type), also Unknown name issues with an imported .mm file, expected expression error on a statement containing :: in a .h file of a .mm file. What I dont get is that these files work correctly in the project I copied them over from. I only took the source from the project. And have added header search paths to the directory. I also selected create references to the added directories option.
For some reason the files arent in the compile source section, and when I try to add them, the file selector tree doesnt contain these source files I added. The added directory is also blue instead of yellow, but empty.
As you know, C++ code can only be used from .mm files. When the compiler complains about namespace being an unknown type, it typically means that the Objective C compiler is being used when the Objective C++ compiler should be used. More simply: you have a .m file that needs to be a .mm.
Speaking generally, there are two options you can pursue. Every time an Objective C file complains, change it to a .mm. This is a slippery slope, and generally results in your entire project cascading into a giant ball of Objective C++. The other option is to quarantine the C++, so that only a bare minimum of your Objective C files need the .mm extension.
Obviously, the latter is the better choice. The likely cause of the confusion is #importing a header file that contains C++ code from elsewhere in your app that doesn't actually require C++. If the C++ is an implementation detail of an Objective C class, you can try to keep the C++ out of the class' header file by leveraging Class Extensions. Otherwise, you can create an Objective C class whose only purpose is to wrap the C++ in its own implementation, while exposing a clean header file for other classes to consume.
Basically, If you can keep your headers clean, then you won't have to worry about accidentally indirectly #importing some C++ into an unsuspecting compilation unit.