How to add a cppm static library with the same configuration as lib__cmake_cxx23a

I found that the generated printing of the library is inconsistent, so I am here to ask.

[main] 正在配置项目: vulkan 
[proc] 正在执行命令: E:\mysoftware\cmake-4.2.0-rc2-windows-x86_64\bin\cmake.EXE -DCMAKE_INSTALL_PREFIX=E:/0_github_project/vulkan/install/ -DCMAKE_C_COMPILER=E:/mysoftware/llvm-mingw-20250910-ucrt-x86_64/bin/gcc.exe -DCMAKE_CXX_COMPILER=E:/mysoftware/llvm-mingw-20250910-ucrt-x86_64/bin/g++.exe -DCMAKE_BUILD_TYPE=Release -DCMAKE_MAKE_PROGRAM=D:/mysoftware/ninja/ninja.exe -S E:/0_github_project/vulkan -B E:/0_github_project/vulkan/build -G Ninja
[cmake] -- The CXX compiler identification is Clang 21.1.1
[cmake] -- Detecting CXX compiler ABI info
[cmake] -- Detecting CXX compiler ABI info - done
[cmake] -- Check for working CXX compiler: E:/mysoftware/llvm-mingw-20250910-ucrt-x86_64/bin/g++.exe - skipped
[cmake] -- Detecting CXX compile features
[cmake] CMake Warning (dev) at E:/mysoftware/cmake-4.2.0-rc2-windows-x86_64/share/cmake-4.2/Modules/Compiler/CMakeCommonCompilerMacros.cmake:248 (cmake_language):
[cmake]   CMake's support for `import std;` in C++23 and newer is experimental.  It
[cmake]   is meant only for experimentation and feedback to CMake developers.
[cmake] Call Stack (most recent call first):
[cmake]   E:/mysoftware/cmake-4.2.0-rc2-windows-x86_64/share/cmake-4.2/Modules/CMakeDetermineCompilerSupport.cmake:113 (cmake_create_cxx_import_std)
[cmake]   E:/mysoftware/cmake-4.2.0-rc2-windows-x86_64/share/cmake-4.2/Modules/CMakeTestCXXCompiler.cmake:83 (CMAKE_DETERMINE_COMPILER_SUPPORT)
[cmake]   CMakeLists.txt:14 (project)
[cmake] This warning is for project developers.  Use -Wno-dev to suppress it.
[proc] 正在执行命令: E:\mysoftware\cmake-4.2.0-rc2-windows-x86_64\bin\cmake.EXE --build E:/0_github_project/vulkan/build --target base --
[build] [1/14] Scanning E:/0_github_project/vulkan/test/base/base.cpp for CXX dependencies
[build] [2/14] Scanning E:/mysoftware/llvm-mingw-20250910-ucrt-x86_64/share/libc++/v1/std.compat.cppm for CXX dependencies
[build] [3/14] Scanning E:/mysoftware/VulkanSDK/1.4.321.1/Include/vulkan/vulkan.cppm for CXX dependencies
[build] [4/14] Scanning E:/mysoftware/llvm-mingw-20250910-ucrt-x86_64/share/libc++/v1/std.cppm for CXX dependencies
[build] [5/14] Generating CXX dyndep file CMakeFiles/__cmake_cxx23.dir/CXX.dd
[build] [6/14] Generating CXX dyndep file CMakeFiles/vulkan_modules.dir/CXX.dd
[build] [7/14] Generating CXX dyndep file CMakeFiles/base.dir/CXX.dd
[build] [8/14] Building CXX object CMakeFiles/__cmake_cxx23.dir/E_/mysoftware/llvm-mingw-20250910-ucrt-x86_64/share/libc++/v1/std.cppm.obj
[build] [9/14] Building CXX object CMakeFiles/__cmake_cxx23.dir/E_/mysoftware/llvm-mingw-20250910-ucrt-x86_64/share/libc++/v1/std.compat.cppm.obj
[build] [10/14] Linking CXX static library lib__cmake_cxx23.a
[build] [11/14] Building CXX object CMakeFiles/vulkan_modules.dir/E_/mysoftware/VulkanSDK/1.4.321.1/Include/vulkan/vulkan.cppm.obj
[build] [12/14] Linking CXX static library libvulkan_modules.a
[build] [13/14] Building CXX object CMakeFiles/base.dir/test/base/base.cpp.obj
[build] [14/14] Linking CXX executable base.exe
[driver] 生成完毕: 00:00:13.497

