Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 57 additions & 5 deletions modules/CheckCXXFeatures.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ macro(vgkit_check_libcxx_linker_mismatch)
#include <unordered_map>
#include <string>
int main() { std::unordered_map<std::string,int> m; m[\"k\"]=1; return 0; }
" VGKIT_LIBCXX_LINKS)
" VGKIT_LIBCXX_LINKS_${PROJECT_NAME})
cmake_pop_check_state()

if (NOT VGKIT_LIBCXX_LINKS)
if (NOT VGKIT_LIBCXX_LINKS_${PROJECT_NAME})
# Derive libc++ lib dir: -print-resource-dir gives <root>/lib/clang/<ver>
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -print-resource-dir
Expand All @@ -97,10 +97,10 @@ int main() { std::unordered_map<std::string,int> m; m[\"k\"]=1; return 0; }
#include <unordered_map>
#include <string>
int main() { std::unordered_map<std::string,int> m; m[\"k\"]=1; return 0; }
" VGKIT_LIBCXX_LINKS_WITH_FLAGS)
" VGKIT_LIBCXX_LINKS_WITH_FLAGS_${PROJECT_NAME})
cmake_pop_check_state()

if (VGKIT_LIBCXX_LINKS_WITH_FLAGS)
if (VGKIT_LIBCXX_LINKS_WITH_FLAGS_${PROJECT_NAME})
if (_clmm_modify_global)
message(STATUS "libc++ linker mismatch detected; adding -L${_clang_libcxx_dir} to global linker flags")
string(APPEND CMAKE_EXE_LINKER_FLAGS
Expand Down Expand Up @@ -137,4 +137,56 @@ int main() { std::unordered_map<std::string,int> m; m[\"k\"]=1; return 0; }

unset(_clmm_modify_global)

endmacro(vgkit_check_libcxx_linker_mismatch)
endmacro(vgkit_check_libcxx_linker_mismatch)

# P0522R0 (relaxed matching of template template arguments) is required by
# code that passes class templates with defaulted parameters (e.g.
# small_vector<T, N=...>) to template template parameters expecting fewer
# args (e.g. template <class> class Container).
#
# - GCC has supported this since GCC 7 (default in all C++17 modes)
# - LLVM Clang enabled it by default in Clang 19; earlier versions need
# -frelaxed-template-template-args
# - AppleClang 17+ works; AppleClang 16 and earlier do not support it at all
#
# This macro tests whether P0522R0 works out of the box and, if not, tries
# adding -frelaxed-template-template-args.
#
# Sets VGKIT_P0522R0_COMPILE_FLAG in the caller's scope to the compile
# option needed (empty string if P0522R0 works natively). The caller
# decides how to apply it (e.g. target_compile_options on specific targets).
# On failure, emits FATAL_ERROR.
macro(vgkit_check_p0522r0)

set(VGKIT_P0522R0_COMPILE_FLAG)

cmake_push_check_state(RESET)
check_cxx_source_compiles("
template <class T, int N = 10> struct SmallVec {};
template <template <class> class C> void f() { C<int> v; }
int main() { f<SmallVec>(); return 0; }
" VGKIT_CXX_HAS_P0522R0)
cmake_pop_check_state()

if (NOT VGKIT_CXX_HAS_P0522R0)
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_FLAGS "-frelaxed-template-template-args")
check_cxx_source_compiles("
template <class T, int N = 10> struct SmallVec {};
template <template <class> class C> void f() { C<int> v; }
int main() { f<SmallVec>(); return 0; }
" VGKIT_CXX_HAS_P0522R0_WITH_FLAG)
cmake_pop_check_state()

if (VGKIT_CXX_HAS_P0522R0_WITH_FLAG)
set(VGKIT_P0522R0_COMPILE_FLAG "-frelaxed-template-template-args")
message(STATUS "P0522R0 requires -frelaxed-template-template-args")
else()
message(FATAL_ERROR
"Compiler does not support P0522R0 (relaxed template template argument matching), "
"even with -frelaxed-template-template-args. Use a newer compiler "
"(GCC >= 7, Clang >= 19, or AppleClang >= 17).")
endif()
endif()

endmacro(vgkit_check_p0522r0)