Builds python27.dll from source using MSVC via the local file registry at ext_libraries/modules/python/.
ext_libraries/modules/python/
metadata.json
2.7.18/
MODULE.bazel
source.json ← URL + overlay hashes
overlay/
MODULE.bazel
BUILD.bazel ← cc_binary + filegroup + cc_library
PC/config.c ← minimal built-in module table (replaces stock PC/config.c)
PC/pyconfig.h ← removes #pragma comment(lib,"python27.lib") auto-link
| Target | Output |
|---|---|
@python//:python27 | python27.dll (linkshared) |
@python//:python27_implib | python27.if.lib (interface_library filegroup) |
@python//:python_headers | Include/*.h + PC/pyconfig.h |
_socket is linked in, not built as _socket.pydUpstream CPython builds a set of extension modules as separate .pyd DLLs (PCbuild/_socket.vcproj, select, unicodedata, _ssl, _ctypes, …). This port has no .pyd extension-module targets at all — python27.dll contains only what PC/config.c lists in _PyImport_Inittab.
socketmodule.c is the one exception, compiled into python27.dll and listed in the overlay's PC/config.c as {"_socket", init_socket}. It is not optional: main/pyuno/source/module/uno.py does import socket at module scope (“since on Windows sal3.dll no longer calls WSAStartup”), so without _socket every import uno raises ImportError: No module named _socket. That kills import pythonloader, so pyuno_loader.cxx's CreateInstance() throws before activate() is ever reached and the whole Python UNO loader is dead — visible as an empty tree and greyed buttons in Tools ▸ Macros ▸ Organize Macros ▸ Python, with the exception swallowed by ProviderCache. ws2_32.lib was already in linkopts.
Expect warning C4005: 'INVALID_SOCKET' : macro redefinition — socketmodule.c defines it before including the SDK's winsock2.h. Harmless, same value.
Still missing: every other extension module. A Python macro that imports select, unicodedata, _ssl, _ctypes, pyexpat, bz2 … will fail the same way. Add them the same way (source into _MODULE_SRCS + entry in PC/config.c) as they are needed, or build real .pyd targets — //build/rules:copy_file.bzl exists for the .dll → .pyd rename, see main/pyuno/readme.md.
Python 2.7.18's tarball does not include PC/python27.def. Exports are produced via __declspec(dllexport) through the Py_BUILD_CORE → PyAPI_FUNC macro chain. No win_def_file is needed.
The Windows pre-generated PC/pyconfig.h is used directly. No autoconf step.
Py_BUILD_CORE — enables __declspec(dllexport) on all public APINTDDI_VERSION=0x06010000 — pre-empts pyconfig.h‘s XP-era #ifndef which conflicts with the toolchain’s /D_WIN32_WINNT=0x0601 (Vista)MS_WINDOWS, WITH_THREAD, NT_THREADS — omitted; PC/pyconfig.h already defines them (adding them again causes C4005 redefinition warnings)snprintf=_snprintf — omitted; Python/pyport.h handles this for MSVCInclude/ — public Python headers (Python.h etc.)PC/ — pyconfig.h (Windows pre-generated)Python/ — internal headers (importdl.h, used by PC/import_nt.c)Python/ (Unix-only or conflicts):
| File | Reason |
|---|---|
dynload_aix/atheos/beos/dl/hpux/os2/shlib/stub.c | OS-specific dynloaders |
dynload_next.c | macOS/NeXTStep — requires mach-o/dyld.h |
mactoolboxglue.c | macOS — requires Carbon/Carbon.h |
getcwd.c | POSIX fallback; Windows uses _getcwd from CRT |
dup2.c, strdup.c | POSIX shims not needed on Windows |
pyfpe.c | SIGFPE handling (Unix-only) |
sigcheck.c | Stub superseded by Modules/signalmodule.c |
intrcheck.c | Stub superseded by Modules/signalmodule.c |
frozenmain.c | Frozen-exe launcher — unresolved PyWinFreeze_* |
Parser/ (pgen build-tool files not part of the runtime DLL):
| File | Reason |
|---|---|
pgenmain.c | pgen main() — duplicates pythonrun/errors symbols |
tokenizer_pgen.c | pgen tokenizer — duplicates tokenizer.c symbols |
pgen.c | Parser generator — build tool only |
printgrammar.c | pgen utility — build tool only |
intrcheck.c | Stub superseded by Modules/signalmodule.c |
Note: Parser/intrcheck.c is distinct from Python/intrcheck.c — both exist in the source tree. Both must be excluded; only the Parser/ one was causing the linker conflict (it is picked up by glob(["Parser/*.c"])).
Python/getopt.c is Python's own command-line option parser providing _PyOS_GetOpt, _PyOS_optind, _PyOS_optarg etc. required by Modules/main.c. It is NOT a POSIX shim and must NOT be excluded.
The stock PC/config.c references modules not compiled into this minimal DLL (CJK codecs, zlib, mmap, audioop, imageop, lsprof, hotshot). An overlay PC/config.c is provided that lists only the modules actually compiled in.
After any change to an overlay file:
cat overlay/FILE | openssl dgst -sha256 -binary | base64source.json with "sha256-<base64>" for the changed filebazel mod deps --lockfile_mode=refreshbazel build @python//:python27If the analysis cache persists stale (observed with glob changes to external modules), run bazel shutdown before bazel mod deps --lockfile_mode=refresh.