Can't compile c++20 module with std module
otreblan opened this issue · comments
OS: Arch linux
cmake=4.1.1-1clang=20.1.8-1ninja=1.12.1-2vulkan-headers=1.4.321.0-1
find_package(Vulkan REQUIRED)
# set up Vulkan C++ module as a library
add_library(VulkanHppModule)
target_sources(VulkanHppModule PUBLIC
FILE_SET CXX_MODULES
BASE_DIRS ${Vulkan_INCLUDE_DIR}
FILES ${Vulkan_INCLUDE_DIR}/vulkan/vulkan.cppm
)
set_target_properties(VulkanHppModule
PROPERTIES
CXX_STANDARD 23
)
target_compile_definitions(VulkanHppModule
PRIVATE
$<$<NOT:$<CONFIG:DEBUG>>:NDEBUG>
PUBLIC
$<$<CONFIG:DEBUG>:VK_DEBUG>
VULKAN_HPP_ENABLE_STD_MODULE
VULKAN_HPP_STD_MODULE=std
)
target_link_libraries(VulkanHppModule PUBLIC Vulkan::Vulkan)
[37/44] Building CXX object deps/CMakeFiles/VulkanHppModule.dir/usr/include/vulkan/vulkan.cppm.o
FAILED: deps/CMakeFiles/VulkanHppModule.dir/usr/include/vulkan/vulkan.cppm.o deps/CMakeFiles/VulkanHppModule.dir/vulkan_hpp.pcm
/usr/bin/clang++ -DVK_DEBUG -DVULKAN_HPP_ENABLE_STD_MODULE -DVULKAN_HPP_STD_MODULE=std -g -std=gnu++23 -D_GLIBCXX_DEBUG -MD -MT deps/CMakeFiles/VulkanHppModule.dir/usr/include/vulkan/vulkan.cppm.o -MF deps/CMakeFiles/VulkanHppModule.dir/usr/include/vulkan/vulkan.cppm.o.d @deps/CMakeFiles/VulkanHppModule.dir/usr/include/vulkan/vulkan.cppm.o.modmap -o deps/CMakeFiles/VulkanHppModule.dir/usr/include/vulkan/vulkan.cppm.o -c /usr/include/vulkan/vulkan.cppm
In file included from /usr/include/vulkan/vulkan.cppm:19:
In file included from /usr/include/vulkan/vulkan.hpp:9366:
/usr/include/vulkan/vulkan_structs.hpp:37811:7: error: missing '#include <stdlib.h>'; 'free' must be declared before it is used
37811 | free( pAddressInfos );
| ^
/usr/include/stdlib.h:687:13: note: declaration here is not visible
687 | extern void free (void *__ptr) __THROW;
| ^
In file included from /usr/include/vulkan/vulkan.cppm:19:
In file included from /usr/include/vulkan/vulkan.hpp:9366:
/usr/include/vulkan/vulkan_structs.hpp:37812:7: error: missing '#include <stdlib.h>'; 'free' must be declared before it is used
37812 | free( pVendorInfos );
| ^
/usr/include/stdlib.h:687:13: note: declaration here is not visible
687 | extern void free (void *__ptr) __THROW;
| ^
In file included from /usr/include/vulkan/vulkan.cppm:19:
In file included from /usr/include/vulkan/vulkan.hpp:9366:
/usr/include/vulkan/vulkan_structs.hpp:37813:7: error: missing '#include <stdlib.h>'; 'free' must be declared before it is used
37813 | free( pVendorBinaryData );
| ^
/usr/include/stdlib.h:687:13: note: declaration here is not visible
687 | extern void free (void *__ptr) __THROW;
| ^
In file included from /usr/include/vulkan/vulkan.cppm:19:
In file included from /usr/include/vulkan/vulkan.hpp:9366:
/usr/include/vulkan/vulkan_structs.hpp:37832:7: error: missing '#include <stdlib.h>'; 'free' must be declared before it is used
37832 | free( pAddressInfos );
| ^
/usr/include/stdlib.h:687:13: note: declaration here is not visible
687 | extern void free (void *__ptr) __THROW;
| ^
In file included from /usr/include/vulkan/vulkan.cppm:19:
In file included from /usr/include/vulkan/vulkan.hpp:9366:
/usr/include/vulkan/vulkan_structs.hpp:37833:7: error: missing '#include <stdlib.h>'; 'free' must be declared before it is used
37833 | free( pVendorInfos );
| ^
/usr/include/stdlib.h:687:13: note: declaration here is not visible
687 | extern void free (void *__ptr) __THROW;
| ^
In file included from /usr/include/vulkan/vulkan.cppm:19:
In file included from /usr/include/vulkan/vulkan.hpp:9366:
/usr/include/vulkan/vulkan_structs.hpp:37834:7: error: missing '#include <stdlib.h>'; 'free' must be declared before it is used
37834 | free( pVendorBinaryData );
| ^
/usr/include/stdlib.h:687:13: note: declaration here is not visible
687 | extern void free (void *__ptr) __THROW;
| ^
6 errors generated.
ninja: build stopped: subcommand failed.
The module implementation has not been touched much since conception, as CI can't really test it yet. Since module tests are currently being improved anyways, I might as well try and see if I can get import std working somehow and fix this issue meanwhile. There are a bunch of things that currently aren't exactly optimal (like forced #includes despite using import std).
Could you share what parameters you run your CMake with? Last time I tried it with CMake, I had issues trying to force it to use the clang stdlib.
On Linux with Clang I suspect the solution will be -stdlib=libc++, as the different std module libraries are not yet compatible with the opposite compiler.
As an aside, the module works for me on MSVC—I suspect (as always) a tooling problem rather than a compiler problem.
@sharadhr do you know whether C library headers are supposed to also be included with the std module? From what I can see, it only includes stuff from the std namespace (makes sense), so things like free() that are part of stdlib.h would not be included (as per the spec at least, implementations seem to differ).
One option would be to just use the C++ variants new and delete for these operations, but I don't have a full overview of how de-/allocations are handled here. @asuessenbach would it be feasible to get rid of C functions here?
Otherwise, C headers would need to be explictly included alongside import std when these functions are used. Or just add it to vulkan.hpp like the other exception headers written there:
Lines 13 to 17 in 16fa896
@sharadhr do you know whether C library headers are supposed to also be included with the std module?
Ahh, I remember this. Sadly no, C headers are not exported by std. Cpplang Slack link. Using new/delete would be the solution.
@otreblan Would you please verify if #2269 actually resolves your issue?
I tried to override my local vulkan-headers with FetchContent but it still uses /usr/include/vulkan/vulkan_core.h.
Also I found out that the module compiles with std if it has VULKAN_HPP_NO_STRUCT_CONSTRUCTORS=1 defined.
....
FetchContent_Declare(
vulkan
GIT_REPOSITORY https://github.com/M2-TE/Vulkan-Hpp
GIT_TAG origin/add-cstdlib-to-module
GIT_SHALLOW ON
GIT_PROGRESS ON
OVERRIDE_FIND_PACKAGE
)
FetchContent_MakeAvailable(imgui VulkanMemoryAllocator-Hpp vkfw vulkan)
find_package(Vulkan REQUIRED)
# set up Vulkan C++ module as a library
add_library(VulkanHppModule)
target_include_directories(VulkanHppModule
INTERFACE
${vulkan_SOURCE_DIR}
)
target_sources(VulkanHppModule PUBLIC
FILE_SET CXX_MODULES
BASE_DIRS ${vulkan_SOURCE_DIR}
FILES ${vulkan_SOURCE_DIR}/vulkan/vulkan.cppm
)
set_target_properties(VulkanHppModule
PROPERTIES
CXX_STANDARD 26
)
target_compile_definitions(VulkanHppModule
PRIVATE
$<$<NOT:$<CONFIG:DEBUG>>:NDEBUG>
PUBLIC
#VULKAN_HPP_NO_STRUCT_CONSTRUCTORS=1
VULKAN_HPP_ENABLE_STD_MODULE
VULKAN_HPP_STD_MODULE=std
)
target_link_libraries(VulkanHppModule PUBLIC Vulkan::Hpp)$ time cmake --build .
[9/37] Building CXX object deps/CMakeFiles/VulkanHppModule.dir/__/_deps/vulkan-src/vulkan/vulkan.cppm.o
FAILED: deps/CMakeFiles/VulkanHppModule.dir/__/_deps/vulkan-src/vulkan/vulkan.cppm.o deps/CMakeFiles/VulkanHppModule.dir/vulkan_hpp.pcm
/usr/bin/clang++ -DVULKAN_HPP_ENABLE_STD_MODULE -DVULKAN_HPP_STD_MODULE=std -I/home/aru/code/fdtd-vulkan/build/_deps/vulkan-src -g -std=gnu++26 -D_GLIBCXX_DEBUG -Wp,-D_FORTIFY_SOURCE=0 -Wno-macro-redefined -MD -MT deps/CMakeFiles/VulkanHppModule.dir/__/_deps/vulkan-src/vulkan/vulkan.cppm.o -MF deps/CMakeFiles/VulkanHppModule.dir/__/_deps/vulkan-src/vulkan/vulkan.cppm.o.d @deps/CMakeFiles/VulkanHppModule.dir/__/_deps/vulkan-src/vulkan/vulkan.cppm.o.modmap -o deps/CMakeFiles/VulkanHppModule.dir/__/_deps/vulkan-src/vulkan/vulkan.cppm.o -c /home/aru/code/fdtd-vulkan/build/_deps/vulkan-src/vulkan/vulkan.cppm
In file included from /home/aru/code/fdtd-vulkan/build/_deps/vulkan-src/vulkan/vulkan.cppm:19:
/home/aru/code/fdtd-vulkan/build/_deps/vulkan-src/vulkan/vulkan.hpp:60:16: error: static assertion failed due to requirement '321 == 326': Wrong VK_HEADER_VERSION!
60 | static_assert( VK_HEADER_VERSION == 326, "Wrong VK_HEADER_VERSION!" );
| ^~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/vulkan/vulkan_core.h:72:27: note: expanded from macro 'VK_HEADER_VERSION'
72 | #define VK_HEADER_VERSION 321
| ^
You could manually symlink /usr/include/vulkan/vulkan_core.h to your own Vulkan-Headers package include directory. I would probably symlink the entire directory /usr/include/vulkan to your Vulkan-Headers dir.
It works. I added the local vulkan headers to the module target.
target_include_directories(VulkanHppModule
PUBLIC
${vulkan_SOURCE_DIR}
${vulkan_SOURCE_DIR}/Vulkan-Headers/include
)Also I found out that the module compiles with std if it has VULKAN_HPP_NO_STRUCT_CONSTRUCTORS=1 defined
Could you open a separate issue about this? That doesn't seem right..
It works.
Assuming, this is related to my question, whether #2269 resolves your issue, I'll merge that.
Thanks a lot for reporting this issue!