Skip to content

Commit 2be28c0

Browse files
committed
compat.pocketpy: one translation unit, as upstream's CMake builds it
CMake's default is a unity build of all of POCKETPY_SRC in one group, and the release's pocketpy.c is the same sources amalgamated; the generated pocketpy_unity.c includes the 84 files in CMake's GLOB_RECURSE order. The sources rely on it: with NDEBUG, PK_INLINE marks functions the headers declare and other files call `inline`, and clang emits no definition of them for the MSVC ABI, so compiled one by one the release profile left PyObject__userdata, pk_typeinfo, c11__bit_length and others undefined on Windows (found by pocketpy-m's CI). Calls across files now inline as in upstream's build. Tested again with GCC (dev, release), LLVM (release) and wasm32-emscripten (release).
1 parent 1a9a38e commit 2be28c0

2 files changed

Lines changed: 115 additions & 13 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
- **compat.pocketpy 2.2.0(新包)。** PocketPy 2:用 C11 写的小型可嵌入 Python 3.x 解释器(MIT,无依赖)。从标签归档
1313
构建 `src/**/*.c`(即上游 CMake 的 POCKETPY_SRC;`_generated.c` 已随源码提供,无需 prebuild.py)为静态库,
14-
逐个源文件编译(同上游 build.sh / run_tests.sh),`-std=gnu11`。配置取 `pocketpy/config.h` 给未定义任何宏的使用者
14+
按上游 CMake 的默认做法作为一个 unity 翻译单元编译(生成的 `pocketpy_unity.c` 按 CMake 的 GLOB_RECURSE 顺序包含 84 个
15+
源文件;源码依赖于此:NDEBUG 下 `PK_INLINE` 把头文件声明、其他文件调用的函数标为 `inline`,clang 在 MSVC ABI 下不输出
16+
其定义,逐个编译会在 Windows 上留下未定义符号),`-std=gnu11`。配置取 `pocketpy/config.h` 给未定义任何宏的使用者
1517
的取值(即使用者的 `<pocketpy.h>` 所见):`PK_ENABLE_OS=1`、`PK_ENABLE_THREADS=0`(CMake 打开它只在其 unity 构建下
1618
能编译:`time.c` 未包含声明 `c11_thrd__yield` 的头文件)、`PK_ENABLE_DLL=0`;另打开两项上游选项:
1719
`PK_ENABLE_DETERMINISM=1` 与 `-ffp-contract=off`(同 CMake,浮点结果跨平台一致)、`PK_ENABLE_WATCHDOG=1`

‎pkgs/c/compat.pocketpy.lua‎

