microsoft / vscode-cpptools

Official repository for the Microsoft C/C++ extension for VS Code.
Other
5.52k stars 1.55k forks source link

Support multiple natvis files in `cppvsdbg` #10917

Open WardenGnaw opened 1 year ago

WardenGnaw commented 1 year ago

Feature Request

Related: https://github.com/microsoft/vscode-cpptools/issues/925

SimonQi1 commented 1 year ago

Will it get support for multplie natvis files?when using cppvsdbg

aiyolo commented 5 months ago

after several months, does this feature has any progress now?

sean-mcmanus commented 5 months ago

@aiyolo No. It's currently the 10th most upvoted debugger feature: https://github.com/Microsoft/vscode-cpptools/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc+label%3Adebugger

dimateos commented 5 months ago

Yeah, I use cppvsdbg and this is a bummer. I tend to use many natvis for boost https://github.com/KindDragon/CPPDebuggerVisualizers...

But I would still prefer a directory (or list of them) to simply target many natvis files https://github.com/microsoft/MIEngine/issues/1049

bradphelan commented 4 months ago

A work-around the concats all natvis files together

natvis.cmake

function(concatenate_natvis_files natvis_files out_file)

    # Prepare the output file path
    set(output_path "${CMAKE_BINARY_DIR}/${out_file}")

    # Define the path to the Python script
    set(PYTHON_SCRIPT "${CMAKE_SOURCE_DIR}/dev/cmake/natvis.py")

    # Call the Python script with the list of natvis files and the output path
    add_custom_command(
        OUTPUT ${output_path}
        COMMAND ${CMAKE_COMMAND} -E echo "Concatenating .natvis files..."
        COMMAND ${CMAKE_COMMAND} -E env python ${PYTHON_SCRIPT} ${natvis_files} ${output_path}
        COMMENT "Running Python script to concatenate .natvis files and remove duplicates"
        DEPENDS ${natvis_files} ${PYTHON_SCRIPT}
    )

    # Ensure the output file is built
    add_custom_target(run_concat_natvis ALL DEPENDS ${output_path})
endfunction()

natvis.py

import os
import sys
import xml.etree.ElementTree as ET

ET.register_namespace('', "http://schemas.microsoft.com/vstudio/debugger/natvis/2010")

def concatenate_natvis_files(natvis_files, output_path):
    seen_types = set()
    namespace = "http://schemas.microsoft.com/vstudio/debugger/natvis/2010"
    auto_visualizer = ET.Element('AutoVisualizer')
    namespaces = {"vis": namespace}

    for natvis_file in natvis_files:
        print(f"Processing {natvis_file}")
        tree = ET.parse(natvis_file)
        root = tree.getroot()
        print(f"Found {len(root)} types")

        for type_element in root.iterfind('vis:Type', namespaces=namespaces):
            type_name = type_element.get('Name')
            print(f"Processing {type_name}")
            if type_name not in seen_types:
                seen_types.add(type_name)
                auto_visualizer.append(type_element)

    tree = ET.ElementTree(auto_visualizer)
    ET.indent(tree, space="\t", level=0)
    tree.write(output_path, encoding='utf-8', xml_declaration=True, method='xml')

if __name__ == "__main__":
    natvis_files = sys.argv[1:-1]
    output_path = sys.argv[-1]
    concatenate_natvis_files(natvis_files, output_path)

In your main CMakeLists.txt

include(natvis)
option(MW_GENERATE_NATVIS "Generate a natvis file that includes all natvis files in the project" OFF)
if(MW_GENERATE_NATVIS)
    # Find all .natvis files recursively under the specified directory
    file(GLOB_RECURSE natvis_files "${CMAKE_SOURCE_DIR}/dev/*.natvis")
    concatenate_natvis_files("${natvis_files}" "all_natvis_files.natvis")
endif()