My configuration is as follows

set(VULKAN_SDK_DIR "E:/mysoftware/VulkanSDK/1.4.321.1")

add_library(vulkan_modules STATIC)
target_sources(vulkan_modules
    PUBLIC
    FILE_SET CXX_MODULES
    BASE_DIRS ${VULKAN_SDK_DIR}
    FILES
    "${VULKAN_SDK_DIR}/Include/vulkan/vulkan.cppm"
)
target_include_directories(vulkan_modules
    PUBLIC
    "${VULKAN_SDK_DIR}/Include"
)
target_compile_features(vulkan_modules PRIVATE cxx_std_23)


# config vulkan
target_compile_definitions(vulkan_modules PUBLIC -DUSE_CPP20_MODULES -DVULKAN_HPP_NO_STRUCT_CONSTRUCTORS)

# for <cstdlib>
target_compile_definitions(vulkan_modules PUBLIC EXIT_SUCCESS=0 EXIT_FAILURE=1)

unset(VULKAN_SDK_DIR)

Everything is normal and running without any issues. The difference is that the ability to integrate clangd is too poor. I found that importing std; It will not cause clangd to crash, but import vulkan_hpp; Easy to cause clangd to crash. Compile_commands.json is the core key, all of which are directly imported as xxx; Why can’t vulkan_hpp compare to std? We know that std is a pure template library that is theoretically much more difficult to recognize than vulkanxpp, but the results were unexpected.

You ask a lot of questions and give us really pure details?

When integrating clangd and jumping to the function implementation provided by “import vulkanxpp;”, it will cause clangd to crash. I want to know if cmake did not configure the static library of cppm properly, because jumping to the template type and internal functions provided by “import std;” will not crash.
Note that “# include<vulkan/vulkan’raii. hpp>” non modular projects can also cause clangd to crash. Would it be much better to modularize ‘import vulkanxpp;’? If not, then that’s the only way.

What do you mean?

Please upload the file.

Compile_commands.json is an automatically generated file.It doesn’t matter.

info

compile_commands.json: https://cmake.org/cmake/help/v4.2/variable/CMAKE_EXPORT_COMPILE_COMMANDS.html

question

To reiterate,How to add a cppm static library with the same configuration as lib__cmake_cxx23.a?
I don’t know if the standard library is consistent with the definition of “vulkan_modules” above, because I can’t see the definition of “lib__cmake_cxx23.a” in “CMakeLists.txt”.
That’s all the questions.

It is always consistently build with CMake and Nina. Try in your build directory:

ninja clean && ninja -v

To help you we need more information:

  • give us your hole CMakeLists.txt
  • Give us your base sources
  • Or create a minimal working example to reproduce the problem!

This works at least on OSX with clang++21 and g++15:

cmake_minimum_required(VERSION 3.28...4.2)

include(cmake/prelude.cmake)

project(vulkan-module VERSION 1.4.328 LANGUAGES CXX)

# Tell CMake that we explicitly want `import std`.
# This will initialize the property on all targets declared after this to 1
message(STATUS "CMAKE_CXX_COMPILER_IMPORT_STD=${CMAKE_CXX_COMPILER_IMPORT_STD}")
if(23 IN_LIST CMAKE_CXX_COMPILER_IMPORT_STD)
    set(CMAKE_CXX_MODULE_STD ON)
    message(STATUS "CMAKE_CXX_MODULE_STD=${CMAKE_CXX_MODULE_STD}")
endif()

