diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 00000000..0bb4db95 --- /dev/null +++ b/.bazelrc @@ -0,0 +1,8 @@ +build --incompatible_use_platforms_repo_for_constraints +build --incompatible_enable_cc_toolchain_resolution +build --incompatible_strict_action_env + +common:ci --announce_rc +common:ci --disk_cache=~/.cache/bazel-disk-cache + +try-import %workspace%/user.bazelrc diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml new file mode 100644 index 00000000..b97233d2 --- /dev/null +++ b/.github/workflows/bazel.yml @@ -0,0 +1,40 @@ +name: bazel + +on: + push: + branches: + - "**" + +concurrency: + group: ${{ github.ref }} + cancel-in-progress: true + +jobs: + bazel-test-windows: + runs-on: windows-latest + steps: + - uses: actions/cache@v3 + with: + path: | + /Users/runneradmin/AppData/Local/bazelisk + /Users/runneradmin/.cache/bazel-disk-cache + key: ${{runner.os}}-bazel-cache + - uses: actions/checkout@v3 + with: + submodules: recursive + fetch-depth: 0 + - run: bazel test --config=ci //... + build-test-linux: + runs-on: ubuntu-latest + steps: + - uses: actions/cache@v3 + with: + path: | + ~/.cache/bazelisk + ~/.cache/bazel-disk-cache + key: ${{runner.os}}-bazel-cache + - uses: actions/checkout@v3 + with: + submodules: recursive + fetch-depth: 0 + - run: bazel test --config=ci //... diff --git a/.gitignore b/.gitignore index 9c258ea3..c5f4012c 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,8 @@ compile_commands.json .github/vagrant/*.log .github/vagrant/.vagrant .github/vagrant/macos/.vagrant -src_singleheader/ \ No newline at end of file +src_singleheader/ + +# bazel +/bazel-* +/user.bazelrc diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 00000000..9a70a36d --- /dev/null +++ b/BUILD.bazel @@ -0,0 +1,79 @@ +load("@rules_cc//cc:defs.bzl", "cc_library") + +package(default_visibility = ["//visibility:public"]) + +constraint_setting(name = "fastfloat", default_constraint_value = ":without_fastfloat") +constraint_value(name = "with_fastfloat", constraint_setting = ":fastfloat") +constraint_value(name = "without_fastfloat", constraint_setting = ":fastfloat") + +cc_library( + name = "c4core", + defines = select({ + ":without_fastfloat": ["C4CORE_NO_FAST_FLOAT"], + ":with_fastfloat": [], + }), + includes = ["src"], + srcs = [ + "src/c4/allocator.hpp", + "src/c4/base64.hpp", + "src/c4/base64.cpp", + "src/c4/blob.hpp", + "src/c4/bitmask.hpp", + "src/c4/charconv.hpp", + "src/c4/c4_pop.hpp", + "src/c4/c4_push.hpp", + "src/c4/char_traits.cpp", + "src/c4/char_traits.hpp", + "src/c4/common.hpp", + "src/c4/compiler.hpp", + "src/c4/config.hpp", + "src/c4/cpu.hpp", + "src/c4/ctor_dtor.hpp", + "src/c4/dump.hpp", + "src/c4/enum.hpp", + "src/c4/error.cpp", + "src/c4/error.hpp", + "src/c4/export.hpp", + "src/c4/format.hpp", + "src/c4/format.cpp", + "src/c4/hash.hpp", + "src/c4/language.hpp", + "src/c4/language.cpp", + "src/c4/memory_resource.cpp", + "src/c4/memory_resource.hpp", + "src/c4/memory_util.cpp", + "src/c4/memory_util.hpp", + "src/c4/platform.hpp", + "src/c4/preprocessor.hpp", + "src/c4/restrict.hpp", + "src/c4/span.hpp", + "src/c4/std/std.hpp", + "src/c4/std/std_fwd.hpp", + "src/c4/std/string.hpp", + "src/c4/std/string_fwd.hpp", + "src/c4/std/tuple.hpp", + "src/c4/std/vector.hpp", + "src/c4/std/vector_fwd.hpp", + "src/c4/substr.hpp", + "src/c4/substr_fwd.hpp", + "src/c4/szconv.hpp", + "src/c4/type_name.hpp", + "src/c4/types.hpp", + "src/c4/unrestrict.hpp", + "src/c4/utf.hpp", + "src/c4/utf.cpp", + "src/c4/windows.hpp", + "src/c4/windows_pop.hpp", + "src/c4/windows_push.hpp", + # + "src/c4/ext/debugbreak/debugbreak.h", + "src/c4/ext/rng/rng.hpp", + "src/c4/ext/sg14/inplace_function.h", + ] + select({ + ":without_fastfloat": [], + ":with_fastfloat": [ + "src/c4/ext/fast_float.hpp", + "src/c4/ext/fast_float_all.h", + ], + }), +) diff --git a/CMakeLists.txt b/CMakeLists.txt index b2450e10..bf387e6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ c4_project(VERSION 0.1.10 option(C4CORE_WITH_FASTFLOAT "use fastfloat to parse floats" ON) +# NOTE: If updating source files list please update BUILD.bazel as well set(C4CORE_SRC_FILES c4/allocator.hpp c4/base64.hpp diff --git a/README.md b/README.md index 00cbb1c7..9e34929a 100644 --- a/README.md +++ b/README.md @@ -84,14 +84,14 @@ init` followed by `git submodule update`. ## Using c4core in your project -c4core can be built with [cmake](#cmake), or can be used header only. It can also be obtained through some package managers. +c4core can be built with [cmake](#cmake) or [bazel](#bazel), or can be used [header only](#header-only). It can also be obtained through some [package managers](#package-managers). ### CMake The recommended way to use c4core is by making it part of your project by using `add_subdirectory(${path_to_c4core_root})` in your CMakeLists.txt. Doing this is not intrusive to your cmake project -because c4core is fast to build, also prefixes every cmake +because c4core is fast to build, and it also prefixes every cmake variable with `C4CORE_`. But more importantly, this will enable you to compile c4core with the exact same compile settings used by your project. @@ -110,6 +110,61 @@ Note above that the call to `target_link_libraries()` is using PUBLIC linking. This is required to make sure the include directories from `c4core` are transitively used by clients of `foo`. +### Bazel + +Add c4core to your `WORKSPACE.bazel`: + +```python +load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") + +git_repository( + name = "c4core", + init_submodules = True, + tag = "v{current_version}", +) +``` + +Use in your `BUILD.bazel` files by adding to your `deps`: + +```python +load("@rules_cc//cc:defs.bzl", "cc_binary") + +cc_binary( + # ... + deps = ["@c4core"], +) +``` + +### Header-only + +If you prefer to pick a single header to get you quickly going, [there is an amalgamation tool](tools/amalgamate.py) which generates this header: +```console +[user@host c4core]$ python tools/amalgamate.py -h +usage: amalgamate.py [-h] [--fastfloat | --no-fastfloat] [--stl | --no-stl] [output] + +positional arguments: + output output file. defaults to stdout + +options: + -h, --help show this help message and exit + --fastfloat enable fastfloat library. this is the default. + --no-fastfloat enable fastfloat library. the default is --fastfloat. + --stl enable stl interop. this is the default. + --no-stl enable stl interop. the default is --stl. +``` + + +### Package managers + +c4core is available through the following package managers: + + * [vcpkg](https://vcpkg.io/en/packages.html): `vcpkg install c4core` + * Arch Linux/Manjaro: + * [rapidyaml](https://aur.archlinux.org/packages/rapidyaml/) + + + + ### Header-only diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel new file mode 100644 index 00000000..73dedf6a --- /dev/null +++ b/WORKSPACE.bazel @@ -0,0 +1,10 @@ +workspace(name = "c4core") + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "doctest", + sha256 = "f52763630aa17bd9772b54e14b6cdd632c87adf0169455a86a49bd94abf2cd83", + strip_prefix = "doctest-2.4.8", + urls = ["https://github.com/doctest/doctest/archive/refs/tags/v2.4.8.tar.gz"], +) diff --git a/tbump.toml b/tbump.toml index fdc06aef..a54a68f3 100644 --- a/tbump.toml +++ b/tbump.toml @@ -32,6 +32,9 @@ search = "c4_project\\(VERSION {current_version}" [[file]] src = "test/test_singleheader/CMakeLists.txt" search = "c4_project\\(VERSION {current_version}" +[[file]] +src = "README.md" +search = "v{current_version}" # You can specify a list of commands to # run after the files have been patched diff --git a/test/BUILD.bazel b/test/BUILD.bazel new file mode 100644 index 00000000..fe028072 --- /dev/null +++ b/test/BUILD.bazel @@ -0,0 +1,263 @@ +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") + +cc_library( + name = "lib", + srcs = [ + "c4/libtest/archetypes.cpp", + "c4/libtest/test.cpp", + "c4/main.cpp", + ], + hdrs = [ + "c4/libtest/archetypes.hpp", + "c4/libtest/supprwarn_pop.hpp", + "c4/libtest/supprwarn_push.hpp", + "c4/test.hpp", + ], + includes = ["."], + deps = [ + "//:c4core", + "@doctest//doctest:custom_main", + ], +) + +cc_test( + name = "allocator", + srcs = ["test_allocator.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "base64", + srcs = ["test_base64.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "bitmask", + srcs = [ + "test_bitmask.cpp", + "test_enum_common.hpp", + ], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "blob", + srcs = ["test_blob.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "char_traits", + srcs = ["test_char_traits.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "charconv", + srcs = [ + "test_charconv.cpp", + "test_numbers.hpp", + ], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "ctor_dtor", + srcs = ["test_ctor_dtor.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "dump", + srcs = ["test_dump.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "enum", + srcs = [ + "test_enum.cpp", + "test_enum_common.hpp", + ], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "error_exception", + srcs = ["test_error_exception.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "error", + srcs = ["test_error.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "format", + srcs = ["test_format.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "memory_util", + srcs = ["test_memory_util.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "preprocessor", + srcs = ["test_preprocessor.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "span", + srcs = ["test_span.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "std_string", + srcs = ["test_std_string.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "std_vector", + srcs = ["test_std_vector.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "substr", + srcs = ["test_substr.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "type_name", + srcs = ["test_type_name.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "types", + srcs = ["test_types.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "utf", + srcs = [ + "test_utf.cpp", + "utfchars.inc", + ], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "memory_resource", + srcs = ["test_memory_resource.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) + +cc_test( + name = "szconv", + srcs = ["test_szconv.cpp"], + includes = ["."], + deps = [ + ":lib", + "//:c4core", + ], +) diff --git a/test/c4/main.cpp b/test/c4/main.cpp index 36c8001e..5cf6b63a 100644 --- a/test/c4/main.cpp +++ b/test/c4/main.cpp @@ -1,3 +1,3 @@ #define DOCTEST_CONFIG_SUPER_FAST_ASSERTS #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN -#include +#include "doctest/doctest.h" diff --git a/test/c4/test.hpp b/test/c4/test.hpp index 936283a2..8733dfd5 100644 --- a/test/c4/test.hpp +++ b/test/c4/test.hpp @@ -18,7 +18,7 @@ #define C4_LOGP(msg, ...) printf(msg) #define DOCTEST_CONFIG_SUPER_FAST_ASSERTS -#include +#include "doctest/doctest.h" #define CHECK_STREQ(lhs, rhs) CHECK_EQ(c4::to_csubstr(lhs), c4::to_csubstr(rhs)) #define CHECK_FLOAT_EQ(lhs, rhs) CHECK((double)(lhs) == doctest::Approx((double)(rhs))) diff --git a/test/test_charconv.cpp b/test/test_charconv.cpp index 5efd8764..97587027 100644 --- a/test/test_charconv.cpp +++ b/test/test_charconv.cpp @@ -2267,9 +2267,10 @@ TEST_CASE_TEMPLATE("atof.hexa", T, float, double) TEST_CASE_TEMPLATE("atof.infnan", T, float, double) { + static_assert(std::numeric_limits::has_quiet_NaN, "quiet indeed"); + T nan = std::numeric_limits::quiet_NaN(); T pinf = std::numeric_limits::infinity(); T ninf = -std::numeric_limits::infinity(); - T nan = std::numeric_limits::quiet_NaN(); T rval = {}; test_ator("infinity", pinf); test_ator("inf", pinf);