diff --git a/CMakeLists.txt b/CMakeLists.txt index 92687aba..7e9d1c06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,9 @@ cmake_minimum_required(VERSION 3.28) -project(msft_proxy VERSION 3.3.0 LANGUAGES CXX) -add_library(msft_proxy INTERFACE) +project(msft_proxy4 VERSION 3.3.0 LANGUAGES CXX) +add_library(msft_proxy4 INTERFACE) +set_target_properties(msft_proxy4 PROPERTIES EXPORT_NAME proxy4) +add_library(msft_proxy::proxy4 ALIAS msft_proxy4) # Do not enable building tests if proxy is consumed as # subdirectory (e.g. by CMake FetchContent_Declare). @@ -19,7 +21,7 @@ if(PROJECT_IS_TOP_LEVEL) ) endif() -target_sources(msft_proxy +target_sources(msft_proxy4 INTERFACE FILE_SET public_headers TYPE HEADERS @@ -28,53 +30,64 @@ target_sources(msft_proxy include/proxy/proxy.h include/proxy/proxy_macros.h include/proxy/proxy_fmt.h - include/proxy/proxy.ixx + include/proxy/v4/proxy.ixx + include/proxy/v4/proxy.h + include/proxy/v4/proxy_macros.h + include/proxy/v4/proxy_fmt.h ) -target_compile_features(msft_proxy INTERFACE cxx_std_20) -target_include_directories(msft_proxy INTERFACE $ +target_compile_features(msft_proxy4 INTERFACE cxx_std_20) +target_include_directories(msft_proxy4 INTERFACE $ $) # Do not set the module target if proxy is consumed as a subdirectory. if(PROJECT_IS_TOP_LEVEL) - set(proxy_INCLUDE_DIR include) + set(proxy4_INCLUDE_DIR include) if(PROXY_BUILD_MODULES) - include(cmake/proxyModuleTargets.cmake) + include(cmake/proxy4ModuleTargets.cmake) endif() else() # Propagate the variable to the parent project - set(proxy_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE) + set(proxy4_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE) endif() # install and export the project. project name - proxy include(GNUInstallDirs) -install(TARGETS msft_proxy - EXPORT proxyTargets +install(TARGETS msft_proxy4 + EXPORT proxy4Targets FILE_SET public_headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) -install(EXPORT proxyTargets DESTINATION ${CMAKE_INSTALL_DATADIR}/proxy) -export(TARGETS msft_proxy FILE proxyTargets.cmake) +install( + EXPORT proxy4Targets + NAMESPACE msft_proxy:: + DESTINATION ${CMAKE_INSTALL_DATADIR}/proxy +) +export( + TARGETS msft_proxy4 + NAMESPACE msft_proxy:: + FILE proxy4Targets.cmake +) include(CMakePackageConfigHelpers) configure_package_config_file( - cmake/proxyConfig.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/cmake/proxyConfig.cmake + cmake/proxy4Config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/cmake/proxy4Config.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_DATADIR}/proxy PATH_VARS CMAKE_INSTALL_INCLUDEDIR ) include(CMakePackageConfigHelpers) -write_basic_package_version_file(cmake/proxyConfigVersion.cmake +write_basic_package_version_file(cmake/proxy4ConfigVersion.cmake COMPATIBILITY SameMajorVersion ARCH_INDEPENDENT) install( FILES - ${CMAKE_CURRENT_BINARY_DIR}/cmake/proxyConfig.cmake - ${CMAKE_CURRENT_BINARY_DIR}/cmake/proxyConfigVersion.cmake + ${CMAKE_CURRENT_BINARY_DIR}/cmake/proxy4Config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/cmake/proxy4ConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_DATADIR}/proxy ) diff --git a/README.md b/README.md index b7923c2e..81dc72ec 100644 --- a/README.md +++ b/README.md @@ -35,12 +35,12 @@ Please refer to the [Proxy's Frequently Asked Questions](https://microsoft.githu ```cmake CPMAddPackage( - NAME proxy + NAME proxy4 GIT_TAG 4.0.0 # or above GIT_REPOSITORY https://github.com/microsoft/proxy.git ) - target_link_libraries(main PRIVATE msft_proxy) + target_link_libraries(main PRIVATE msft_proxy::proxy4) ``` ### Hello World diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt index 393f5cd9..e99356d5 100644 --- a/benchmarks/CMakeLists.txt +++ b/benchmarks/CMakeLists.txt @@ -22,7 +22,7 @@ add_executable(msft_proxy_benchmarks proxy_management_benchmark.cpp ) target_include_directories(msft_proxy_benchmarks PRIVATE .) -target_link_libraries(msft_proxy_benchmarks PRIVATE msft_proxy benchmark::benchmark benchmark::benchmark_main) +target_link_libraries(msft_proxy_benchmarks PRIVATE msft_proxy::proxy4 benchmark::benchmark benchmark::benchmark_main) if (MSVC) target_compile_options(msft_proxy_benchmarks PRIVATE /W4) diff --git a/cmake/proxy4Config.cmake.in b/cmake/proxy4Config.cmake.in new file mode 100644 index 00000000..b0f9e4ed --- /dev/null +++ b/cmake/proxy4Config.cmake.in @@ -0,0 +1,5 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/proxy4Targets.cmake") + +set(proxy4_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@") diff --git a/cmake/proxy4ModuleTargets.cmake b/cmake/proxy4ModuleTargets.cmake new file mode 100644 index 00000000..5ec96bc2 --- /dev/null +++ b/cmake/proxy4ModuleTargets.cmake @@ -0,0 +1,25 @@ + +if(NOT DEFINED proxy4_INCLUDE_DIR) + message(FATAL_ERROR "proxy4_INCLUDE_DIR must be defined to use this script.") +endif() + +message(STATUS "Declaring `msft_proxy::proxy4_module` target for include path ${proxy4_INCLUDE_DIR}") + +add_library(msft_proxy4_module) +set_target_properties( + msft_proxy4_module + PROPERTIES + SYSTEM TRUE + EXCLUDE_FROM_ALL TRUE +) + +add_library(msft_proxy::proxy4_module ALIAS msft_proxy4_module) +target_sources(msft_proxy4_module PUBLIC + FILE_SET CXX_MODULES + BASE_DIRS ${proxy4_INCLUDE_DIR} + FILES + ${proxy4_INCLUDE_DIR}/proxy/v4/proxy.ixx +) +target_compile_features(msft_proxy4_module PUBLIC cxx_std_20) +target_link_libraries(msft_proxy4_module PUBLIC msft_proxy::proxy4) + diff --git a/cmake/proxyConfig.cmake.in b/cmake/proxyConfig.cmake.in deleted file mode 100644 index 6023b7e3..00000000 --- a/cmake/proxyConfig.cmake.in +++ /dev/null @@ -1,5 +0,0 @@ -@PACKAGE_INIT@ - -include("${CMAKE_CURRENT_LIST_DIR}/proxyTargets.cmake") - -set(proxy_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@") diff --git a/cmake/proxyModuleTargets.cmake b/cmake/proxyModuleTargets.cmake deleted file mode 100644 index 7cf2878b..00000000 --- a/cmake/proxyModuleTargets.cmake +++ /dev/null @@ -1,25 +0,0 @@ - -if(NOT DEFINED proxy_INCLUDE_DIR) - message(FATAL_ERROR "proxy_INCLUDE_DIR must be defined to use this script.") -endif() - -message(STATUS "Declaring `msft_proxy::module` target for include path ${proxy_INCLUDE_DIR}") - -add_library(msft_proxy_module) -set_target_properties( - msft_proxy_module - PROPERTIES - SYSTEM TRUE - EXCLUDE_FROM_ALL TRUE -) - -add_library(msft_proxy::module ALIAS msft_proxy_module) -target_sources(msft_proxy_module PUBLIC - FILE_SET CXX_MODULES - BASE_DIRS ${proxy_INCLUDE_DIR} - FILES - ${proxy_INCLUDE_DIR}/proxy/proxy.ixx -) -target_compile_features(msft_proxy_module PUBLIC cxx_std_20) -target_link_libraries(msft_proxy_module PUBLIC msft_proxy) - diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 875f42c3..32ad4831 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -17,7 +17,7 @@ set_source_files_properties(${EXAMPLE_SOURCES} PROPERTIES GENERATED TRUE) foreach(SOURCE ${EXAMPLE_SOURCES}) get_filename_component(EXECUTABLE_NAME ${SOURCE} NAME_WE) add_executable(${EXECUTABLE_NAME} ${SOURCE}) - target_link_libraries(${EXECUTABLE_NAME} PRIVATE msft_proxy) + target_link_libraries(${EXECUTABLE_NAME} PRIVATE msft_proxy::proxy4) if (MSVC) target_compile_options(${EXECUTABLE_NAME} PRIVATE /W4) elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") diff --git a/docs/cpp20_modules_support.md b/docs/cpp20_modules_support.md index 752a1196..932d4e8c 100644 --- a/docs/cpp20_modules_support.md +++ b/docs/cpp20_modules_support.md @@ -5,43 +5,43 @@ The "Proxy" library ships with `.ixx` files starting with version **4.0.0**. Com As of 2025-05-11, CMake lacks support for forward compatibility when consuming C++ modules, which causes consumers with newer C++ standard to be unable to use modules with older standard. Until this is implemented by CMake, a CMake target containing the module can be manually declared using the following CMake script: ```cmake -find_package(proxy REQUIRED) +find_package(proxy4 REQUIRED) -if(NOT DEFINED proxy_INCLUDE_DIR) # (1) +if(NOT DEFINED proxy4_INCLUDE_DIR) # (1) if(NOT DEFINED proxy_SOURCE_DIR) - message(FATAL_ERROR "proxy_INCLUDE_DIR or proxy_SOURCE_DIR must be defined to use this script.") + message(FATAL_ERROR "proxy4_INCLUDE_DIR or proxy_SOURCE_DIR must be defined to use this script.") endif() - set(proxy_INCLUDE_DIR ${proxy_SOURCE_DIR}/include) + set(proxy4_INCLUDE_DIR ${proxy_SOURCE_DIR}/include) endif() -message(STATUS "Declaring `msft_proxy::module` target for include path ${proxy_INCLUDE_DIR}") +message(STATUS "Declaring `msft_proxy::proxy4_module` target for include path ${proxy4_INCLUDE_DIR}") -add_library(msft_proxy_module) +add_library(msft_proxy4_module) set_target_properties( - msft_proxy_module + msft_proxy4_module PROPERTIES SYSTEM TRUE EXCLUDE_FROM_ALL TRUE ) -add_library(msft_proxy::module ALIAS msft_proxy_module) -target_sources(msft_proxy_module PUBLIC +add_library(msft_proxy::proxy4_module ALIAS msft_proxy4_module) +target_sources(msft_proxy4_module PUBLIC FILE_SET CXX_MODULES - BASE_DIRS ${proxy_INCLUDE_DIR} + BASE_DIRS ${proxy4_INCLUDE_DIR} FILES - ${proxy_INCLUDE_DIR}/proxy/proxy.ixx + ${proxy4_INCLUDE_DIR}/proxy/v4/proxy.ixx ) -target_compile_features(msft_proxy_module PUBLIC cxx_std_20) # (2) -target_link_libraries(msft_proxy_module PUBLIC msft_proxy) +target_compile_features(msft_proxy4_module PUBLIC cxx_std_20) # (2) +target_link_libraries(msft_proxy4_module PUBLIC msft_proxy::proxy4) ``` -- (1) `proxy_INCLUDE_DIR` is automatically declared after `find_package(proxy)`. CPM uses a slightly different convention where `proxy_SOURCE_DIR` is declared after `CPMAddPackage`. -- (2) The C++ standard version for `msft_proxy_module` target should be the same or higher than the consumer CMake target. For example if your project is using C++23 mode, this line should be changed to `cxx_std_23` or `cxx_std_26` / newer standards. +- (1) `proxy4_INCLUDE_DIR` is automatically declared after `find_package(proxy4)`. CPM uses a slightly different convention where `proxy_SOURCE_DIR` is declared after `CPMAddPackage`. +- (2) The C++ standard version for `msft_proxy4_module` target should be the same or higher than the consumer CMake target. For example if your project is using C++23 mode, this line should be changed to `cxx_std_23` or `cxx_std_26` / newer standards. It can then be consumed like this: ```cmake -target_link_libraries(main PRIVATE msft_proxy::module) +target_link_libraries(main PRIVATE msft_proxy::proxy4_module) ``` ## Example @@ -58,7 +58,7 @@ module; export module dictionary; -import proxy; // (3) +import proxy.v4; // (3) extern "C++" { // (4) PRO_DEF_MEM_DISPATCH(MemAt, at); @@ -77,7 +77,7 @@ Client: #include #include -import proxy; +import proxy.v4; import dictionary; int main() { @@ -90,6 +90,6 @@ int main() { - (1) This is a traditional header rather than a module. It should be declared in global fragment (after `module` and before `export module`). - (2) This makes all `PRO_DEF_` macros available. This header file contains only some macros and are therefore very fast to compile. -- (3) `import proxy;` makes all public interfaces from `pro` namespace available in the current translation unit. +- (3) `import proxy.v4;` makes all public interfaces from `pro::v4` namespace available in the current translation unit. - (4) As of 2025-05-11, clangd requires the accessor struct to be either `export`-ed, or be declared within an `extern "C++"` block, in order to have auto completion working. diff --git a/include/proxy/proxy.h b/include/proxy/proxy.h index c3697d94..665e2829 100644 --- a/include/proxy/proxy.h +++ b/include/proxy/proxy.h @@ -4,2378 +4,6 @@ #ifndef _MSFT_PROXY_ #define _MSFT_PROXY_ -#include "proxy_macros.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if __STDC_HOSTED__ -#include -#if __has_include() -#include -#endif // __has_include() -#endif // __STDC_HOSTED__ - -#if __cpp_rtti >= 199711L -#include -#include -#endif // __cpp_rtti >= 199711L - -#if __has_cpp_attribute(msvc::no_unique_address) -#define ___PRO_NO_UNIQUE_ADDRESS_ATTRIBUTE msvc::no_unique_address -#elif __has_cpp_attribute(no_unique_address) -#define ___PRO_NO_UNIQUE_ADDRESS_ATTRIBUTE no_unique_address -#else -#error Proxy requires C++20 attribute no_unique_address. -#endif - -#if __cpp_exceptions >= 199711L -#define ___PRO_THROW(...) throw __VA_ARGS__ -#else -#define ___PRO_THROW(...) std::abort() -#endif // __cpp_exceptions >= 199711L - -namespace pro { - -namespace details { - -struct applicable_traits { static constexpr bool applicable = true; }; -struct inapplicable_traits { static constexpr bool applicable = false; }; - -template