# XXX find Vulkan SDK on OSX:
set(Vulkan_DIR
    /usr/local/Cellar/vulkan-headers/2.4.328.1/share/cmake/VulkanHeaders
)
find_package(Vulkan 1.3.256 REQUIRED CONFIG NAMES VulkanHeaders)

# Require Vulkan version ≥ 1.3.256 (earliest version when the Vulkan module was available)
if(${Vulkan_VERSION} VERSION_LESS "1.3.256")
    message(
        FATAL_ERROR
        "Minimum required Vulkan version for C++ modules is 1.3.256. "
        "Found ${Vulkan_VERSION}."
    )
endif()

# set up Vulkan C++ module as a library
add_library(VulkanHppModule)
if(NOT DEFINED Vulkan_INCLUDE_DIR)
    set(Vulkan_INCLUDE_DIR /usr/local/include)
endif()
target_sources(
    VulkanHppModule
    PUBLIC
        FILE_SET CXX_MODULES
            BASE_DIRS ${Vulkan_INCLUDE_DIR}
            FILES ${Vulkan_INCLUDE_DIR}/vulkan/vulkan.cppm
    # XXX /usr/local/include/vulkan/vulkan.cppm
)
target_compile_features(VulkanHppModule PUBLIC cxx_std_23)
target_link_libraries(VulkanHppModule PUBLIC Vulkan::Headers)

if(CMAKE_CXX_MODULE_STD)
    # FIXME: target_compile_definitions( VulkanHppModule PUBLIC VULKAN_HPP_STD_MODULE std)
else()
    target_compile_definitions(VulkanHppModule PUBLIC VULKAN_HPP_NO_STD_MODULE)
endif()

# config vulkan
target_compile_definitions(
    VulkanHppModule
    PUBLIC VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1
)
# ...
target_compile_definitions(VulkanHppModule PUBLIC VULKAN_HPP_NO_STRUCT_CONSTRUCTORS)

# for <cstdlib>
target_compile_definitions(VulkanHppModule PUBLIC EXIT_SUCCESS=0 EXIT_FAILURE=1)


# link Vulkan C++ module into your project
add_executable(YourProject main.cpp)
target_link_libraries(YourProject PRIVATE VulkanHppModule)

Thanks for continuing to reply. This is not a question of whether cmake builds and runs properly.
I have no doubts, everything is expected, remember that the crashing program is clangd and not cmake, I just did everything possible or potential to avoid crashes, and I came here to ask.

See cmake 3.28 CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS-NOTFOUND: not found - #6 by ben.boeckel

the source file belongs to a file set of type CXX_MODULES, it will be scanned.
I’ve done that, and if the cppm can’t be scanned, the build can’t be successful.
It should not be able to analyze large files before crashing, and no prompts or improved configurations can be found to be set.

Whatever you mean?

The Problem is caused by the `import VULKAN_HPP_STD_MODULE;` here:

// Copyright 2015-2025 The Khronos Group Inc.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//

// This header is generated from the Khronos Vulkan XML API Registry.

// Note: This module is still in an experimental state.
// Any feedback is welcome on https://github.com/KhronosGroup/Vulkan-Hpp/issues.

module;

#include <version>
#if defined( __cpp_lib_modules ) && !defined( VULKAN_HPP_NO_STD_MODULE )
#  define VULKAN_HPP_ENABLE_STD_MODULE
#endif

#include <vulkan/vulkan.hpp>
#include <vulkan/vulkan_extension_inspection.hpp>
#include <vulkan/vulkan_format_traits.hpp>
#include <vulkan/vulkan_hash.hpp>
#include <vulkan/vulkan_raii.hpp>
#include <vulkan/vulkan_shared.hpp>

export module vulkan_hpp;
#if defined( VULKAN_HPP_ENABLE_STD_MODULE )
export import std;
#endif

