-
Notifications
You must be signed in to change notification settings - Fork 308
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
Add support for C++20 modules #1580
Comments
@mtavenrath has experiences with compiling Vulkan as a C++ module and can surely share his experiences. Using VulkanHpp as a C++ module was beneficial for compile times. Progress with C++20 modules in Cmake, clang and gcc as been considerable recently, tough I believe only msvc has a released (non-development) compiler version with full standard conform support. I think we still have to be careful since not all compilers support full C++20 yet. Instead of |
Good points on modularised code being opt-in. That said, I refer to the MSVC STL as an exemplar (they have even implemented C++23 Also good points on the feature test macro, especially since not all compilers have landed complete support for it (even MSVC emits C1001 internal compiler errors sometimes). I used As for build tools, there's experimental CMake support detailed in this blog post by KitWare, and the I think the time is ripe to attempt modularising |
For clang-17 (nightly, Ubuntu clang version 17.0.0 (++20230523041032+61bc3ada1f90-1 // module;
// #include <algorithm>
export module foo;
export namespace foo {
int foo = 1;
} with but not when I would uncomment the first few lines. As mentioned in the Kitware article, clang seems to have problems with not standard C++. For both libc++ and libstdc++, it fails to process
The following would work
Also CMake (3.26.4) module support is still experimental
So, for non-msvc compilers this would require a bit more on the compiler side or work-arounds for the header generation. MSVC worked fine for you? |
Yes, it did! More importantly, seeing your comment, here's an example on Compiler Explorer using clang 16.0.0, the experimental CMake API, and the If we want to use modules without CMake, then there has to be a pre-compilation pass as seen in the Clang documentation; it's not as straightforward as Otherwise, P1689R5 enables compilers to scan source code for module dependencies before-hand, thus allowing build tools to produce a dependency graph and then compile modules in the correct order. As documented in the Kitware blog post, CMake's experimental API will assist for compilers that have implemented this proposal (MSVC ≥ 19.34, Clang ≥ 16.0.0) by extracting the module dependencies without requiring that the user specify the module and implementation files in the correct order. I am guessing it is marked 'experimental' because, like you said, compiler support can be patchy, and the documentation especially is lacking; we require clear examples to proceed with modules. |
An additional Did you manage to compile the EDIT: apparently, you can use |
I think this is the most reasonable way forward. We could simply have a However, it appears my initial comment is not as straightforward; each of the VULKAN_HPP_MODULE_FRAGMENT // #defined as `module;`
#include <cstring>
VULKAN_HPP_EXPORT_MODULE // #defined as `export module vk;`
VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
{
...
struct ApplicationInfo
{
...
}
...
}
I have been trying to hand-convert
Could you elaborate on this? I haven't seen this before! |
I was trying your approach with if (VULKAN_HPP_EXPERIMENTAL_CPP20_MODULES)
# See https://www.kitware.com/import-cmake-c20-modules/
cmake_minimum_required(VERSION 3.26)
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
add_library(VulkanHppModule)
set_target_properties(VulkanHppModule PROPERTIES
CXX_STANDARD 20
CXX_EXTENSIONS OFF)
target_sources(VulkanHppModule
PUBLIC
FILE_SET cxx_modules TYPE CXX_MODULES FILES
${VulkanHeaders_INCLUDE_DIR}/vulkan/vulkan.hpp
#${VulkanHeaders_INCLUDE_DIR}/vulkan/vulkan_raii.hpp
)
set_source_files_properties(
${VulkanHeaders_INCLUDE_DIR}/vulkan/vulkan.hpp
#${VulkanHeaders_INCLUDE_DIR}/vulkan/vulkan_raii.hpp
PROPERTIES LANGUAGE CXX)
target_compile_definitions(VulkanHppModule PRIVATE -DVULKAN_HPP_EXPERIMENTAL_CPP20_MODULES=1)
endif()
to compile FAILED: CMakeFiles/VulkanHppModule.dir/CXX.dd
/snap/cmake/1299/bin/cmake -E cmake_ninja_dyndep --tdi=CMakeFiles/VulkanHppModule.dir/CXXDependInfo.json --lang=CXX --modmapfmt=clang --dd=CMakeFiles/VulkanHppModule.dir/CXX.dd @CM
akeFiles/VulkanHppModule.dir/CXX.dd.rsp
CMake Error: Output CMakeFiles/VulkanHppModule.dir/vulkan/vulkan.hpp.o is of type `CXX_MODULES` but does not provide a module with module;
#include <map>
#include <set>
#include <memory>
#include <utility> // std::exchange, std::forward
#include <cstring> // strcmp
#include <algorithm>
#include <vector>
#include <array>
#if __cpp_lib_format
# include <format> // std::format
#else
# include <sstream> // std::stringstream
#endif
#include <vulkan/vulkan.h>
export module vulkan;
#include <vulkan/vulkan.hpp> You can get quite close to a working module. Since I'm using
which causes a problem for the functions that are declared I think the cleanest solution would be to just re-export the symbols from a separate module file (e.g. main...theHamsta:Vulkan-Hpp:cpp20-modules). Do you want to create a PR to generate such a file(s) that define C++ modules? |
Yep, this is the same error I'm running into: main...sharadhr:Vulkan-Hpp:cpp20-modules, although my work is a lot less clean, I was still figuring out the codebase and I sort of mixed it in with my
Agreed on this, and your implementation looks great (never thought of One question: your code So, to summarise, we could have something like: module;
#include <vulkan/vulkan.hpp> // maybe defines `VULKAN_HPP_MODULE`?
#include <vulkan/vulkan_raii.hpp>
export module VULKAN_HPP_MODULE;
export namespace VULKAN_HPP_NAMESPACE {
using vk::ApplicationInfo;
using vk::createInstance;
using vk::InstanceCreateInfo;
using vk::Instance;
using vk::SystemError;
...
namespace VULKAN_HPP_RAII_NAMESPACE {
using namespace vk::raii::Buffer;
using namespace vk::raii::Image;
...
constexpr auto cApiVersion1_1 = VK_API_VERSION_1_1; // 'c' prefix for **c**onstant
...
}
Sounds good; I'll reset my code back and start working on the generator to produce |
Having
I think it would be fine for a first iteration of VulkanHpp modules to not be "complete". We always can add more exports if we see that something is missing in terms of feature parity with
I have no opinion on the file extension. |
But you're right. We don't need dyndeps for VulkanHpp. If it stays opt-in, it would be possible to do preprocessor magic with modules. |
@theHamsta, I have opened a PR, #1582. Looking forward to your feedback! |
That you! I'll have a look on Tuesday. I also want the main maintainer of this repo to do the final review. |
I've been wanting to add support for C++20 modules to Vulkan-Hpp ever since I began using it. I was thinking of implementing something similar to the MSVC STL macro for the C++ standard library, so that users could perform something like
The implementation follows. We could have, somewhere in
vulkan.hpp
:And in
vulkan_structs.hpp
:This is a fairly straightforward change that should massively improve compile times for modern compilers (MSVC ≥ 19.29 and Clang ≥ 16.0.0); I hope this is considered.
I've been working on adding this directly into the generator instead of hand-modifying the generated
.hpp
files, but I got sidetracked (#1579).The text was updated successfully, but these errors were encountered: