Vscode-cmake-tools: support target based cpptools configuration for source files

Created on 13 Feb 2020  路  16Comments  路  Source: microsoft/vscode-cmake-tools

As discussed with @bobbrow I would like to rise a feature request. I'm currently working on a project where multple targets use the same source file. Doing this, cpptools doesn't get proper information to configure IntelliSense and is not able to resolve preprocessor directives based on the selected target.

configure cpptools integration bug fixed (release pending)

All 16 comments

Thanks for opening the issue. I linked it to a PR that should address this problem.

@bobbrow Is this the same issue that I opened a while ago, but got moved out of this project into cpptools? https://github.com/microsoft/vscode-cpptools/issues/3960

@ghuser404, your issue was about header files. This one is about configurations for source files (translation units).

I would say that this issue could achieve that behavior in some scenarios if the source files in question are from different targets, but we interpreted the issue you linked as a more general case that cpptools would need to address.

Your issue is interpreted as follows:
I have a.cpp and b.cpp open in the editor and they are both part of the same target. They both include foo.h which is also open in the editor. foo.h has something like:

#if defined(_INCLUDED_FROM_A_CPP_)
  // do something
#elif defined(_INCLUDED_FROM_B_CPP_)
  // do something else
#endif

cpptools assigns a header file to a single translation unit when it is first opened in the editor. There is no way to change that currently so long as a.cpp and b.cpp are both open in the editor. The way to achieve your scenario before we fix it requires you to close all additional translation units that reference your header file so that we can reassign it to an active translation unit. (e.g. if foo.h was assigned to a.cpp, then close a.cpp and we will reassign foo.h to b.cpp when a.cpp's translation unit is destroyed)

When we address the issue you've opened, you'll be able to assign foo.h to the translation unit at any time. This issue would compliment yours in the event that a.cpp is included in multiple targets and compiled differently each time, but you would still need to change the active target to apply the configuration that you need for the header file.

(@ghuser404, you can check the current assignment of header files by running the C/C++: Log Diagnostics command and looking in the "Translation Unit Mappings" section.)

@bobbrow That's a lot of useful information, thanks!

I also have a somewhat related question. Is it possible for CMake Tools to stop vscode being confused by multiple header definitions? If I go-to-definition of a header from a source/header file, vscode sometimes says that there multiple definitions of such header, and I have to manually select which one I think is used. Does cpptools provide such API that CMake Tools could potentially use? Surely, CMake Tools knows what #include <algorithm> will resolve into during build?

Edit: for some reason I though CMake Tools wasn't passing some information onto cpptools. But I think cpptools has all the information (all include paths), and it could just show definition from a correct header file (AFAIK, the first that it encounters). Is my understanding correct?

@ghuser404 let's talk about that in a new issue so we don't lose track of it. Please head over to #1135 and we'll discuss it there.

@ghuser404 Go to Def on headers is fixed with https://github.com/microsoft/vscode-cpptools/releases/tag/0.28.0-insiders .

CMake Tools 1.4.0 Beta is available on GitHub.
https://github.com/microsoft/vscode-cmake-tools/releases/tag/1.4.0-beta

Please try it out and let us know if you encounter any issues.

This fix is available in CMake Tools #1.4.0 which has been released.

@andreeis How does the extension decide which target is active when [all] target is selected? Can I see the actual active target somehow?

Anyone can answer the above question?

If you are using the "icon" mode for the status bar, then you won't be able to see it there. You should always be able to see it in the outline view though. The rocket is the debug/launch target and the hammer is the build target. If the emojis aren't there, then the target is not set. [all] can only be selected as a build target.

image

~Ahh, so IntelliSense depends on the debug/launch target. I didn't realise that, thanks a lot! PS. Not using "icon" mode [yet], just a bit confused.~

I'm not sure I understand what you mean. IntelliSense is not related to this. The current debug/launch target only determines which binary is launched when you click the "debug" icon.

The only setting from CMake Tools that matters for IntelliSense is the active Kit (e.g. the C and CXX compiler or toolchain file). And this will actually only affect IntelliSense if you enable CMake Tools as the 'configuration provider' (use the "C/C++: Change Configuration Provider" command to set it). This allows the C++ extension to configure IntelliSense for your files based on the information in your CMakeLists.txt instead of manually setting it with the c_cpp_properties.json file.

Alright, I've just got to my PC and tested this, and yes, that doesn't answer my question, sadly.

Let me try to explain. So this issue is about showing correct IntelliSense depending on what build target is currently active. Consider the following files:
CMakeLists.txt

cmake_minimum_required(VERSION 3.11)

project(Test)

add_executable(test1 main.cpp)
target_compile_definitions(test1 PRIVATE OK=1)

add_executable(test2 main.cpp)
target_compile_definitions(test2 PRIVATE OK=2)

main.cpp

int main()
{
    int ok = OK;
    return 0;
}

If I select test1 as build target and hover over OK in main.cpp, I'll see 1 - if I select test2 as build target and hover over OK in main.cpp, I'll see 2. However, if I select ALL_BUILD as build target, it will show either 1 or 2, depending on which it thinks is the current build target. So my question was how does it decide for which build target to show IntelliSense when ALL_BUILD is selected?

I understand now. The answer is that this is currently non-deterministic. The extension doesn't do anything for this case and is subject to the order in which information is received from CMake or processed. If you want a specific configuration for IntelliSense based on a specific target, then you need to select that target.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

amigo421 picture amigo421  路  3Comments

decimad picture decimad  路  6Comments

gabyx picture gabyx  路  5Comments

andschwa picture andschwa  路  6Comments

retifrav picture retifrav  路  5Comments