Skip to content

Commit a09708a

Browse files
authored
Add meson build system (#50)
* Add meson build system * Sync cmake's installation layout to Makefile and Meson builds * meson: remove cmake config target generation this pulls in an extra dependency on the cmake binary, CMake users can use the PkgConfig module instead. * ci: add meson tests * build: default to c++17 * ci: fix cmake builds * tests: fix memory leak in tests * ci: workaround clang sanitizer linking bug * build: install headers into a subdir
1 parent 02ef118 commit a09708a

File tree

5 files changed

+219
-16
lines changed

5 files changed

+219
-16
lines changed

.github/workflows/ci.yml

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ jobs:
3030
build-type: Release
3131
build-shared: 'ON'
3232
cxx-standard: 17
33-
cc_compiler: clang
34-
cxx_compiler: clang++
33+
cxx-compiler: clang++
34+
cxx-flags: ''
35+
cc-compiler: clang
3536
compiler-desc: clang
3637
os: ubuntu-latest
3738

@@ -42,8 +43,9 @@ jobs:
4243
build-type: Debug
4344
build-shared: 'ON'
4445
cxx-standard: 17
45-
cc_compiler: clang
46-
cxx_compiler: clang++
46+
cxx-compiler: clang++
47+
cxx-flags: ''
48+
cc-compiler: clang
4749
compiler-desc: clang
4850
os: ubuntu-latest
4951

@@ -55,6 +57,7 @@ jobs:
5557
build-shared: 'ON'
5658
cxx-standard: 17
5759
cxx-compiler: g++
60+
cxx-flags: ''
5861
cc-compiler: gcc
5962
compiler-desc: gcc
6063
os: ubuntu-latest
@@ -67,6 +70,7 @@ jobs:
6770
build-shared: 'ON'
6871
cxx-standard: 17
6972
cxx-compiler: g++
73+
cxx-flags: ''
7074
cc-compiler: gcc
7175
compiler-desc: gcc
7276
os: ubuntu-latest
@@ -99,7 +103,7 @@ jobs:
99103
working-directory: _build
100104
- name: Test
101105
run: |
102-
ctest --build-config ${{ matrix.build_type }} --verbose
106+
ctest --build-config ${{ matrix.build-type }} --verbose
103107
working-directory: _build
104108

105109
# ---------------------------------------------------------------------------
@@ -119,6 +123,7 @@ jobs:
119123
build-type: Release
120124
build-shared: 'ON'
121125
cxx-standard: 17
126+
cxx-flags: ''
122127
os: macos-latest
123128

124129
# Debug
@@ -127,6 +132,7 @@ jobs:
127132
build-shared: 'ON'
128133
build-docs: 'OFF'
129134
cxx-standard: 17
135+
cxx-flags: ''
130136
os: macos-latest
131137

132138
steps:
@@ -155,7 +161,7 @@ jobs:
155161
working-directory: _build
156162
- name: Test
157163
run: |
158-
ctest --build-config ${{ matrix.build_type }} --verbose
164+
ctest --build-config ${{ matrix.build-type }} --verbose
159165
working-directory: _build
160166

161167
# ---------------------------------------------------------------------------
@@ -175,13 +181,15 @@ jobs:
175181
build-type: Release
176182
build-shared: 'ON'
177183
cxx-standard: 17
184+
cxx-flags: ''
178185
os: windows-latest
179186

180187
# Debug
181188
- build: 2
182189
build-type: Debug
183190
build-shared: 'ON'
184191
cxx-standard: 17
192+
cxx-flags: ''
185193
os: windows-latest
186194

187195

@@ -217,4 +225,4 @@ jobs:
217225
run: |
218226
ctest -C ${{ matrix.build-type }}
219227
shell: bash
220-
working-directory: _build
228+
working-directory: _build

.github/workflows/meson.yml

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
name: Meson
2+
3+
on:
4+
pull_request:
5+
push:
6+
7+
jobs:
8+
meson-build-and-tests:
9+
runs-on: ${{ matrix.platform }}
10+
name: ${{ matrix.platform }}, ${{ matrix.mode.name }} ${{ matrix.flavor }}
11+
strategy:
12+
fail-fast: false
13+
matrix:
14+
flavor:
15+
- debug
16+
- release
17+
mode:
18+
- name: default
19+
extra_envs: {}
20+
21+
# Alternative compiler setups
22+
- name: gcc
23+
extra_envs:
24+
CC: gcc
25+
CXX: g++
26+
- name: clang
27+
extra_envs:
28+
CC: clang
29+
CXX: clang++
30+
31+
- name: sanitize
32+
args: >-
33+
"-Db_sanitize=address,undefined"
34+
extra_envs: {}
35+
36+
# This is for MSVC, which only supports AddressSanitizer.
37+
# https://learn.microsoft.com/en-us/cpp/sanitizers/
38+
- name: sanitize+asanonly
39+
args: -Db_sanitize=address
40+
extra_envs:
41+
ASAN_OPTIONS: report_globals=0:halt_on_error=1:abort_on_error=1:print_summary=1
42+
43+
- name: clang+sanitize
44+
args: >-
45+
"-Db_sanitize=address,undefined"
46+
extra_envs:
47+
CC: clang
48+
CXX: clang++
49+
50+
# default clang on GitHub hosted runners is from MSYS2.
51+
# Use Visual Studio supplied clang-cl instead.
52+
- name: clang-cl+sanitize
53+
args: >-
54+
"-Db_sanitize=address,undefined"
55+
extra_envs:
56+
CC: clang-cl
57+
CXX: clang-cl
58+
platform:
59+
- ubuntu-22.04
60+
- windows-2022
61+
- macos-latest
62+
63+
exclude:
64+
# clang-cl only makes sense on windows.
65+
- platform: ubuntu-22.04
66+
mode:
67+
name: clang-cl+sanitize
68+
- platform: macos-latest
69+
mode:
70+
name: clang-cl+sanitize
71+
72+
# Use clang-cl instead of MSYS2 clang.
73+
#
74+
# we already tested clang+sanitize on linux,
75+
# if this doesn't work, it should be an issue for MSYS2 team to consider.
76+
- platform: windows-2022
77+
mode:
78+
name: clang
79+
- platform: windows-2022
80+
mode:
81+
name: clang+sanitize
82+
83+
# MSVC-only sanitizers
84+
- platform: ubuntu-22.04
85+
mode:
86+
name: sanitize+asanonly
87+
- platform: macos-latest
88+
mode:
89+
name: sanitize+asanonly
90+
- platform: windows-2022
91+
mode:
92+
name: sanitize
93+
94+
# clang is the default on macos
95+
# also gcc is an alias to clang
96+
- platform: macos-latest
97+
mode:
98+
name: clang
99+
- platform: macos-latest
100+
mode:
101+
name: gcc
102+
103+
# gcc is the default on linux
104+
- platform: ubuntu-22.04
105+
mode:
106+
name: gcc
107+
108+
# only run sanitizer tests on linux
109+
#
110+
# gcc/clang's codegen shouldn't massively change across platforms,
111+
# and linux supports most of the sanitizers.
112+
- platform: macos-latest
113+
mode:
114+
name: clang+sanitize
115+
- platform: macos-latest
116+
mode:
117+
name: sanitize
118+
steps:
119+
- name: Setup meson
120+
run: |
121+
pipx install meson ninja
122+
- name: Checkout
123+
uses: actions/checkout@v4
124+
- name: Activate MSVC and Configure
125+
if: ${{ matrix.platform == 'windows-2022' }}
126+
env: ${{ matrix.mode.extra_envs }}
127+
run: |
128+
meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} -Ddefault_library=static ${{ matrix.mode.args }} --vsenv
129+
- name: Configuring
130+
if: ${{ matrix.platform != 'windows-2022' }}
131+
env: ${{ matrix.mode.extra_envs }}
132+
run: |
133+
meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} -Db_lundef=false ${{ matrix.mode.args }}
134+
- name: Building
135+
run: |
136+
meson compile -C build-${{ matrix.flavor }}
137+
- name: Running tests
138+
env: ${{ matrix.mode.extra_envs }}
139+
run: |
140+
meson test -C build-${{ matrix.flavor }} --timeout-multiplier 0
141+
- uses: actions/upload-artifact@v4
142+
if: failure()
143+
with:
144+
name: ${{ matrix.platform }}-${{ matrix.mode.name }}-${{ matrix.flavor }}-logs
145+
path: build-${{ matrix.flavor }}/meson-logs

CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
cmake_minimum_required(VERSION 3.5)
2-
project(pystring CXX)
2+
project(pystring LANGUAGES CXX VERSION 1.1.4)
33

44
option (BUILD_SHARED_LIBS "Build shared libraries (set to OFF to build static libs)" ON)
55

66
add_library(pystring
77
pystring.cpp
88
pystring.h
99
)
10+
set_target_properties(pystring PROPERTIES
11+
VERSION ${PROJECT_VERSION}
12+
SOVERSION ${PROJECT_VERSION_MAJOR}
13+
)
1014

1115
add_executable (pystring_test test.cpp)
1216
TARGET_LINK_LIBRARIES (pystring_test pystring)

meson.build

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
project(
2+
'pystring',
3+
'cpp',
4+
version: '1.1.4',
5+
license: 'BSD-3-Clause',
6+
license_files: 'LICENSE',
7+
meson_version: '>=1.3',
8+
default_options: ['cpp_std=c++17,c++11', 'warning_level=3'],
9+
)
10+
11+
inc = include_directories('.')
12+
13+
srcs = files('pystring.cpp')
14+
hdrs = files('pystring.h')
15+
16+
pystring_lib = library(
17+
'pystring',
18+
srcs,
19+
implicit_include_directories: false,
20+
include_directories: inc,
21+
version: meson.project_version(),
22+
install: true,
23+
)
24+
pystring_dep = declare_dependency(
25+
link_with: pystring_lib,
26+
include_directories: inc,
27+
)
28+
meson.override_dependency('pystring', pystring_dep)
29+
30+
test(
31+
'PyStringTest',
32+
executable(
33+
'pystring_test',
34+
'test.cpp',
35+
dependencies: pystring_dep,
36+
build_by_default: false,
37+
),
38+
)
39+
40+
install_headers(hdrs, subdir: 'pystring')
41+
42+
pkgconfig = import('pkgconfig')
43+
pkgconfig.generate(
44+
pystring_lib,
45+
description: 'C++ functions matching the interface and behavior of python string methods with std::string',
46+
)