Lines changed: 112 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
-- C11 (MIT).
33
--
44
-- Shape A (C-source compat): upstream's library target, built from the tag
5-
-- archive with each source compiled on its own, as upstream's build.sh and
6-
-- run_tests.sh build it. A consumer writes `#include <pocketpy.h>` and links
7-
-- the lib.
5+
-- archive as upstream's CMake builds it by default. A consumer writes
6+
-- `#include <pocketpy.h>` and links the lib.
87
--
98
-- WHAT IS COMPILED. Every src/**/*.c, which is exactly CMake's POCKETPY_SRC
109
-- (`file(GLOB_RECURSE … src/*.c)`): the compiler, the VM, the public C API
@@ -16,6 +15,18 @@
1615
-- msgpack and periphery modules, each OFF in CMakeOptions.txt), and the
1716
-- pybind11-style C++ layer under include/pybind11 (header-only, not built).
1817
--
18+
-- ONE TRANSLATION UNIT, as upstream builds it: CMake's default is a unity
19+
-- build of the whole of POCKETPY_SRC in one group (PK_BUILD_WITH_UNITY,
20+
-- UNITY_BUILD_MODE GROUP), and the release's pocketpy.c is the same sources
21+
-- amalgamated. The generated pocketpy_unity.c below includes the 84 files in
22+
-- CMake's order (GLOB_RECURSE sorts them). The sources rely on it: with
23+
-- NDEBUG, PK_INLINE marks functions the headers declare and other files call
24+
-- (py_retval, py_peek, PyObject__userdata …) `inline`, whose definitions
25+
-- clang does not emit for the MSVC ABI, so compiled one by one they leave
26+
-- undefined symbols on Windows; and calls across files inline as upstream's
27+
-- build inlines them. The file list is 2.2.0's: a new version's must be
28+
-- checked against its src/.
29+
--
1930
-- INCLUDE PATH. `*/include`, upstream's INTERFACE include directory
2031
-- (`target_include_directories(pocketpy INTERFACE include)`): a consumer
2132
-- includes <pocketpy.h>, which defines PK_IS_PUBLIC_INCLUDE and so declares
@@ -31,13 +42,11 @@
3142
-- that are on here:
3243
-- PK_ENABLE_OS=1 the os module, file import, the debugger
3344
-- (config.h's default; CMake's too).
34-
-- PK_ENABLE_THREADS=0 config.h's default. CMake turns it on, but only
35-
-- its unity build compiles that way: src/modules/
36-
-- time.c calls c11_thrd__yield without including
37-
-- the header that declares it, which a separate
38-
-- compilation (GCC 14+) rejects. Off, pkpy has no
39-
-- ComputeThread and names are interned without a
40-
-- lock; the same on every platform, the Web included.
45+
-- PK_ENABLE_THREADS=0 config.h's default (CMake's is on). Off, pkpy has
46+
-- no ComputeThread and names are interned without a
47+
-- lock: the same on every platform, the Web
48+
-- included, where a program has no threads unless
49+
-- built for shared memory (-pthread).
4150
-- PK_ENABLE_DLL=0 config.h's default: no import of native modules
4251
-- from shared libraries (dlopen / LoadLibrary).
4352
-- PK_ENABLE_DETERMINISM=1 and -ffp-contract=off, as CMake builds it: float
@@ -56,7 +65,7 @@
5665
-- py_callcfunc as a function without NDEBUG and as a macro with it.
5766
--
5867
-- PLATFORMS. Linux (GCC, LLVM), macOS, Windows (clang targeting the MSVC ABI)
59-
-- and wasm32-emscripten, the same sources and flags. Linux links libm for a
68+
-- and wasm32-emscripten, the same translation unit and flags. Linux links libm for a
6069
-- consumer linked by the C driver. Windows links ws2_32 (CMake, for the
6170
-- debugger's socket) and defines _CRT_SECURE_NO_WARNINGS as CMake does.
6271
--
@@ -117,7 +126,98 @@ package = {
117126
import_std = false,
118127
c_standard = "gnu11",
119128
include_dirs = { "*/include" },
120-
sources = { "*/src/**/*.c" },
129+
sources = { "*/mcpp/pocketpy_unity.c" },
130+
generated_files = {
131+
["pocketpy-2.2.0/mcpp/pocketpy_unity.c"] = [==[
132+
/* compat.pocketpy: upstream's unity build (CMakeLists.txt, PK_BUILD_WITH_UNITY,
133+
one UNITY_GROUP): every C source under src of 2.2.0, in the order of
134+
CMake's GLOB_RECURSE. */
135+
#include "../src/bindings/py_array.c"
136+
#include "../src/bindings/py_mappingproxy.c"
137+
#include "../src/bindings/py_method.c"
138+
#include "../src/bindings/py_number.c"
139+
#include "../src/bindings/py_object.c"
140+
#include "../src/bindings/py_property.c"
141+
#include "../src/bindings/py_range.c"
142+
#include "../src/bindings/py_str.c"
143+
#include "../src/common/_generated.c"
144+
#include "../src/common/algorithm.c"
145+
#include "../src/common/chunkedvector.c"
146+
#include "../src/common/dmath.c"
147+
#include "../src/common/memorypool.c"
148+
#include "../src/common/name.c"
149+
#include "../src/common/serialize.c"
150+
#include "../src/common/smallmap.c"
151+
#include "../src/common/socket.c"
152+
#include "../src/common/sourcedata.c"
153+
#include "../src/common/sstream.c"
154+
#include "../src/common/str.c"
155+
#include "../src/common/threads.c"
156+
#include "../src/common/vector.c"
157+
#include "../src/compiler/compiler.c"
158+
#include "../src/compiler/lexer.c"
159+
#include "../src/debugger/core.c"
160+
#include "../src/debugger/dap.c"
161+
#include "../src/interpreter/ceval.c"
162+
#include "../src/interpreter/dll.c"
163+
#include "../src/interpreter/frame.c"
164+
#include "../src/interpreter/generator.c"
165+
#include "../src/interpreter/heap.c"
166+
#include "../src/interpreter/line_profiler.c"
167+
#include "../src/interpreter/objectpool.c"
168+
#include "../src/interpreter/py_compile.c"
169+
#include "../src/interpreter/typeinfo.c"
170+
#include "../src/interpreter/vm.c"
171+
#include "../src/interpreter/vmx.c"
172+
#include "../src/modules/array2d.c"
173+
#include "../src/modules/base64.c"
174+
#include "../src/modules/builtins.c"
175+
#include "../src/modules/colorcvt.c"
176+
#include "../src/modules/conio.c"
177+
#include "../src/modules/dis.c"
178+
#include "../src/modules/easing.c"
179+
#include "../src/modules/enum.c"
180+
#include "../src/modules/gc.c"
181+
#include "../src/modules/importlib.c"
182+
#include "../src/modules/inspect.c"
183+
#include "../src/modules/json.c"
184+
#include "../src/modules/lz4.c"
185+
#include "../src/modules/math.c"
186+
#include "../src/modules/os.c"
187+
#include "../src/modules/pickle.c"
188+
#include "../src/modules/picoterm.c"
189+
#include "../src/modules/pkpy.c"
190+
#include "../src/modules/random.c"
191+
#include "../src/modules/stdc.c"
192+
#include "../src/modules/time.c"
193+
#include "../src/modules/traceback.c"
194+
#include "../src/modules/unicodedata.c"
195+
#include "../src/modules/vmath.c"
196+
#include "../src/objects/bintree.c"
197+
#include "../src/objects/codeobject.c"
198+
#include "../src/objects/codeobject_ser.c"
199+
#include "../src/objects/container.c"
200+
#include "../src/objects/namedict.c"
201+
#include "../src/objects/object.c"
202+
#include "../src/public/Bindings.c"
203+
#include "../src/public/CodeExecution.c"
204+
#include "../src/public/DictSlots.c"
205+
#include "../src/public/FrameOps.c"
206+
#include "../src/public/GlobalSetup.c"
207+
#include "../src/public/Inspection.c"
208+
#include "../src/public/ModuleSystem.c"
209+
#include "../src/public/PyDict.c"
210+
#include "../src/public/PyException.c"
211+
#include "../src/public/PyList.c"
212+
#include "../src/public/PySlice.c"
213+
#include "../src/public/PyTuple.c"
214+
#include "../src/public/PythonOps.c"
215+
#include "../src/public/StackOps.c"
216+
#include "../src/public/TypeSystem.c"
217+
#include "../src/public/ValueCast.c"
218+
#include "../src/public/ValueCreation.c"
219+
]==],
220+
},
121221
cflags = {
122222
"-ffp-contract=off",
123223
"-DPK_ENABLE_OS=1",

0 commit comments

Comments
 (0)