From 32e8ddf676fba6e90a3d6b8339697585ecd8c294 Mon Sep 17 00:00:00 2001 From: JoGei <62236820+JoGei@users.noreply.github.com> Date: Thu, 26 Mar 2026 16:34:25 +0100 Subject: [PATCH] Add configurable clang stdlib selection to vrtlmod. CMake parameter VRTLMOD_STDLIB={libstdc++, libc++} Default VRTLMOD_STDLIB to libstdc++, wire it through test/exported clang invocations, and inject matching standard library include paths for clang parsing. Also keep current systems working by auto-adding host GCC libstdc++ headers and warning when libc++ is selected but not installed. --- CMakeLists.txt | 49 +++++++++++++++++++++++++++++++++++ cmake/vrtlmod-config.cmake.in | 8 +++++- test/CMakeLists.txt | 8 +++--- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7290f5f..1a3b057 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,11 @@ endif() option(BUILD_TESTING "Enable Tests" OFF) include(CTest) +set(VRTLMOD_STDLIB "libstdc++" CACHE STRING "C++ standard library passed to clang when parsing vrtlmod inputs") +set_property(CACHE VRTLMOD_STDLIB PROPERTY STRINGS libstdc++ libc++) +if(NOT VRTLMOD_STDLIB STREQUAL "libstdc++" AND NOT VRTLMOD_STDLIB STREQUAL "libc++") + message(FATAL_ERROR "Unsupported VRTLMOD_STDLIB='${VRTLMOD_STDLIB}'. Expected one of: libstdc++, libc++") +endif() option (FORCE_COLORED_OUTPUT "Always produce ANSI-colored output (GNU/Clang only)." True) if (${FORCE_COLORED_OUTPUT}) @@ -110,12 +115,14 @@ else() add_compile_definitions(LLVM_VERSION_MAJOR=${LLVM_VERSION_MAJOR}) + message(STATUS "LLVM_VERSION_MAJOR=${LLVM_VERSION_MAJOR}") if (LLVM_VERSION_MAJOR LESS 16) set(CLANG_INCLUDE_DIRS ${LLVM_LIBRARY_DIRS}/clang/${LLVM_VERSION}/include) else() set(CLANG_INCLUDE_DIRS ${LLVM_LIBRARY_DIRS}/clang/${LLVM_VERSION_MAJOR}/include) endif() + message(STATUS "CLANG_INCLUDE_DIRS=${CLANG_INCLUDE_DIRS}") if(LLVM_VERSION_MAJOR GREATER 15 AND CMAKE_CXX_STANDARD LESS 17) message(FATAL_ERROR "LLVM_VERSION_MAJOR[${LLVM_VERSION_MAJOR}] requires c++std>=17! Is ${CMAKE_CXX_STANDARD}") endif() @@ -185,7 +192,49 @@ if(LLVM_FOUND AND Clang_FOUND AND verilator_FOUND) src/passes/rewritemacrosaction.cpp ) + set(VRTLMOD_CLANG_STDLIB_FLAG "-stdlib=${VRTLMOD_STDLIB}") set(AUTO_INCLUDE_DIRS ${CLANG_INCLUDE_DIRS} ${VERILATOR_INCLUDE_DIRS}) + set(VRTLMOD_STDLIB_INCLUDE_DIRS) + if(VRTLMOD_STDLIB STREQUAL "libstdc++") + string(REGEX MATCH "^[0-9]+" HOST_CXX_VERSION_MAJOR "${CMAKE_CXX_COMPILER_VERSION}") + set(HOST_CXX_INCLUDE_DIRS + "/usr/include/c++/${HOST_CXX_VERSION_MAJOR}" + "/usr/include/c++/${HOST_CXX_VERSION_MAJOR}/backward" + ) + if(CMAKE_LIBRARY_ARCHITECTURE) + list(APPEND HOST_CXX_INCLUDE_DIRS + "/usr/include/${CMAKE_LIBRARY_ARCHITECTURE}/c++/${HOST_CXX_VERSION_MAJOR}" + "/usr/lib/gcc/${CMAKE_LIBRARY_ARCHITECTURE}/${HOST_CXX_VERSION_MAJOR}/include" + ) + endif() + foreach(dir IN LISTS HOST_CXX_INCLUDE_DIRS) + if(EXISTS "${dir}") + list(APPEND VRTLMOD_STDLIB_INCLUDE_DIRS "${dir}") + endif() + endforeach() + else() + set(LIBCXX_INCLUDE_CANDIDATES + "/usr/include/c++/v1" + "${LLVM_INSTALL_PREFIX}/include/c++/v1" + ) + foreach(llvm_lib_dir IN LISTS LLVM_LIBRARY_DIRS) + list(APPEND LIBCXX_INCLUDE_CANDIDATES + "${llvm_lib_dir}/../include/c++/v1" + ) + endforeach() + foreach(dir IN LISTS LIBCXX_INCLUDE_CANDIDATES) + if(EXISTS "${dir}") + list(APPEND VRTLMOD_STDLIB_INCLUDE_DIRS "${dir}") + endif() + endforeach() + if(NOT VRTLMOD_STDLIB_INCLUDE_DIRS) + message(WARNING + "VRTLMOD_STDLIB=libc++ selected, but no libc++ header directories were found. " + "Clang parsing may fail unless libc++ is installed in a standard location." + ) + endif() + endif() + list(APPEND AUTO_INCLUDE_DIRS ${VRTLMOD_STDLIB_INCLUDE_DIRS}) list(LENGTH AUTO_INCLUDE_DIRS AUTO_INCLUDE_DIRS_SIZE) list(TRANSFORM AUTO_INCLUDE_DIRS PREPEND "\"-I") list(TRANSFORM AUTO_INCLUDE_DIRS APPEND "\"") diff --git a/cmake/vrtlmod-config.cmake.in b/cmake/vrtlmod-config.cmake.in index 0198e76..5a0fa15 100644 --- a/cmake/vrtlmod-config.cmake.in +++ b/cmake/vrtlmod-config.cmake.in @@ -109,6 +109,12 @@ function(vrtlmod) set(LLVM_TOOLS_BINARY_DIR "@LLVM_TOOLS_BINARY_DIR@") endif() + if(VRTLMOD_STDLIB) + set(VRTLMOD_CLANG_STDLIB "${VRTLMOD_STDLIB}") + else() + set(VRTLMOD_CLANG_STDLIB "@VRTLMOD_STDLIB@") + endif() + if(VRTLMOD_SILENT) set(SILENT --silent) endif() @@ -132,7 +138,7 @@ function(vrtlmod) ${OUT_DIR} ${SOURCES} ) - set(CLANG_ARGS ${VERBOSE} -Wno-null-character -xc++ -stdlib=libstdc++ -std=c++${CMAKE_CXX_STANDARD} ${INCLUDE_DIRS}) + set(CLANG_ARGS ${VERBOSE} -Wno-null-character -xc++ -stdlib=${VRTLMOD_CLANG_STDLIB} -std=c++${CMAKE_CXX_STANDARD} ${INCLUDE_DIRS}) set(ARGS_FILE ${CMAKE_CURRENT_BINARY_DIR}/vrtlmod-args.txt) string(REPLACE ";" " " COMMAND_SPACES "${VRTLMOD} ${VRTLMOD_ARGS} -- ${LLVM_TOOLS_BINARY_DIR}/clang++ ${CLANG_ARGS}") diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3bb073e..f398a61 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -96,8 +96,8 @@ if(BUILD_TESTING) add_custom_command( OUTPUT ${COUT} ${CC_SUBDIR}/vrtlmod/V${DUT_NAME}_vrtlmodapi.hpp ${GENERATED_API_SRCS} DEPENDS null ${PROJECT_NAME}-bin - COMMAND ${PROJECT_BINARY_DIR}/${PROJECT_NAME} ARGS --out=${CC_SUBDIR}/vrtlmod/ ${CIN} -v -- ${LLVM_TOOLS_BINARY_DIR}/clang++ -v -Wno-null-character -xc++ -stdlib=libstdc++ -std=c++${CMAKE_CXX_STANDARD} -I${CC_SUBDIR}/vrtlmod/ -I${VERILATOR_INCLUDE_DIRECTORY} -I${VERILATOR_INCLUDE_DIRECTORY}/vltstd -I${CLANG_INCLUDE_DIRS} - COMMENT "executing vrtlmod: .. ${PROJECT_BINARY_DIR}/${PROJECT_NAME} --out=${CC_SUBDIR}/vrtlmod ${CIN_STR} -v -- ${LLVM_TOOLS_BINARY_DIR}/clang++ -v -Wno-null-character -xc++ -stdlib=libstdc++ -std=c++${CMAKE_CXX_STANDARD} -I${CC_SUBDIR}/vrtlmod/ -I${VERILATOR_INCLUDE_DIRECTORY} -I${VERILATOR_INCLUDE_DIRECTORY}/vltstd -I${CLANG_INCLUDE_DIRS}" + COMMAND ${PROJECT_BINARY_DIR}/${PROJECT_NAME} ARGS --out=${CC_SUBDIR}/vrtlmod/ ${CIN} -v -- ${LLVM_TOOLS_BINARY_DIR}/clang++ -v -Wno-null-character -xc++ ${VRTLMOD_CLANG_STDLIB_FLAG} -std=c++${CMAKE_CXX_STANDARD} -I${CC_SUBDIR}/vrtlmod/ -I${VERILATOR_INCLUDE_DIRECTORY} -I${VERILATOR_INCLUDE_DIRECTORY}/vltstd -I${CLANG_INCLUDE_DIRS} + COMMENT "executing vrtlmod: .. ${PROJECT_BINARY_DIR}/${PROJECT_NAME} --out=${CC_SUBDIR}/vrtlmod ${CIN_STR} -v -- ${LLVM_TOOLS_BINARY_DIR}/clang++ -v -Wno-null-character -xc++ ${VRTLMOD_CLANG_STDLIB_FLAG} -std=c++${CMAKE_CXX_STANDARD} -I${CC_SUBDIR}/vrtlmod/ -I${VERILATOR_INCLUDE_DIRECTORY} -I${VERILATOR_INCLUDE_DIRECTORY}/vltstd -I${CLANG_INCLUDE_DIRS}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) @@ -162,8 +162,8 @@ if(BUILD_TESTING) add_custom_command( OUTPUT ${SCOUT} ${SC_SUBDIR}/vrtlmod/V${DUT_NAME}_vrtlmodapi.hpp ${GENERATED_API_SRCS} DEPENDS sc-null ${PROJECT_NAME}-bin - COMMAND ${PROJECT_BINARY_DIR}/${PROJECT_NAME} ARGS --systemc --out=${SC_SUBDIR}/vrtlmod ${SCIN} -v -- ${LLVM_TOOLS_BINARY_DIR}/clang++ -Wno-null-character -xc++ -stdlib=libstdc++ -std=c++${CMAKE_CXX_STANDARD} -I${SC_SUBDIR}/vrtlmod -I${VERILATOR_INCLUDE_DIRECTORY} -I${VERILATOR_INCLUDE_DIRECTORY}/vltstd -I${CLANG_INCLUDE_DIRS} -I${SYSTEMC_INCLUDE_DIRS} - COMMENT "executing vrtlmod: .. ${PROJECT_BINARY_DIR}/${PROJECT_NAME} --systemc --out=${SC_SUBDIR}/vrtlmod ${SCIN_STR} -v -- clang++ -Wno-null-character -xc++ -stdlib=libstdc++ -std=c++${CMAKE_CXX_STANDARD} -I${SC_SUBDIR}/vrtlmod -I${VERILATOR_INCLUDE_DIRECTORY} -I${VERILATOR_INCLUDE_DIRECTORY}/vltstd -I${CLANG_INCLUDE_DIRS} -I${SYSTEMC_INCLUDE_DIRS}" + COMMAND ${PROJECT_BINARY_DIR}/${PROJECT_NAME} ARGS --systemc --out=${SC_SUBDIR}/vrtlmod ${SCIN} -v -- ${LLVM_TOOLS_BINARY_DIR}/clang++ -Wno-null-character -xc++ ${VRTLMOD_CLANG_STDLIB_FLAG} -std=c++${CMAKE_CXX_STANDARD} -I${SC_SUBDIR}/vrtlmod -I${VERILATOR_INCLUDE_DIRECTORY} -I${VERILATOR_INCLUDE_DIRECTORY}/vltstd -I${CLANG_INCLUDE_DIRS} -I${SYSTEMC_INCLUDE_DIRS} + COMMENT "executing vrtlmod: .. ${PROJECT_BINARY_DIR}/${PROJECT_NAME} --systemc --out=${SC_SUBDIR}/vrtlmod ${SCIN_STR} -v -- clang++ -Wno-null-character -xc++ ${VRTLMOD_CLANG_STDLIB_FLAG} -std=c++${CMAKE_CXX_STANDARD} -I${SC_SUBDIR}/vrtlmod -I${VERILATOR_INCLUDE_DIRECTORY} -I${VERILATOR_INCLUDE_DIRECTORY}/vltstd -I${CLANG_INCLUDE_DIRS} -I${SYSTEMC_INCLUDE_DIRS}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} )