Skip to content

Commit fc75883

Browse files
authored
Add Meson Build (#696)
1 parent 0c258ff commit fc75883

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+618
-307
lines changed

.github/workflows/ci.yml

Lines changed: 61 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,17 @@ on:
77
branches: [main]
88

99
jobs:
10-
test-ubuntu-py38:
11-
runs-on: ${{matrix.os}}
10+
test-ubuntu-py39-coverage:
11+
runs-on: ubuntu-latest
1212
timeout-minutes: 20
13-
strategy:
14-
fail-fast: false
15-
matrix:
16-
os: [ubuntu-latest]
17-
python-version:
18-
- "3.8"
1913

2014
steps:
2115
- uses: actions/checkout@v3
2216

23-
- name: Set up Python ${{ matrix.python-version }}
17+
- name: Set up Python 3.9
2418
uses: actions/setup-python@v4
2519
with:
26-
python-version: ${{ matrix.python-version }}
20+
python-version: "3.9"
2721

2822
- name: Upgrade pip version
2923
run: |
@@ -33,19 +27,23 @@ jobs:
3327
run: |
3428
python -m pip install -r requirements.txt
3529
python -m pip install -r docs/requirements.txt
30+
python -m pip install spin
3631
3732
- name: Install lcov
3833
run: |
3934
sudo apt-get update
4035
sudo apt-get install -y lcov
4136
4237
- name: Build package
38+
env:
39+
CXXFLAGS: "-std=c++17 --coverage"
40+
CFLAGS: "--coverage"
4341
run: |
44-
CXXFLAGS="-std=c++17 --coverage" CFLAGS="--coverage" python scripts/build/install.py
45-
# coverage tests
42+
spin build -v
43+
4644
- name: Run tests
4745
run: |
48-
python -m pytest --doctest-modules --cov=./ --cov-report=xml -s
46+
spin test -v
4947
5048
- name: Capture Coverage Data with lcov
5149
run: |
@@ -72,7 +70,7 @@ jobs:
7270
run: |
7371
sphinx-build -b html docs/source/ docs/build/html
7472
75-
test-ubuntu-py39-py310:
73+
test-ubuntu-py39-py310-py311:
7674
runs-on: ${{matrix.os}}
7775
timeout-minutes: 20
7876
strategy:
@@ -82,6 +80,7 @@ jobs:
8280
python-version:
8381
- "3.9"
8482
- "3.10"
83+
- "3.11"
8584

8685
steps:
8786
- uses: actions/checkout@v3
@@ -99,14 +98,17 @@ jobs:
9998
run: |
10099
python -m pip install -r requirements.txt
101100
python -m pip install -r docs/requirements.txt
101+
python -m pip install spin
102102
103103
- name: Build package
104+
env:
105+
CXXFLAGS: "-std=c++17"
104106
run: |
105-
CXXFLAGS="-std=c++17" python scripts/build/install.py
107+
spin build -v
106108
107109
- name: Run tests
108110
run: |
109-
python -c "import pydatastructs; pydatastructs.test(only_benchmarks=True)"
111+
spin test -v
110112
111113
- name: Build Documentation
112114
run: |
@@ -120,9 +122,9 @@ jobs:
120122
matrix:
121123
os: [macos-latest]
122124
python-version:
123-
- "3.8"
124125
- "3.9"
125126
- "3.10"
127+
- "3.11"
126128

127129
steps:
128130
- uses: actions/checkout@v3
@@ -140,66 +142,57 @@ jobs:
140142
run: |
141143
python -m pip install -r requirements.txt
142144
python -m pip install -r docs/requirements.txt
145+
python -m pip install spin
143146
144147
- name: Build package
145148
env:
146149
MACOSX_DEPLOYMENT_TARGET: 11.0
150+
CXXFLAGS: "-std=c++17"
147151
run: |
148-
CXXFLAGS="-std=c++17" python scripts/build/install.py
152+
spin build -v
153+
149154
- name: Run tests
150155
run: |
151-
python -c "import pydatastructs; pydatastructs.test()"
156+
spin test -v
152157
153158
- name: Build Documentation
154159
run: |
155160
sphinx-build -b html docs/source/ docs/build/html
156161
157-
# test-windows:
158-
# runs-on: ${{matrix.os}}
159-
# timeout-minutes: 20
160-
# strategy:
161-
# fail-fast: false
162-
# matrix:
163-
# os: [windows-latest]
164-
# python-version:
165-
# - "3.8"
166-
167-
# steps:
168-
# - uses: actions/checkout@v3
169-
170-
# - name: Set up Python ${{ matrix.python-version }}
171-
# uses: actions/setup-python@v4
172-
# with:
173-
# python-version: ${{ matrix.python-version }}
174-
175-
# - name: Setup conda
176-
# uses: s-weigand/setup-conda@v1
177-
# with:
178-
# update-conda: true
179-
# python-version: ${{ matrix.python-version }}
180-
# conda-channels: anaconda, conda-forge
181-
# # - run: conda --version # This fails due to unknown reasons
182-
# - run: which python
183-
184-
# - name: Upgrade pip version
185-
# run: |
186-
# python -m pip install --upgrade pip
187-
188-
# - name: Install requirements
189-
# run: |
190-
# python -m pip install -r requirements.txt
191-
# python -m pip install -r docs/requirements.txt
192-
193-
# - name: Build package
194-
# env:
195-
# CL: "/std:c++17"
196-
# run: |
197-
# python scripts/build/install.py
198-
199-
# - name: Run tests
200-
# run: |
201-
# python -c "import pydatastructs; pydatastructs.test()"
202-
203-
# - name: Build Documentation
204-
# run: |
205-
# sphinx-build -b html docs/source/ docs/build/html
162+
test-windows:
163+
runs-on: windows-latest
164+
strategy:
165+
fail-fast: false
166+
matrix:
167+
python-version: ["3.9", "3.10", "3.11"]
168+
169+
steps:
170+
- uses: actions/checkout@v3
171+
172+
- uses: actions/setup-python@v4
173+
with:
174+
python-version: ${{ matrix.python-version }}
175+
176+
- uses: ilammy/msvc-dev-cmd@v1
177+
178+
- name: Upgrade pip
179+
run: python -m pip install --upgrade pip
180+
181+
- name: Install requirements
182+
run: |
183+
python -m pip install -r requirements.txt
184+
python -m pip install -r docs/requirements.txt
185+
python -m pip install spin
186+
187+
- name: Build package
188+
env:
189+
CFLAGS: "/MD"
190+
CXXFLAGS: "/std:c++17 /MD /Zc:strictStrings-"
191+
CL: "/std:c++17 /MD /Zc:strictStrings-"
192+
run: spin build -v
193+
194+
- name: Run tests
195+
run: spin test -v
196+
197+
- name: Build Documentation
198+
run: sphinx-build -b html docs/source/ docs/build/html

environment.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ dependencies:
99
- pip:
1010
- codecov
1111
- pytest-cov
12+
- spin
13+
- meson
1214
- sphinx==5.0
1315
- sphinx-readable-theme==1.3.0
1416
- myst_nb==0.17.2

meson.build

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
project('pydatastructs', 'cpp',
2+
version : '1.0.1-dev',
3+
default_options : ['cpp_std=c++17'])
4+
5+
6+
python = import('python').find_installation(pure: false)
7+
8+
subdir('pydatastructs')

pydatastructs/graphs/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from . import algorithms
1010
from . import adjacency_list
1111
from . import adjacency_matrix
12-
from . import _extensions
1312

1413
from .algorithms import (
1514
breadth_first_search,

pydatastructs/graphs/_backend/cpp/graph.cpp

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,59 +4,71 @@
44
#include "AdjacencyMatrix.hpp"
55
#include "AdjacencyListGraphNode.hpp"
66
#include "AdjacencyMatrixGraphNode.hpp"
7+
#include "GraphEdge.hpp"
8+
#include "GraphNode.hpp"
79
#include "graph_bindings.hpp"
10+
#include "Algorithms.hpp"
811

9-
#ifdef __cplusplus
10-
extern "C" {
11-
#endif
12-
13-
PyMODINIT_FUNC PyInit__graph(void);
14-
15-
#ifdef __cplusplus
16-
}
17-
#endif
12+
static PyMethodDef GraphMethods[] = {
13+
{"bfs_adjacency_list", (PyCFunction)breadth_first_search_adjacency_list, METH_VARARGS | METH_KEYWORDS, "Run BFS on adjacency list with callback"},
14+
{"bfs_adjacency_matrix", (PyCFunction)breadth_first_search_adjacency_matrix, METH_VARARGS | METH_KEYWORDS, "Run BFS on adjacency matrix with callback"},
15+
{"minimum_spanning_tree_prim_adjacency_list", (PyCFunction)minimum_spanning_tree_prim_adjacency_list, METH_VARARGS | METH_KEYWORDS, "Run Prim's algorithm on adjacency list"},
16+
{"shortest_paths_dijkstra_adjacency_list", (PyCFunction)shortest_paths_dijkstra_adjacency_list, METH_VARARGS | METH_KEYWORDS, "Dijkstra's algorithm for adjacency list graphs"},
17+
{NULL, NULL, 0, NULL}
18+
};
1819

1920
static struct PyModuleDef graph_module = {
2021
PyModuleDef_HEAD_INIT,
2122
"_graph",
2223
"C++ module for graphs",
2324
-1,
24-
NULL,
25+
GraphMethods,
2526
};
2627

2728
PyMODINIT_FUNC PyInit__graph(void) {
2829
PyObject* m;
2930

30-
if (PyType_Ready(&AdjacencyListGraphType) < 0)
31+
if (PyType_Ready(&GraphNodeType) < 0)
3132
return NULL;
3233

3334
if (PyType_Ready(&AdjacencyListGraphNodeType) < 0)
3435
return NULL;
3536

36-
if (PyType_Ready(&AdjacencyMatrixGraphType) < 0)
37+
if (PyType_Ready(&AdjacencyMatrixGraphNodeType) < 0)
3738
return NULL;
3839

39-
if (PyType_Ready(&AdjacencyMatrixGraphNodeType) < 0)
40+
if (PyType_Ready(&GraphEdgeType) < 0)
41+
return NULL;
42+
43+
if (PyType_Ready(&AdjacencyListGraphType) < 0)
44+
return NULL;
45+
46+
if (PyType_Ready(&AdjacencyMatrixGraphType) < 0)
4047
return NULL;
4148

4249
m = PyModule_Create(&graph_module);
4350
if (m == NULL)
4451
return NULL;
4552

53+
Py_INCREF(&GraphNodeType);
54+
PyModule_AddObject(m, "GraphNode", (PyObject*)&GraphNodeType);
55+
56+
Py_INCREF(&AdjacencyListGraphNodeType);
57+
PyModule_AddObject(m, "AdjacencyListGraphNode", (PyObject*)&AdjacencyListGraphNodeType);
58+
59+
Py_INCREF(&AdjacencyMatrixGraphNodeType);
60+
PyModule_AddObject(m, "AdjacencyMatrixGraphNode", (PyObject*)&AdjacencyMatrixGraphNodeType);
61+
62+
Py_INCREF(&GraphEdgeType);
63+
PyModule_AddObject(m, "GraphEdge", (PyObject*)&GraphEdgeType);
64+
4665
Py_INCREF(&AdjacencyListGraphType);
4766
if (PyModule_AddObject(m, "AdjacencyListGraph", (PyObject*)&AdjacencyListGraphType) < 0) {
4867
Py_DECREF(&AdjacencyListGraphType);
4968
Py_DECREF(m);
5069
return NULL;
5170
}
5271

53-
Py_INCREF(&AdjacencyListGraphNodeType);
54-
if (PyModule_AddObject(m, "AdjacencyListGraphNode", (PyObject*)&AdjacencyListGraphNodeType) < 0) {
55-
Py_DECREF(&AdjacencyListGraphNodeType);
56-
Py_DECREF(m);
57-
return NULL;
58-
}
59-
6072
Py_INCREF(&AdjacencyMatrixGraphType);
6173
if (PyModule_AddObject(m, "AdjacencyMatrixGraph", (PyObject*)&AdjacencyMatrixGraphType) < 0) {
6274
Py_DECREF(&AdjacencyMatrixGraphType);

pydatastructs/graphs/algorithms.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def breadth_first_search(
9292
return getattr(algorithms, func)(
9393
graph, source_node, operation, *args, **kwargs)
9494
else:
95-
from pydatastructs.graphs._backend.cpp._algorithms import bfs_adjacency_list, bfs_adjacency_matrix
95+
from pydatastructs.graphs._backend.cpp._graph import bfs_adjacency_list, bfs_adjacency_matrix
9696
if (graph._impl == "adjacency_list"):
9797
extra_args = args if args else ()
9898
return bfs_adjacency_list(graph, source_node, operation, extra_args)
@@ -349,7 +349,7 @@ def minimum_spanning_tree(graph, algorithm, **kwargs):
349349
%(algorithm, graph._impl))
350350
return getattr(algorithms, func)(graph)
351351
else:
352-
from pydatastructs.graphs._backend.cpp._algorithms import minimum_spanning_tree_prim_adjacency_list
352+
from pydatastructs.graphs._backend.cpp._graph import minimum_spanning_tree_prim_adjacency_list
353353
if graph._impl == "adjacency_list" and algorithm == 'prim':
354354
return minimum_spanning_tree_prim_adjacency_list(graph)
355355

@@ -814,7 +814,7 @@ def shortest_paths(graph: Graph, algorithm: str,
814814
"finding shortest paths in graphs."%(algorithm))
815815
return getattr(algorithms, func)(graph, source, target)
816816
else:
817-
from pydatastructs.graphs._backend.cpp._algorithms import shortest_paths_dijkstra_adjacency_list
817+
from pydatastructs.graphs._backend.cpp._graph import shortest_paths_dijkstra_adjacency_list
818818
if graph._impl == "adjacency_list" and algorithm == 'dijkstra':
819819
return shortest_paths_dijkstra_adjacency_list(graph, source, target)
820820

pydatastructs/graphs/meson.build

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
python = import('python').find_installation(pure: false)
2+
3+
python.install_sources(
4+
[
5+
'__init__.py',
6+
'adjacency_list.py',
7+
'adjacency_matrix.py',
8+
'algorithms.py',
9+
'graph.py'
10+
],
11+
subdir: 'pydatastructs/graphs'
12+
)
13+
14+
python.install_sources(
15+
['_backend/__init__.py', '_backend/cpp/__init__.py'],
16+
subdir: 'pydatastructs/graphs/_backend'
17+
)
18+
19+
py_include = include_directories('../utils/_backend/cpp')
20+
21+
python.extension_module(
22+
'_graph',
23+
[
24+
'_backend/cpp/graph.cpp',
25+
'_backend/cpp/algorithms.cpp',
26+
'../utils/_backend/cpp/graph_utils.cpp',
27+
],
28+
include_directories: py_include,
29+
install: true,
30+
subdir: 'pydatastructs/graphs/_backend/cpp'
31+
)
32+
33+
34+
subdir('tests')

0 commit comments

Comments
 (0)