Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tools for Integrating Gamer with VS Code #382

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions doc/wiki/Developing-with-VS-Code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Developing Gamer with Visual Studio Code

This guide provides step-by-step instructions on how to set up and use Visual Studio Code (VS Code) for developing the Gamer codebase.

## Setup

### Prerequisites

- **Quick Start**: Follow the instructions in the [[Quick Start | Quick-Start]] guide to download Gamer and do at least one [[demo | Quick-Start:-1D-Shock-Tube]].
- **Visual Studio Code**: Download and install from [https://code.visualstudio.com/](https://code.visualstudio.com/).
- **C/C++ Extension**: Install the "C/C++" extension from the VS Code Marketplace.

### Setting up the workspace

1. **Launch VS Code**.
2. **Open the Gamer Project Folder**:
- Go to `File` > `Open Folder...`.
- Select your Gamer project directory.

### Disabling auto-formatting

To disable auto-formatting in VS Code, add the following to your `settings.json`:

Access `settings.json` by navigating to `File` > `Preferences` > `Settings`, then search for `C_Cpp.formatting` and set it to `"disabled"`.

### Configuring VS Code to integrate with Gamer

Run the following script from the root directory of the Gamer project:
```bash
sh tool/vscode/copy_to_vscode.sh
```
This script copies the necessary configuration files to the `.vscode` directory, integrating Gamer with VS Code. This script will ask you to enter the working directory under `bin/` where the executables are located. These paths of working directories are located in the `launch.json` and `tasks.json` files.

## Developing with VS Code

### Run build task

After configuring Gamer with [configure.py](https://github.com/gamer-project/gamer/wiki/Installation%3A-Configure.py), select `Terminal` > `Run Build Task...` or press `Ctrl + Shift + B` to start the build task. This will update the macros, providing IntelliSense highlighting support.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that debugging with parallel at vscode is difficult (not only mpi, but also openmp). Should we remind to disable mpi and openmp here?

Copy link
Contributor Author

@technic960183 technic960183 Jan 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a note for the macOS users. But have not provide an explicit solusion yet.


Note: To make sure the debugger works correctly, ensure the compiler flags in `Makefile` are set to `-g -O0`. (TBD: Add a argument to `configure.py` to set the flags.)

### Start debugging

To start debugging Gamer, select `Run` > `Start Debugging` or press `F5`. This will launch the debugger. See the [official documentation](https://code.visualstudio.com/docs/editor/debugging) to learn more about debugging with VS Code.

## Understanding Configuration Files

These are the configuration files that are copied to the `.vscode` directory:
- `c_cpp_properties.json`: Configures IntelliSense settings, including include paths and macros. See the [official documentation](https://code.visualstudio.com/docs/cpp/c-cpp-properties-schema-reference) for more information and the [document of IntelliSense](https://code.visualstudio.com/docs/editor/intellisense) to learn about IntelliSense in VS Code.
- `launch.json`: Contains debugging configurations such as executable paths and arguments. See the [official documentation](https://code.visualstudio.com/docs/cpp/launch-json-reference) for more information.
- `tasks.json`: Specifies the build and other dependent tasks. Learn more about [tasks in VS Code](https://code.visualstudio.com/docs/editor/tasks).
- `gamercpp.natvis`: Defines custom visualizations for data structures in the debugger. Learn more about [customizing the visualization of data structures](https://learn.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects?view=vs-2022).
1 change: 1 addition & 0 deletions doc/wiki/_Sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@
* [[ ELBDM Spectral Interpolation | ELBDM-Spectral-Interpolation ]]
* [[ Style Guide | Style-Guide ]]
* [[ How to Contribute | How-to-Contribute ]]
* [[ Developing with VS Code | Developing-with-VS-Code ]]
24 changes: 24 additions & 0 deletions tool/vscode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Integrating Gamer with Visual Studio Code

## Setup
- Install VS Code Extension: "C/C++"
- To disable auto-formatting, add the following to your `settings.json`:
```json
{
"C_Cpp.formatting": "disabled"
}
```

## Usage
- Run `sh tool/vscode/copy_to_vscode.sh` to copy the necessary files to `.vscode` directory to integrate Gamer with VS Code.
- After configuring Gamer with `configure.py`, press `Ctrl + Shift + B` to build gamer. This will update the macros, providing IntelliSense highlighting support.
- Press `F5` to debug Gamer.

## Files in this directory
- `c_cpp_properties.json`: Contains the IntelliSense configuration for VS Code.
- `gamercpp.natvis`: Contains the visualization configuration for VS Code debugger.
- `launch.json`: Contains the debug configuration for VS Code.
- `tasks.json`: Contains the build configuration for VS Code.
- `extract_macros.py`: Script to extract the macros from the `Makefile.log` to `c_cpp_properties.json`.
- `copy_to_vscode.sh`: Script to copy the above files to `.vscode` directory and set up the working path.
- `README.md`: This file.
15 changes: 15 additions & 0 deletions tool/vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${default}",
"${workspaceFolder}/include"
],
"cStandard": "c17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}
56 changes: 56 additions & 0 deletions tool/vscode/copy_to_vscode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/bin/sh

# Change to the directory where the script is located
cd "$(dirname "$0")"

# Set source and destination paths relative to the script's location
SOURCE_DIR="."
TARGET_DIR="../../.vscode"

# Specify files to exclude (space-separated list, e.g., "file1 file2")
EXCLUDE_FILES="copy_to_vscode.sh README.md"

if [ ! -d "$(realpath "$TARGET_DIR")" ]; then
echo "Target directory $(realpath "$TARGET_DIR") does not exist."
mkdir -p "$(realpath "$TARGET_DIR")"
echo "Target directory $(realpath "$TARGET_DIR") created."
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The realpath has different usage at mac os. Is it necessary to avoid the problem of not absolute path? If not, maybe can switch to

if [ ! -d "$TARGET_DIR" ]; then
  echo "Target directory $TARGET_DIR does not exist."
  mkdir -p "$TARGET_DIR"
  echo "Target directory $TARGET_DIR created."
fi

so it can run at both os.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed all of the realpath. I would like to make the message to be more informative before.
Please help me to test it again. Thanks!


# Prompt the user for the working directory under bin
echo "Enter the working directory under bin/: (e.g. shocktube)"
read -r WORKING_DIR

# Function to check if a file is in the exclude list
is_excluded() {
for excluded in $EXCLUDE_FILES; do
if [ "$excluded" = "$1" ]; then
return 0
fi
done
return 1
}

for file in "$SOURCE_DIR"/*; do
filename=$(basename "$file")

if is_excluded "$filename"; then
continue
fi

if [ -e "$TARGET_DIR/$filename" ]; then
echo "File $filename already exists in $TARGET_DIR. Overwrite? (y/n)"
read -r answer

if [ "$answer" = "y" ] || [ "$answer" = "Y" ]; then
cp "$file" "$TARGET_DIR/$filename"
echo "$filename overwritten."
else
echo "$filename not copied."
fi
else
cp "$file" "$TARGET_DIR/$filename"
echo "$filename copied."
fi

sed -i "s/Gamer_Working_SubDir/$WORKING_DIR/g" "$TARGET_DIR/$filename"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The usage of sed is different between linux and mac os.

sed "s/Gamer_Working_SubDir/$WORKING_DIR/g" "$TARGET_DIR/$filename" > "$TARGET_DIR/$filename.tmp" && mv "$TARGET_DIR/$filename.tmp" "$TARGET_DIR/$filename"

This might can run on both os.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I change the way to setup the working directory. So sed is not needed anymore.

done
56 changes: 56 additions & 0 deletions tool/vscode/extract_macros.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import re
import json

'''
This script updates the "defines" section in the .vscode/c_cpp_properties.json file in Visual Studio Code
by directly parsing the Makefile.log file to extract relevant compiler macros (definitions). It provides an automated
way to synchronize project-specific preprocessor definitions with the VSCode configuration. This approach allows
VSCode to recognize the defines directly from your build configuration, improving VSCode IntelliSense and error
detection without manual intervention.

Usage:
1. Place this script under the `.vscode` folder of your project.
2. Set the paths to `Makefile.log` and `c_cpp_properties.json` in the script as follows:
- `makefile_log_path`: Path to `Makefile.log`, which contains compiler settings output (default: "../src/Makefile.log").
- `c_cpp_properties_path`: Path to the VSCode C++ configuration file (default: "c_cpp_properties.json").
3. Run the script each time `Makefile.log` is updated, or set it as a pre-build or post-build task in VSCode
to keep the configuration in sync.
'''
# Path to Makefile.log and c_cpp_properties.json
makefile_log_path = "../src/Makefile.log"
c_cpp_properties_path = "c_cpp_properties.json"

# Pattern to match the setting in the format of " MODEL : HYDRO"
pattern = re.compile(r":\s+(\w+)\s*:\s+(\w+)")
defines = []

# Read Makefile.log and extract macros
with open(makefile_log_path, 'r') as log_file:
print(f"Reading {makefile_log_path} and extracting defines...")
for line in log_file:
match = pattern.search(line)
if match:
key, value = match.groups()
if value == 'False':
continue
elif value == 'True':
defines.append(f"{key}")
else:
defines.append(f"{key}={value}")
print(f"Extracted {len(defines)} macros from {makefile_log_path}.")

# Load c_cpp_properties.json
with open(c_cpp_properties_path, 'r') as cpp_properties_file:
print(f"Loading {c_cpp_properties_path}...")
cpp_properties = json.load(cpp_properties_file)

# Update the "defines" array in c_cpp_properties.json
print("Updating defines in c_cpp_properties.json...")
cpp_properties['configurations'][0]['defines'] = defines

# Write the updated content back to c_cpp_properties.json
with open(c_cpp_properties_path, 'w') as cpp_properties_file:
print(f"Writing updates to {c_cpp_properties_path}...")
json.dump(cpp_properties, cpp_properties_file, indent=4)

print("Update completed successfully.")
7 changes: 7 additions & 0 deletions tool/vscode/gamercpp.natvis
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="Timer_t">
<DisplayString Condition="Status">Timer running</DisplayString>
<DisplayString Condition="!Status">Timer stop: {Time*1.0e-6} sec</DisplayString>
</Type>
</AutoVisualizer>
33 changes: 33 additions & 0 deletions tool/vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Gamer",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/bin/Gamer_Working_SubDir/gamer",
"args": [],
"stopAtEntry": true,
"cwd": "${workspaceFolder}/bin/Gamer_Working_SubDir/",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"miDebuggerPath": "/usr/bin/gdb",
"miDebuggerArgs": "-quiet",
"logging": {
"engineLogging": false
},
"internalConsoleOptions": "openOnSessionStart",
"preLaunchTask": "clean-work-dir",
"visualizerFile": "${workspaceFolder}/.vscode/gamercpp.natvis",
"showDisplayString": true
}
]
}
68 changes: 68 additions & 0 deletions tool/vscode/tasks.json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will be more convenient if it can automatically copy the new build gamer into the work directory. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also maybe run sh generate_make.sh automatically?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have integrated copying the new executable into the building task.
And added a new task for configuring.

Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"tasks": [
{
"label": "make-clean",
"type": "shell",
"command": "make",
"args": [
"clean"
],
"options": {
"cwd": "${workspaceFolder}/src"
}
},
{
"label": "extract-macros",
"type": "shell",
"command": "python3",
"args": [
"extract_macros.py"
],
"options": {
"cwd": "${workspaceFolder}/.vscode"
}
},
{
"label": "build-gamer",
"type": "shell",
"command": "make",
"args": [
"-j",
"8"
],
"options": {
"cwd": "${workspaceFolder}/src"
},
"problemMatcher": [
"$gcc"
],
"dependsOn": [
"make-clean",
"extract-macros"
],
"dependsOrder": "sequence",
"group": {
"kind": "build",
"isDefault": true
},
"detail": "After you configure the Makefile, run this task to build the project."
},
{
"label": "clean-work-dir",
"type": "shell",
"command": "sh",
"args": [
"clean.sh"
],
"group": {
"kind": "build",
"isDefault": false
},
"options": {
"cwd": "${workspaceFolder}/bin/Gamer_Working_SubDir/"
},
"problemMatcher": []
}
],
"version": "2.0.0"
}