From e2987f000ab25370a0a0e5c2bd241e3677d4ef08 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Wed, 10 Sep 2025 22:29:50 +0800 Subject: [PATCH 1/9] Add meson build system --- meson.build | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 meson.build diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..1c3ca01 --- /dev/null +++ b/meson.build @@ -0,0 +1,51 @@ +project( + 'pystring', + 'cpp', + version: '1.1.4', + license: 'BSD-3-Clause', + license_files: 'LICENSE', + meson_version: '>=1.3', + default_options: ['cpp_std=c++11', 'warning_level=3'], +) + +inc = include_directories('.') + +srcs = files('pystring.cpp') +hdrs = files('pystring.h') + +pystring_lib = library( + 'pystring', + srcs, + implicit_include_directories: false, + include_directories: inc, + version: meson.project_version(), + install: true, +) +pystring_dep = declare_dependency( + link_with: pystring_lib, + include_directories: inc, +) +meson.override_dependency('pystring', pystring_dep) + +test( + 'PyStringTest', + executable( + 'pystring_test', + 'test.cpp', + dependencies: pystring_dep, + build_by_default: false, + ), +) + +install_headers(hdrs) + +pkgconfig = import('pkgconfig') +pkgconfig.generate( + pystring_lib, + description: 'C++ functions matching the interface and behavior of python string methods with std::string', +) +cmake = import('cmake') +cmake.write_basic_package_version_file( + name: 'pystring', + version: meson.project_version(), +) From 6d514259c4f128dfa0ab64db556ae3e33b382c22 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Wed, 10 Sep 2025 22:30:42 +0800 Subject: [PATCH 2/9] Sync cmake's installation layout to Makefile and Meson builds --- CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 758b20a..b96105d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5) -project(pystring CXX) +project(pystring LANGUAGES CXX VERSION 1.1.4) option (BUILD_SHARED_LIBS "Build shared libraries (set to OFF to build static libs)" ON) @@ -7,6 +7,10 @@ add_library(pystring pystring.cpp pystring.h ) +set_target_properties(pystring PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} +) add_executable (pystring_test test.cpp) TARGET_LINK_LIBRARIES (pystring_test pystring) @@ -20,7 +24,7 @@ install(TARGETS pystring LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install (FILES pystring.h - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT developer ) From 584570ae1fcd01e6b0ee8e4747ac99a19fbb29b3 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Wed, 10 Sep 2025 22:41:22 +0800 Subject: [PATCH 3/9] meson: remove cmake config target generation this pulls in an extra dependency on the cmake binary, CMake users can use the PkgConfig module instead. --- meson.build | 5 ----- 1 file changed, 5 deletions(-) diff --git a/meson.build b/meson.build index 1c3ca01..d43c512 100644 --- a/meson.build +++ b/meson.build @@ -44,8 +44,3 @@ pkgconfig.generate( pystring_lib, description: 'C++ functions matching the interface and behavior of python string methods with std::string', ) -cmake = import('cmake') -cmake.write_basic_package_version_file( - name: 'pystring', - version: meson.project_version(), -) From 6e0ee052a82d41250a9f7d921b9ecdbd34a3a2b7 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Thu, 11 Sep 2025 09:04:37 +0800 Subject: [PATCH 4/9] ci: add meson tests --- .github/workflows/meson.yml | 149 ++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 .github/workflows/meson.yml diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml new file mode 100644 index 0000000..a294578 --- /dev/null +++ b/.github/workflows/meson.yml @@ -0,0 +1,149 @@ +name: Meson + +on: + pull_request: + push: + +jobs: + meson-build-and-tests: + runs-on: ${{ matrix.platform }} + name: ${{ matrix.platform }}, ${{ matrix.mode.name }} ${{ matrix.flavor }} + strategy: + fail-fast: false + matrix: + flavor: + - debug + - release + mode: + - name: default + extra_envs: {} + + # Alternative compiler setups + - name: gcc + extra_envs: + CC: gcc + CXX: g++ + - name: clang + extra_envs: + CC: clang + CXX: clang++ + + - name: sanitize + args: >- + "-Db_sanitize=address,undefined" + extra_envs: {} + + # This is for MSVC, which only supports AddressSanitizer. + # https://learn.microsoft.com/en-us/cpp/sanitizers/ + - name: sanitize+asanonly + args: -Db_sanitize=address + extra_envs: + ASAN_OPTIONS: report_globals=0:halt_on_error=1:abort_on_error=1:print_summary=1 + + - name: clang+sanitize + args: >- + "-Db_sanitize=address,undefined" + extra_envs: + CC: clang + CXX: clang++ + + # default clang on GitHub hosted runners is from MSYS2. + # Use Visual Studio supplied clang-cl instead. + - name: clang-cl+sanitize + args: >- + "-Db_sanitize=address,undefined" + extra_envs: + CC: clang-cl + CXX: clang-cl + platform: + - ubuntu-22.04 + - windows-2022 + - macos-latest + + exclude: + # clang-cl only makes sense on windows. + - platform: ubuntu-22.04 + mode: + name: clang-cl+sanitize + - platform: macos-latest + mode: + name: clang-cl+sanitize + + # Use clang-cl instead of MSYS2 clang. + # + # we already tested clang+sanitize on linux, + # if this doesn't work, it should be an issue for MSYS2 team to consider. + - platform: windows-2022 + mode: + name: clang + - platform: windows-2022 + mode: + name: clang+sanitize + + # MSVC-only sanitizers + - platform: ubuntu-22.04 + mode: + name: sanitize+asanonly + - platform: macos-latest + mode: + name: sanitize+asanonly + - platform: windows-2022 + mode: + name: sanitize + + # clang is the default on macos + # also gcc is an alias to clang + - platform: macos-latest + mode: + name: clang + - platform: macos-latest + mode: + name: gcc + + # gcc is the default on linux + - platform: ubuntu-22.04 + mode: + name: gcc + + # only run sanitizer tests on linux + # + # gcc/clang's codegen shouldn't massively change across platforms, + # and linux supports most of the sanitizers. + - platform: macos-latest + mode: + name: clang+sanitize + - platform: macos-latest + mode: + name: sanitize + steps: + - name: Setup meson + run: | + pipx install meson ninja + - name: Setup sanitizers + if: ${{ matrix.platform == 'ubuntu-22.04' }} + run: | + sudo apt update && sudo apt install libasan8 libubsan1 -y + - name: Checkout + uses: actions/checkout@v4 + - name: Activate MSVC and Configure + if: ${{ matrix.platform == 'windows-2022' }} + env: ${{ matrix.mode.extra_envs }} + run: | + meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} -Ddefault_library=static ${{ matrix.mode.args }} --vsenv + - name: Configuring + if: ${{ matrix.platform != 'windows-2022' }} + env: ${{ matrix.mode.extra_envs }} + run: | + meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} ${{ matrix.mode.args }} + - name: Building + run: | + meson compile -C build-${{ matrix.flavor }} + - name: Running tests + env: ${{ matrix.mode.extra_envs }} + run: | + meson test -C build-${{ matrix.flavor }} --timeout-multiplier 0 + - uses: actions/upload-artifact@v4 + if: failure() + with: + name: ${{ matrix.platform }}-${{ matrix.mode.name }}-${{ matrix.flavor }}-logs + path: build-${{ matrix.flavor }}/meson-logs From 2a9c452bbc026ef78df4f36200e48bc6d0357cab Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Fri, 12 Sep 2025 23:57:00 +0800 Subject: [PATCH 5/9] build: default to c++17 --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index d43c512..a4233dd 100644 --- a/meson.build +++ b/meson.build @@ -5,7 +5,7 @@ project( license: 'BSD-3-Clause', license_files: 'LICENSE', meson_version: '>=1.3', - default_options: ['cpp_std=c++11', 'warning_level=3'], + default_options: ['cpp_std=c++17,c++11', 'warning_level=3'], ) inc = include_directories('.') From 7ae262712a7749b7eb05c5d37b0647bb6e29e4b6 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Fri, 12 Sep 2025 23:57:13 +0800 Subject: [PATCH 6/9] ci: fix cmake builds --- .github/workflows/ci.yml | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7cfe295..b980d84 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,8 +30,9 @@ jobs: build-type: Release build-shared: 'ON' cxx-standard: 17 - cc_compiler: clang - cxx_compiler: clang++ + cxx-compiler: clang++ + cxx-flags: '' + cc-compiler: clang compiler-desc: clang os: ubuntu-latest @@ -42,8 +43,9 @@ jobs: build-type: Debug build-shared: 'ON' cxx-standard: 17 - cc_compiler: clang - cxx_compiler: clang++ + cxx-compiler: clang++ + cxx-flags: '' + cc-compiler: clang compiler-desc: clang os: ubuntu-latest @@ -55,6 +57,7 @@ jobs: build-shared: 'ON' cxx-standard: 17 cxx-compiler: g++ + cxx-flags: '' cc-compiler: gcc compiler-desc: gcc os: ubuntu-latest @@ -67,6 +70,7 @@ jobs: build-shared: 'ON' cxx-standard: 17 cxx-compiler: g++ + cxx-flags: '' cc-compiler: gcc compiler-desc: gcc os: ubuntu-latest @@ -99,7 +103,7 @@ jobs: working-directory: _build - name: Test run: | - ctest --build-config ${{ matrix.build_type }} --verbose + ctest --build-config ${{ matrix.build-type }} --verbose working-directory: _build # --------------------------------------------------------------------------- @@ -119,6 +123,7 @@ jobs: build-type: Release build-shared: 'ON' cxx-standard: 17 + cxx-flags: '' os: macos-latest # Debug @@ -127,6 +132,7 @@ jobs: build-shared: 'ON' build-docs: 'OFF' cxx-standard: 17 + cxx-flags: '' os: macos-latest steps: @@ -155,7 +161,7 @@ jobs: working-directory: _build - name: Test run: | - ctest --build-config ${{ matrix.build_type }} --verbose + ctest --build-config ${{ matrix.build-type }} --verbose working-directory: _build # --------------------------------------------------------------------------- @@ -175,6 +181,7 @@ jobs: build-type: Release build-shared: 'ON' cxx-standard: 17 + cxx-flags: '' os: windows-latest # Debug @@ -182,6 +189,7 @@ jobs: build-type: Debug build-shared: 'ON' cxx-standard: 17 + cxx-flags: '' os: windows-latest @@ -217,4 +225,4 @@ jobs: run: | ctest -C ${{ matrix.build-type }} shell: bash - working-directory: _build \ No newline at end of file + working-directory: _build From 853581b03071b460763c2fa322f9763daf1374d9 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Sat, 13 Sep 2025 00:12:49 +0800 Subject: [PATCH 7/9] tests: fix memory leak in tests --- unittest.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/unittest.h b/unittest.h index 536d9cb..7412029 100644 --- a/unittest.h +++ b/unittest.h @@ -23,11 +23,11 @@ struct PYSTRINGTest PYSTRINGTestFunc function; }; -typedef std::vector UnitTests; +typedef std::vector UnitTests; UnitTests& GetUnitTests(); -struct AddTest { AddTest(PYSTRINGTest* test); }; +struct AddTest { AddTest(PYSTRINGTest&& test); }; /// PYSTRING_CHECK_* macros checks if the conditions is met, and if not, /// prints an error message indicating the module and line where the @@ -102,22 +102,22 @@ struct AddTest { AddTest(PYSTRINGTest* test); }; #define PYSTRING_ADD_TEST(group, name) \ static void pystringtest_##group##_##name(); \ - AddTest pystringaddtest_##group##_##name(new PYSTRINGTest(#group, #name, pystringtest_##group##_##name)); \ + AddTest pystringaddtest_##group##_##name(PYSTRINGTest(#group, #name, pystringtest_##group##_##name)); \ static void pystringtest_##group##_##name() #define PYSTRING_TEST_SETUP() \ int unit_test_failures = 0 #define PYSTRING_TEST_APP(app) \ - std::vector& GetUnitTests() { \ - static std::vector pystring_unit_tests; \ + std::vector& GetUnitTests() { \ + static std::vector pystring_unit_tests; \ return pystring_unit_tests; } \ - AddTest::AddTest(PYSTRINGTest* test){GetUnitTests().push_back(test);}; \ + AddTest::AddTest(PYSTRINGTest&& test){GetUnitTests().emplace_back(test);}; \ PYSTRING_TEST_SETUP(); \ int main(int, char **) { std::cerr << "\n" << #app <<"\n\n"; \ for(size_t i = 0; i < GetUnitTests().size(); ++i) { \ - int _tmp = unit_test_failures; GetUnitTests()[i]->function(); \ - std::cerr << "Test [" << GetUnitTests()[i]->group << "] [" << GetUnitTests()[i]->name << "] - "; \ + int _tmp = unit_test_failures; GetUnitTests()[i].function(); \ + std::cerr << "Test [" << GetUnitTests()[i].group << "] [" << GetUnitTests()[i].name << "] - "; \ std::cerr << (_tmp == unit_test_failures ? "PASSED" : "FAILED") << "\n"; } \ std::cerr << "\n" << unit_test_failures << " tests failed\n\n"; \ return unit_test_failures; } From ebd51ada6647ae70401135e789fe43efa98b96f9 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Sat, 13 Sep 2025 01:01:41 +0800 Subject: [PATCH 8/9] ci: workaround clang sanitizer linking bug --- .github/workflows/meson.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml index a294578..b653f4e 100644 --- a/.github/workflows/meson.yml +++ b/.github/workflows/meson.yml @@ -119,10 +119,6 @@ jobs: - name: Setup meson run: | pipx install meson ninja - - name: Setup sanitizers - if: ${{ matrix.platform == 'ubuntu-22.04' }} - run: | - sudo apt update && sudo apt install libasan8 libubsan1 -y - name: Checkout uses: actions/checkout@v4 - name: Activate MSVC and Configure @@ -134,7 +130,7 @@ jobs: if: ${{ matrix.platform != 'windows-2022' }} env: ${{ matrix.mode.extra_envs }} run: | - meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} ${{ matrix.mode.args }} + meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} -Db_lundef=false ${{ matrix.mode.args }} - name: Building run: | meson compile -C build-${{ matrix.flavor }} From 2ef3ff20b301724839fc1e6032bda32a78e6ca56 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Mon, 29 Sep 2025 11:21:55 +0800 Subject: [PATCH 9/9] build: install headers into a subdir --- CMakeLists.txt | 2 +- meson.build | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b96105d..595a262 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ install(TARGETS pystring LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install (FILES pystring.h - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} COMPONENT developer ) diff --git a/meson.build b/meson.build index a4233dd..db5f121 100644 --- a/meson.build +++ b/meson.build @@ -37,7 +37,7 @@ test( ), ) -install_headers(hdrs) +install_headers(hdrs, subdir: 'pystring') pkgconfig = import('pkgconfig') pkgconfig.generate(