I know it is possible to add defines for Visual Studio Code in c_cpp_properties.json and I manually define __GNUC__ for my code, but is it possible to undo/remove defines that Visual Studio Code assumes for itself? For example if I set intelliSenseMode to clang-x64 the macro __clang__ is defined which completely destroys my intellisense because I don't have appropriate include files for libraries I use and include selection for __clang__ happens before __GNUC__. Same for msvc-x64 value. If I manually #undef __clang__ in my include files then everything is perfect.
Is it possible to undo macro in Visual Studio Code configuration?
Yes
First, create a header file called, say, vscode-preinclude.h. Put it anywhere; I'll assume it is in the workspace folder (the one that also has .vscode in it). Inside that file use #undef to undefine the symbols you need turned off. Example:
#undef __clang__
Next, use the Command Palette (Ctrl+Shift+P) and open "C/C++: Edit Configurations (UI)". Go down to the bottom and open "Advanced Settings". Scroll down to "Forced include", and add a line:
${workspaceFolder}/vscode-preinclude.h
That's it!
Troubleshooting
If it doesn't work, take a look at the output of the "C/C++: Log Diagnostics" command. It should show something like:
Forced Includes:
D:\WRK\LEARN\VSCODE\CPPHELLO\VSCODE-PREINCLUDE.H
in its output.
If you don't want the C++ extension to auto-configure your system includes & defines, you can set "compilerPath": "" for your configuration in your c_cpp_properties.json and the extension will stop auto-configuring you.
Related
When using the "Default" intellisense engine, some of the symbols in my C++ project cannot be resolved. It turns out that it's because they are in headers where they are guarded by an #ifdef that depends on a macro passed to gcc with the -D flag by the makefile. How can I tell the intellisense engine about these defines so that it is able to compile those parts of the header?
Project makefile defines are set in .vscode/c_cpp_properties.json.
"configurations": [
{
...
"defines":[
"MYSYMBOL",
"MYVALUE=1"
]
}
], ...
Here are some methods to open c_cpp_properties.json:
Find a green squiggle on something like an include statement that Intellisense can't resolve. Hover around and click the lightbulb that appears (which is tiny and a bit of a game to click). It will open the project config file in the editor.
Same as above, but put cursor on the green squiggle line and press Ctrl+..
Use the command pallet: ctrl+shift+P, then select C/C++: Edit configurations (JSON).
If the file already exists in your .vscode folder, open it with File->Open.
Although vscode will reprocess the settings after c_cpp_properties.json is modified, I found a restart is sometimes required when changing values.
There is basic and incomplete information here: https://code.visualstudio.com/docs/languages/cpp
This is a good link about the c_cpp_properties.json file itself: https://code.visualstudio.com/docs/cpp/c-cpp-properties-schema-reference
The other answers so far have two issues that don't seem trivial to fix:
There might be times where different source files need different compiler flags.
It could be painfully tedious to manually figure out what compiler flags are necessary and manually add them.
Luckily, VS Code's C/C++ extension supports a compile_commands.json database. This stores information specific to every individual source file including the defines, include directories, and other compiler command line flags. I just posted a more detailed description of how to generate one and get VS Code to use it over here: https://stackoverflow.com/a/59618515/12663912
This capability has now been added: https://github.com/Microsoft/vscode-cpptools/issues/304
you can set "defines" in your c_cpp_properties.json file
After following the advice in this thread I still couldn't get vscode to recognise the macros I'd defined in c_cpp_properties.json.
Turns out, if you're using the CMake extension for vscode and have the "all" target selected then any macros you've defined in your CMakeLists won't be recognised, nor will any in the c_cpp_properties.json. It was as straightforward as selecting a target to build from the status bar and intellisense was able to pick up any macros defined for that target. No need for the c_cpp_properties.json.
I need to conditionally compile C++ source files based on either environment variables or other input parameters. Is there a mechanism in VS2019 to do this?
This solution works with VS2017 but I don't know of any reason why it wouldn't also work with VS2019.
You can "import" environment variables as preprocessor definitions. In your Visual Studio project's properties go to Configuration Properties -> C/C++ -> Preprocessor. Click in the Preprocessor Definitions field, hit the down arrow at the far right and select Edit.
Here, you can add preprocessor definitions that include environment variables. Each line represents a definition with the notation [name]=[value] which defines a preprocessor definition named [name] which will be substituted by [value]. Environment variables should be wrapped in a $() to be resolved. So, for example, to import the environment variable MY_ENV_VAR you would add the definition MY_ENV_VAR=$(MY_ENV_VAR). If MY_ENV_VAR had say 5 at the time of compilation, this definition would be equivalent to having a #define MY_ENV_VAR 5 available across the project.
In your source file, you can then wrap your code with a #if/#endif guard to conditionally compile that code. Using the same example, to only compile a source file if MY_ENV_VAR is exactly 1, you would write :
#if MY_ENV_VAR == 1
// Entire source file
#endif // #if MY_ENV_VAR == 1
Note that environment variables are loaded when Visual Studio launches. You may need to restart Visual Studio if you want recent changes to the environment variables to be visible.
This can actually be accomplished directly by editing the project's .vcxproj file by adding a "Condition" attribute to the CLCompile element for the file in question.
Note that if you do add a Condition attribute then change the properties specifically for that file VS may remove the attribute (I am not sure whether VS does so or not, but it is something to keep in mind).
This question already has an answer here:
Hide a C++ code block from Intellisense
(1 answer)
Closed 3 years ago.
Is it possible to have a macro be set to true when building but otherwise is set to false? I realize there are macros to detect build configurations (e.g. debug/release) but I am looking for a macro that is set when the compiler starts building. It's okay if the macro is very specific to a particular compiler.
The use case is to help intellisense with some complex macros by simplifying them. The autocomplete does not work with the complex macros. However the simplified macros are very slow at runtime.
This one would probably work:
#define ONLY_TRUE_AT_COMPILE_TIME true
You can set a macro in your IDE and don't use it in the build process
#ifdef IDE_MACRO
#define SIMPLE_MACROS
#else
#define COMPLEX_MACROS
#endif
In Visual Studio Code you can set
"configurations": [
{
...
"defines":[
"IDE_MACRO"
]
}
]
in
.vscode/c_cpp_properties.json
defines A list of preprocessor definitions for the IntelliSense engine
to use while parsing files. Optionally, use = to set a value, for
example VERSION=1.
This only works if compileCommands is not set
compileCommands (optional) The full path to the compile_commands.json
file for the workspace. The include paths and defines discovered in
this file will be used instead of the values set for includePath and
defines settings. If the compile commands database does not contain an
entry for the translation unit that corresponds to the file you opened
in the editor, then a warning message will appear and the extension
will use the includePath and defines settings instead.
As you can read in the quote you can also use compile_commands.json to set macros and IntelliSense will consider them.
In Eclipse CDT it's in C/C++ Build -> Build Variables. There you can set a Variable IDE_MACRO. Now Eclipse CDT uses SIMPLE_MACROS instead of COMPLEX_MACROS. In the build process the macro IDE_MACRO is not defined and the compiler uses COMPLEX_MACROS.
When using the "Default" intellisense engine, some of the symbols in my C++ project cannot be resolved. It turns out that it's because they are in headers where they are guarded by an #ifdef that depends on a macro passed to gcc with the -D flag by the makefile. How can I tell the intellisense engine about these defines so that it is able to compile those parts of the header?
Project makefile defines are set in .vscode/c_cpp_properties.json.
"configurations": [
{
...
"defines":[
"MYSYMBOL",
"MYVALUE=1"
]
}
], ...
Here are some methods to open c_cpp_properties.json:
Find a green squiggle on something like an include statement that Intellisense can't resolve. Hover around and click the lightbulb that appears (which is tiny and a bit of a game to click). It will open the project config file in the editor.
Same as above, but put cursor on the green squiggle line and press Ctrl+..
Use the command pallet: ctrl+shift+P, then select C/C++: Edit configurations (JSON).
If the file already exists in your .vscode folder, open it with File->Open.
Although vscode will reprocess the settings after c_cpp_properties.json is modified, I found a restart is sometimes required when changing values.
There is basic and incomplete information here: https://code.visualstudio.com/docs/languages/cpp
This is a good link about the c_cpp_properties.json file itself: https://code.visualstudio.com/docs/cpp/c-cpp-properties-schema-reference
The other answers so far have two issues that don't seem trivial to fix:
There might be times where different source files need different compiler flags.
It could be painfully tedious to manually figure out what compiler flags are necessary and manually add them.
Luckily, VS Code's C/C++ extension supports a compile_commands.json database. This stores information specific to every individual source file including the defines, include directories, and other compiler command line flags. I just posted a more detailed description of how to generate one and get VS Code to use it over here: https://stackoverflow.com/a/59618515/12663912
This capability has now been added: https://github.com/Microsoft/vscode-cpptools/issues/304
you can set "defines" in your c_cpp_properties.json file
After following the advice in this thread I still couldn't get vscode to recognise the macros I'd defined in c_cpp_properties.json.
Turns out, if you're using the CMake extension for vscode and have the "all" target selected then any macros you've defined in your CMakeLists won't be recognised, nor will any in the c_cpp_properties.json. It was as straightforward as selecting a target to build from the status bar and intellisense was able to pick up any macros defined for that target. No need for the c_cpp_properties.json.
What I mean is, in each of my source files I have to insert #define NOGDI to stop windows.h from including GDI defines (since it's BITMAP define conflicts with mine).
e.g.
#define NOGDI
#include <windows.h>
Unfortunately, I have to do this in every seperate source file which includes windows.h, which I do not want to do.
I am using Visual Studio 2005, is there any way I can set it to #define something globally? (i.e. in all of the source files).
Project Settings -> C/C++ -> Preprocessor -> Preprocessor definitions
Here you can define symbols that are applied globally to all source code in your project.
I had set up the needed define for whole project, as described, in
Project Settings -> C/C++ -> Preprocessor -> Preprocessor definitions
But nevertheless this didn't work!
Eventually it turned out that problem was in checked NoInherit checkbox,
"Inherit from parent or project defaults"
In defines' line of Preprocessor Definitions Dialog it's seen as:
WIN32;_DEBUG;_WINDOWS;_MBCS;$(NoInherit)
Checked the thing back and the define finally recognized.
For VS2015 I edited the .vcxproj file and added a section such as this:
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>MY_VARIABLE=SOMETHING</PreprocessorDefinitions>