diff --git a/.cmake-format b/.cmake-format new file mode 100644 index 0000000..981cd19 --- /dev/null +++ b/.cmake-format @@ -0,0 +1,25 @@ +format: + line_width: 100 + tab_size: 4 + use_tabchars: false + max_subgroups_hwrap: 3 + max_pargs_hwrap: 5 + separate_ctrl_name_with_space: false + separate_fn_name_with_space: false + dangle_parens: false + dangle_align: child + line_ending: unix + command_case: canonical + keyword_case: upper + enable_sort: true + autosort: true +markup: + bullet_char: "*" + enum_char: . + enable_markup: false +additional_commands: + target_link_libraries: + kwargs: + PUBLIC: "*" + SHARED: "*" + PRIVATE: "*" diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..997504b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# SCM syntax highlighting & preventing 3-way merges +pixi.lock merge=binary linguist-language=YAML linguist-generated=true -diff diff --git a/.gitignore b/.gitignore index 24dd39e..d019ea7 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,8 @@ .idea/workspace.xml /build/ /clang-coverage/ -*.gcov \ No newline at end of file +*.gcov +*.bin +# pixi environments +.pixi/* +!.pixi/config.toml diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d95a37..e96e0c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,48 +9,56 @@ include(CheckCXXCompilerFlag) include(cmake/Coverage.cmake) include(cmake/Valgrind.cmake) -if (MSVC) +if(MSVC) check_cxx_compiler_flag("/arch:AVX2" COMPILER_SUPPORTS_AVX2) -else () +else() check_cxx_compiler_flag("-mavx2" COMPILER_SUPPORTS_AVX2) -endif () +endif() option(OMATH_BUILD_TESTS "Build unit tests" OFF) option(OMATH_BUILD_BENCHMARK "Build benchmarks" OFF) -option(OMATH_THREAT_WARNING_AS_ERROR "Set highest level of warnings and force compiler to treat them as errors" ON) +option(OMATH_THREAT_WARNING_AS_ERROR + "Set highest level of warnings and force compiler to treat them as errors" ON) option(OMATH_BUILD_AS_SHARED_LIBRARY "Build Omath as .so or .dll" OFF) option(OMATH_USE_AVX2 "Omath will use AVX2 to boost performance" ${COMPILER_SUPPORTS_AVX2}) option(OMATH_IMGUI_INTEGRATION "Omath will define method to convert omath types to imgui types" OFF) option(OMATH_BUILD_EXAMPLES "Build example projects with you can learn & play" OFF) option(OMATH_STATIC_MSVC_RUNTIME_LIBRARY "Force Omath to link static runtime" OFF) -option(OMATH_SUPRESS_SAFETY_CHECKS "Supress some safety checks in release build to improve general performance" ON) -option(OMATH_ENABLE_LEGACY "Will enable legacy classes that MUST be used ONLY for backward compatibility" ON) +option(OMATH_ENABLE_LEGACY + "Will enable legacy classes that MUST be used ONLY for backward compatibility" ON) +option(OMATH_SUPRESS_SAFETY_CHECKS + "Supress some safety checks in release build to improve general performance" ON) option(OMATH_ENABLE_COVERAGE "Enable coverage" OFF) -option(OMATH_ENABLE_FORCE_INLINE "Will for compiler to make some functions to be force inlined no matter what" ON) -if (VCPKG_MANIFEST_FEATURES) - foreach (omath_feature IN LISTS VCPKG_MANIFEST_FEATURES) - if (omath_feature STREQUAL "imgui") +option(OMATH_ENABLE_FORCE_INLINE + "Will for compiler to make some functions to be force inlined no matter what" ON) +if(VCPKG_MANIFEST_FEATURES) + foreach(omath_feature IN LISTS VCPKG_MANIFEST_FEATURES) + if(omath_feature STREQUAL "imgui") set(OMATH_IMGUI_INTEGRATION ON) - elseif (omath_feature STREQUAL "avx2") + elseif(omath_feature STREQUAL "avx2") set(OMATH_USE_AVX2 ${COMPILER_SUPPORTS_AVX2}) - elseif (omath_feature STREQUAL "tests") + elseif(omath_feature STREQUAL "tests") set(OMATH_BUILD_TESTS ON) - elseif (omath_feature STREQUAL "benchmark") + elseif(omath_feature STREQUAL "benchmark") set(OMATH_BUILD_BENCHMARK ON) - elseif (omath_feature STREQUAL "examples") + elseif(omath_feature STREQUAL "examples") set(OMATH_BUILD_EXAMPLES ON) - endif () + endif() - endforeach () -endif () + endforeach() +endif() -if (OMATH_USE_AVX2 AND NOT COMPILER_SUPPORTS_AVX2) - message(WARNING "OMATH_USE_AVX2 requested, but compiler/target does not support AVX2. Disabling.") +if(OMATH_USE_AVX2 AND NOT COMPILER_SUPPORTS_AVX2) + message( + WARNING "OMATH_USE_AVX2 requested, but compiler/target does not support AVX2. Disabling.") set(OMATH_USE_AVX2 OFF CACHE BOOL "Omath will use AVX2 to boost performance" FORCE) -endif () +endif() -if (${PROJECT_IS_TOP_LEVEL}) - message(STATUS "[${PROJECT_NAME}]: Building on ${CMAKE_HOST_SYSTEM_NAME}, compiler ${CMAKE_CXX_COMPILER_ID}") +if(${PROJECT_IS_TOP_LEVEL}) + message( + STATUS + "[${PROJECT_NAME}]: Building on ${CMAKE_HOST_SYSTEM_NAME}, compiler ${CMAKE_CXX_COMPILER_ID}" + ) message(STATUS "[${PROJECT_NAME}]: Warnings as errors ${OMATH_THREAT_WARNING_AS_ERROR}") message(STATUS "[${PROJECT_NAME}]: Build unit tests ${OMATH_BUILD_TESTS}") message(STATUS "[${PROJECT_NAME}]: Build benchmark ${OMATH_BUILD_BENCHMARK}") @@ -64,62 +72,63 @@ if (${PROJECT_IS_TOP_LEVEL}) message(STATUS "[${PROJECT_NAME}]: Building using vcpkg ${OMATH_BUILD_VIA_VCPKG}") message(STATUS "[${PROJECT_NAME}]: Coverage feature status ${OMATH_ENABLE_COVERAGE}") message(STATUS "[${PROJECT_NAME}]: Valgrind feature status ${OMATH_ENABLE_VALGRIND}") -endif () +endif() file(GLOB_RECURSE OMATH_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp") file(GLOB_RECURSE OMATH_HEADERS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp") -if (OMATH_BUILD_AS_SHARED_LIBRARY) +if(OMATH_BUILD_AS_SHARED_LIBRARY) add_library(${PROJECT_NAME} SHARED ${OMATH_SOURCES} ${OMATH_HEADERS}) -else () +else() add_library(${PROJECT_NAME} STATIC ${OMATH_SOURCES} ${OMATH_HEADERS}) -endif () - +endif() add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) target_compile_definitions(${PROJECT_NAME} PUBLIC OMATH_VERSION="${PROJECT_VERSION}") -if (OMATH_IMGUI_INTEGRATION) +if(OMATH_IMGUI_INTEGRATION) target_compile_definitions(${PROJECT_NAME} PUBLIC OMATH_IMGUI_INTEGRATION) # IMGUI is being linked as submodule - if (TARGET imgui) + if(TARGET imgui) target_link_libraries(${PROJECT_NAME} PUBLIC imgui) - install(TARGETS imgui - EXPORT omathTargets - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin) - else () + install( + TARGETS imgui + EXPORT omathTargets + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin) + else() # Assume that IMGUI linked via VCPKG. find_package(imgui CONFIG REQUIRED) target_link_libraries(${PROJECT_NAME} PUBLIC imgui::imgui) - endif () + endif() -endif () +endif() -if (OMATH_USE_AVX2) +if(OMATH_USE_AVX2) target_compile_definitions(${PROJECT_NAME} PUBLIC OMATH_USE_AVX2) -endif () +endif() -if (OMATH_SUPRESS_SAFETY_CHECKS) +if(OMATH_SUPRESS_SAFETY_CHECKS) target_compile_definitions(${PROJECT_NAME} PUBLIC OMATH_SUPRESS_SAFETY_CHECKS) -endif () +endif() -if (OMATH_ENABLE_LEGACY) +if(OMATH_ENABLE_LEGACY) target_compile_definitions(${PROJECT_NAME} PUBLIC OMATH_ENABLE_LEGACY) -endif () +endif() -if (OMATH_ENABLE_FORCE_INLINE) +if(OMATH_ENABLE_FORCE_INLINE) target_compile_definitions(${PROJECT_NAME} PUBLIC OMATH_ENABLE_FORCE_INLINE) -endif () +endif() -set_target_properties(${PROJECT_NAME} PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" - CXX_STANDARD 23 - CXX_STANDARD_REQUIRED ON) +set_target_properties( + ${PROJECT_NAME} + PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" + CXX_STANDARD 23 + CXX_STANDARD_REQUIRED ON) if (OMATH_STATIC_MSVC_RUNTIME_LIBRARY) set_target_properties(${PROJECT_NAME} PROPERTIES @@ -127,15 +136,15 @@ if (OMATH_STATIC_MSVC_RUNTIME_LIBRARY) ) endif () -if (OMATH_USE_AVX2) - if (MSVC) +if(OMATH_USE_AVX2) + if(MSVC) target_compile_options(${PROJECT_NAME} PUBLIC /arch:AVX2) - elseif (EMSCRIPTEN) + elseif(EMSCRIPTEN) target_compile_options(${PROJECT_NAME} PUBLIC -msimd128 -mavx2) - elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") + elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") target_compile_options(${PROJECT_NAME} PUBLIC -mfma -mavx2) - endif () -endif () + endif() +endif() if(EMSCRIPTEN) target_compile_options(${PROJECT_NAME} PUBLIC -fexceptions) @@ -144,79 +153,79 @@ endif() target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23) - -if (OMATH_BUILD_TESTS) +if(OMATH_BUILD_TESTS) add_subdirectory(tests) target_compile_definitions(${PROJECT_NAME} PUBLIC OMATH_BUILD_TESTS) if(OMATH_ENABLE_COVERAGE) omath_setup_coverage(${PROJECT_NAME}) endif() -endif () +endif() -if (OMATH_BUILD_BENCHMARK) +if(OMATH_BUILD_BENCHMARK) add_subdirectory(benchmark) -endif () +endif() -if (OMATH_BUILD_EXAMPLES) +if(OMATH_BUILD_EXAMPLES) add_subdirectory(examples) -endif () +endif() - -if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND OMATH_THREAT_WARNING_AS_ERROR) +if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND OMATH_THREAT_WARNING_AS_ERROR) target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX) -elseif (OMATH_THREAT_WARNING_AS_ERROR) +elseif(OMATH_THREAT_WARNING_AS_ERROR) target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Wpedantic -Werror) -endif () +endif() # Windows SDK redefine min/max via preprocessor and break std::min and std::max -if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") +if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") target_compile_definitions(${PROJECT_NAME} INTERFACE NOMINMAX) -endif () - -target_include_directories(${PROJECT_NAME} - PUBLIC - $ # Use this path when building the project - $ # Use this path when the project is installed -) +endif() +target_include_directories( + ${PROJECT_NAME} + PUBLIC $ # Use this path + # when building + # the project + $ # Use this path when the project is + # installed + ) # Installation rules # Install the library -install(TARGETS ${PROJECT_NAME} - EXPORT ${PROJECT_NAME}Targets - ARCHIVE DESTINATION lib COMPONENT ${PROJECT_NAME} # For static libraries - LIBRARY DESTINATION lib COMPONENT ${PROJECT_NAME} # For shared libraries - RUNTIME DESTINATION bin COMPONENT ${PROJECT_NAME} # For executables (on Windows) -) +install( + TARGETS ${PROJECT_NAME} + EXPORT ${PROJECT_NAME}Targets + ARCHIVE DESTINATION lib COMPONENT ${PROJECT_NAME} # For static libraries + LIBRARY DESTINATION lib COMPONENT ${PROJECT_NAME} # For shared libraries + RUNTIME DESTINATION bin COMPONENT ${PROJECT_NAME} # For executables (on + # Windows) + ) # Install headers as part of omath_component install(DIRECTORY include/ DESTINATION include COMPONENT ${PROJECT_NAME}) # Export omath target for CMake find_package support, also under omath_component -install(EXPORT ${PROJECT_NAME}Targets - FILE ${PROJECT_NAME}Targets.cmake - NAMESPACE ${PROJECT_NAME}:: - DESTINATION lib/cmake/${PROJECT_NAME} COMPONENT ${PROJECT_NAME} -) +install( + EXPORT ${PROJECT_NAME}Targets + FILE ${PROJECT_NAME}Targets.cmake + NAMESPACE ${PROJECT_NAME}:: + DESTINATION lib/cmake/${PROJECT_NAME} + COMPONENT ${PROJECT_NAME}) # Generate the omathConfigVersion.cmake file -write_basic_package_version_file( - "${CMAKE_CURRENT_BINARY_DIR}/omathConfigVersion.cmake" - VERSION ${PROJECT_VERSION} - COMPATIBILITY AnyNewerVersion -) +write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/omathConfigVersion.cmake" + VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion) -# Generate the omathConfig.cmake file from the template (which is in the cmake/ folder) +# Generate the omathConfig.cmake file from the template (which is in the cmake/ +# folder) configure_package_config_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/omathConfig.cmake.in" # Path to the .in file - "${CMAKE_CURRENT_BINARY_DIR}/omathConfig.cmake" # Output path for the generated file - INSTALL_DESTINATION lib/cmake/${PROJECT_NAME} -) + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/omathConfig.cmake.in" # Path to the .in + # file + "${CMAKE_CURRENT_BINARY_DIR}/omathConfig.cmake" # Output path for the + # generated file + INSTALL_DESTINATION lib/cmake/${PROJECT_NAME}) # Install the generated config files -install(FILES - "${CMAKE_CURRENT_BINARY_DIR}/omathConfig.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/omathConfigVersion.cmake" - DESTINATION lib/cmake/${PROJECT_NAME} -) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/omathConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/omathConfigVersion.cmake" + DESTINATION lib/cmake/${PROJECT_NAME}) diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index ecca66a..29a2b1a 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -1,22 +1,23 @@ project(omath_benchmark) - file(GLOB_RECURSE OMATH_BENCHMARK_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") add_executable(${PROJECT_NAME} ${OMATH_BENCHMARK_SOURCES}) -set_target_properties(${PROJECT_NAME} PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" - CXX_STANDARD 23 - CXX_STANDARD_REQUIRED ON) +set_target_properties( + ${PROJECT_NAME} + PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" + CXX_STANDARD 23 + CXX_STANDARD_REQUIRED ON) -if (TARGET benchmark::benchmark) # Benchmark is being linked as submodule +if(TARGET benchmark::benchmark) # Benchmark is being linked as submodule target_link_libraries(${PROJECT_NAME} PRIVATE benchmark::benchmark omath) else() - find_package(benchmark CONFIG REQUIRED) # Benchmark is being linked as vcpkg package + find_package(benchmark CONFIG REQUIRED) # Benchmark is being linked as vcpkg + # package target_link_libraries(${PROJECT_NAME} PRIVATE benchmark::benchmark omath) -endif () +endif() if(OMATH_ENABLE_VALGRIND) omath_setup_valgrind(${PROJECT_NAME}) diff --git a/cmake/Coverage.cmake b/cmake/Coverage.cmake index ea91526..5791409 100644 --- a/cmake/Coverage.cmake +++ b/cmake/Coverage.cmake @@ -7,38 +7,23 @@ function(omath_setup_coverage TARGET_NAME) endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND MSVC) - target_compile_options(${TARGET_NAME} PRIVATE - -fprofile-instr-generate - -fcoverage-mapping - /Zi - ) - target_link_options(${TARGET_NAME} PRIVATE + target_compile_options(${TARGET_NAME} PRIVATE -fprofile-instr-generate -fcoverage-mapping + /Zi) + target_link_options( + ${TARGET_NAME} + PRIVATE -fprofile-instr-generate -fcoverage-mapping /DEBUG:FULL /INCREMENTAL:NO - /PROFILE - ) + /PROFILE) elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang") - target_compile_options(${TARGET_NAME} PRIVATE - -fprofile-instr-generate - -fcoverage-mapping - -g - -O0 - ) - target_link_options(${TARGET_NAME} PRIVATE - -fprofile-instr-generate - -fcoverage-mapping - ) + target_compile_options(${TARGET_NAME} PRIVATE -fprofile-instr-generate -fcoverage-mapping + -g -O0) + target_link_options(${TARGET_NAME} PRIVATE -fprofile-instr-generate -fcoverage-mapping) elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - target_compile_options(${TARGET_NAME} PRIVATE - --coverage - -g - -O0 - ) - target_link_options(${TARGET_NAME} PRIVATE - --coverage - ) + target_compile_options(${TARGET_NAME} PRIVATE --coverage -g -O0) + target_link_options(${TARGET_NAME} PRIVATE --coverage) endif() if(TARGET coverage) @@ -47,40 +32,36 @@ function(omath_setup_coverage TARGET_NAME) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND MSVC) message(STATUS "MSVC detected: Use VS Code Coverage from CI workflow") - add_custom_target(coverage + add_custom_target( + coverage DEPENDS unit_tests COMMAND $ WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" - COMMENT "Running tests for coverage (use VS Code Coverage from CI)" - ) + COMMENT "Running tests for coverage (use VS Code Coverage from CI)") elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang") - add_custom_target(coverage + add_custom_target( + coverage DEPENDS unit_tests - COMMAND bash "${CMAKE_SOURCE_DIR}/scripts/coverage-llvm.sh" - "${CMAKE_SOURCE_DIR}" - "${CMAKE_BINARY_DIR}" - "$" - "${CMAKE_BINARY_DIR}/coverage" + COMMAND bash "${CMAKE_SOURCE_DIR}/scripts/coverage-llvm.sh" "${CMAKE_SOURCE_DIR}" + "${CMAKE_BINARY_DIR}" "$" "${CMAKE_BINARY_DIR}/coverage" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" - COMMENT "Running LLVM coverage" - ) + COMMENT "Running LLVM coverage") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - add_custom_target(coverage + add_custom_target( + coverage DEPENDS unit_tests COMMAND $ || true - COMMAND lcov --capture --directory "${CMAKE_BINARY_DIR}" - --output-file "${CMAKE_BINARY_DIR}/coverage.info" - --ignore-errors mismatch,gcov - COMMAND lcov --remove "${CMAKE_BINARY_DIR}/coverage.info" - "*/tests/*" "*/gtest/*" "*/googletest/*" "*/_deps/*" "/usr/*" - --output-file "${CMAKE_BINARY_DIR}/coverage.info" - --ignore-errors unused - COMMAND genhtml "${CMAKE_BINARY_DIR}/coverage.info" - --output-directory "${CMAKE_BINARY_DIR}/coverage" + COMMAND lcov --capture --directory "${CMAKE_BINARY_DIR}" --output-file + "${CMAKE_BINARY_DIR}/coverage.info" --ignore-errors mismatch,gcov + COMMAND + lcov --remove "${CMAKE_BINARY_DIR}/coverage.info" "*/tests/*" "*/gtest/*" + "*/googletest/*" "*/_deps/*" "/usr/*" --output-file + "${CMAKE_BINARY_DIR}/coverage.info" --ignore-errors unused + COMMAND genhtml "${CMAKE_BINARY_DIR}/coverage.info" --output-directory + "${CMAKE_BINARY_DIR}/coverage" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - COMMENT "Running lcov/genhtml" - ) + COMMENT "Running lcov/genhtml") endif() endfunction() diff --git a/cmake/Valgrind.cmake b/cmake/Valgrind.cmake index cd5f5c0..bab197e 100644 --- a/cmake/Valgrind.cmake +++ b/cmake/Valgrind.cmake @@ -22,23 +22,19 @@ function(omath_setup_valgrind TARGET_NAME) return() endif() - set(VALGRIND_FLAGS - --leak-check=full - --show-leak-kinds=all - --track-origins=yes - --error-exitcode=99 - ) + set(VALGRIND_FLAGS --leak-check=full --show-leak-kinds=all --track-origins=yes + --error-exitcode=99) set(VALGRIND_TARGET "valgrind_${TARGET_NAME}") if(NOT TARGET ${VALGRIND_TARGET}) - add_custom_target(${VALGRIND_TARGET} + add_custom_target( + ${VALGRIND_TARGET} DEPENDS ${TARGET_NAME} COMMAND ${VALGRIND_EXECUTABLE} ${VALGRIND_FLAGS} $ WORKING_DIRECTORY $ COMMENT "Running Valgrind memory check on ${TARGET_NAME}..." - USES_TERMINAL - ) + USES_TERMINAL) add_dependencies(valgrind_all ${VALGRIND_TARGET}) endif() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 016f3be..e8f005c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,37 +1,38 @@ project(examples) add_executable(example_projection_matrix_builder example_proj_mat_builder.cpp) -set_target_properties(example_projection_matrix_builder PROPERTIES - CXX_STANDARD 26 - ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" -) +set_target_properties( + example_projection_matrix_builder + PROPERTIES CXX_STANDARD 23 + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}") target_link_libraries(example_projection_matrix_builder PRIVATE omath::omath) add_executable(example_signature_scan example_signature_scan.cpp) -set_target_properties(example_signature_scan PROPERTIES - CXX_STANDARD 26 - ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" -) +set_target_properties( + example_signature_scan + PROPERTIES CXX_STANDARD 23 + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}") target_link_libraries(example_signature_scan PRIVATE omath::omath) - add_executable(example_glfw3 example_glfw3.cpp) -set_target_properties(example_glfw3 PROPERTIES CXX_STANDARD 26 - ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" -) +set_target_properties( + example_glfw3 + PROPERTIES CXX_STANDARD 23 + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}") +find_package(OpenGL) find_package(GLEW REQUIRED) find_package(glfw3 CONFIG REQUIRED) -target_link_libraries(example_glfw3 PRIVATE omath::omath GLEW::GLEW glfw) +target_link_libraries(example_glfw3 PRIVATE omath::omath GLEW::GLEW glfw OpenGL::OpenGL) if(OMATH_ENABLE_VALGRIND) - omath_setup_valgrind(example_projection_matrix_builder) - omath_setup_valgrind(example_signature_scan) - omath_setup_valgrind(example_glfw3) + omath_setup_valgrind(example_projection_matrix_builder) + omath_setup_valgrind(example_signature_scan) + omath_setup_valgrind(example_glfw3) endif() diff --git a/pixi.toml b/pixi.toml new file mode 100644 index 0000000..ca51768 --- /dev/null +++ b/pixi.toml @@ -0,0 +1,51 @@ +[workspace] +name = "omath" +version = "5.7.0" +description = "Cross-platform modern general purpose math library written in C++23 that suitable for cheat/game development." +authors = [ + "orange-cpp " +] + +license = "Zlib" +license-file = "LICENSE" +readme = "README.md" +documentation = "http://libomath.org" +repository = "https://github.com/orange-cpp/omath" + +channels = ["conda-forge"] +platforms = ["win-64", "linux-64", "linux-aarch64", "osx-64", "osx-arm64"] + +[tasks] +format = { cwd = "pixi", cmd = "cmake -P fmt.cmake" } +configure = { cmd = "cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DOMATH_USE_AVX2=OFF -DOMATH_IMGUI_INTEGRATION=ON -DOMATH_BUILD_TESTS=ON -DOMATH_BUILD_BENCHMARK=ON -DOMATH_BUILD_EXAMPLES=ON .", depends-on = ["format"] } +build = { cmd = "cmake --build build --config Debug -j", depends-on = ["configure"] } +examples = { cwd = "pixi", cmd = "cmake -DCMAKE_BUILD_TYPE=Debug -P run.examples.cmake", depends-on = ["build"] } +tests = { cwd = "pixi", cmd = "cmake -DCMAKE_BUILD_TYPE=Debug -P run.unit.tests.cmake", depends-on = ["build"] } +benchmark = { cwd = "pixi", cmd = "cmake -DCMAKE_BUILD_TYPE=Debug -P run.benchmark.cmake", depends-on = ["build"] } + +[dependencies] +benchmark = ">=1.9.5,<2" +ccache = ">=4.12.2,<5" +cmake = ">=4.2.3,<5" +cmake-format = ">=0.6.13,<0.7" +cxx-compiler = ">=1.11.0,<2" +imgui = ">=1.92.3,<2" +gtest = ">=1.17.0,<2" +glew = ">=2.3.0,<3" +glfw = ">=3.4,<4" +ninja = ">=1.13.2,<2" + +[target.linux-64.dependencies] +mesa-libgl-devel-cos7-x86_64 = ">=18.3.4,<19" + +[target.win-64.dependencies] +mesa-libgl-devel-cos7-x86_64 = ">=18.3.4,<19" + +[target.osx-64.dependencies] +mesa-libgl-devel-cos7-x86_64 = ">=18.3.4,<19" + +[target.osx-arm64.dependencies] +mesa-libgl-devel-cos7-aarch64 = ">=18.3.4,<19" + +[target.linux-aarch64.dependencies] +mesa-libgl-devel-cos7-aarch64 = ">=18.3.4,<19" diff --git a/pixi/fmt.cmake b/pixi/fmt.cmake new file mode 100644 index 0000000..978fb3b --- /dev/null +++ b/pixi/fmt.cmake @@ -0,0 +1,36 @@ +# cmake/Format.cmake + +# Find cmake-format executable +find_program(CMAKE_FORMAT_EXECUTABLE NAMES cmake-format) + +if(NOT CMAKE_FORMAT_EXECUTABLE) + message(FATAL_ERROR "cmake-format not found. Please install it first.") +endif() + +# Get the project root directory (assuming this script is in cmake/ +# subdirectory) +get_filename_component(PROJECT_ROOT "../${CMAKE_CURRENT_LIST_DIR}" ABSOLUTE) + +# Iterate over all files in the project root +file(GLOB_RECURSE ALL_FILES "${PROJECT_ROOT}/*") + +foreach(FILE ${ALL_FILES}) + # Basic ignores for common directories to avoid formatting external/build + # files Note: We check for substrings in the full path + if("${FILE}" MATCHES "/\\.git/" + OR "${FILE}" MATCHES "/build/" + OR "${FILE}" MATCHES "/cmake-build/" + OR "${FILE}" MATCHES "/\\.pixi/" + OR "${FILE}" MATCHES "/vcpkg_installed/") + continue() + endif() + + get_filename_component(FILENAME "${FILE}" NAME) + + # Check if file ends with .cmake or matches exactly to CMakeLists.txt + if("${FILENAME}" STREQUAL "CMakeLists.txt" OR "${FILENAME}" MATCHES "\\.cmake$") + message(STATUS "Formatting ${FILE}") + execute_process(COMMAND ${CMAKE_FORMAT_EXECUTABLE} --config-files + "${PROJECT_ROOT}/.cmake-format" -i "${FILE}") + endif() +endforeach() diff --git a/pixi/run.benchmark.cmake b/pixi/run.benchmark.cmake new file mode 100644 index 0000000..643f55b --- /dev/null +++ b/pixi/run.benchmark.cmake @@ -0,0 +1,63 @@ +# cmake/run.examples.cmake + +# Get the project root directory (assuming this script is in cmake/ subdirectory) +get_filename_component(PROJECT_ROOT "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) + +# Default to Debug if CMAKE_BUILD_TYPE is not specified +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug") +else() + message(STATUS "CMAKE_BUILD_TYPE is set to: ${CMAKE_BUILD_TYPE}") +endif() + +# Define the directory where executables are located +# Based on CMakeLists.txt: "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" +set(EXAMPLES_BIN_DIR "${PROJECT_ROOT}/out/${CMAKE_BUILD_TYPE}") + +if(NOT EXISTS "${EXAMPLES_BIN_DIR}") + message(FATAL_ERROR "Examples binary directory not found: ${EXAMPLES_BIN_DIR}. Please build the project first.") +endif() + +message(STATUS "Looking for benchmark executables in: ${EXAMPLES_BIN_DIR}") + +# Find all files starting with "omath_benchmark" +file(GLOB EXAMPLE_FILES "${EXAMPLES_BIN_DIR}/omath_benchmark*") + +foreach(EXAMPLE_PATH ${EXAMPLE_FILES}) + # Skip directories + if(IS_DIRECTORY "${EXAMPLE_PATH}") + continue() + endif() + + get_filename_component(FILENAME "${EXAMPLE_PATH}" NAME) + get_filename_component(EXTENSION "${EXAMPLE_PATH}" EXT) + + # Filter out potential debug symbols or non-executable artifacts + if(EXTENSION STREQUAL ".pdb" OR EXTENSION STREQUAL ".ilk" OR EXTENSION STREQUAL ".obj") + continue() + endif() + + # On Windows, we expect .exe + if(MSVC AND NOT EXTENSION STREQUAL ".exe") + continue() + endif() + + # On Linux/macOS, check permissions or just try to run it. + + message(STATUS "-------------------------------------------------") + message(STATUS "Running benchmark: ${FILENAME}") + message(STATUS "-------------------------------------------------") + + execute_process( + COMMAND "${EXAMPLE_PATH}" + WORKING_DIRECTORY "${PROJECT_ROOT}" + RESULT_VARIABLE EXIT_CODE + ) + + if(NOT EXIT_CODE EQUAL 0) + message(WARNING "Benchmark ${FILENAME} exited with error code: ${EXIT_CODE}") + else() + message(STATUS "Benchmark ${FILENAME} completed successfully.") + endif() + +endforeach() diff --git a/pixi/run.examples.cmake b/pixi/run.examples.cmake new file mode 100644 index 0000000..39d6308 --- /dev/null +++ b/pixi/run.examples.cmake @@ -0,0 +1,63 @@ +# cmake/run.examples.cmake + +# Get the project root directory (assuming this script is in cmake/ subdirectory) +get_filename_component(PROJECT_ROOT "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) + +# Default to Debug if CMAKE_BUILD_TYPE is not specified +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug") +else() + message(STATUS "CMAKE_BUILD_TYPE is set to: ${CMAKE_BUILD_TYPE}") +endif() + +# Define the directory where executables are located +# Based on CMakeLists.txt: "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" +set(EXAMPLES_BIN_DIR "${PROJECT_ROOT}/out/${CMAKE_BUILD_TYPE}") + +if(NOT EXISTS "${EXAMPLES_BIN_DIR}") + message(FATAL_ERROR "Examples binary directory not found: ${EXAMPLES_BIN_DIR}. Please build the project first.") +endif() + +message(STATUS "Looking for example executables in: ${EXAMPLES_BIN_DIR}") + +# Find all files starting with "example_" +file(GLOB EXAMPLE_FILES "${EXAMPLES_BIN_DIR}/example_*") + +foreach(EXAMPLE_PATH ${EXAMPLE_FILES}) + # Skip directories + if(IS_DIRECTORY "${EXAMPLE_PATH}") + continue() + endif() + + get_filename_component(FILENAME "${EXAMPLE_PATH}" NAME) + get_filename_component(EXTENSION "${EXAMPLE_PATH}" EXT) + + # Filter out potential debug symbols or non-executable artifacts + if(EXTENSION STREQUAL ".pdb" OR EXTENSION STREQUAL ".ilk" OR EXTENSION STREQUAL ".obj") + continue() + endif() + + # On Windows, we expect .exe + if(MSVC AND NOT EXTENSION STREQUAL ".exe") + continue() + endif() + + # On Linux/macOS, check permissions or just try to run it. + + message(STATUS "-------------------------------------------------") + message(STATUS "Running example: ${FILENAME}") + message(STATUS "-------------------------------------------------") + + execute_process( + COMMAND "${EXAMPLE_PATH}" + WORKING_DIRECTORY "${PROJECT_ROOT}" + RESULT_VARIABLE EXIT_CODE + ) + + if(NOT EXIT_CODE EQUAL 0) + message(WARNING "Example ${FILENAME} exited with error code: ${EXIT_CODE}") + else() + message(STATUS "Example ${FILENAME} completed successfully.") + endif() + +endforeach() diff --git a/pixi/run.unit.tests.cmake b/pixi/run.unit.tests.cmake new file mode 100644 index 0000000..36e995b --- /dev/null +++ b/pixi/run.unit.tests.cmake @@ -0,0 +1,63 @@ +# cmake/run.examples.cmake + +# Get the project root directory (assuming this script is in cmake/ subdirectory) +get_filename_component(PROJECT_ROOT "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) + +# Default to Debug if CMAKE_BUILD_TYPE is not specified +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug") +else() + message(STATUS "CMAKE_BUILD_TYPE is set to: ${CMAKE_BUILD_TYPE}") +endif() + +# Define the directory where executables are located +# Based on CMakeLists.txt: "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" +set(EXAMPLES_BIN_DIR "${PROJECT_ROOT}/out/${CMAKE_BUILD_TYPE}") + +if(NOT EXISTS "${EXAMPLES_BIN_DIR}") + message(FATAL_ERROR "Examples binary directory not found: ${EXAMPLES_BIN_DIR}. Please build the project first.") +endif() + +message(STATUS "Looking for unit test executables in: ${EXAMPLES_BIN_DIR}") + +# Find all files starting with "unit_tests" +file(GLOB EXAMPLE_FILES "${EXAMPLES_BIN_DIR}/unit_tests*") + +foreach(EXAMPLE_PATH ${EXAMPLE_FILES}) + # Skip directories + if(IS_DIRECTORY "${EXAMPLE_PATH}") + continue() + endif() + + get_filename_component(FILENAME "${EXAMPLE_PATH}" NAME) + get_filename_component(EXTENSION "${EXAMPLE_PATH}" EXT) + + # Filter out potential debug symbols or non-executable artifacts + if(EXTENSION STREQUAL ".pdb" OR EXTENSION STREQUAL ".ilk" OR EXTENSION STREQUAL ".obj") + continue() + endif() + + # On Windows, we expect .exe + if(MSVC AND NOT EXTENSION STREQUAL ".exe") + continue() + endif() + + # On Linux/macOS, check permissions or just try to run it. + + message(STATUS "-------------------------------------------------") + message(STATUS "Running unit_tests: ${FILENAME}") + message(STATUS "-------------------------------------------------") + + execute_process( + COMMAND "${EXAMPLE_PATH}" + WORKING_DIRECTORY "${PROJECT_ROOT}" + RESULT_VARIABLE EXIT_CODE + ) + + if(NOT EXIT_CODE EQUAL 0) + message(WARNING "Example ${FILENAME} exited with error code: ${EXIT_CODE}") + else() + message(STATUS "Example ${FILENAME} completed successfully.") + endif() + +endforeach() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 76ef3a7..de4f83b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -7,14 +7,15 @@ include(GoogleTest) file(GLOB_RECURSE UNIT_TESTS_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") add_executable(${PROJECT_NAME} ${UNIT_TESTS_SOURCES}) -set_target_properties(${PROJECT_NAME} PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" - CXX_STANDARD 23 - CXX_STANDARD_REQUIRED ON) +set_target_properties( + ${PROJECT_NAME} + PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" + CXX_STANDARD 23 + CXX_STANDARD_REQUIRED ON) -if (TARGET gtest) # GTest is being linked as submodule +if(TARGET gtest) # GTest is being linked as submodule target_link_libraries(${PROJECT_NAME} PRIVATE gtest gtest_main omath::omath) else() # GTest is being linked as vcpkg package find_package(GTest CONFIG REQUIRED) @@ -30,7 +31,8 @@ if(OMATH_ENABLE_VALGRIND) omath_setup_valgrind(${PROJECT_NAME}) endif() -# Skip test discovery for Android/iOS builds or when cross-compiling - binaries cannot run on host -if (NOT (ANDROID OR IOS OR EMSCRIPTEN)) +# Skip test discovery for Android/iOS builds or when cross-compiling - binaries +# cannot run on host +if(NOT (ANDROID OR IOS OR EMSCRIPTEN)) gtest_discover_tests(${PROJECT_NAME}) endif()