export namespace VULKAN_HPP_NAMESPACE
{
// ....

the original Vulkan-Hpp/vulkan/vulkan.cppm at main · KhronosGroup/Vulkan-Hpp · GitHub is fixed!

And this is my main.cpp, that works with clangd too:

// Copyright(c) 2024, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// VulkanHpp Test : Cpp20Module
//                  Compile test on using c++20 modules

#include <print>  // std::print
// XXX #include <memory>    // std::unique_ptr (seems to be needed on Windows)
#include <string>  // std::string

import vulkan_hpp;

namespace {
    const std::string AppName{"Cpp20Module"};
    const std::string EngineName{"Vulkan.cppm"};
}  // namespace

#if VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1
namespace vk::detail {
    DispatchLoaderDynamic defaultDispatchLoaderDynamic;
}  // namespace vk::detail
#endif

int main(int /*argc*/, char** /*argv*/) {
    std::println("test {}", AppName);

    /* VULKAN_HPP_KEY_START */
    try {
#if (VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1)
        // initialize minimal set of function pointers
        vk::detail::defaultDispatchLoaderDynamic.init();
#endif

        // initialize the vk::ApplicationInfo structure
        // XXX vk::ApplicationInfo appInfo(AppName.c_str(), 1, EngineName.c_str(), 1, vk::makeApiVersion(1, 0, 0, 0));
        vk::ApplicationInfo appInfo{};
        appInfo.pApplicationName = AppName.c_str();
        appInfo.applicationVersion = vk::makeVersion(1, 0, 0);  // app version
        appInfo.pEngineName = EngineName.c_str();
        appInfo.engineVersion = vk::makeVersion(1, 0, 0);  // engine version
        appInfo.apiVersion = vk::makeVersion(1, 0, 0);     // Vulkan 1.0 API

        // initialize the vk::InstanceCreateInfo
        vk::InstanceCreateInfo instanceCreateInfo({}, &appInfo);

        // create an Instance
        vk::Instance instance = vk::createInstance(instanceCreateInfo);

#if (VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1)
        // initialize function pointers for instance
        vk::detail::defaultDispatchLoaderDynamic.init(instance);
#endif

        // destroy it again
        instance.destroy();
    } catch (vk::SystemError& err) {
        std::println("vk::SystemError: {}", err.what());
        exit(-1);
    } catch (std::exception& err) {
        std::println("std::exception: {}", err.what());
        exit(-1);
    } catch (...) {
        std::println("unknown error");
        exit(-1);
    }

    /* VULKAN_HPP_KEY_END */

    return 0;
}

I works fine for me:

CXX=clang++ cmake -G Ninja -S . -B build --fresh
-- CXXFLAGS=-stdlib=libc++
'brew' '--prefix' 'llvm'
-- LLVM_PATH=/usr/local/Cellar/llvm/21.1.5
-- CMAKE_CXX_STDLIB_MODULES_JSON=/usr/local/Cellar/llvm/21.1.5/lib/c++/libc++.modules.json
-- The CXX compiler identification is Clang 21.1.5
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/local/Cellar/llvm/21.1.5/bin/clang++ - skipped
-- Detecting CXX compile features
CMake Warning (dev) at /Users/clausklein/.local/share/cmake-4.2/Modules/Compiler/CMakeCommonCompilerMacros.cmake:248 (cmake_language):
  CMake's support for `import std;` in C++23 and newer is experimental.  It
  is meant only for experimentation and feedback to CMake developers.
Call Stack (most recent call first):
  /Users/clausklein/.local/share/cmake-4.2/Modules/CMakeDetermineCompilerSupport.cmake:113 (cmake_create_cxx_import_std)
  /Users/clausklein/.local/share/cmake-4.2/Modules/CMakeTestCXXCompiler.cmake:83 (CMAKE_DETERMINE_COMPILER_SUPPORT)
  CMakeLists.txt:5 (project)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Detecting CXX compile features - done
-- CMAKE_CXX_COMPILER_IMPORT_STD=23;26
-- CMAKE_CXX_MODULE_STD=ON
-- Configuring done (2.3s)
-- Generating done (0.0s)
-- Build files have been written to: /Users/clausklein/Workspace/cpp/vulkan/build
bash-5.3$ ninja -C build/
ninja: Entering directory `build/'
[14/14] Linking CXX executable YourProject
bash-5.3$