cmake config

This commit is contained in:
Barrett Ruth 2025-08-30 19:01:11 -05:00
parent 6f5ed47f3f
commit c2ff10026d
8 changed files with 186 additions and 164 deletions

View file

@ -22,9 +22,16 @@ jobs:
build-and-test:
runs-on: ubuntu-latest
strategy:
matrix:
build_type: [Debug, Release]
steps:
- uses: actions/checkout@v4
- name: Install compiler
run: sudo apt-get update && sudo apt-get install -y g++
- name: Debug tests (asserts + sanitizers)
run: make test MODE=debug
run: sudo apt-get update && sudo apt-get install -y g++ cmake
- name: Configure CMake
run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
- name: Build
run: cmake --build build
- name: Test
run: ctest --test-dir build --output-on-failure

2
.gitignore vendored
View file

@ -1,4 +1,6 @@
build/
build-release/
.cache/
*.o
*.a
*.swp

82
CMakeLists.txt Normal file
View file

@ -0,0 +1,82 @@
cmake_minimum_required(VERSION 3.20)
project(
bmath
VERSION 0.1.0
DESCRIPTION "Header-only C++23 math library"
LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_library(bmath INTERFACE)
add_library(bmath::bmath ALIAS bmath)
target_include_directories(
bmath INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL
"Clang")
target_compile_options(
bmath
INTERFACE -pedantic-errors
-Wall
-Wextra
-Wpedantic
-Wshadow
-Wformat=2
-Wfloat-equal
-Wlogical-op
-Wshift-overflow=2
-Wnon-virtual-dtor
-Wold-style-cast
-Wcast-qual
-Wuseless-cast
-Wno-sign-promotion
-Wcast-align
-Wunused
-Woverloaded-virtual
-Wconversion
-Wmisleading-indentation
-Wduplicated-cond
-Wduplicated-branches
-Wnull-dereference
-Wno-conversion
-Wformat-overflow
-Wformat-truncation
-Wdouble-promotion
-Wundef)
endif()
target_compile_definitions(bmath INTERFACE LOCAL)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options(
bmath
INTERFACE -O0
-g3
-fsanitize=address,undefined
-fsanitize=float-divide-by-zero
-fsanitize=float-cast-overflow
-fno-sanitize-recover=all
-fstack-protector-all
-fno-omit-frame-pointer
-fno-inline
-ffunction-sections)
target_compile_definitions(bmath INTERFACE _GLIBCXX_DEBUG
_GLIBCXX_DEBUG_PEDANTIC)
target_link_options(
bmath INTERFACE -fsanitize=address,undefined
-fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow)
else()
target_compile_options(bmath INTERFACE -O2)
target_compile_definitions(bmath INTERFACE NDEBUG)
endif()
enable_testing()
add_subdirectory(tests)

View file

@ -1,30 +0,0 @@
-pedantic-errors
-O2
-Wall
-Wextra
-Wpedantic
-Wshadow
-Wformat=2
-Wfloat-equal
-Wlogical-op
-Wshift-overflow=2
-Wnon-virtual-dtor
-Wold-style-cast
-Wcast-qual
-Wuseless-cast
-Wno-sign-promotion
-Wcast-align
-Wunused
-Woverloaded-virtual
-Wconversion
-Wmisleading-indentation
-Wduplicated-cond
-Wduplicated-branches
-Wlogical-op
-Wnull-dereference
-Wformat=2
-Wformat-overflow
-Wformat-truncation
-Wdouble-promotion
-Wundef
-DLOCAL

108
makefile
View file

@ -1,108 +0,0 @@
CXX ?= g++
INCLUDE_DIR := include
TEST_DIR := tests
BUILD_ROOT := build
MODE ?= release
STD := -std=c++23
WARNFLAGS := \
-pedantic-errors \
-Wall -Wextra -Wpedantic \
-Wshadow \
-Wformat=2 \
-Wfloat-equal \
-Wlogical-op \
-Wshift-overflow=2 \
-Wnon-virtual-dtor \
-Wold-style-cast \
-Wcast-qual \
-Wuseless-cast \
-Wno-sign-promotion \
-Wcast-align \
-Wunused \
-Woverloaded-virtual \
-Wconversion \
-Wmisleading-indentation \
-Wduplicated-cond \
-Wduplicated-branches \
-Wnull-dereference \
-Wno-conversion \
-Wformat-overflow \
-Wformat-truncation \
-Wdouble-promotion \
-Wundef
BASEDEFS := -DLOCAL
INCLUDES := -I$(INCLUDE_DIR)
RELFLAGS := -O2 -DNDEBUG
DBGFLAGS := \
-O0 -g3 \
-fsanitize=address,undefined \
-fsanitize=float-divide-by-zero \
-fsanitize=float-cast-overflow \
-fno-sanitize-recover=all \
-fstack-protector-all \
-fstack-usage \
-fno-omit-frame-pointer \
-fno-inline \
-ffunction-sections \
-D_GLIBCXX_DEBUG \
-D_GLIBCXX_DEBUG_PEDANTIC
DBG_LDFLAGS := \
-fsanitize=address,undefined \
-fsanitize=float-divide-by-zero \
-fsanitize=float-cast-overflow
CXXFLAGS := $(STD) $(WARNFLAGS) $(INCLUDES) $(BASEDEFS)
CXXFLAGS += -MMD -MP
ifeq ($(MODE),debug)
CXXFLAGS += $(DBGFLAGS)
LDFLAGS += $(DBG_LDFLAGS)
else
CXXFLAGS += $(RELFLAGS)
endif
BUILD_DIR := $(BUILD_ROOT)/$(MODE)
TEST_SRC := $(wildcard $(TEST_DIR)/*.cc)
TEST_OBJ := $(patsubst $(TEST_DIR)/%.cc,$(BUILD_DIR)/$(TEST_DIR)/%.o,$(TEST_SRC))
TEST_EXE := $(BUILD_DIR)/test_bmath
.PHONY: all release debug test clean distclean flags .TEST
all: release
release:
$(MAKE) MODE=release .TEST
debug:
$(MAKE) MODE=debug .TEST
test: .TEST
.TEST: $(TEST_EXE)
./$(TEST_EXE)
$(BUILD_DIR)/$(TEST_DIR)/%.o: $(TEST_DIR)/%.cc
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) -c $< -o $@
-include $(TEST_OBJ:.o=.d)
$(TEST_EXE): $(TEST_OBJ)
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
flags:
@{ \
printf "%s\n%s\n%s\n" $(STD) $(INCLUDES) $(WARNFLAGS) $(BASEDEFS) \
[ "$(MODE)" = "debug" ] && printf "%s\n" $(DBGFLAGS) || printf "%s\n" $(RELFLAGS) \
} > compile_flags.txt
clean:
@rm -rf "$(BUILD_DIR)"
distclean:
@rm -rf "$(BUILD_ROOT)" compile_flags.txt

17
tests/CMakeLists.txt Normal file
View file

@ -0,0 +1,17 @@
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.14.0
)
set(gtest_force_shared_crt
ON
CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
add_executable(test_bmath test_bmath.cc)
target_link_libraries(test_bmath PRIVATE bmath::bmath gtest_main)
include(GoogleTest)
gtest_discover_tests(test_bmath)

75
tests/test_bmath.cc Normal file
View file

@ -0,0 +1,75 @@
#include <gtest/gtest.h>
#include <cstdint>
#include <format>
#include "../include/bmath.hh"
using namespace bmath;
TEST(MintTest, BasicConstruction) {
mint<uint64_t> four{4};
static_assert(std::is_trivially_copyable_v<mint<uint64_t>>);
EXPECT_EQ(four.get(), 4);
}
TEST(MintTest, Formatting) {
mint<uint64_t> four{4};
auto formatted = std::format("{}", four);
EXPECT_EQ(formatted, "4");
auto string_result = to_string(four);
EXPECT_EQ(string_result, "4");
}
TEST(MintTest, Addition) {
mint<uint64_t> a{3};
mint<uint64_t> b{5};
auto result = a + b;
EXPECT_EQ(result.get(), 8);
}
TEST(MintTest, Subtraction) {
mint<uint64_t> a{10};
mint<uint64_t> b{3};
auto result = a - b;
EXPECT_EQ(result.get(), 7);
}
TEST(MintTest, Multiplication) {
mint<uint64_t> a{6};
mint<uint64_t> b{7};
auto result = a * b;
EXPECT_EQ(result.get(), 42);
}
TEST(MintTest, Modular) {
constexpr uint64_t mod = 13;
mint<uint64_t, mod> a{15};
EXPECT_EQ(a.get(), 2);
}
TEST(PowerTest, BasicPower) {
mint<uint64_t> base{2};
auto result = pow(base, 3);
EXPECT_EQ(result.get(), 8);
}
TEST(PowerTest, PowerOfOne) {
mint<uint64_t> base{5};
auto result = pow(base, 0);
EXPECT_EQ(result.get(), 1);
}
TEST(PowerTest, PowerOfZero) {
mint<uint64_t> base{0};
auto result = pow(base, 5);
EXPECT_EQ(result.get(), 0);
}

View file

@ -1,23 +0,0 @@
#include <cassert>
#include <cstdint>
#include <iostream>
#include "../include/bmath.hh"
using namespace bmath;
using namespace std;
int main() {
mint<uint64_t> four{4};
// should be trivially copyable
static_assert(is_trivially_copyable_v<mint<uint64_t>>);
// should be able to format
auto formatted = format("{}\n", four);
// and use to_string
formatted = to_string(four);
return 0;
}