Vscode-cpptools: macOS framework support for IntelliSense

Created on 12 Aug 2017  ·  23Comments  ·  Source: microsoft/vscode-cpptools

Feature Request for macOS

Please consider supporting the finding of include files in macOS frameworks, where the include files are located together with libraries inside framework bundles.
Compilers on macOS have built-in support for frameworks.

An example based on the Qt Core framework:

QtCore.framework/
  |── Headers -> Versions/Current/Headers
  |── Resources -> Versions/Current/Resources
  └── Versions
    |── 5
    |   |── Headers
             ...
             qiodevice.h
             QProcess.h
    |  └── Resources
    └── Current -> 5

The file QProcess.h has include directive #include <QtCore/qiodevice.h>, and it is impossible to define the macOS includePath in a way that IntelliSense would find the included header.

Additional links on the framework bundles:
https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html#//apple_ref/doc/uid/20002253-99920-BAJFEJFI
http://blog.bfitz.us/?p=1793 - see chapter Frameworks (NeXT/Mac OS X)

Feature Request Language Service fixed (release pending)

Most helpful comment

Since there was no clear winner, we decided to support both options. So you can specify the framework include path either way and we'll accept it.

All 23 comments

I am experiencing the same exact problem with IOKit and other macOS frameworks, it would be very nice to support intellisense.

I think you can work around the issue by creating a symbolic link with the same name as the framework or header path name (e.g. QTCore) and then add a path to that file to includePath. Are you able to get that to work?

Yes, it is possible to use this kind of work-around.
However I do not think this is a permanent solution since a lot of Apple's and third party frameworks are packaged this way, and I am not willing to touch system framework bundles.
I personally will use XCode if I develop applications using macOS frameworks, which is a shame since XCode's UX is horrible compared to VS Code.

We plan to add better support for frameworks. It won't make it into the 0.12.3 release, but the plan is to have it in the next one.

That's great!
If I can help with something (testing for example), please let me know.

We plan to add better support for frameworks. It won't make it into the 0.12.3 release, but the plan is to have it in the next one.

That would be awesome, for now I'm sticking with CLion but today I was very surprised by the effort you are putting into C++ support in VSCode.

Quick question for those following along. We are considering two different options for letting you specify the framework paths. Which option best matches how you would expect it to work? Please respond with your vote.

Option 1 - just put it in the "includePath" with all the other paths

        {
            "name": "Mac",
            "includePath": [
                "/System/Library/Frameworks",
                "${workspaceRoot}"
            ],
            ...
        }

or

Option 2 - create a new property for it (which is only evaluated on Mac systems)

        {
            "name": "Mac",
            "includePath": [
                "${workspaceRoot}"
            ],
            "frameworksPath": [
                "/System/Library/Frameworks"
            ],
            ...
        }

I prefer option 1.

I prefer option 2

I prefer option 1, to keep the configuration properties at the minimum possible.

Don't really care, both would solve the problem for me. For example gcc and ld have special option "-framework", so solution 2 would be OK as well.

This is about how the voting turned out among the people I asked here at Microsoft. :smile:

I personally lean toward option 1, but wanted to make sure that it wouldn't be confusing for people before committing to that design. I don't like the idea of a property that only applies to one platform (option 2), but I can understand that people might want to think about frameworks as a separate entity because of how you have to craft the command line for the compiler. In the same breath, there may be people who are less familiar with the command line because of IDE's and tools that do this for you and therefore they think of this as simply another path that serves to resolve #include statements, and is therefore just an "includePath"

Does anyone think that the absence of a specific property to declare your framework paths would leave people guessing as to where to put them? Or do you think they would instinctively try the includePath first before having to search the Internet for answers?

I would probably start typing "framew...." side by side the to "includePath" in the json file hoping that intellisense would popup something meaningful.
That's actually what I have been doing before searching the internet and finding this issue 😄

Since there was no clear winner, we decided to support both options. So you can specify the framework include path either way and we'll accept it.

The fix for this is in 0.12.4. The new property in c_cpp_properties.json is called "macFrameworkPath" and it should be auto-added to your c_cpp_properties.json file when you open your folder on a Mac. Let us know if you have any trouble with it.

I just realized that we didn't send the paths through our variable resolver, so ${workspaceRoot}, ~, and environment variables don't work with these paths yet, but we'll fix that for the next release.

Unfortunately this feature seems to not work on my side,

As you can see i tried different things, put the root folder or frameworks/headers directories directly.
The result is always the same.

If i switch "fuzzy" mode on & off the result is the same (well in fuzzy mode it's underlined in green with a message telling to update includePath). Did I miss something ?

OSX 10.14.3
VSCode 1.32.3
CPP Tools 0.21.0

@jbltx You should remove the .framework folders from the "includePath" (i.e. only use the ${workspacefolder}. But your configurationProvider is set to cmake-tools, so you might try removing that if it was unintentional.

@sean-mcmanus I just deleted all paths in includePath but ${workspacefolder} and the same error appears. I also deleted the configurationProvider but doesn't change anything. I use CMake tools extension to build Ninja projects inside VSCode directly.

@jbltx If you're using the "Tag Parser" intelliSenseMode then you may need to copy the framework path to the browse.path setting....otherwise this could be a bug should investigate (i.e. I could move it to a new issue). We're about to release 0.22.0, but this scenario isn't expected to have changes.

I am not using Tag Parser right now, here are my settings :

 "C_Cpp.intelliSenseEngineFallback": "Disabled",
 "C_Cpp.errorSquiggles": "Disabled",
 "C_Cpp.intelliSenseEngine": "Default",

Finally I think there's something different between putting manually the path of headers and confirming the suggestion given by tool. In fact when I did it manually, errors still there, but using the suggestion the error has disappeared :

As you can see it suggests the real path (not the symbolic link of Headers directory). The fun part is, if now i edit this path in the settings with my previous path put manually, or something even more global like :
"/Users/mickaelb/dev/libs/Qt/5.12.2/clang_64/lib/**"

... Well, no error appears no more 🤔

Based on what I see in the picture you showed above, the correct way to include QMainWindow is:

#include <QtWidgets/QMainWindow>

When the compiler resolves frameworks, it trims the part of the path from .framework to Headers. The bug here is that the extension is suggesting the raw path to the header, but it should be suggesting you fix the way you include it. I'll update the bug @sean-mcmanus created to track this issue.

Though looking back at the original error, it seems the extension should have picked up the dependency. I'll have to try this out on my mac tomorrow. But let's move the conversation over to #3323 since this issue is closed.

Was this page helpful?
0 / 5 - 0 ratings