unittest.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ struct PYSTRINGTest
2323
PYSTRINGTestFunc function;
2424
};
2525

26-
typedef std::vector<PYSTRINGTest*> UnitTests;
26+
typedef std::vector<PYSTRINGTest> UnitTests;
2727

2828
UnitTests& GetUnitTests();
2929

30-
struct AddTest { AddTest(PYSTRINGTest* test); };
30+
struct AddTest { AddTest(PYSTRINGTest&& test); };
3131

3232
/// PYSTRING_CHECK_* macros checks if the conditions is met, and if not,
3333
/// prints an error message indicating the module and line where the
@@ -102,22 +102,22 @@ struct AddTest { AddTest(PYSTRINGTest* test); };
102102

103103
#define PYSTRING_ADD_TEST(group, name) \
104104
static void pystringtest_##group##_##name(); \
105-
AddTest pystringaddtest_##group##_##name(new PYSTRINGTest(#group, #name, pystringtest_##group##_##name)); \
105+
AddTest pystringaddtest_##group##_##name(PYSTRINGTest(#group, #name, pystringtest_##group##_##name)); \
106106
static void pystringtest_##group##_##name()
107107

108108
#define PYSTRING_TEST_SETUP() \
109109
int unit_test_failures = 0
110110

111111
#define PYSTRING_TEST_APP(app) \
112-
std::vector<PYSTRINGTest*>& GetUnitTests() { \
113-
static std::vector<PYSTRINGTest*> pystring_unit_tests; \
112+
std::vector<PYSTRINGTest>& GetUnitTests() { \
113+
static std::vector<PYSTRINGTest> pystring_unit_tests; \
114114
return pystring_unit_tests; } \
115-
AddTest::AddTest(PYSTRINGTest* test){GetUnitTests().push_back(test);}; \
115+
AddTest::AddTest(PYSTRINGTest&& test){GetUnitTests().emplace_back(test);}; \
116116
PYSTRING_TEST_SETUP(); \
117117
int main(int, char **) { std::cerr << "\n" << #app <<"\n\n"; \
118118
for(size_t i = 0; i < GetUnitTests().size(); ++i) { \
119-
int _tmp = unit_test_failures; GetUnitTests()[i]->function(); \
120-
std::cerr << "Test [" << GetUnitTests()[i]->group << "] [" << GetUnitTests()[i]->name << "] - "; \
119+
int _tmp = unit_test_failures; GetUnitTests()[i].function(); \
120+
std::cerr << "Test [" << GetUnitTests()[i].group << "] [" << GetUnitTests()[i].name << "] - "; \
121121
std::cerr << (_tmp == unit_test_failures ? "PASSED" : "FAILED") << "\n"; } \
122122
std::cerr << "\n" << unit_test_failures << " tests failed\n\n"; \
123123
return unit_test_failures; }

0 commit comments

Comments
 (0)