diff --git a/CMakeLists.txt b/CMakeLists.txt index 11da64e5..2f5548e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,57 +4,54 @@ project (ecs CXX) set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# Set up some options +set(CMAKE_COMPILE_WARNING_AS_ERROR ON) set(ECS_STANDALONE_PROJECT OFF) + + +# Set up some user-changeable options option(ECS_COMPILE_AS_MODULE "Compile 'ecs' to a module" OFF) option(ECS_ENABLE_CONTRACTS "Use contracts internally to verify state" ON) option(ECS_ENABLE_CONTRACTS_AUDIT "Enable expensive contracts. Should only be used for debugging" OFF) + +# Set up the project if (ECS_COMPILE_AS_MODULE) # Module stuff (experimental) include(cxx_modules_rules.cmake) + # creates module library 'ecs' add_library(ecs) target_compile_definitions(ecs PUBLIC ECS_USE_MODULES) target_sources(ecs PUBLIC FILE_SET CXX_MODULES FILES "include/ecs/ecs.ixx") - if (ECS_ENABLE_CONTRACTS) - target_compile_definitions(ecs PUBLIC ECS_ENABLE_CONTRACTS) - - if (ECS_ENABLE_CONTRACTS_AUDIT) - target_compile_definitions(ecs PUBLIC ECS_ENABLE_CONTRACTS_AUDIT) - endif () - endif () + # Set project scope + set(ECS_INTERNAL_SCOPE PUBLIC) + set(ECS_INTERNAL_SCOPE_PRIV PRIVATE) else() - # creates a library 'ecs' which is an interface (header files only) + # creates header-only library 'ecs' add_library(ecs INTERFACE) - - install( - DIRECTORY include/ecs - DESTINATION include - ) - target_compile_definitions(ecs INTERFACE ECS_EXPORT=) - if (ECS_ENABLE_CONTRACTS) - target_compile_definitions(ecs INTERFACE ECS_ENABLE_CONTRACTS) - - if (ECS_ENABLE_CONTRACTS_AUDIT) - target_compile_definitions(ecs INTERFACE ECS_ENABLE_CONTRACTS_AUDIT) - endif () - endif () + # Set project scope + set(ECS_INTERNAL_SCOPE INTERFACE) + set(ECS_INTERNAL_SCOPE_PRIV INTERFACE) endif() + +# Setup contract definitions +target_compile_definitions(ecs ${ECS_INTERNAL_SCOPE_PRIV} + ECS_ENABLE_CONTRACTS=$ + ECS_ENABLE_CONTRACTS_AUDIT=$,$>,1,0> +) + # determine whether this is a standalone project or included by other projects if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(ECS_STANDALONE_PROJECT ON) endif () +# Set compiler-specific flags if (MSVC) - target_compile_options(ecs INTERFACE - #/std:c++latest - + target_compile_options(ecs ${ECS_INTERNAL_SCOPE} # enable lots of warnings /W4 @@ -62,9 +59,6 @@ if (MSVC) /experimental:module /EHsc - # treat warnings as errors - /WX - # -- Dump compilation info --- #/Bt # total time spent in frontend (d1) and backend (d2) #/d1templateStats # show info regarding template use @@ -87,23 +81,16 @@ if (MSVC) # Enable address sanitizer #/fsanitize=address - ) - - # enable profiling - #target_compile_options(ecs INTERFACE /Zi) - #target_link_options(ecs INTERFACE /PROFILE) - - # Disable C++ exceptions. - #string(REGEX REPLACE "/EH[a-z]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHs-c-") - #add_definitions(-D_HAS_EXCEPTIONS=0) + ) - # Disable RTTI. - #string(REGEX REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-") + # enable profiling for 'RelWithDebInfo' builds + if (CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo) + target_compile_options(ecs ${ECS_INTERNAL_SCOPE} /Zi) + target_link_options(ecs ${ECS_INTERNAL_SCOPE} /PROFILE) + endif() else() # lots of warnings - target_compile_options(ecs INTERFACE + target_compile_options(ecs ${ECS_INTERNAL_SCOPE} #-std=c++2a -Wall -Wextra @@ -112,43 +99,40 @@ else() #-Wsign-conversion #-ftime-trace # produce json flamegraph files. open with chrome://tracing or edge://tracing ) - target_link_options(ecs INTERFACE -pthread) - - # Disable C++ exceptions. - # - fails to compile on gcc 10 - if (Clang) - string(REGEX REPLACE "-fexceptions" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions") - endif() - - # Disable RTTI. - # - clang's std::function::target needs rtti -_- - if (GNU) - string(REGEX REPLACE "-frtti" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") - endif() + target_link_options(ecs ${ECS_INTERNAL_SCOPE} -pthread) endif() -# Project headers + +# Project headers. # add include folders to the library and targets that consume it # the SYSTEM keyword suppresses warnings for users of the library -if(ECS_STANDALONE_PROJECT) - target_include_directories(ecs INTERFACE - $ - ) +if (ECS_COMPILE_AS_MODULE) + if(ECS_STANDALONE_PROJECT) + target_include_directories(ecs SYSTEM ${ECS_INTERNAL_SCOPE} + $ + ) + endif() else() - target_include_directories(ecs SYSTEM INTERFACE - $ - ) + if(ECS_STANDALONE_PROJECT) + target_include_directories(ecs INTERFACE + $ + ) + else() + target_include_directories(ecs SYSTEM INTERFACE + $ + ) + endif() endif() # add tls library add_subdirectory ("tls") -target_link_libraries(ecs INTERFACE tls) +target_link_libraries(ecs ${ECS_INTERNAL_SCOPE} tls) if (ECS_STANDALONE_PROJECT) # Benchmark diff --git a/include/ecs/detail/contract.h b/include/ecs/detail/contract.h index 9f4344a7..dd491b2a 100644 --- a/include/ecs/detail/contract.h +++ b/include/ecs/detail/contract.h @@ -47,7 +47,7 @@ template auto contract_violation_handler = ecs::detail::default_contract_violation_impl{}; } -#if defined(ECS_ENABLE_CONTRACTS) +#if ECS_ENABLE_CONTRACTS namespace ecs::detail { template @@ -89,7 +89,7 @@ inline void do_postcondition_violation(char const* what, char const* how) { } while (false) // Audit contracts. Used for expensive checks; can be disabled. -#if defined(ECS_ENABLE_CONTRACTS_AUDIT) +#if ECS_ENABLE_CONTRACTS_AUDIT #define AssertAudit(expression, message) Assert(expression, message) #define PreAudit(expression, message) Pre(expression, message) #define PostAudit(expression, message) Post(expression, message) diff --git a/include/ecs/ecs.ixx b/include/ecs/ecs.ixx index 9c9adf11..afe1d59a 100644 --- a/include/ecs/ecs.ixx +++ b/include/ecs/ecs.ixx @@ -931,7 +931,7 @@ template auto contract_violation_handler = ecs::detail::default_contract_violation_impl{}; } -#if defined(ECS_ENABLE_CONTRACTS) +#if ECS_ENABLE_CONTRACTS namespace ecs::detail { template @@ -973,7 +973,7 @@ inline void do_postcondition_violation(char const* what, char const* how) { } while (false) // Audit contracts. Used for expensive checks; can be disabled. -#if defined(ECS_ENABLE_CONTRACTS_AUDIT) +#if ECS_ENABLE_CONTRACTS_AUDIT #define AssertAudit(expression, message) Assert(expression, message) #define PreAudit(expression, message) Pre(expression, message) #define PostAudit(expression, message) Post(expression, message) diff --git a/include/ecs/ecs_sh.h b/include/ecs/ecs_sh.h index b21d6db7..0fbc54c4 100644 --- a/include/ecs/ecs_sh.h +++ b/include/ecs/ecs_sh.h @@ -931,7 +931,7 @@ template auto contract_violation_handler = ecs::detail::default_contract_violation_impl{}; } -#if defined(ECS_ENABLE_CONTRACTS) +#if ECS_ENABLE_CONTRACTS namespace ecs::detail { template @@ -973,7 +973,7 @@ inline void do_postcondition_violation(char const* what, char const* how) { } while (false) // Audit contracts. Used for expensive checks; can be disabled. -#if defined(ECS_ENABLE_CONTRACTS_AUDIT) +#if ECS_ENABLE_CONTRACTS_AUDIT #define AssertAudit(expression, message) Assert(expression, message) #define PreAudit(expression, message) Pre(expression, message) #define PostAudit(expression, message) Post(expression, message)