In a CMake library project I've a class that's basically a wrapper to boost::uuids::uuid
:
class UUID {
public:
static bool IsValidUUIDText(std::string_view text);
static UUID CreateNull();
public:
UUID();
UUID(const UUID& other);
UUID(UUID&& other);
UUID(std::string_view id);
UUID(const std::array<uint8_t, 16>& byteArray);
~UUID();
std::string getText() const;
std::array<uint8_t, 16> getByteArray() const;
size_t getHash() const;
public:
bool operator==(const UUID& other) const;
bool operator!=(const UUID& other) const;
bool operator<(const UUID& other) const;
bool operator>(const UUID& other) const;
bool operator<=(const UUID& other) const;
bool operator>=(const UUID& other) const;
UUID& operator=(const UUID& other);
UUID& operator=(UUID&& other) noexcept;
private:
boost::uuids::uuid* m_uuid{ nullptr };
};
inline std::ostream& operator<<(std::ostream& os, const UUID& uuid) {
os << uuid.getText();
return os;
}
I'd like to show the value of the uuid in the visual studio debugger windows (Locals for example). So I've create a .natvis file by following this other thread and I've put it into a resources
folder in my CMake project.
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="boost::uuids::uuid">
<DisplayString>{{{data[0],nvoXb}{data[1],nvoXb}{data[2],nvoXb}{data[3],nvoXb}-{data[4],nvoXb}{data[5],nvoXb}-{data[6],nvoXb}{data[7],nvoXb}-{data[8],nvoXb}{data[9],nvoXb}-{data[10],nvoXb}{data[11],nvoXb}{data[12],nvoXb}{data[13],nvoXb}{data[14],nvoXb}{data[15],nvoXb}}}</DisplayString>
</Type>
</AutoVisualizer>
Then in my CMakeLists.txt
I've added the /NATVIS flag:
cmake_minimum_required (VERSION ${PROJECT_CMAKE_VERSION})
project (mylib)
add_definitions (-DBOOST_UUID_FORCE_AUTO_LINK)
add_definitions (-DMYLIB_EXPORTS)
find_package (Boost CONFIG REQUIRED QUIET)
set (PROJECT_SRC
UUID.cpp
Exception.cpp
)
add_library (${PROJECT_NAME} SHARED ${PROJECT_SRC})
target_link_libraries(${PROJECT_NAME} PRIVATE ${Boost_LIBRARIES})
target_compile_features (${PROJECT_NAME} PUBLIC ${PROJECT_CXX_STANDARD})
target_include_directories (${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../)
target_include_directories (${PROJECT_NAME} PUBLIC ${Boost_INCLUDE_DIRS})
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
get_filename_component(NATVIS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../resources/natvis/mulib.natvis" ABSOLUTE)
message (STATUS "MyLib natvis file is ${NATVIS_DIR}")
target_link_options(${PROJECT_NAME} PRIVATE /NATVIS:${NATVIS_DIR})
endif()
The CMake is configured, and the message appears. but when I debug the library, the .natvis doesn't seem to work, I see the plain data of boost::uuids::uuid
.
How can I fix it and show the uuid string in debugger window?
You're overcomplicating things. You can simply add the .natvis
file to your target sources and it will work as expected¹:
add_library (${PROJECT_NAME} SHARED ${PROJECT_SRC})
# ...
target_sources(${PROJECT_NAME}
PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:${CMAKE_CURRENT_SOURCE_DIR}/../../../resources/natvis/mulib.natvis>
)
No need for any manual fiddling with compiler flags. You should take care though that the natvis file is placed inside the CMake source tree as part of general CMake best practices.
¹ - Proper handling of .natvis
files was added to CMake in version 3.7