Skip to content

Commit 741ab91

Browse files
authored
[Feature] Windows support (#28)
Summary: Windows support Test Plan: All tests on Windows, Linux and Darwin Reviewed-by: - Issue: closes #5
1 parent 35aba77 commit 741ab91

12 files changed

Lines changed: 420 additions & 126 deletions

File tree

.github/workflows/check.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
# for actions/setup-python:
2020
# https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json
2121
python: [ '3.8', '3.9', '3.10', '3.11', '3.12' ]
22-
os: [ ubuntu-latest, macOS-latest ]
22+
os: [ ubuntu-latest, macOS-latest, windows-latest ]
2323

2424
steps:
2525
- uses: actions/checkout@v4
@@ -38,7 +38,7 @@ jobs:
3838
runs-on: ${{ matrix.os }}
3939
strategy:
4040
matrix:
41-
os: [ ubuntu-latest, macOS-latest ]
41+
os: [ ubuntu-latest, macOS-latest, windows-latest ]
4242
conda-py: [ '3.8', '3.9', '3.10', '3.11', '3.12' ]
4343

4444
steps:

.github/workflows/performance.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ concurrency:
1212

1313
jobs:
1414
perf-import:
15-
runs-on: ubuntu-latest
15+
runs-on: ${{ matrix.os }}
16+
strategy:
17+
matrix:
18+
os: [ ubuntu-latest, macOS-latest, windows-latest ]
1619

1720
steps:
1821
- uses: actions/checkout@v4
@@ -28,7 +31,10 @@ jobs:
2831
sh scripts/perf_import.sh
2932
3033
pyperformance:
31-
runs-on: ubuntu-latest
34+
runs-on: ${{ matrix.os }}
35+
strategy:
36+
matrix:
37+
os: [ ubuntu-latest, macOS-latest, windows-latest ]
3238

3339
steps:
3440
- uses: actions/checkout@v4

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
runs-on: ${{ matrix.os }}
2828
strategy:
2929
matrix:
30-
os: [ ubuntu-latest, macOS-latest ]
30+
os: [ ubuntu-latest, macOS-latest, windows-latest ]
3131

3232
steps:
3333
- uses: actions/checkout@v4

CMakeLists.txt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ cmake_minimum_required(VERSION 3.20)
22
project(pycds)
33

44
set(CMAKE_C_STANDARD 11)
5-
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=implicit-function-declaration")
5+
if (MSVC)
6+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /we4013")
7+
else ()
8+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=implicit-function-declaration")
9+
endif ()
610

711
# Only for IDE linting, skbuild will handle wheel dependencies.
812
if (NOT SKBUILD)
@@ -11,16 +15,16 @@ endif ()
1115

1216
find_package(Python 3.8 REQUIRED COMPONENTS Interpreter Development.Module)
1317

14-
add_compile_definitions(Py_BUILD_CORE) # for sizeof(PyGC_Head)
18+
add_compile_definitions(Py_BUILD_CORE Py_BUILD_CORE_MODULE) # for sizeof(PyGC_Head)
1519
add_compile_definitions(NEED_OPCODE_TABLES) # for _PyOpcode_Caches and _PyOpcode_Deopt
1620

17-
python_add_library(_cds MODULE WITH_SOABI src/_cds/_cdsmodule.c src/_cds/lookup_table.c src/_cds/hashtable.c)
21+
python_add_library(_cds MODULE WITH_SOABI src/_cds/_cdsmodule.c src/_cds/lookup_table.c src/_cds/hashtable.c src/_cds/platforms.c)
1822
# clinic-generated files access core header.
1923
target_include_directories(_cds PRIVATE "${Python_INCLUDE_DIRS}/internal")
2024

2125
# todo: if find cpython repo, run clinic
2226
# currently we manually run `python3 ../cpython/Tools/clinic/clinic.py --make --srcdir src/_cds`
2327

24-
install(TARGETS _cds DESTINATION .)
28+
install(TARGETS _cds LIBRARY DESTINATION .)
2529

2630
install(FILES src/artifacts/pycds.pth DESTINATION .)

noxfile.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,22 @@
1717
RELEASE = platform.release()
1818
PYCDS_ROOT = os.path.dirname(__file__)
1919

20+
GA = os.environ.get('GITHUB_ACTIONS') == 'true'
21+
2022
CDS_PYPERFORMANCE = 'git+https://github.com/oraluben/pyperformance.git@cds'
2123

2224

25+
def _clean_nox():
26+
from nox.virtualenv import shutil
27+
28+
shutil.rmtree(os.path.join(PYCDS_ROOT, '.nox'), ignore_errors=True)
29+
30+
31+
def ci_session_cleanup():
32+
if OS == 'Windows' and GA:
33+
_clean_nox()
34+
35+
2336
def _py_version(session: nox.Session):
2437
"""
2538
:return: "3.9", "3.10", ...
@@ -132,9 +145,11 @@ def test_import_third_party(session: nox.Session, package):
132145
img = os.path.join(tmp, 'test.img')
133146

134147
session.run('python', '-c', package.import_stmt, env={'PYCDSMODE': 'TRACE', 'PYCDSLIST': lst})
135-
session.run('python', '-c', f'import cds.dump; cds.dump.run_dump("{lst}", "{img}")')
148+
session.run('python', '-c', f'import cds.dump; cds.dump.run_dump({repr(lst)}, {repr(img)})')
136149
session.run('python', '-c', package.import_stmt, env={'PYCDSMODE': 'SHARE', 'PYCDSARCHIVE': img})
137150

151+
ci_session_cleanup()
152+
138153

139154
@nox.session(name=f'test_import_third_party_perf-{py}', tags=['test_import_third_party_perf'], python=py)
140155
@nox.parametrize('package', [package for package in PACKAGES if not package.should_skip(py)])
@@ -158,7 +173,7 @@ def test_import_third_party_perf(session: nox.Session, package):
158173

159174
logger.info(f'start generating CDS archive for {package.name}')
160175
session.run('python', '-c', package.import_stmt, env={'PYCDSMODE': 'TRACE', 'PYCDSLIST': lst}, log=False)
161-
session.run('python', '-c', f'import cds.dump; cds.dump.run_dump("{lst}", "{img}")', log=False)
176+
session.run('python', '-c', f'import cds.dump; cds.dump.run_dump({repr(lst)}, {repr(img)})', log=False)
162177
session.run('python', '-c', package.import_stmt, env={'PYCDSMODE': 'SHARE', 'PYCDSARCHIVE': img}, log=False)
163178
logger.info(f'finish generating CDS archive for {package.name}')
164179

@@ -172,6 +187,8 @@ def test_import_third_party_perf(session: nox.Session, package):
172187
'python', '-c', package.import_stmt,
173188
env={'PYCDSMODE': 'SHARE', 'PYCDSARCHIVE': img})
174189

190+
ci_session_cleanup()
191+
175192

176193
def _pyperformance(session: nox.Session, pyperformance_args=None):
177194
session.install(CDS_PYPERFORMANCE)

pyproject.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ requires-python = ">=3.8"
66
classifiers = [
77
'Development Status :: 3 - Alpha',
88
'Operating System :: MacOS :: MacOS X',
9-
# 'Operating System :: Microsoft :: Windows',
9+
'Operating System :: Microsoft :: Windows',
1010
'Operating System :: POSIX :: Linux',
1111
'Programming Language :: Python :: 3.8',
1212
'Programming Language :: Python :: 3.9',
@@ -33,5 +33,9 @@ skip = "*-musllinux*"
3333
[tool.cibuildwheel.macos]
3434
archs = ["x86_64", "universal2", "arm64"]
3535

36+
[tool.cibuildwheel.windows]
37+
archs = ["AMD64", "ARM64"]
38+
test-skip = "*-win_arm64"
39+
3640
[tool.scikit-build]
3741
wheel.packages = ["src/cds"]

src/_cds/_cdscontext.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#ifndef PYCDS__CDSCONTEXT_H
2+
#define PYCDS__CDSCONTEXT_H
3+
4+
#include <Python.h>
5+
#include <stdbool.h>
6+
7+
#include "lookup_table.h"
8+
#include "platforms.h"
9+
10+
struct StringRefItem {
11+
PyObject **ref;
12+
struct StringRefItem *next;
13+
};
14+
15+
struct StringRefList {
16+
PyObject *str;
17+
struct StringRefItem *refs;
18+
struct StringRefList *next;
19+
};
20+
21+
struct CDSArchiveHeader {
22+
void *mapped_addr;
23+
void *none_addr;
24+
void *true_addr;
25+
void *false_addr;
26+
void *ellipsis_addr;
27+
size_t used;
28+
29+
PyObject *obj;
30+
31+
struct StringRefList *all_string_ref;
32+
};
33+
34+
struct MoveInContext {
35+
int n_alloc;
36+
37+
table *orig_pyobject_to_in_heap_pyobject_map;
38+
table *in_heap_str_to_string_ref_list_map;
39+
40+
#if PY_MINOR_VERSION >= 12
41+
PyObject *static_strings;
42+
#endif
43+
};
44+
45+
struct CDSStatus {
46+
int verbose;
47+
int mode;
48+
49+
// Prevent re-entry of cds.init_from_env()
50+
bool initialized;
51+
52+
long shift;
53+
bool traverse_error;
54+
55+
const char *archive;
56+
fd_type archive_fd;
57+
#if IS_WINDOWS
58+
fd_type mapping;
59+
#endif
60+
61+
struct CDSArchiveHeader *archive_header;
62+
63+
PyObject *flags;
64+
65+
struct MoveInContext *move_in_ctx;
66+
};
67+
68+
#endif // PYCDS__CDSCONTEXT_H

0 commit comments

Comments
 (0)