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.
Related
I am looking for a way to easily define macros / preprocessor directives at project build/cook time for an Unreal Engine project.
For example, if I want a defined C++ macro MY_BUILDTIME_VAR to be 0 in certain builds, and 1 in others, without having to modify source code every time, in a similar approach to environment varibles in many tools (i.e. NODE_ENV in node.js), or to the command-line approach of i.e. g++ (see here).
I am aware it's possible to define target-wide macros in a project's target.cs with GlobalDefintions.Add("MY_TARGET_VAR=0") or module-wide macros in a module's Build.cs with PublicDefinitions.Add("MY_MODULE_VAR=0"). It helps to have all things defined in one place, but those definitions are still baked in the source file, and can't be changed at build time.
The official documentation mentions several ways of building/cooking an Unreal project with custom parameters, such as the Project Launcher tool and the RunUAT script file. Do any of them allow for build-time macro definitions?
Note: I am not using MS Visual Studio, but JetBrains Rider with .uproject only, so I can't define them in an .sln solution file.
Use an environment variable and read it in your build.cs file. Based on the environment variable set the value of your macro.
This is a handy utility method I use for this purpose:
private void AddEnvironmentVariableDefinition(string variableName, string defName, string defaultValue = "0")
{
string value = System.Environment.GetEnvironmentVariable(variableName) ?? defaultValue;
PublicDefinitions.Add(String.Format("{0}={1}", defName, value));
}
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).
I am trying to use the OutDir Macro from the Project properties within my c++ file to build a path.
But I can't find a way to assign the OutDir content to a variable in my code.
I tried this:
#define OUTPUT_DIR $OutDir
I can't seem to use this correctly.
You can specify pre-processor definitions in the "Project Properties->C/C++->Preprocessor->Preprocessor Definitions" list as:
OUTPUT_DIR=$(OutDir)
and then you can use that macro in your source code. You may need to textify it first. i.e.
#define TEXTIFY(x) #x
then use it as
TEXTIFY(OUTPUT_DIR)
see this answer. Although looking at this answer, it is possible that VC++ 2017 has some issues with this.
I believe you can also add the quotes into the options itself which might be a way round it.
OUTPUT_DIR="$(OutDir)"
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.