Skip to content

Instantly share code, notes, and snippets.

@gvanem
Last active March 2, 2024 14:29
Show Gist options
  • Save gvanem/4de19f1e36edff9577173074787ea402 to your computer and use it in GitHub Desktop.
Save gvanem/4de19f1e36edff9577173074787ea402 to your computer and use it in GitHub Desktop.
Python 3.x Makefile for MSVC and clang-cl (x86/x64)
#
# GNU-Makefile for Python 3.x.
#
# Targeting Windows 32 + 64-bits using MSVC-201x or clang-cl.
#
# By G. Vanem <gvanem@yahoo.no> 2015 - 2022.
#
THIS_FILE = Makefile.Windows
DATE := $(shell date +%d-%B-%Y)
NOW := $(shell date '+%d-%B-%Y (%T)')
comma := ,
GREP1 := grep --max-count=1
MAKEFLAGS += --warn-undefined-variables
default: all
#
# Do a 'make -f Makefile.Windows CC=[cl | clang-cl] vclean' after changing any of these:
# (except 'USE_ASTYLE').
#
# Link with 'Wsock-trace' library and not 'ws2_32.lib'.
# Ref: https://github.com/gvanem/wsock-trace
#
USE_WSOCK_TRACE ?= 1
#
# Enable Debug-code in Python's core code; '-DPy_DEBUG'.
# Not for production code.
#
USE_PY_DEBUG ?= 0
#
# Enable "Dynamic Execution Profiling"
#
USE_DXP ?= 0
#
# Enable "Emscripten". Unfinished.
#
USE_EMSCRIPTEN ?= 0
#
# Compile for JIT (experimaental)
#
USE_JIT ?= 0
#
# Compile with 'mimalloc'?
#
USE_MIMALLOC ?= 1
#
# Compile with 'cl -MP' for MSVC. A lot faster.
#
USE_MP_COMPILE ?= 1
#
# Use 'astyle' in the 'CXX_preprocess' macro below.
#
USE_ASTYLE ?= 1
USE_MACRO_DEBUG ?= 1
#
# '$(VCToolkitInstallDir)' should already be set if you installed MSVC the correct way.
#
VC_ROOT = $(realpath $(VCToolkitInstallDir))
#
# Change these as needed:
#
CLANG_CL32_ROOT ?= f:/ProgramFiler/LLVM-17.0/win32
CLANG_CL64_ROOT ?= f:/ProgramFiler/LLVM-17.0/win64
CLANG_CL32_ROOT_WIN = $(subst /,\,$(CLANG_CL32_ROOT))
CLANG_CL64_ROOT_WIN = $(subst /,\,$(CLANG_CL64_ROOT))
#
# Find needed tools:
#
file_exist = $(word 1,$(wildcard $(1)))
path_find = $(call file_exist, $(addsuffix /$(1),$(subst ;, ,$(subst \,/,$(PATH)))))
echo_prog = $(subst /,\, $(call path_find,echo.exe))
tee_prog = $(subst /,\, $(call path_find,tee.exe))
#
# Used in the '%.c: %.i' and 'link_xx' rules below.
#
# Note: it MUST exist on PATH prior to generating a local 'py.exe' here.
#
PYTHON = $(call path_find,py.exe)
PYTHON3 = $(PYTHON) -3
#
# For generated .bat-files in 'run_tests_1' and 'run_tests_2'.
#
TMP = $(realpath $(TEMP))
#
# Microsoft's 'HTML Help Compiler' used in 'chm_doc_build'.
#
hhc_proc = $(call path_find, hhc.exe)
#
# These env-vars could confuse 'clang-cl'. Remove them.
#
export CL=
export C_INCLUDE_PATH=
export CPLUS_INCLUDE_PATH=
define Usage
Usage: "make -f $(THIS_FILE) <CPU=x86 | x64> CC=[cl | clang-cl] [all | clean | realclean | depend]"
Specify CC=cl - use MSVC
Specify CC=clang-cl - use clang-cl
endef
export Usage
ifeq ($(CPU),x86)
BITS = 32
else ifeq ($(CPU),x64)
BITS = 64
else
$(error Unsupported $$(CPU)-value: '$(CPU)'.)
endif
#
# The 64-bit libraries are in 'libs/x64'.
#
ifeq ($(BITS),64)
LIBS_DIR = libs/x64
WIN_AMD = amd64
else
LIBS_DIR = libs
WIN_AMD = win32
endif
OBJ_DIR = obj/$(CPU)
ifeq ($(CC),cl)
BUILDER = MSVC
else ifeq ($(CC),clang-cl)
BUILDER = clang-cl
else
$(error $(Usage))
endif
#
# Root directories for external packages.
# You may need to run 'cmd /c PCbuild\get_externals.bat' to get some of these:
#
# The below basenames should be the same as in 'PCbuild\get_externals.bat'.
#
BZIP2_ROOT = externals/bzip2-1.0.8
LZMA_ROOT = externals/xz-5.2.5
LIBFFI_ROOT = externals/libffi-3.4.4
OPENSSL_ROOT = externals/openssl-bin-3.0.13/$(WIN_AMD)
SQLITE3_ROOT = externals/sqlite-3.45.1.0
ZLIB_ROOT = externals/zlib-1.3.1
TCLTK_ROOT = externals/tcltk-8.6.13.1/$(WIN_AMD)
TCL_CORE_ROOT = externals/tcl-core-8.6.13.1
#
# A created directory to copy
# $(TCLTK_ROOT)/lib/tcl8.6/init.tcl -> Lib/tcl8.6
#
TCL_ROOT = Lib/tcl8.6
#
# Refer 'Include/patchlevel.h' for this mess:
#
PY_VER_MAJOR := $(shell $(GREP1) '#define PY_MAJOR_VERSION' Include/patchlevel.h | $(GREP1) -o '[0-9]*' | cut -d' ' -f1)
PY_VER_MINOR := $(shell $(GREP1) '#define PY_MINOR_VERSION' Include/patchlevel.h | $(GREP1) -o '[0-9]*' | cut -d' ' -f1)
PY_RELEASE_SERIAL := $(shell $(GREP1) '#define PY_RELEASE_SERIAL' Include/patchlevel.h | $(GREP1) -o '[0-9]*' | cut -d' ' -f1)
PY_VER_STR := $(shell $(GREP1) '#define PY_VERSION' Include/patchlevel.h | cut -d'"' -f2)
PY_VER := $(PY_VER_MAJOR).$(PY_VER_MINOR)
_PY_VER := $(PY_VER_MAJOR)$(PY_VER_MINOR)
ver_test py_ver_test:
$(call green_msg0,PY_VER_MAJOR: '$(PY_VER_MAJOR)'.)
$(call green_msg0,PY_VER_MINOR: '$(PY_VER_MINOR)'.)
$(call green_msg0,PY_VER: '$(PY_VER)'.)
$(call green_msg0,PY_VER_STR: '$(PY_VER_STR)'.)
$(call green_msg0,PY_RELEASE_SERIAL: '$(PY_RELEASE_SERIAL)'.)
#
# 'DLLs/sqlite.dll' has it's own rather complicated .rc-file.
#
SQLITE3_VERSION = $(shell $(GREP1) '#define SQLITE_VERSION' $(SQLITE3_ROOT)/sqlite3.h | \
$(GREP1) -o '[0-9]*' | cut -d' ' -f1)
SQLITE3_MAJOR_VERSION = $(word 1, $(SQLITE3_VERSION))
SQLITE3_MINOR_VERSION = $(word 2, $(SQLITE3_VERSION))
SQLITE3_MICRO_VERSION = $(word 3, $(SQLITE3_VERSION))
sq_ver_test:
@echo 'SQLITE3_VERSION: "$(SQLITE3_VERSION)".'
@echo 'SQLITE3_MAJOR_VERSION: "$(SQLITE3_MAJOR_VERSION)".'
@echo 'SQLITE3_MINOR_VERSION: "$(SQLITE3_MINOR_VERSION)".'
@echo 'SQLITE3_MICRO_VERSION: "$(SQLITE3_MICRO_VERSION)".'
VPATH = PC \
Modules \
$(addprefix Modules/, \
cjkcodecs \
expat \
_blake2 \
_blake2/impl \
_ctypes \
_decimal \
_hacl \
_io \
_multiprocessing \
_sre \
_sqlite) \
Objects \
Parser \
Parser/lexer \
Parser/tokenizer \
Programs \
Python
VPATH += $(addprefix $(LZMA_ROOT)/src/, \
common \
liblzma \
liblzma/check \
liblzma/common \
liblzma/delta \
liblzma/lzma \
liblzma/lz \
liblzma/rangecoder \
liblzma/simple) \
\
$(OBJ_DIR) \
$(OPENSSL_ROOT)/include # for applink.c
OBJ_DIRS = $(addprefix $(OBJ_DIR)/, \
bzip2 \
core \
ctypes \
decimal \
elementtree \
lzma \
pyexpat \
sqlite3 \
_sqlite3 \
_testcapi \
_testinternalcapi \
zlib)
LDFLAGS = -nologo -verbose -incremental:no -map -debug -machine:$(CPU) -nodefaultlib:uuid.lib
CFLAGS = -nologo -Zi -arch:AVX2 -MD -O2 -GS -GF- -Ob2 -Oy -DHAVE_AVX2 -DHAVE_SSE2
RCFLAGS = -nologo
#
# All 'DLLs/*.pyd', '$(PYTHON_DLL)', 'pythonw.exe', 'pyw.exe'
# and 'venvwlauncher.exe' are linked with this GUI link-flag.
#
GUI_LDFLAGS = -subsystem:windows
ifeq ($(CC),clang-cl)
CFLAGS += -fms-compatibility \
-ferror-limit=5
#
# '-Wall' generated a lot of warnings.
#
CFLAGS += -Wall
else
CFLAGS += -W3
endif
ifeq ($(USE_WSOCK_TRACE),1)
WS2_32_LIB = wsock_trace-$(CPU).lib
else
WS2_32_LIB = ws2_32.lib
endif
c_to_i = $(addprefix $(2), $(notdir $(1:.c=.i)))
c_to_obj = $(addprefix $(OBJ_DIR)/$(strip $(2)), $(notdir $(1:.c=.obj)))
asm_to_obj = $(addprefix $(OBJ_DIR)/$(strip $(2)), $(notdir $(1:.asm=.obj)))
CFLAGS += -FI./Include/pyconfig.h \
-I. \
-I./Python \
-I./Include \
-I./Include/internal \
-I./Modules/_blake2/impl \
-I./Modules/_hacl/include \
-I./PC \
-I./$(OBJ_DIR)
#
# Keep these here.
#
CFLAGS += -I./$(ZLIB_ROOT) \
-I./$(OPENSSL_ROOT)/include
ifeq ($(USE_PY_DEBUG),1)
CFLAGS += -DPy_DEBUG
else
CFLAGS += -DNDEBUG
endif
ifeq ($(USE_DXP),1)
CFLAGS += -DDYNAMIC_EXECUTION_PROFILE
endif
GENERATED = Include/pyconfig.h \
$(OBJ_DIR)/pyconfig.h \
$(OBJ_DIR)/pythonnt_rc.h \
$(CC).args
# GENERATED += Modules/_sre/sre_constants.h \
# Modules/_sre/sre_targets.h
ifeq ($(CC),clang-cl)
GENERATED += clang-cl-$(BITS).bat
endif
#
# .py-files used to generate the "frozen" module.
# I.e. the fixed byte-code is put into '$(FROZEN_GENERATED)' header files.
#
# Ref: https://wiki.python.org/moin/Freeze
#
FROZEN_FILES_PY = $(addprefix Lib/, \
importlib/_bootstrap.py \
importlib/_bootstrap_external.py \
zipimport.py \
abc.py \
codecs.py \
io.py \
_collections_abc.py \
_sitebuiltins.py \
genericpath.py \
ntpath.py \
posixpath.py \
os.py \
site.py \
stat.py \
__hello__.py \
__phello__/__init__.py \
__phello__/ham/__init__.py \
__phello__/ham/eggs.py \
__phello__/spam.py)
#
# Map all above files:
# Lib/x/y.py
#
# file to:
# Python/frozen_modules/x.y.h
#
FROZEN_FILES_H = $(subst Lib.,,$(addprefix Python/frozen_modules/,$(notdir $(subst /,.,$(FROZEN_FILES_PY:.py=.h)))))
FROZEN_GENERATED = $(FROZEN_FILES_H)
#
# Since it does not fi in the above '$(subst ..)', add manually.
#
FROZEN_GENERATED += Python/frozen_modules/getpath.h
list_frozen:
$(call green_msg, FROZEN_GENERATED:)
@$(foreach f, $(FROZEN_GENERATED), echo -e ' $(BRIGHT_WHITE)$(f)\e[0m' ; )
@echo
$(call green_msg, FROZEN_FILES_H:)
@$(foreach f, $(FROZEN_FILES_H), echo -e ' $(BRIGHT_WHITE)$(f)\e[0m' ; )
@echo
gen_frozen: frozen_info $(FROZEN_GENERATED)
frozen_info:
$(call green_msg, Generating 'FROZEN_GENERATED' files.)
@echo
rm_frozen:
$(call green_msg, Deleting 'FROZEN_GENERATED' files.)
rm -f $(FROZEN_GENERATED) $(OBJ_DIR)/core/frozen.obj
@echo
#
# These are the Windows specific .c-sources for '$(PYTHON_DLL)':
#
PC_SRC = $(addprefix PC/, \
config.c \
dl_nt.c \
invalid_parameter_handler.c \
msvcrtmodule.c \
winreg.c \
winsound.c)
# PC_SRC += PC/empty.c
#
# These are the .c-sources for the built-in modules in '$(PYTHON_DLL)'.
#
MODULES_SRC = $(addprefix Modules/, \
_abc.c \
_bisectmodule.c \
_codecsmodule.c \
_collectionsmodule.c \
_contextvarsmodule.c \
_csv.c \
_datetimemodule.c \
_functoolsmodule.c \
_heapqmodule.c \
_io/_iomodule.c \
_io/bufferedio.c \
_io/bytesio.c \
_io/fileio.c \
_io/iobase.c \
_io/stringio.c \
_io/textio.c \
_io/winconsoleio.c \
_json.c \
_localemodule.c \
_lsprof.c \
_opcode.c \
_operator.c \
_pickle.c \
_randommodule.c \
_stat.c \
_statisticsmodule.c \
_struct.c \
_suggestions.c \
_sysconfig.c \
_threadmodule.c \
_tracemalloc.c \
_typingmodule.c \
_weakref.c \
_winapi.c \
_xxinterpchannelsmodule.c \
_xxinterpqueuesmodule.c \
_xxsubinterpretersmodule.c \
arraymodule.c \
atexitmodule.c \
binascii.c \
cmathmodule.c \
getbuildinfo.c \
gcmodule.c \
errnomodule.c \
faulthandler.c \
itertoolsmodule.c \
main.c \
mathmodule.c \
md5module.c \
mmapmodule.c \
posixmodule.c \
rotatingtree.c \
sha1module.c \
sha2module.c \
sha3module.c \
signalmodule.c \
symtablemodule.c \
timemodule.c \
xxsubtype.c \
zlibmodule.c \
_sre/sre.c)
MODULES_SRC += $(addprefix Modules/cjkcodecs/, \
_codecs_cn.c \
_codecs_hk.c \
_codecs_iso2022.c \
_codecs_jp.c \
_codecs_kr.c \
_codecs_tw.c \
multibytecodec.c)
MODULES_SRC += $(addprefix Modules/_blake2/, \
blake2module.c \
blake2b_impl.c \
blake2s_impl.c)
MODULES_SRC += $(addprefix Modules/_blake2/impl/, \
blake2b-ref.c \
blake2s-ref.c)
MODULES_SRC += $(addprefix Modules/_hacl/, \
Hacl_Hash_MD5.c \
Hacl_Hash_SHA1.c \
Hacl_Hash_SHA2.c \
Hacl_Hash_SHA3.c)
OBJECTS_SRC = $(addprefix Objects/, \
abstract.c \
boolobject.c \
bytearrayobject.c \
bytes_methods.c \
bytesobject.c \
call.c \
capsule.c \
cellobject.c \
classobject.c \
codeobject.c \
complexobject.c \
descrobject.c \
dictobject.c \
enumobject.c \
exceptions.c \
fileobject.c \
floatobject.c \
frameobject.c \
funcobject.c \
genericaliasobject.c \
genobject.c \
interpreteridobject.c \
iterobject.c \
listobject.c \
longobject.c \
memoryobject.c \
methodobject.c \
moduleobject.c \
namespaceobject.c \
object.c \
obmalloc.c \
odictobject.c \
picklebufobject.c \
rangeobject.c \
setobject.c \
sliceobject.c \
structseq.c \
tupleobject.c \
typeobject.c \
typevarobject.c \
unicodectype.c \
unicodeobject.c \
unionobject.c \
weakrefobject.c)
ifeq ($(USE_MIMALLOC),1)
CFLAGS += -DUSE_MIMALLOC=1 \
-DWITH_MIMALLOC=1 \
-I./Include/internal/mimalloc
endif
ifeq ($(USE_JIT),1)
CFLAGS += -D_Py_JIT=1
GENERATED += $(OBJ_DIR)/jit_stencils.h
endif
PARSER_SRC = $(addprefix Parser/, \
action_helpers.c \
myreadline.c \
parser.c \
peg_api.c \
pegen.c \
pegen_errors.c \
string_parser.c \
token.c)
PARSER_SRC += $(addprefix Parser/lexer/, \
buffer.c \
lexer.c \
state.c)
PARSER_SRC += $(addprefix Parser/tokenizer/, \
file_tokenizer.c \
helpers.c \
readline_tokenizer.c \
string_tokenizer.c \
utf8_tokenizer.c)
PYTHON_SRC = $(addprefix Python/, \
_warnings.c \
asdl.c \
assemble.c \
ast.c \
ast_opt.c \
ast_unparse.c \
bltinmodule.c \
bootstrap_hash.c \
brc.c \
ceval.c \
ceval_gil.c \
codecs.c \
compile.c \
context.c \
critical_section.c \
crossinterp.c \
dtoa.c \
dynamic_annotations.c \
dynload_win.c \
frame.c \
errors.c \
fileutils.c \
flowgraph.c \
formatter_unicode.c \
future.c \
gc.c \
gc_free_threading.c \
gc_gil.c \
getargs.c \
getcompiler.c \
getcopyright.c \
getopt.c \
getplatform.c \
getversion.c \
hamt.c \
hashtable.c \
import.c \
importdl.c \
initconfig.c \
instrumentation.c \
intrinsics.c \
jit.c \
legacy_tracing.c \
lock.c \
marshal.c \
modsupport.c \
mysnprintf.c \
mystrtoul.c \
object_stack.c \
optimizer.c \
optimizer_analysis.c \
optimizer_symbols.c \
parking_lot.c \
pathconfig.c \
perf_trampoline.c \
preconfig.c \
pyarena.c \
pyctype.c \
pyfpe.c \
pyhash.c \
pylifecycle.c \
pymath.c \
pystate.c \
pystrcmp.c \
pystrhex.c \
pystrtod.c \
pytime.c \
Python-ast.c \
Python-tokenize.c \
pythonrun.c \
qsbr.c \
specialize.c \
structmember.c \
suggestions.c \
symtable.c \
sysmodule.c \
thread.c \
traceback.c \
tracemalloc.c)
#
# Unfinished.
#
ifeq ($(USE_EMSCRIPTEN),1)
PYTHON_SRC += Python/emscripten_signal.c \
Python/emscripten_trampoline.c
endif
PY_IMP_LIB = $(LIBS_DIR)/python$(_PY_VER).lib
PY3_IMP_LIB = $(LIBS_DIR)/python3.lib
PY_SHELLEXT_LIB = $(LIBS_DIR)/pyshellext.lib
SQLITE3_LIB = $(LIBS_DIR)/sqlite3.lib
ZLIB_LIB = $(LIBS_DIR)/zlib.lib
#
# This library is pulled in via a '#pragma comment'.
# Do not add it by default.
#
LDFLAGS += -nodefaultlib:$(notdir $(PY_IMP_LIB))
#
# Put this libpath before '$(VC_ROOT)/lib/$(CPU)'
# to avoid shadowing for the needed 'clang_rt.builtins-x86_64.lib'
#
ifeq ($(CC)_$(BITS),clang-cl_64)
# LDFLAGS += -libpath:$(CLANG_CL64_ROOT)/lib/clang/$(CLANG_VER)/lib/windows
endif
#
# No need to use a '$(VC_ROOT)/bin/HostX86/$(CPU)/link.exe' since the
# 'link.exe' on PATH is able to link both 32-bit and 64-bit programs.
#
# But we need to use the correct directory for CRT libraries (msvcrt.lib etc).
#
LDFLAGS += -libpath:$(VC_ROOT)/lib/$(CPU)
#
# 'WindowsKits' root is in '$(WK_ROOT)' and
# 'WindowsKits' version is in '$(WK_VER)'.
#
# E.g.:
# set WK_ROOT=f:\ProgramFiler-x86\WindowsKits
# set WK_VER=10.0.10586.0
#
# Hence the User-Mode libraries for 'x86' is in:
# $(WK_ROOT)/Lib/$(WK_VER)/um/x86/
#
LDFLAGS += -libpath:$(realpath $(WK_ROOT)/Lib/$(WK_VER)/um/$(CPU))
#
# Ditto mess for the UCRT libraries: for 'x86' the UCRT libs are in:
# $(WK_ROOT)/Lib/$(WK_VER)/ucrt/x86/
#
LDFLAGS += -libpath:$(realpath $(WK_ROOT)/Lib/$(WK_VER)/ucrt/$(CPU))
#
# The path to our libraries:
#
LDFLAGS += -libpath:$(LIBS_DIR)
#
# The different chunks for '$(PYTHON_DLL)':
#
PC_OBJ = $(call c_to_obj, $(PC_SRC), core/)
OBJECTS_OBJ = $(call c_to_obj, $(OBJECTS_SRC), core/)
PARSER_OBJ = $(call c_to_obj, $(PARSER_SRC), core/)
PYTHON_OBJ = $(call c_to_obj, $(PYTHON_SRC), core/)
MODULES_OBJ = $(call c_to_obj, $(MODULES_SRC), core/)
PYTHON_DLL_OBJ = $(PC_OBJ) \
$(OBJECTS_OBJ) \
$(PARSER_OBJ) \
$(PYTHON_OBJ) \
$(MODULES_OBJ) \
# $(OBJ_DIR)/core/_xxsubinterpretersmodule.obj
PYTHON_DLL_I = $(notdir $(PYTHON_DLL_OBJ:.obj=.i))
#
# Handle this mess specially:
#
MODULES_SRC2 = $(filter-out Modules/_pickle.c, $(MODULES_SRC))
MODULES_OBJ2 = $(filter-out $(OBJ_DIR)/core/_pickle.obj, $(MODULES_OBJ))
#
# Targets
#
PYTHON_DLL = python$(_PY_VER).dll
#
# The programs that generates "frozen" modules
#
ifeq ($(CPU),x86)
FROZEN_MODULE = PCBuild/win32/_freeze_module.exe
BOOTSTRAP_PYTHON = PCBuild/win32/_bootstrap_python.exe
else
FROZEN_MODULE = PCBuild/amd64/_freeze_module.exe
BOOTSTRAP_PYTHON = PCBuild/amd64/_bootstrap_python.exe
endif
PROGRAMS = python.exe \
pythonw.exe \
py.exe \
pyw.exe \
venvlauncher.exe \
venvwlauncher.exe \
_testembed.exe \
$(FROZEN_MODULE)
PYD_FILES = $(addprefix DLLs/, \
pyexpat.pyd \
select.pyd \
unicodedata.pyd \
winsound.pyd \
xxlimited.pyd \
_asyncio.pyd \
_bz2.pyd \
_contextvars.pyd \
_ctypes.pyd \
_ctypes_test.pyd \
_decimal.pyd \
_elementtree.pyd \
_hashlib.pyd \
_lzma.pyd \
_multiprocessing.pyd \
_overlapped.pyd \
_queue.pyd \
_random.pyd \
_socket.pyd \
_ssl.pyd \
_sqlite3.pyd \
_tkinter.pyd \
_testbuffer.pyd \
_testcapi.pyd \
_testconsole.pyd \
_testclinic.pyd \
_testclinic_limited.pyd \
_testinternalcapi.pyd \
_testimportmultiple.pyd \
_testmultiphase.pyd \
_testsinglephase.pyd \
_uuid.pyd \
_wmi.pyd \
_zoneinfo.pyd)
PYD_FILES := $(sort $(PYD_FILES))
DLL_FILES = $(PYTHON_DLL) \
python3.dll \
DLLs/sqlite3.dll
#
# 'clang-cl' fail to compile 'PC/pyshellext.cpp'.
#
ifneq ($(CC),clang-cl)
DLL_FILES += pyshellext.dll
endif
TARGETS = $(DLL_FILES) \
$(PYD_FILES) \
$(PROGRAMS) \
python.bat \
pythonw.bat
all: check_py make_dirs $(GENERATED) $(FROZEN_GENERATED) $(TARGETS) copy_into_DLLs epilogue
help:
@echo "$$Usage"
$(call green_msg0,\n Extra targets: $(BRIGHT_GREEN)chm_doc$(comma) pdf_doc$(comma) pythoninfo_test$(comma) all_tests$(comma) regression_test)
epilogue:
$(call green_msg, Welcome to Python ver. $(PY_VER_STR) (bits:$(BITS)).)
make_dirs:
$(call create_dirs, $(OBJ_DIRS) $(LIBS_DIR) $(TCL_ROOT) PCBuild/win32 PCBuild/amd64 DLLs tmp)
$(OBJ_DIR) PCBuild/win32 PCBuild/amd64 tmp:
@mkdir --parents $@
everything: all chm_doc pdf_doc
#
# Create a 'Python*.reg' file for the Registry keys under 'HKLM\SOFTWARE\Python\PythonCore\$(PY_VER)-$(BITS)'.
# Do it under the 32-bit registry; '-reg:32'.
# These keys are read by 'py.exe'.
#
# Use e.g.:
# reg delete HKLM\SOFTWARE\Python\PythonCore\3.9-32 to remove it.
# reg delete HKLM\SOFTWARE\Python\PythonCore\3.9-64 to remove it.
#
top_key = HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\$(PY_VER)-$(BITS)
reg_file: Python.reg
Python.reg: $(THIS_FILE)
$(call green_msg, Generating $@)
$(file > $@,$(Python_REG))
#
# Note: The 'sphinx-build' called in 'make.bat' could be using Python 2.x.
# Fix your PATH or do a 'pip install python_doc_theme' for Python 2.x.
#
# Also, the 'sphinx-build' in 'make.bat' could be different from the one
# used in the 'pdf_doc_step_1' rule.
#
chm_doc: chm_doc_build chm_hhc_run
cp --update Doc/build/htmlhelp/python*.chm Python$(_PY_VER).chm
chm_doc_build:
cd Doc ; \
cmd.exe /C make.bat htmlhelp
#
# Should be only one generated .hhp file here:
#
HHP_FILE = $(wildcard Doc/build/htmlhelp/*.hhp)
chm_hhc_run:
$(call green_msg, Running 'hhc' on '$(HHP_FILE)')
- ( cd Doc/build/htmlhelp ; \
$(hhc_proc) $(notdir $(HHP_FILE)) )
pdf_doc: pdf_doc_step_1 pdf_doc_step_2
cp Doc/build/latex/library.pdf Python$(_PY_VER).pdf
#
# This needs the 'l3backend'. Use 'MikTeX-console.exe' to get it.
#
pdf_doc_step_1:
$(call green_msg, Step [1/3]; creating $(BRIGHT_WHITE)Doc/build/latex/library.tex)
cd Doc ; \
cmd.exe /C make.bat latex
pdf_doc_step_2:
$(call green_msg, Step [3/3]; running $(BRIGHT_WHITE)xelatex$(BRIGHT_GREEN) 4 times with merging of index $(BRIGHT_WHITE)Doc/build/latex/library.pdf)
- (cd Doc/build/latex ; \
xelatex -quiet library.tex ; \
xelatex -quiet library.tex ; \
makeindex -s python.ist library.idx ; \
xelatex -quiet library.tex ; \
xelatex -quiet library.tex)
clean_doc:
rm -f Doc/build/htmlhelp/python*.chm Python3*.{chm,pdf}
rm -fr Doc/build
############ Test targets ###################################################################
TESTS0 = $(addsuffix .py, \
$(addprefix Lib/test/, \
test_netrc \
test_nntplib \
test_ntpath \
test_numeric_tower \
test_operator \
test_optparse \
test_ordered_dict \
test_os \
test_ossaudiodev \
test_osx_env \
test_parser \
test_pathlib \
test_pdb \
test_peepholer \
test_pickle \
test_pickletools \
test_pipes \
test_pkg \
test_pkgimport \
test_pkgutil \
test_platform \
test_plistlib \
test_poll \
test_popen \
test_poplib \
test_posix \
test_posixpath \
test_pow \
test_pprint \
test_print \
test_profile \
test_property \
test_pstats \
test_pty \
test_pulldom \
test_pwd \
test_py_compile \
test_pyclbr \
test_pydoc \
test_pyexpat \
test_queue \
test_quopri \
test_raise \
test_random \
test_range \
test_re \
test_readline \
test_reprlib \
test_resource \
test_richcmp \
test_rlcompleter \
test_robotparser \
test_runpy \
test_sax \
test_sched \
test_scope \
test_script_helper \
test_secrets \
test_select \
test_selectors \
test_set \
test_setcomps \
test_shelve \
test_shlex \
test_shutil \
test_signal \
test_site \
test_slice \
test_smtpd \
test_smtplib \
test_smtpnet \
test_sndhdr \
test_socket \
test_socketserver \
test_sort \
test_source_encoding \
test_sqlite \
test_ssl \
test_startfile \
test_stat \
test_statistics \
test_strftime \
test_string \
test_string_literals \
test_stringprep \
test_strptime \
test_strtod \
test_struct \
test_structmembers \
test_structseq \
test_subclassinit \
test_subprocess \
test_sunau \
test_sundry \
test_super \
test_symbol \
test_symtable \
test_syntax \
test_sys \
test_sys_setprofile \
test_sys_settrace \
test_sysconfig \
test_tarfile \
test_tcl \
test_telnetlib \
test_tempfile \
test_textwrap \
test_thread \
test_threaded_import \
test_threadedtempfile \
test_threading \
test_threading_local \
test_threadsignals \
test_time \
test_timeit \
test_timeout \
test_tk \
test_tokenize \
test_tools \
test_trace \
test_traceback \
test_tracemalloc \
test_ttk_guionly \
test_ttk_textonly \
test_tuple \
test_turtle \
test_typechecks \
test_typing \
test_ucn \
test_unary \
test_unicode \
test_unicode_file \
test_unicode_file_functions \
test_unicode_identifiers \
test_unicodedata \
test_univnewlines \
test_unpack \
test_unpack_ex \
test_urllib \
test_urllib2 \
test_urllib2_localnet \
test_urllib2net \
test_urllib_response \
test_urllibnet \
test_urlparse \
test_userdict \
test_userlist \
test_userstring \
test_utf8source \
test_uu \
test_uuid \
test_venv \
test_warnings/__main__ \
test_wave \
test_weakref \
test_weakset \
test_webbrowser \
test_winconsoleio \
test_winreg \
test_winsound \
test_with \
test_wsgiref \
test_xdrlib \
test_xml_dom_minicompat \
test_xml_etree \
test_xml_etree_c \
test_xmlrpc \
test_xmlrpc_net \
test_yield_from \
test_zipapp \
test_zipfile \
test_zipfile64 \
test_zipimport \
test_zipimport_support \
test_zlib))
TESTS1 = $(wildcard Lib/test/test_*.py) \
Lib/test/test_warnings/__main__.py
TESTS1 := $(filter-out Lib/test/test_gdb.py, $(TESTS1))
TESTS1 := $(filter-out Lib/test/test_regrtest.py, $(TESTS1))
TESTS2 = $(addsuffix .py, \
$(addprefix Lib/test/, \
test_netrc \
test_nntplib \
test_ntpath \
test_numeric_tower))
#
# Test cases for '_testembed.exe' except 'test_audit_run_startup'
# that is interactive only (?)
#
TESTEMBED_CASES = test_audit \
test_audit_run_command \
test_audit_run_file \
test_audit_run_interactivehook \
test_audit_run_stdin \
test_audit_subinterpreter \
test_bpo20891 \
test_forced_io_encoding \
test_get_argc_argv \
test_init_compat_config \
test_init_compat_env \
test_init_dev_mode \
test_init_dont_configure_locale \
test_init_dont_parse_argv \
test_init_env_dev_mode \
test_init_env_dev_mode_alloc \
test_init_from_config \
test_init_global_config \
test_init_initialize_config \
test_init_isolated_config \
test_init_isolated_flag \
test_init_main \
test_init_parse_argv \
test_init_python_config \
test_init_python_env \
test_init_read_set \
test_init_run_main \
test_init_set_config \
test_init_setpath \
test_init_setpath_config \
test_init_setpythonhome \
test_init_sys_add \
test_init_warnoptions \
test_initialize_pymain \
test_initialize_twice \
test_open_code_hook \
test_pre_initialization_api \
test_pre_initialization_sys_options \
test_preinit_compat_config \
test_preinit_dont_parse_argv \
test_preinit_isolated1 \
test_preinit_isolated2 \
test_preinit_isolated_config \
test_preinit_parse_argv \
test_preinit_python_config \
test_repeated_init_and_subinterpreters \
test_run_main
.PHONY: check_py check_echo check_tee all_tests \
run_tests_1 run_tests_2 run_tests_3 run_tests_4 \
pythoninfo_test regression_test run_embedded_tests
check_echo:
ifeq ($(echo_prog),)
$(error Cygwin or MSys "echo.exe" not found on path. Edit $(THIS_FILE) manually.)
endif
echo_prog += -ne "$(strip $(1))\e[0m\n"
check_tee:
ifeq ($(tee_prog),)
$(error Cygwin or MSys "tee.exe" not found on path. Edit $(THIS_FILE) manually.)
endif
check_py:
ifeq ($(PYTHON),)
$(error 'py.exe' not found on PATH!)
else
$(call green_msg, 'py.exe' found at '$(PYTHON)')
endif
all_tests: all run_tests_1 run_tests_2 run_tests_3 run_tests_4 pythoninfo_test regression_test run_embedded_tests
$(TMP)/run_tests_1.bat: $(THIS_FILE)
$(call generate, $@, ::)
$(file >> $@,$(RUN_TESTS_BAT))
$(foreach t, $(TESTS1), $(call write_single_test, $@, $(t), run_tests_1.results))
$(file > run_tests_1.results)
$(TMP)/run_tests_2.bat: $(THIS_FILE)
$(call generate, $@, ::)
$(file >> $@,$(RUN_TESTS_BAT))
$(foreach t, $(TESTS2), $(call write_single_test, $@, $(t), run_tests_2.results))
$(file > run_tests_2.results)
run_tests_1: python.bat check_echo check_tee $(TMP)/run_tests_1.bat
cmd /C $(TEMP)\run_tests_1.bat
$(call green_msg, Look in run_tests_1.results for results.)
run_tests_2: python.bat check_echo check_tee $(TMP)/run_tests_2.bat
cmd /C $(TEMP)\run_tests_2.bat
$(call green_msg, Look in run_tests_2.results for results.)
run_tests_3: python.bat
$(file > run_tests_3.results)
python.bat -m test -j3 | run_tests_3.results
$(call green_msg, Look in run_tests_3.results for results.)
run_tests_4: python.bat
$(file > run_tests_4.results)
export PYTHON_EXTRA_PATH=$(realpath ./Lib/test) && \
python.bat -m libregrtest -v | run_tests_4.results
$(call green_msg, Look in run_tests_4.results for results.)
pythoninfo_test: all python.bat
python.bat -m test.pythoninfo
#
# From a 'python.bat -m test -h' output:
#
audio_test: python.bat
python.bat -m test audio
cpu_test: python.bat
python.bat -m test cpu
curses_test: python.bat
python.bat -m test curses
decimal_test: python.bat
python.bat -m test decimal
gui_test: python.bat
python.bat -m test gui
network_test: python.bat
python.bat -m test network
subprocess_test: python.bat
python.bat -m test subprocess
tzdata_test: python.bat
python.bat -m test tzdata
urlfetch_test: python.bat
python.bat -m test urlfetch
regression_test: python.bat
python.bat -m test all
# python.bat -u -Wd -E -bb -m test
run_embedded_tests: _testembed.exe check_echo $(TMP)/embedded_tests.bat
cmd /C $(TEMP)\embedded_tests.bat | tee embedded_tests.results
run_regress_tests: python.bat
cd Lib/test ; \
cmd.exe /C ../../python.bat test_regrtest.py
$(TMP)/embedded_tests.bat: $(THIS_FILE)
$(call generate, $@, ::)
$(file >> $@,$(EMBEDDED_TESTS_BAT))
$(foreach t, $(TESTEMBED_CASES), $(call write_single_embed_test, $@, $(t)) )
$(file >> $@, $(call echo_prog, $(BRIGHT_WHITE)Success! All $(words $(TESTEMBED_CASES)) tests passed.))
python.bat: $(THIS_FILE)
$(call generate, $@, ::)
$(file >> $@,$(PYTHON_BAT_COMMON))
$(file >> $@, %PYTHONHOME%\python.exe %*)
pythonw.bat: $(THIS_FILE)
$(call generate, $@, ::)
$(file >> $@,$(PYTHON_BAT_COMMON))
$(file >> $@, %PYTHONHOME%\pythonw.exe %*)
############ python*.zip rules ###################################################################
files_for_zip = $(wildcard Lib/*.py)
PYTHON_ZIP = $(PYTHON_DLL:.dll=.zip)
# dir /bs *.py > t
# grep --invert-match --only '$(realpath .)' t
define make_zip
import shutil
shutil.make_archive ("test", "zip", "Lib", ".")
endef
make_zip:
$(call green_msg, Creating '$(PYTHON_ZIP)' with $(words $(files_for_zip)) files.)
# zip -qr $(PYTHON_ZIP) $(files_for_zip)
#
# Compile all 'Lib/*.py' files into 'tmp/*.pyc' files.
# Except any 'test_*.py' and 'unittest_*.py' files.
#
compile_lib_to_pyc: tmp python.bat
export PYTHONPYCACHEPREFIX=./tmp ; \
cmd.exe /C python.bat Lib/compileall.py -x "test_*." -s $(realpath .)/Lib Lib
############ MSVC 'cl -MP' rules #################################################################
ifeq ($(CC)-$(USE_MP_COMPILE),cl-1)
$(MODULES_OBJ2): $(MODULES_SRC2) | $(CC).args $(OBJ_DIR)/core
$(call C_compile_MP, $(OBJ_DIR)/core\\, $(MODULES_SRC2))
$(OBJECTS_OBJ): $(OBJECTS_SRC) | $(CC).args $(OBJ_DIR)/core
$(call C_compile_MP, $(OBJ_DIR)/core\\, $(OBJECTS_SRC))
$(PARSER_OBJ): $(PARSER_SRC) | $(CC).args $(OBJ_DIR)/core
$(call C_compile_MP, $(OBJ_DIR)/core\\, $(PARSER_SRC))
$(PYTHON_OBJ): $(PYTHON_SRC) | $(CC).args $(OBJ_DIR)/core
$(call C_compile_MP, $(OBJ_DIR)/core\\, $(PYTHON_SRC))
endif
############ Dynamic target rules ################################################################
$(OBJ_DIR)/python.obj \
$(PYTHON_DLL_OBJ) \
$(PYTHON_DLL_I) \
python.i: EXTRA_CFLAGS += -DPy_BUILD_CORE -DPy_BUILD_CORE_BUILTIN
$(OBJ_DIR)/_asynciomodule.obj \
$(OBJ_DIR)/_queuemodule.obj \
$(OBJ_DIR)/_randommodule.obj \
_asynciomodule.i \
_queuemodule.i \
_randommodule.i: EXTRA_CFLAGS += -DPy_BUILD_CORE -DPy_BUILD_CORE_MODULE
$(OBJ_DIR)/_zoneinfo.obj \
$(OBJ_DIR)/unicodedata.obj \
_zoneinfo.i \
unicodedata.i: EXTRA_CFLAGS += -DPy_BUILD_CORE_MODULE
$(PY_IMP_LIB): $(PYTHON_DLL)
$(PYTHON_DLL): $(PYTHON_DLL_OBJ) \
$(OBJ_DIR)/getpath.obj \
$(OBJ_DIR)/core/_bootstrap_python.obj \
$(OBJ_DIR)/python$(_PY_VER).res \
$(ZLIB_LIB) | check-for-unused-libs.py
$(call link_DLL, $@, $(GUI_LDFLAGS) $^ kernel32.lib user32.lib winmm.lib \
bcrypt.lib advapi32.lib pathcch.lib version.lib \
$(WS2_32_LIB), $(PY_IMP_LIB))
python3.dll: $(OBJ_DIR)/python3dll.obj $(OBJ_DIR)/python3dll.res | check-for-unused-libs.py
$(call link_DLL, $@, $(GUI_LDFLAGS) $^, $(PY3_IMP_LIB))
#
# Special 'LDFLAGS' for these:
# python.exe pythonw.exe:
#
PY_LDFLAGS = -stack:2000000 -base:0x1D000000 -dynamicbase -nxcompat
ifeq ($(BITS),32)
PY_LDFLAGS += -safeseh
endif
########### Program rules ########################################################################
python.exe: $(OBJ_DIR)/python.obj $(OBJ_DIR)/python_exe.res $(PY_IMP_LIB) | check-for-unused-libs.py
$(call link_EXE, $@, $^ $(PY_LDFLAGS))
pythonw.exe: $(OBJ_DIR)/WinMain.obj $(OBJ_DIR)/pythonw_exe.res $(PY_IMP_LIB) | check-for-unused-libs.py
$(call link_EXE_GUI, $@, $^ $(PY_LDFLAGS))
py.exe: $(OBJ_DIR)/launcher.obj $(OBJ_DIR)/py.res | check-for-unused-libs.py
$(call link_EXE, $@, $^ advapi32.lib shell32.lib version.lib)
pyw.exe: $(OBJ_DIR)/launcher_w.obj $(OBJ_DIR)/pyw.res | check-for-unused-libs.py
$(call link_EXE_GUI, $@, $^ advapi32.lib shell32.lib user32.lib version.lib)
venvlauncher.exe: $(OBJ_DIR)/venvlauncher.obj $(OBJ_DIR)/venvlauncher.res | check-for-unused-libs.py
$(call link_EXE, $@, $^ pathcch.lib)
venvwlauncher.exe: $(OBJ_DIR)/venvwlauncher.obj $(OBJ_DIR)/venvwlauncher.res | check-for-unused-libs.py
$(call link_EXE_GUI, $@, $^ pathcch.lib user32.lib)
_testembed.exe: $(OBJ_DIR)/_testembed.obj $(PY_IMP_LIB) | check-for-unused-libs.py
$(call link_EXE, $@, $^)
##################################################################################################
$(OBJ_DIR)/core/_pickle.obj _pickle.i: EXTRA_CFLAGS = -DPy_BUILD_CORE_BUILTIN -DCOMPILING_PICKLE
#
# The Python launchers 'pyw.exe' and 'venvwlauncher.exe' should be Unicode and have GUI Message boxes:
#
$(OBJ_DIR)/launcher_w.obj launcher_w.i: EXTRA_CFLAGS = -DCOMPILING_LAUNCHER_W
$(OBJ_DIR)/launcher_w.obj: PC/launcher.c | $(CC).args $(OBJ_DIR)
$(call C_compile, $@, $<)
$(OBJ_DIR)/venvlauncher.obj venvlauncher.i: EXTRA_CFLAGS = -DVENV_REDIRECT
$(OBJ_DIR)/venvwlauncher.obj venvwlauncher.i: EXTRA_CFLAGS = -DVENV_REDIRECT -DCOMPILING_LAUNCHER_W
# $(OBJ_DIR)/venvlauncher.obj: PC/venvlauncher.c | $(CC).args $(OBJ_DIR)
# $(call C_compile, $@, $<)
$(OBJ_DIR)/venvwlauncher.obj: PC/venvlauncher.c | $(CC).args $(OBJ_DIR)
$(call C_compile, $@, $<)
##################################################################################################
regen-frozen: Tools/build/freeze_modules.py $(FROZEN_FILES_PY) $(FROZEN_MODULE)
$(call green_msg, Running '$<')
$(PYTHON3) $<
@echo
$(OBJ_DIR)/core/frozen.obj: regen-frozen $(FROZEN_GENERATED)
$(OBJ_DIR)/core/frozen.obj \
$(OBJ_DIR)/core/_freeze_module.obj \
$(OBJ_DIR)/getpath_noop.obj \
$(OBJ_DIR)/getpath.obj \
frozen.i \
_freeze_module.i \
getpath.i \
getpath_noop.i: EXTRA_CFLAGS += -DPy_BUILD_CORE -DPy_BUILD_CORE_BUILTIN
$(OBJ_DIR)/getpath.obj \
getpath.i: EXTRA_CFLAGS += -DCOMPILING_GETPATH_C
frozen_module: $(FROZEN_MODULE)
FROZEN_OBJ = $(OBJ_DIR)/_freeze_module.obj \
$(OBJ_DIR)/getpath_noop.obj \
$(PYTHON_DLL_OBJ)
$(FROZEN_OBJ): EXTRA_CFLAGS += -DPy_BUILD_CORE
$(FROZEN_MODULE): $(FROZEN_OBJ) $(ZLIB_LIB) | PCBuild/amd64 PCBuild/win32 check-for-unused-libs.py
$(call link_EXE, $@, $^ bcrypt.lib advapi32.lib pathcch.lib user32.lib version.lib winmm.lib $(WS2_32_LIB))
#
# An alternative "frozen" generation.
# Not used; only for testing.
#
_bootstrap_python: $(BOOTSTRAP_PYTHON)
_BOOTSTRAP_OBJ = $(OBJ_DIR)/core/_bootstrap_python.obj \
$(OBJ_DIR)/core/main.obj \
$(OBJ_DIR)/getpath.obj \
$(PYTHON_DLL_OBJ)
_bootstrap_python.i \
$(OBJ_DIR)/core/_bootstrap_python.obj \
$(OBJ_DIR)/core/main.obj: EXTRA_CFLAGS = -DPy_BUILD_CORE
$(BOOTSTRAP_PYTHON): $(_BOOTSTRAP_OBJ) $(ZLIB_LIB) | check-for-unused-libs.py
$(call link_EXE, $@, $^ bcrypt.lib advapi32.lib pathcch.lib user32.lib version.lib winmm.lib $(WS2_32_LIB))
_bootstrap_test: $(BOOTSTRAP_PYTHON)
$(call green_msg, Testing $< with 'Lib/abc.py')
export WSOCK_TRACE_LEVEL= && \
$< ./Programs/_freeze_module.py abc ./Lib/abc.py Python/frozen_modules/abc.h
define gen_frozen_h
$(call green_msg, Generating$(BRIGHT_WHITE)$(2) $(BRIGHT_GREEN)from$(BRIGHT_WHITE)$(1))
export WSOCK_TRACE_LEVEL= && \
$(FROZEN_MODULE) $(strip $(notdir $(2:.h=)) $(1) $(2))
@echo
endef
Python/frozen_modules/importlib._bootstrap.h: Lib/importlib/_bootstrap.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/importlib._bootstrap_external.h: Lib/importlib/_bootstrap_external.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/zipimport.h: Lib/zipimport.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/abc.h: Lib/abc.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/codecs.h: Lib/codecs.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/getpath.h: Modules/getpath.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/io.h: Lib/io.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/_collections_abc.h: Lib/_collections_abc.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/_sitebuiltins.h: Lib/_sitebuiltins.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/genericpath.h: Lib/genericpath.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/ntpath.h: Lib/ntpath.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/posixpath.h:Lib/posixpath.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/os.h: Lib/os.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/site.h: Lib/site.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/stat.h: Lib/stat.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/__hello__.h: Lib/__hello__.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/__phello__.__init__.h: Lib/__phello__/__init__.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/__phello__.ham.__init__.h: Lib/__phello__/ham/__init__.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/__phello__.ham.eggs.h: Lib/__phello__/ham/eggs.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
Python/frozen_modules/__phello__.spam.h: Lib/__phello__/spam.py $(FROZEN_MODULE)
$(call gen_frozen_h, $<, $@)
##################################################################################################
#
# First, the link rules for all the "easy" .PYD files:
#
DLLs/unicodedata.pyd: $(OBJ_DIR)/unicodedata.obj $(OBJ_DIR)/unicodedata.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^)
DLLs/_multiprocessing.pyd: $(OBJ_DIR)/multiprocessing.obj $(OBJ_DIR)/semaphore.obj $(OBJ_DIR)/_multiprocessing.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^ $(WS2_32_LIB))
DLLs/_overlapped.pyd: $(OBJ_DIR)/overlapped.obj $(OBJ_DIR)/_overlapped.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^ $(WS2_32_LIB))
DLLs/_queue.pyd: $(OBJ_DIR)/_queuemodule.obj $(OBJ_DIR)/_queue.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^)
DLLs/select.pyd: $(OBJ_DIR)/selectmodule.obj $(OBJ_DIR)/select.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^ kernel32.lib $(WS2_32_LIB))
DLLs/_socket.pyd: $(OBJ_DIR)/socketmodule.obj $(OBJ_DIR)/_socket.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^ $(WS2_32_LIB) iphlpapi.lib rpcrt4.lib)
DLLs/_uuid.pyd: $(OBJ_DIR)/_uuidmodule.obj $(OBJ_DIR)/_uuid.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^ $(PY_IMP_LIB) rpcrt4.lib)
DLLs/_zoneinfo.pyd: $(OBJ_DIR)/_zoneinfo.obj $(OBJ_DIR)/_zoneinfo.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^ $(PY_IMP_LIB))
DLLs/winsound.pyd: $(OBJ_DIR)/winsound.obj $(OBJ_DIR)/winsound.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^ user32.lib winmm.lib)
DLLs/xxlimited.pyd: $(OBJ_DIR)/xxlimited.obj $(OBJ_DIR)/xxlimited.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^)
##################################################################################################
OPENSSL_LIBS = $(OPENSSL_ROOT)/libcrypto.lib \
$(OPENSSL_ROOT)/libssl.lib
OPENSSL_DLLs = $(OPENSSL_ROOT)/libcrypto-3.dll \
$(OPENSSL_ROOT)/libssl-3.dll
OPENSSL_PDBs = $(OPENSSL_DLLs:.dll=.pdb)
$(OBJ_DIR)/_hashopenssl.obj: EXTRA_CFLAGS += -DCOMPILING_HASH_OPENSSL
DLLs/_hashlib.pyd: $(OBJ_DIR)/_hashopenssl.obj $(OBJ_DIR)/_hashlib.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^ $(OPENSSL_ROOT)/libcrypto.lib)
DLLs/_ssl.pyd: $(OBJ_DIR)/_ssl.obj $(OBJ_DIR)/applink.obj $(OBJ_DIR)/_ssl.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^ $(OPENSSL_ROOT)/libcrypto.lib $(OPENSSL_ROOT)/libssl.lib crypt32.lib $(WS2_32_LIB))
##################################################################################################
_testcapi_SRC = Modules/_testcapimodule.c
_testcapi_SRC += $(addprefix Modules/_testcapi/, \
abstract.c \
buffer.c \
bytearray.c \
bytes.c \
code.c \
codec.c \
complex.c \
datetime.c \
dict.c \
docstring.c \
exceptions.c \
file.c \
float.c \
gc.c \
getargs.c \
hash.c \
heaptype.c \
heaptype_relative.c \
immortal.c \
list.c \
long.c \
mem.c \
numbers.c \
pyatomic.c \
pyos.c \
set.c \
structmember.c \
sys.c \
time.c \
tuple.c \
unicode.c \
vectorcall.c \
vectorcall_limited.c \
watchers.c)
_testcapi_OBJ = $(call c_to_obj, $(_testcapi_SRC), _testcapi/)
$(OBJ_DIR)/_testcapi/_testcapimodule.obj: Modules/_testcapimodule.c | $(CC).args $(OBJ_DIR)/_testcapi
$(call C_compile, $@, $<)
$(OBJ_DIR)/_testcapi/%.obj: Modules/_testcapi/%.c | $(CC).args $(OBJ_DIR)/_testcapi
$(call C_compile, $@, $<)
DLLs/_testcapi.pyd: $(_testcapi_OBJ) $(OBJ_DIR)/_testcapi.res $(PY_IMP_LIB)
$(call link_PYD, $@, -export:PyInit__testcapi $^)
##################################################################################################
_testinternalcapi_SRC = Modules/_testinternalcapi.c
_testinternalcapi_SRC += $(addprefix Modules/_testinternalcapi/, \
pytime.c \
set.c \
test_critical_sections.c \
test_lock.c)
_testinternalcapi_OBJ = $(call c_to_obj, $(_testinternalcapi_SRC), _testinternalcapi/)
_testinternalcapi_I = $(call c_to_i, $(_testinternalcapi_SRC), _testinternalcapi_)
$(_testinternalcapi_OBJ) \
$(_testinternalcapi_I): EXTRA_CFLAGS = -DPy_BUILD_CORE_BUILTIN -DPy_BUILD_CORE_MODULE
#
# How on earth does '-DPy_DEBUG' become effective here?
#
ifeq ($(USE_PY_DEBUG),0)
$(_testinternalcapi_OBJ) \
$(_testinternalcapi_I): EXTRA_CFLAGS += -UPy_DEBUG
endif
$(OBJ_DIR)/_testinternalcapi/_testinternalcapi.obj: Modules/_testinternalcapi.c | $(CC).args $(OBJ_DIR)/_testinternalcapi
$(call C_compile, $@, $<)
$(OBJ_DIR)/_testinternalcapi/%.obj: Modules/_testinternalcapi/%.c | $(CC).args $(OBJ_DIR)/_testinternalcapi
$(call C_compile, $@, $<)
DLLs/_testinternalcapi.pyd: $(_testinternalcapi_OBJ) $(OBJ_DIR)/_testinternalcapi.res $(PY_IMP_LIB)
$(call link_PYD, $@, -export:PyInit__testinternalcapi $^)
##################################################################################################
_SQLITE3_SRC = $(addprefix Modules/_sqlite/, \
blob.c \
connection.c \
cursor.c \
microprotocols.c \
module.c \
prepare_protocol.c \
row.c \
statement.c \
util.c)
_SQLITE3_OBJ = $(call c_to_obj, $(_SQLITE3_SRC), _sqlite3/)
_SQLITE3_I = $(call c_to_i, $(_SQLITE3_SRC),)
$(_SQLITE3_OBJ) $(_SQLITE3_I): EXTRA_CFLAGS = -I$(SQLITE3_ROOT) -DMODULE_NAME=\"sqlite3\"
ifeq ($(CC)-$(USE_MP_COMPILE),cl-1)
$(_SQLITE3_OBJ): $(_SQLITE3_SRC) | $(CC).args $(OBJ_DIR)/_sqlite3
$(call C_compile_MP, $(OBJ_DIR)/_sqlite3\\, $(_SQLITE3_SRC))
else
$(OBJ_DIR)/_sqlite3/%.obj: Modules/_sqlite/%.c | $(CC).args $(OBJ_DIR)/_sqlite3
$(call C_compile, $@, $<)
endif
DLLs/_sqlite3.pyd: $(_SQLITE3_OBJ) $(OBJ_DIR)/_sqlite3.res $(SQLITE3_LIB) $(PY_IMP_LIB)
$(call link_PYD, $@, $^)
$(OBJ_DIR)/_sqlite3.res: PC/python_nt.rc
$(call create_res_file, $@, _sqlite3.pyd, $<,)
##################################################################################################
SQLITE3_SRC = $(SQLITE3_ROOT)/sqlite3.c
SQLITE3_OBJ = $(call c_to_obj, $(SQLITE3_SRC), sqlite3/)
SQLITE3_I = $(call c_to_i, $(SQLITE3_SRC),)
$(SQLITE3_OBJ) $(SQLITE3_I): EXTRA_CFLAGS = -DCOMPILING_SQLITE3
SQLITE3_RCFLAGS = -DSQLITE_MAJOR_VERSION=$(SQLITE3_MAJOR_VERSION) \
-DSQLITE_MINOR_VERSION=$(SQLITE3_MINOR_VERSION) \
-DSQLITE_MICRO_VERSION=$(SQLITE3_MICRO_VERSION) \
-DSQLITE_PATCH_VERSION=0 \
-DSQLITE_VERSION=$(SQLITE3_MAJOR_VERSION).$(SQLITE3_MINOR_VERSION).$(SQLITE3_MICRO_VERSION)
$(OBJ_DIR)/sqlite3/sqlite3.obj: $(SQLITE3_ROOT)/sqlite3.c | $(CC).args $(OBJ_DIR)/sqlite3
$(call C_compile, $@, $<)
$(SQLITE3_LIB): DLLs/sqlite3.dll
DLLs/sqlite3.dll: $(OBJ_DIR)/sqlite3/sqlite3.obj $(OBJ_DIR)/sqlite3.res | check-for-unused-libs.py
$(call link_DLL, $@, -subsystem:console $^, $(SQLITE3_LIB))
$(OBJ_DIR)/sqlite3.res: PC/sqlite3.rc
$(call create_res_file, $@, sqlite3.dll, $<, $(SQLITE3_RCFLAGS))
##################################################################################################
BZIP2_SRC = Modules/_bz2module.c \
$(addprefix $(BZIP2_ROOT)/, \
blocksort.c \
bzlib.c \
compress.c \
crctable.c \
decompress.c \
huffman.c \
randtable.c)
BZIP2_OBJ = $(call c_to_obj, $(BZIP2_SRC), bzip2/)
BZIP2_I = $(call c_to_i, $(BZIP2_SRC),)
$(BZIP2_OBJ) $(BZIP2_I): EXTRA_CFLAGS = -I$(BZIP2_ROOT)
$(OBJ_DIR)/bzip2/_bz2module.obj: Modules/_bz2module.c | $(CC).args $(OBJ_DIR)/bzip2
$(call C_compile, $@, $<)
$(OBJ_DIR)/bzip2/%.obj: $(BZIP2_ROOT)/%.c | $(CC).args $(OBJ_DIR)/bzip2
$(call C_compile, $@, $<)
DLLs/_bz2.pyd: $(BZIP2_OBJ) $(OBJ_DIR)/_bz2.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^)
##################################################################################################
ZLIB_SRC = $(addprefix $(ZLIB_ROOT)/, \
adler32.c \
compress.c \
crc32.c \
deflate.c \
gzclose.c \
gzlib.c \
gzread.c \
gzwrite.c \
infback.c \
inffast.c \
inflate.c \
inftrees.c \
trees.c \
uncompr.c \
zutil.c)
#
# Drop most of 'Include/pyconfig.h' for '$(ZLIB_SRC)':
#
ZLIB_CFLAGS = -DCOMPILING_ZLIB -DHAVE_STDARG_H -DZLIB_CONST
ZLIB_OBJ = $(call c_to_obj, $(ZLIB_SRC), zlib/)
ZLIB_I = $(call c_to_i, $(ZLIB_SRC),)
$(ZLIB_OBJ) $(ZLIB_I): EXTRA_CFLAGS = $(ZLIB_CFLAGS)
$(ZLIB_LIB): $(ZLIB_OBJ)
$(call create_lib, $@, $^)
ifeq ($(CC)-$(USE_MP_COMPILE),cl-1)
$(ZLIB_OBJ): $(ZLIB_SRC) | $(CC).args $(OBJ_DIR)/zlib
$(call C_compile_MP, $(OBJ_DIR)/zlib\\, $(ZLIB_SRC))
else
$(OBJ_DIR)/zlib/%.obj: $(ZLIB_ROOT)/%.c | $(CC).args $(OBJ_DIR)/zlib
$(call C_compile, $@, $<)
endif
##################################################################################################
ELEMENTTREE_SRC = $(addprefix Modules/expat/, \
xmlparse.c \
xmlrole.c \
xmltok.c \
xmltok_impl.c \
xmltok_ns.c)
ELEMENTTREE_OBJ = $(call c_to_obj, $(ELEMENTTREE_SRC), elementtree/)
ELEMENTTREE_I = $(call c_to_i, $(ELEMENTTREE_SRC),)
#
# Also used for 'PYEXPAT_SRC':
#
EXPAT_CFLAGS = -I./Modules/expat -DCOMPILING_EXPAT
$(ELEMENTTREE_OBJ) \
$(ELEMENTTREE_I): EXTRA_CFLAGS = $(EXPAT_CFLAGS)
$(OBJ_DIR)/elementtree/%.obj: %.c | $(CC).args $(OBJ_DIR)/elementtree
$(call C_compile, $@, $<)
DLLs/_elementtree.pyd: $(ELEMENTTREE_OBJ) $(OBJ_DIR)/_elementree.res
$(call link_PYD, $@, $^)
##################################################################################################
CTYPES_SRC = $(addprefix Modules/_ctypes/, \
_ctypes.c \
callbacks.c \
callproc.c \
cfield.c \
malloc_closure.c \
stgdict.c)
CTYPES_OBJ = $(call c_to_obj, $(CTYPES_SRC), ctypes/)
CTYPES_I = $(call c_to_i, $(CTYPES_SRC),)
CTYPES_CFLAGS = -DPy_BUILD_CORE_MODULE -DUSING_MALLOC_CLOSURE_DOT_C=1 -I$(LIBFFI_ROOT)/$(WIN_AMD)/include # -DFFI_BUILDING
CTYPES_LDFLAGS = -export:DllGetClassObject,PRIVATE \
-export:DllCanUnloadNow,PRIVATE
$(CTYPES_OBJ) $(CTYPES_I): EXTRA_CFLAGS += $(CTYPES_CFLAGS)
LIBFFI_LIB = $(LIBFFI_ROOT)/$(WIN_AMD)/libffi-8.lib
LIBFFI_DLL = $(LIBFFI_ROOT)/$(WIN_AMD)/libffi-8.dll
$(OBJ_DIR)/ctypes/%.obj: %.c | $(CC).args $(OBJ_DIR)/ctypes
$(call C_compile, $@, $<)
DLLs/_ctypes.pyd: $(CTYPES_OBJ) $(OBJ_DIR)/_ctypes.res $(PY_IMP_LIB) $(LIBFFI_LIB)
$(call link_PYD, $@, $(CTYPES_LDFLAGS) $^ ole32.lib oleaut32.lib uuid.lib)
DLLs/_ctypes_test.pyd: $(OBJ_DIR)/_ctypes_test.obj $(OBJ_DIR)/_ctypes_test.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^ oleaut32.lib uuid.lib)
##################################################################################################
DECIMAL_C_SRC = $(addprefix Modules/_decimal/, \
_decimal.c \
$(addprefix libmpdec/, \
basearith.c \
constants.c \
context.c \
convolute.c \
crt.c \
difradix2.c \
fnt.c \
fourstep.c \
io.c \
mpalloc.c \
mpdecimal.c \
numbertheory.c \
sixstep.c \
transpose.c))
DECIMAL_C_SRC += $(OBJ_DIR)/decimal/hacks.c
DECIMAL_CFLAGS = -DMASM \
-DCONFIG_$(BITS) \
-I./Modules/_decimal/libmpdec
ifeq ($(BITS),64)
DECIMAL_ASM_SRC = Modules/_decimal/libmpdec/vcdiv64.asm
ifeq ($(CC),clang-cl)
# clang_runtime = clang_rt.builtins-x86_64.lib
endif
else
DECIMAL_CFLAGS += -DPPRO
DECIMAL_ASM_SRC =
endif
clang_runtime ?=
DECIMAL_C_OBJ = $(call c_to_obj, $(DECIMAL_C_SRC), decimal/)
DECIMAL_ASM_OBJ = $(call asm_to_obj, $(DECIMAL_ASM_SRC), decimal/)
DECIMAL_I = $(call c_to_i, $(DECIMAL_C_SRC), decimal_)
$(DECIMAL_C_OBJ) $(DECIMAL_I): EXTRA_CFLAGS = $(DECIMAL_CFLAGS)
ifeq ($(CC)-$(USE_MP_COMPILE),cl-1)
$(DECIMAL_C_OBJ): $(DECIMAL_C_SRC) | $(CC).args $(OBJ_DIR)/decimal
$(call C_compile_MP, $(OBJ_DIR)/decimal\\, $(DECIMAL_C_SRC))
else
$(OBJ_DIR)/decimal/hacks.obj: $(OBJ_DIR)/decimal/hacks.c | $(CC).args $(OBJ_DIR)/decimal
$(call C_compile, $@, $<)
endif
$(OBJ_DIR)/decimal/%.obj: Modules/_decimal/%.c | $(CC).args $(OBJ_DIR)/decimal
$(call C_compile, $@, $<)
$(OBJ_DIR)/decimal/%.obj: Modules/_decimal/libmpdec/%.c | $(CC).args $(OBJ_DIR)/decimal
$(call C_compile, $@, $<)
$(OBJ_DIR)/decimal/vcdiv64.obj: Modules/_decimal/libmpdec/vcdiv64.asm $(OBJ_DIR)/decimal
$(call assemble_x64, $@, $<)
DLLs/_decimal.pyd: $(DECIMAL_C_OBJ) $(DECIMAL_ASM_OBJ) $(OBJ_DIR)/_decimal.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^ $(clang_runtime))
##################################################################################################
LZMA_SRC = Modules/_lzmamodule.c \
$(addprefix $(LZMA_ROOT)/src/, \
common/tuklib_cpucores.c \
common/tuklib_physmem.c \
liblzma/check/check.c \
liblzma/check/crc32_fast.c \
liblzma/check/crc32_table.c \
liblzma/check/crc64_fast.c \
liblzma/check/crc64_table.c \
liblzma/check/sha256.c \
liblzma/common/alone_decoder.c \
liblzma/common/alone_encoder.c \
liblzma/common/auto_decoder.c \
liblzma/common/block_buffer_decoder.c \
liblzma/common/block_buffer_encoder.c \
liblzma/common/block_decoder.c \
liblzma/common/block_encoder.c \
liblzma/common/block_header_decoder.c \
liblzma/common/block_header_encoder.c \
liblzma/common/block_util.c \
liblzma/common/common.c \
liblzma/common/easy_buffer_encoder.c \
liblzma/common/easy_decoder_memusage.c \
liblzma/common/easy_encoder.c \
liblzma/common/easy_encoder_memusage.c \
liblzma/common/easy_preset.c \
liblzma/common/filter_buffer_decoder.c \
liblzma/common/filter_buffer_encoder.c \
liblzma/common/filter_common.c \
liblzma/common/filter_decoder.c \
liblzma/common/filter_encoder.c \
liblzma/common/filter_flags_decoder.c \
liblzma/common/filter_flags_encoder.c \
liblzma/common/hardware_physmem.c \
liblzma/common/index.c \
liblzma/common/index_decoder.c \
liblzma/common/index_encoder.c \
liblzma/common/index_hash.c \
liblzma/common/outqueue.c \
liblzma/common/stream_flags_common.c \
liblzma/common/stream_buffer_decoder.c \
liblzma/common/stream_encoder.c \
liblzma/common/stream_buffer_encoder.c \
liblzma/common/stream_decoder.c \
liblzma/common/stream_flags_encoder.c \
liblzma/common/stream_flags_decoder.c \
liblzma/common/vli_decoder.c \
liblzma/common/vli_encoder.c \
liblzma/common/vli_size.c \
liblzma/delta/delta_common.c \
liblzma/delta/delta_decoder.c \
liblzma/delta/delta_encoder.c \
liblzma/lzma/fastpos_table.c \
liblzma/lzma/lzma2_decoder.c \
liblzma/lzma/lzma2_encoder.c \
liblzma/lzma/lzma_decoder.c \
liblzma/lzma/lzma_encoder.c \
liblzma/lzma/lzma_encoder_optimum_fast.c \
liblzma/lzma/lzma_encoder_optimum_normal.c \
liblzma/lzma/lzma_encoder_presets.c \
liblzma/lz/lz_decoder.c \
liblzma/lz/lz_encoder.c \
liblzma/lz/lz_encoder_mf.c \
liblzma/rangecoder/price_table.c \
liblzma/simple/arm.c \
liblzma/simple/armthumb.c \
liblzma/simple/ia64.c \
liblzma/simple/powerpc.c \
liblzma/simple/simple_coder.c \
liblzma/simple/simple_decoder.c \
liblzma/simple/simple_encoder.c \
liblzma/simple/sparc.c \
liblzma/simple/x86.c)
ifeq ($(CC),clang-cl)
LZMA_SRC += $(OBJ_DIR)/lzma/hacks.c
endif
LZMA_OBJ = $(call c_to_obj, $(LZMA_SRC), lzma/)
LZMA_I = $(call c_to_i, $(LZMA_SRC), lzma_)
LZMA_CFLAGS = -I$(LZMA_ROOT)/include \
-I$(LZMA_ROOT)/src/common \
-I$(LZMA_ROOT)/src/liblzma/common \
-I$(LZMA_ROOT)/src/liblzma/api \
-I$(LZMA_ROOT)/src/liblzma/check \
-I$(LZMA_ROOT)/src/liblzma/lzma \
-I$(LZMA_ROOT)/src/liblzma/lz \
-I$(LZMA_ROOT)/src/liblzma/delta \
-I$(LZMA_ROOT)/src/liblzma/simple \
-I$(LZMA_ROOT)/src/liblzma/rangecoder \
-I$(LZMA_ROOT)/windows \
-DHAVE_CONFIG_H \
-DLZMA_API_STATIC
$(LZMA_OBJ) $(LZMA_I): EXTRA_CFLAGS = $(LZMA_CFLAGS)
ifeq ($(CC)-$(USE_MP_COMPILE),cl-1)
$(LZMA_OBJ): $(LZMA_SRC) | $(CC).args $(OBJ_DIR)/lzma
$(call C_compile_MP, $(OBJ_DIR)/lzma\\, $(LZMA_SRC))
else
$(OBJ_DIR)/lzma/%.obj: %.c | $(CC).args $(OBJ_DIR)/lzma
$(call C_compile, $@, $<)
endif
DLLs/_lzma.pyd: $(LZMA_OBJ) $(OBJ_DIR)/_lzma.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^)
##################################################################################################
PYEXPAT_SRC = $(addprefix Modules/, \
pyexpat.c \
expat/xmlparse.c \
expat/xmlrole.c \
expat/xmltok.c)
PYEXPAT_OBJ = $(call c_to_obj, $(PYEXPAT_SRC), pyexpat/)
PYEXPAT_I = $(call c_to_i, $(PYEXPAT_SRC), pyexpat_)
$(PYEXPAT_OBJ) $(PYEXPAT_I): EXTRA_CFLAGS = $(EXPAT_CFLAGS)
$(OBJ_DIR)/pyexpat/%.obj: %.c | $(CC).args $(OBJ_DIR)/pyexpat
$(call C_compile, $@, $<)
DLLs/pyexpat.pyd: $(PYEXPAT_OBJ) $(OBJ_DIR)/pyexpat.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^)
##################################################################################################
TKINTER_SRC = Modules/_tkinter.c \
Modules/tkappinit.c
TKINTER_OBJ = $(call c_to_obj, $(TKINTER_SRC),)
TKINTER_I = $(call c_to_i, $(TKINTER_SRC),)
TCLTK_DLLs = $(TCLTK_ROOT)/bin/tk86t.dll \
$(TCLTK_ROOT)/bin/tcl86t.dll
TKINTER_LIBS = $(TCLTK_ROOT)/lib/tcl86t.lib \
$(TCLTK_ROOT)/lib/tk86t.lib
TKINTER_CFLAGS = -I$(TCLTK_ROOT)/include -DWITH_APPINIT
$(TKINTER_OBJ) $(TKINTER_I): EXTRA_CFLAGS = $(TKINTER_CFLAGS)
DLLs/_tkinter.pyd: $(TKINTER_OBJ) $(OBJ_DIR)/_tkinter.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^ $(TKINTER_LIBS))
#
# The below $(SECONDARY_OBJ) will get deleted after 'all' is done.
# To prevent that, define them as a '.SECONDARY' list of files.
#
SECONDARY_OBJ = $(addprefix $(OBJ_DIR)/, \
_asynciomodule.obj \
_asynciomodule.res \
_contextvarsmodule.obj \
_contextvarsmodule.res \
_ctypes_test.obj \
_ctypes_test.res \
_randommodule.obj \
_randommodule.res \
_testbuffer.obj \
_testbuffer.res \
_testimportmultiple.obj \
_testimportmultiple.res \
_testconsole.obj \
_testconsole.res \
_testclinic.obj \
_testclinic.res \
_testclinic_limited.obj \
_testclinic_limited.res \
_testinternalcapi.obj \
_testinternalcapi.res \
_testcapimodule.obj \
_testcapimodule.res \
_testmultiphase.obj \
_testmultiphase.res \
_testsinglephase.obj \
_testsinglephase.res \
_abcmodule.res)
# SECONDARY_OBJ += $(OBJ_DIR)/_xxsubinterpretersmodule.obj \
# $(OBJ_DIR)/_xxsubinterpretersmodule.res
.SECONDARY: $(SECONDARY_OBJ)
#
# These rules will match the "easy" PYDs.
# Like 'DLLs/_asyncio.pyd' and 'DLLs/_testclinic*.pyd' etc.
#
DLLs/_%.pyd: $(OBJ_DIR)/%module.obj $(OBJ_DIR)/%module.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^)
DLLs/_%.pyd: $(OBJ_DIR)/_%module.obj $(OBJ_DIR)/_%module.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^)
DLLs/_%.pyd: $(OBJ_DIR)/_%.obj $(OBJ_DIR)/_%.res $(PY_IMP_LIB)
$(call link_PYD, $@, $^)
#
# All objects go into '$(OBJ_DIR)' or sub-dirs under it.
#
$(OBJ_DIR)/core/%.obj: %.c | $(CC).args $(OBJ_DIR)/core
$(call C_compile, $@, $<)
#
# For .c-files in the 'VPATH':
#
$(OBJ_DIR)/%.obj: %.c | $(CC).args $(OBJ_DIR)
$(call C_compile, $@, $<)
#
# Compile .res files from the generated '$(OBJ_DIR)/pythonnt_rc.h' and
# respective .rc-file.
#
# The .EXE-files have their own .rc-files, but all .DLLs (except 'DLLs/sqlite3.dll') and .PYDs depends
# simply on 'PC/python_nt.rc'.
#
$(OBJ_DIR)/python_exe.res: PC/python_exe.rc
$(call create_res_file, $@, python.exe, $<,)
$(OBJ_DIR)/pythonw_exe.res: PC/pythonw_exe.rc
$(call create_res_file, $@, pythonw.exe, $<,)
res_deps = PC/pylauncher.rc \
PC/python_ver_rc.h \
PC/python.manifest \
$(wildcard PC/icons/*.ico)
$(OBJ_DIR)/py.res: $(res_deps)
$(call create_res_file, $@, py.exe, $<,)
$(OBJ_DIR)/pyw.res: $(res_deps)
$(call create_res_file, $@, pyw.exe, $<,)
$(OBJ_DIR)/python$(_PY_VER).res: PC/python_nt.rc
$(call create_res_file, $@, $(PYTHON_DLL), $<,)
$(OBJ_DIR)/python3dll.res: PC/python_nt.rc
$(call create_res_file, $@, python3.dll, $<,)
$(OBJ_DIR)/venvlauncher.res: $(res_deps)
$(call create_res_file, $@, venvlauncher.exe, $<, -DPY_ICON)
$(OBJ_DIR)/venvwlauncher.res: $(res_deps)
$(call create_res_file, $@, venvwlauncher.exe, $<, -DPYW_ICON)
#
# A "match all" rule for .res-files in PYD-files.
# E.g. a '$(OBJ_DIR)/_socket.res' uses this rule.
#
# TODO: add a 'create_rc_file' macro for more sensible " FileDescription".
# Not simply "FileDescription: Python Core" for most .PYDs
#
$(OBJ_DIR)/%.res: PC/python_nt.rc
$(call create_res_file, $@, $*.pyd, $<,)
$(OBJ_DIR)/pythonnt_rc.h: $(THIS_FILE) | $(OBJ_DIR)
$(call generate, $@, //)
$(file >> $@,$(PYTHONNT_RC_H))
##########################################################################
pyshellext.i: EXTRA_CFLAGS = -DCOMPILING_PYSHELLEXT
pyshellext.dll: PC/pyshellext.def $(OBJ_DIR)/pyshellext.obj | check-for-unused-libs.py
$(call link_DLL, $@, -def:$^ user32.lib shell32.lib shlwapi.lib advapi32.lib mincore.lib, $(PY_SHELLEXT_LIB))
$(OBJ_DIR)/pyshellext.obj: PC/pyshellext.cpp | $(CC).args
$(call CPP_compile, $@, -DCOMPILING_PYSHELLEXT $<)
##########################################################################
DLLs/_wmi.pyd: $(OBJ_DIR)/_wmimodule.obj $(OBJ_DIR)/_wmi.res $(PY_IMP_LIB) | check-for-unused-libs.py
$(call link_PYD, $@, -nodefaultlib:user32.lib $^ propsys.lib wbemuuid.lib)
$(OBJ_DIR)/_wmimodule.obj: PC/_wmimodule.cpp | $(CC).args
$(call CPP_compile, $@, $<)
##########################################################################
copy_into_DLLs:
$(call copy_files, ./DLLs, $(LIBFFI_DLL) $(OPENSSL_DLLs) $(OPENSSL_PDBs) $(TCLTK_DLLs))
$(call copy_files, $(TCL_ROOT), $(TCLTK_ROOT)/lib/tcl8.6/init.tcl)
##########################################################################
clean: rm_frozen
rm -fr $(OBJ_DIR)
- rmdir obj
rm -f $(GENERATED) .depend.tmp cpp-filter.py check-for-unused-libs.py vc1*.pdb \
link.args link.tmp Python.reg python.bat pythonw.bat \
cl.args clang-cl.args clang-cl-32.bat clang-cl-64.bat install.bat
#
# Cleanup after a Cygwin build via 'gv-build-cygwin.bat'.
# Not called here. Use as needed.
#
clean_cygwin:
$(call green_msg, Cleaning up after Cygwin.)
rm -f config.log config.status Makefile.pre Misc/python-config.sh Misc/python-embed.pc Misc/python.pc
rm -f Modules/ld_so_aix Modules/Setup.bootstrap Modules/Setup.local Modules/Setup.stdlib
@echo
realclean vclean: clean clean_doc clean_tests clean_pycaches
rm -f python3*.{dll,map,pdb} pyshellext.{dll,map,pdb} .depend.Windows
rm -f $(PROGRAMS:.exe=.{exe,pdb,map}) $(BOOTSTRAP_PYTHON:.exe=.{exe,pdb,map})
rm -fr $(TCL_ROOT) DLLs libs PCBuild/win32 PCBuild/amd64
#
# Clean-up after running 'Lib/tests/test_*.py' and 'Lib/tests/libregrtest/*.py' scripts:
#
PYCACHE_DIRS = __pycache__ \
Doc/tools/extensions/__pycache__ \
Lib/__pycache__ \
Parser/__pycache__ \
Tools/scripts/__pycache__ \
$(addprefix Lib/, \
$(addsuffix /__pycache__, \
asyncio \
collections \
concurrent \
concurrent/futures \
ctypes \
email \
email/mime \
encodings \
ensurepip \
http \
importlib \
importlib/resources \
json \
logging \
multiprocessing \
multiprocessing/dummy \
test \
test/test_asyncio \
test/encoded_modules \
test/test_email \
test/test_import \
test/test_importlib \
test/test_importlib/builtin \
test/test_importlib/data \
test/test_importlib/data/unwritable \
test/test_importlib/data01 \
test/test_importlib/data01/subdirectory \
test/test_importlib/data02 \
test/test_importlib/data02/one \
test/test_importlib/data02/two \
test/test_importlib/data03 \
test/test_importlib/extension \
test/test_importlib/frozen \
test/test_importlib/import_ \
test/test_importlib/source \
test/test_importlib/zipdata01 \
test/test_importlib/zipdata02 \
test/test_json \
test/leakers \
test/libregrtest \
test/support \
test/test_tools \
test/test_tools/test_c_analyzer \
test/test_tools/test_c_analyzer/test_common \
test/test_tools/test_c_analyzer/test_cpython \
test/test_tools/test_c_analyzer/test_parser \
test/test_tools/test_c_analyzer/test_symbols \
test/test_tools/test_c_analyzer/test_variables \
test/test_warnings \
test/tracedmodules \
unittest \
urllib \
xml \
xml/etree))
TEST_DATA_FILES = $(addprefix Lib/test/data/, \
BIG5.TXT \
BIG5HKSCS-2004.TXT \
CP932.TXT \
CP936.TXT \
CP949.TXT \
CP950.TXT \
EUC-CN.TXT \
EUC-JISX0213.TXT \
EUC-JP.TXT \
EUC-KR.TXT \
gb-18030-2000.xml \
JOHAB.TXT \
SHIFT_JISX0213.TXT \
SHIFTJIS.TXT \
blake2b.txt \
blake2s.txt \
NamedSequences.txt \
NormalizationTest.txt \
sha3_224.txt \
sha3_256.txt \
sha3_384.txt \
sha3_512.txt \
shake_128.txt \
shake_256.txt)
TEST_DATA_FILES += $(addprefix Lib/lib2to3/, \
Grammar*.pickle \
PatternGrammar*.pickle)
TEST_DATA_FILES += run_tests_1.results \
run_tests_2.results \
run_tests_3.results \
run_tests_4.results \
embedded_tests.results
define delete_dir
echo -e '$(BRIGHT_GREEN)Deleting $(BRIGHT_WHITE)$(strip $(1))/*\e[0m'
rm -fr $(strip $(1))
endef
clean_tests:
- rmdir build
$(call green_msg, Deleting $(BRIGHT_WHITE)TEST_DATA_FILES)
rm -f $(TEST_DATA_FILES)
clean_pycaches:
@$(foreach d, $(PYCACHE_DIRS), $(call delete_dir, $(d)) ; )
install: install.bat $(THIS_FILE)
install.bat: check_echo py.exe Python.reg
$(call generate, $@,::)
$(file >> $@,$(INSTALL_BAT))
$(call green_msg, Execute '$@' at own risk.)
#
# Generate these .bat-files to compile with correct 'clang-cl'.
#
clang-cl-32.bat: $(THIS_FILE)
$(call generate, $@,::)
$(file >> $@, @$(_CMDPROC))
$(file >> $@, @$(CLANG_CL32_ROOT_WIN)\bin\clang-cl.exe %*)
clang-cl-64.bat: $(THIS_FILE)
$(call generate, $@,::)
$(file >> $@, @$(_CMDPROC))
$(file >> $@, @$(CLANG_CL64_ROOT_WIN)\bin\clang-cl.exe %*)
#
# MSVC 32/64-bit selection without the 'vcvarsall.bat' stupidity.
# Assumes Visual-Studio 2017+ layout.
#
ifeq ($(CC),cl)
_CC = $(VC_ROOT)/bin/HostX86/$(CPU)/cl.exe
else
#
# This .bat file is generated early in 'all:'
#
_CC = clang-cl-$(BITS).bat
endif
vpath %.c $(ZLIB_ROOT) $(BZIP2_ROOT) $(SQLITE3_ROOT)
#
# The resulting .c.i file could be compiled with 'cl -c -Tc foo.i'
# The resulting .cpp.i file could be compiled with 'cl -c -Tp foo.i'
#
# vpath %.i Modules/_decimal/libmpdec
%.i: Modules/_decimal/libmpdec/%.c FORCE cpp-filter.py $(GENERATED) # $(FROZEN_GENERATED)
$(call CXX_preprocess, $@, $<, c)
%.i: %.c FORCE cpp-filter.py $(GENERATED) # $(FROZEN_GENERATED)
$(call CXX_preprocess, $@, $<, c)
%.i: %.cpp FORCE cpp-filter.py $(GENERATED) $(FROZEN_GENERATED)
$(call CXX_preprocess, $@, -TP $<, cpp)
FORCE:
cpp-filter.py: $(THIS_FILE)
$(call generate_PY,$@,$(CPP_FILTER_PY))
check-for-unused-libs.py: $(THIS_FILE)
$(call generate_PY,$@,$(CHECK_FOR_UNUSED_LIBS_PY))
Include/pyconfig.h: $(THIS_FILE)
$(call generate, $@, //)
$(file >> $@,$(PY_CONFIG_H))
$(OBJ_DIR)/pyconfig.h: PC/pyconfig.h.in $(THIS_FILE)
$(call generate, $@, //)
cat $< >> $@
@echo
$(OBJ_DIR)/decimal/hacks.c: $(THIS_FILE)
$(call generate, $@, //)
$(file >> $@,$(DEC_HACKS_C))
$(OBJ_DIR)/jit_stencils.h: $(THIS_FILE) Tools/jit/*.c Tools/jit/*.py Python/executor_cases.c.h Include/pyconfig.h
$(call green_msg, Generating '$@' using 'Tools/jit/build.py')
$(PYTHON) Tools/jit/build.py
@echo
$(OBJ_DIR)/lzma/hacks.c: $(THIS_FILE)
$(call generate, $@, //)
$(file >> $@,$(LZ_HACKS_C))
$(CC).args: $(THIS_FILE)
$(call green_msg, Creating $@)
$(call create_resp_file, $@, -c $(CFLAGS))
#
# GNU-make macros:
#
# The following codes used in macro 'colour_msg' assumes you have
# MSys/Cygwin's echo with colour support.
#
BRIGHT_RED = \e[1;31m
BRIGHT_GREEN = \e[1;32m
BRIGHT_WHITE = \e[1;37m
colour_msg = @echo -e "$(1)\e[0m"
green_msg = $(call colour_msg,$(BRIGHT_GREEN)$(strip $(1)))
green_msg0 = $(call colour_msg,$(BRIGHT_GREEN)$(1))
white_msg = $(call colour_msg,$(BRIGHT_WHITE)$(strip $(1)))
define generate
$(call green_msg, Generating $(1))
$(file > $(1), $(2))
$(file >> $(1), $(2) DO NOT EDIT! This file was automatically generated)
$(file >> $(1), $(2) from $(realpath $(THIS_FILE)))
$(file >> $(1), $(2) at $(NOW). Edit that file instead.)
$(file >> $(1), $(2))
endef
define generate_PY
$(call generate,$(1),#)
$(file >> $(1),from __future__ import print_function)
$(file >> $(1),if 1:)
$(file >> $(1),$(2))
endef
EXTRA_CFLAGS ?=
CXXFLAGS ?= -std:c++20 -EHsc -permissive-
#
# C/C++ compile macros:
#
define C_compile
$(strip $(_CC) @$(CC).args $(sort $(EXTRA_CFLAGS)) -Fo./$(strip $(1)) $(2))
@echo
endef
define CPP_compile
$(strip $(_CC) @$(CC).args $(CXXFLAGS) $(sort $(EXTRA_CFLAGS)) -Fo./$(strip $(1)) $(2))
@echo
endef
define C_compile_MP
$(call green_msg, Compiling $(words $(2)) .c-files:)
$(call C_compile, $(1), -MP $(2))
endef
#
# 32-bit assembly macro (currently not needed).
#
define assemble_x86
$(call green_msg, Assembling $(2):)
ml -c -nologo -coff -safeseh -Zd -Zi -Fl./$(strip $(1:.obj=.lst)) -Fo./$(strip $(1)) $(2)
@echo
endef
#
# 64-bit assembly macro. Currently needed for 'Modules/_decimal/libmpdec/vcdiv64.asm' only.
#
define assemble_x64
$(call green_msg, Assembling $(2):)
ml64 -c -nologo -Zd -Zi -Fo./$(strip $(1)) -Fl./$(strip $(1:.obj=.lst)) $(2)
@echo
endef
#
# Create a static library:
#
define create_lib
$(call green_msg, Creating $(1):)
lib -nologo -out:$(strip $(1)) $(2)
@echo
endef
#
# Use this Python script to check 'link.tmp' for unused libraries after
# a successful 'link'.
#
check_for_unused_libs = @$(PYTHON3) check-for-unused-libs.py link.tmp
define link_EXE
$(call green_msg, Linking $(1):)
$(call create_resp_file, link.args, $(LDFLAGS) $(2))
link -out:$(strip $(1)) @link.args > link.tmp
@cat link.tmp >> $(1:.exe=.map)
$(check_for_unused_libs)
@rm -f $(1:.exe=.lib) $(1:.exe=.exp)
endef
define link_EXE_GUI
$(call link_EXE, $(1), $(GUI_LDFLAGS) $(2))
endef
define link_DLL
$(call green_msg, Linking $(1):)
$(call create_resp_file, link.args, -dll $(LDFLAGS) -implib:$(strip $(3)) $(2))
link -out:$(strip $(1)) @link.args > link.tmp
@cat link.tmp >> $(1:.dll=.map)
$(check_for_unused_libs)
@rm -f $(3:.lib=.exp)
endef
define link_PYD
$(call green_msg, Linking $(1):)
$(call create_resp_file, link.args, -dll $(LDFLAGS) $(2))
link -out:$(strip $(1)) @link.args > link.tmp
@cat link.tmp >> $(1:.pyd=.map)
$(check_for_unused_libs)
@rm -f $(1:.pyd=.lib) $(1:.pyd=.exp)
endef
#
# Make a response file; Each word in $(2) is written on a separate line.
#
define create_resp_file
$(file > $(1))
$(foreach f, $(2), $(file >> $(1),$(strip $(f))) )
endef
#
# copy files macro:
# arg1, $(1): directory (must exist)
# arg2, $(2): files.
#
define copy_files
$(call green_msg, Copying these files into $(BRIGHT_WHITE)$(strip $(1)):)
@$(foreach f, $(1), echo ' $(f)' ; )
@cp --update --preserve=timestamps $(2) $(1)
@echo
endef
#
# Create directories macro:
# arg1, $(1): list of directories; >= 1
#
define create_dirs
$(call green_msg, Creating directories:)
@$(foreach d, $(1), echo -e ' $(BRIGHT_WHITE)$(d)\e[0m' ; )
@mkdir --parents $(1)
@echo
endef
#
# Run a .rc-file through the resource compiler.
# $(1): the .res-file.
# $(2): the 'PYTHON_DLL_NAME'.
# $(3): the .rc-file
# $(4): optional '-Dxx' arguments.
#
define create_res_file
$(file > $(OBJ_DIR)/tmp.rc, /* Temporary .rc-file for creating '$(strip $(1))' */)
$(file >> $(OBJ_DIR)/tmp.rc, #include <windows.h>)
$(file >> $(OBJ_DIR)/tmp.rc,)
$(file >> $(OBJ_DIR)/tmp.rc, #define PYTHON_DLL_NAME "$(strip $(2))")
$(file >> $(OBJ_DIR)/tmp.rc, #define ORIGINAL_FILENAME "$(strip $(2))")
$(file >> $(OBJ_DIR)/tmp.rc,)
$(file >> $(OBJ_DIR)/tmp.rc, #define FIELD3 (100 + $(PY_RELEASE_SERIAL)) /* Will 'rc' parse this as '102'? */)
$(file >> $(OBJ_DIR)/tmp.rc, #include <$(notdir $(3))>)
$(call green_msg, Creating $(BRIGHT_WHITE)$(strip $(1)) $(BRIGHT_GREEN)via $(BRIGHT_WHITE)$(OBJ_DIR)/tmp.rc)
rc $(RCFLAGS) -I./include -I./PC $(4) -fo $(1) $(OBJ_DIR)/tmp.rc
@echo
endef
#
# '2>&1': redirect 'stderr' into 'stdout' and pipes through 'tee'
#
define write_single_test
$(file >> $(1), $(call echo_prog, \n$(BRIGHT_GREEN)====================================================================== \
\nRunning $(BRIGHT_WHITE)$(strip $(2)) -v:) | $(tee_prog) --append $(3))
$(file >> $(1), call python.bat $(2) -v 2>&1 | $(tee_prog) --append $(3))
$(file >> $(1),)
endef
define write_single_embed_test
$(file >> $(1), $(call echo_prog, \n$(BRIGHT_GREEN)====================================================================== \
\nRunning $(BRIGHT_WHITE)_testembed.exe $(strip $(2)):))
$(file >> $(1), _testembed.exe $(strip $(2)))
$(file >> $(1), if NOT errorlevel 0 ($(call echo_prog, $(BRIGHT_RED)Failed) & exit /b 1))
endef
#
# The "meat" of '$(OBJ_DIR)/pythonnt_rc.h':
#
define PYTHONNT_RC_H
/*
* The 'FIELD3' is needed only by 'PC/python_ver_rc.h' to define the
* 'PYVERSION64' variable. This is used for 'FILEVERSION' and
* 'PRODUCTVERSION' in the resource version section of each .res-file.
*
* In 'PCBuild/Python.props' it is defined as:
* Field3Value - 2101 for '3.5.2a1' (== 1000*2 + 10*10 ('a') + 1)
*
* But it seems to also be the same as '(100 + $$(PY_RELEASE_SERIAL))'
*/
#if defined(RC_INVOKED)
#define FIELD3 (100 + $(PY_RELEASE_SERIAL)) /* Will 'rc' parse this as '102'? */
#endif
#define MS_DLL_ID "$(PY_VER)-$(BITS)"
endef
#
# Make some pre-processed output of .c/.cpp-files to make sense of
# this mess :-)
#
# Optionally with the use of 'astyle'.
# Use as e.g.
# make -f Makefile.Windows CC=cl pythonrun.i
#
# clang-cl: /d1PP Retain macro definitions in /E mode
#
ifeq ($(CC)-$(USE_MACRO_DEBUG),clang-cl-1)
d1PP = -d1PP
else
d1PP =
endif
ifeq ($(USE_ASTYLE),1)
define CXX_preprocess
$(file > $(1),/* The preprocessed and AStyled output of '$(filter %.c %.cpp, $(2))':)
$(file >> $(1), * $(_CC) -E)
$(foreach f, $(CFLAGS) $(d1PP) $(EXTRA_CFLAGS), $(file >> $(1), * $(f)))
$(file >> $(1), *---------------------------------------------------------)
$(file >> $(1), */)
$(_CC) -E @$(CC).args $(EXTRA_CFLAGS) $(d1PP) $(2) | $(PYTHON3) cpp-filter.py | astyle >> $(1)
@echo
endef
else
define CXX_preprocess
$(file > $(1),/* The raw preprocessed output of '$(filter %.c %.cpp, $(2))':)
$(file >> $(1), * $(_CC) -E)
$(foreach f, $(CFLAGS) $(d1PP) $(EXTRA_CFLAGS), $(file >> $(1), * $(f)))
$(file >> $(1), *---------------------------------------------------------)
$(file >> $(1), */)
$(_CC) -E @$(CC).args $(EXTRA_CFLAGS) $(d1PP) $(2) | $(PYTHON3) cpp-filter.py | astyle >> $(1)
@echo
endef
endif
define PY_CONFIG_H
#ifndef Py_HACK_CONFIG_H
#define Py_HACK_CONFIG_H
/* Turn off a lot of clang-cl warnings with '-Wall':
*/
#if defined(__clang__)
#pragma clang diagnostic ignored "-Wassign-enum"
#pragma clang diagnostic ignored "-Wbad-function-cast"
#pragma clang diagnostic ignored "-Wcast-align"
#pragma clang diagnostic ignored "-Wcast-qual"
#pragma clang diagnostic ignored "-Wcast-function-type"
#pragma clang diagnostic ignored "-Wcomma"
#pragma clang diagnostic ignored "-Wconstant-conversion"
#pragma clang diagnostic ignored "-Warray-bounds-pointer-arithmetic"
#pragma clang diagnostic ignored "-Wconditional-uninitialized"
#pragma clang diagnostic ignored "-Wcovered-switch-default"
#pragma clang diagnostic ignored "-Wdate-time"
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
#pragma clang diagnostic ignored "-Wdocumentation"
#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
#pragma clang diagnostic ignored "-Wdouble-promotion"
#pragma clang diagnostic ignored "-Wextra-semi-stmt"
#pragma clang diagnostic ignored "-Wfloat-conversion"
#pragma clang diagnostic ignored "-Wfloat-equal"
#pragma clang diagnostic ignored "-Wformat-non-iso"
#pragma clang diagnostic ignored "-Wformat-nonliteral"
#pragma clang diagnostic ignored "-Wignored-pragmas"
#pragma clang diagnostic ignored "-Wignored-pragma-optimize"
#pragma clang diagnostic ignored "-Wimplicit-int-conversion"
#pragma clang diagnostic ignored "-Wimplicit-float-conversion"
#pragma clang diagnostic ignored "-Wimplicitly-unsigned-literal"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers"
#pragma clang diagnostic ignored "-Winvalid-noreturn"
#pragma clang diagnostic ignored "-Wlanguage-extension-token"
#pragma clang diagnostic ignored "-Wmicrosoft-include"
#pragma clang diagnostic ignored "-Wmissing-braces"
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
#pragma clang diagnostic ignored "-Wmissing-noreturn"
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#pragma clang diagnostic ignored "-Wmissing-variable-declarations"
#pragma clang diagnostic ignored "-Winconsistent-dllimport"
#pragma clang diagnostic ignored "-Wnewline-eof"
#pragma clang diagnostic ignored "-Wmacro-redefined"
#pragma clang diagnostic ignored "-Wnonportable-include-path"
#pragma clang diagnostic ignored "-Wnonportable-system-include-path"
#pragma clang diagnostic ignored "-Woverlength-strings"
#pragma clang diagnostic ignored "-Wparentheses"
#pragma clang diagnostic ignored "-Wpedantic"
#pragma clang diagnostic ignored "-Wpointer-sign"
#pragma clang diagnostic ignored "-Wpragma-pack"
#pragma clang diagnostic ignored "-Wsometimes-uninitialized"
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
#pragma clang diagnostic ignored "-Wsign-compare"
#pragma clang diagnostic ignored "-Wsign-conversion"
#pragma clang diagnostic ignored "-Wstatic-in-inline"
#pragma clang diagnostic ignored "-Wstrict-prototypes"
#pragma clang diagnostic ignored "-Wswitch-enum"
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
#pragma clang diagnostic ignored "-Wtautological-type-limit-compare"
#pragma clang diagnostic ignored "-Wundef"
#pragma clang diagnostic ignored "-Wundefined-inline"
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunreachable-code-break"
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#pragma clang diagnostic ignored "-Wunused-function"
#pragma clang diagnostic ignored "-Wunused-macros"
#pragma clang diagnostic ignored "-Wunused-label"
#pragma clang diagnostic ignored "-Wunused-parameter"
#pragma clang diagnostic ignored "-Wunused-variable"
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#pragma clang diagnostic ignored "-Wvisibility"
#pragma clang diagnostic ignored "-Wreserved-identifier"
#pragma clang diagnostic ignored "-Wshadow"
#pragma clang diagnostic ignored "-Wdeclaration-after-statement"
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
/*
* Warning-control for 'USE_MIMALLOC=1':
*/
#if defined(USE_MIMALLOC)
#pragma clang diagnostic ignored "-Wclass-varargs"
#endif
/*
* Warning-control for C++:
*/
#if defined(__cplusplus)
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
#pragma clang diagnostic ignored "-Wc++98-compat"
#pragma clang diagnostic ignored "-Wc++98-compat-extra-semi"
#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
#pragma clang diagnostic ignored "-Wold-style-cast"
#endif
#else
/*
* Turn off these warnings:
* warning C4028: formal parameter 1 different from declaration
* warning C4068: unknown pragma 'GCC'
* warning C4113: 'FARPROC' differs in parameter lists from 'BOOL (__stdcall *)(LPMEMORYSTATUSEX)'
* warning C4244: 'function': conversion from 'Py_ssize_t' to 'unsigned int', possible loss of data
* warning C4267: 'function': conversion from 'size_t' to 'unsigned int', possible loss of data
* warning C4311: 'type cast': pointer truncation from 'void *' to 'DWORD'
*/
#pragma warning (disable: 4028 4068 4113 4244 4267 4311)
#endif
/* Turn off a lot of SDK warnings:
*/
#undef _CRT_SECURE_NO_WARNINGS
#undef _CRT_SECURE_NO_DEPRECATE
#undef _CRT_NONSTDC_NO_DEPRECATE
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_NONSTDC_NO_DEPRECATE
#define Py_ENABLE_SHARED 1 /* Always create and use .DLLs */
#define _Py_HAVE_ZLIB 1 /* We have an internal zlib */
#define _FILE_OFFSET_BITS 64 /* Enable >2GB file support. Irrelevant on Windows? */
#define BYTEORDER 1234 /* We are little-endian */
#define HAVE_ACCEPT 1
#define HAVE_BIND 1
#define HAVE_BZLIB_H 1
#define HAVE_CONNECT 1
#define HAVE_CLOCK_T 1
#define HAVE_DUP 1
#define HAVE_GETHOSTBYADDR 1
#define HAVE_GETHOSTNAME 1
#define HAVE_GETPROTOBYNAME 1
#define HAVE_GETSERVBYNAME 1
#define HAVE_GETSERVBYPORT 1
#define HAVE_GETSOCKNAME 1
#define HAVE_INET_NTOA 1
#define HAVE_INET_PTON 1
#define HAVE_LIBB2 1
#define HAVE_LIBSQLITE3 1
#define HAVE_LISTEN 1
#define HAVE_LONG_DOUBLE 1
#define HAVE_RECVFROM 1
#define HAVE_SENDTO 1
#define HAVE_SETSOCKOPT 1
#define HAVE_SOCKET 1
#define HAVE_SOCKLEN_T 1
#define HAVE_STDIO_H 1
#define USE_ZLIB_CRC32 1
#define VPATH "."
#ifndef PY_SQLITE_HAVE_SERIALIZE
#define PY_SQLITE_HAVE_SERIALIZE 1
#endif
#ifndef PY_SQLITE_ENABLE_LOAD_EXTENSION
#define PY_SQLITE_ENABLE_LOAD_EXTENSION 1
#endif
#ifndef WIN32
#define WIN32 /* '#ifdef WIN32' (and not '_WIN32') is used in several places */
#endif
#define PY3_DLLNAME L"python3.dll"
#define PYTHON_DLL_NAME "$(PYTHON_DLL)"
#if defined(COMPILING_GETPATH_C)
#define PREFIX ""
#define EXEC_PREFIX ""
#define PLATLIBDIR "lib"
#define VERSION "$(PY_VER_STR)"
#endif
#if defined(COMPILING_LAUNCHER_W) || defined(COMPILING_PYSHELLEXT)
#define UNICODE
#define _UNICODE
#define _WINDOWS
#else
/* Turn off the warning:
* 'GetVersion' is deprecated [-Wdeprecated-declarations]
*/
#define BUILD_WINDOWS
/* I think this has the same effect as 'BUILD_WINDOWS'.
*/
#define _WINSOCK_DEPRECATED_NO_WARNINGS
/* Win8; must match the value of 'Py_WINVER' in the below 'Include/pyconfig.h'
*/
#if !defined(_WIN32_WINNT ) || (_WIN32_WINNT < 0x0602)
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0602
#endif
#endif
#include "pythonnt_rc.h" /* Defines 'MS_DLL_ID' */
#ifndef GITVERSION
#define GITVERSION "$(shell git --git-dir Git-Latest/.git rev-parse --short HEAD)"
#endif
#ifndef GITTAG
#define GITTAG "v$(PY_VER_STR)"
#endif
#ifndef GITBRANCH
#define GITBRANCH "master"
#endif
#if !defined(COMPILING_ZLIB) /* Rest of file */
/*
* This file gets generated into './Include' and forcefully included as:
* "-FI./Include/pyconfig.h" when building ALL objects.
*
* The purpose of this file is just to tweak the normal MSVC '$$(OBJ_DIR)/pyconfig.h'
* with acceptable config-values for all compilers. Not just MSVC.
* Especially it fixes the horrid '_Py_STRINGIZE()' macro to work for '__clang__'.
*
* The '../PC/' directory should be relative to '$(realpath .)/Include' when using
* Python from outside Python's build directory.
* Ideally the below files should be 'cat'ed into place.
*/
#include "$(OBJ_DIR)/pyconfig.h"
/*
* Just a hack for 'make depend' (gcc -MM).
* Python goes bananas if it does not see a '_MSC_VER' in many .c-files.
*/
#if defined(DOING_CPP_PROCESSING) && defined(__GNUC__)
#define _MSC_VER 1800
#define _S_IREAD 0400
#define CONFIG_32
#endif
#if !defined(RC_INVOKED)
#if !defined(DOING_CPP_PROCESSING)
#if defined(_MSC_VER) && defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_MODULE)
#if (_WIN32_WINNT != Py_WINVER)
#error "_WIN32_WINNT != Py_WINVER."
#endif
#endif
#if !defined(_MSC_VER)
#undef SIZEOF_TIME_T
#define SIZEOF_TIME_T 8
#endif
#if (SIZEOF_TIME_T != 8)
#error "SIZEOF_TIME_T is not 8!!"
#endif
#endif /* !DOING_CPP_PROCESSING */
#if defined(__clang__)
#undef _Py_PASTE_VERSION
#undef _Py_STRINGIZE
#undef _Py_STRINGIZE2
#define _Py_STRINGIZE2(x) #x
#define _Py_STRINGIZE(x) _Py_STRINGIZE2(x)
#define _Py_PASTE_VERSION(SUFFIX) ("[Clang-cl v." _Py_STRINGIZE(__clang_major__) "." \
_Py_STRINGIZE(__clang_minor__) "." \
_Py_STRINGIZE(__clang_patchlevel__) " " \
SUFFIX "]")
#endif
#define _CRT_RAND_S /* Needed for 'rand_s()' */
#include <stdlib.h>
/*
* 'struct timeval' is needed ahead of '<Include/pytime.h>'.
* Otherwise clang-cl barfs.
*
* But when compiling 'Module/_pickle.c', do not include '<winsock2.h>' which
* includes '<windows.h>'. That causes 'FLOAT' etc. from '<minwindef.h>' to
* clash with the 'FLOAT' enums in 'Module/_pickle.c'.
*/
#if !defined(COMPILING_PICKLE) && !defined(COMPILING_PYSHELLEXT)
#include <winsock2.h>
#endif
#include <limits.h> /* INT_MAX */
#ifndef MAXINT
#define MAXINT INT_MAX /* Only needed in 'PC/launcher.c' */
#endif
#if defined(_WINBASE_)
#undef Yield
#undef small
#endif
#if defined(COMPILING_SQLITE3)
#define SQLITE_ENABLE_FTS4 1
#define SQLITE_ENABLE_FTS5 1
#define SQLITE_ENABLE_JSON1 1
#define SQLITE_ENABLE_MATH_FUNCTIONS 1
#define SQLITE_ENABLE_RTREE 1
#define SQLITE_API __declspec(dllexport)
#endif
#if defined(COMPILING_HASH_OPENSSL)
#define PY_OPENSSL_HAS_SHAKE 1
#define PY_OPENSSL_HAS_SHA3 1
#endif
#if defined(COMPILING_EXPAT)
#define ELEMENT_TYPE expat_ELEMENT_TYPE
// #define USE_PYEXPAT_CAPI 1
#define HAVE_MEMMOVE 1
#define HAVE_EXPAT_H 1
#define XML_STATIC 1
#define XML_NS 1
#define XML_DTD 1
#define XML_CONTEXT_BYTES 1024
#endif
#endif /* !RC_INVOKED */
#endif /* !COMPILING_ZLIB */
#endif /* Py_HACK_CONFIG_H */
endef
define DEC_HACKS_C
/*
* Gross hacks for '_decimal.pyd' in '_DEBUG' mode.
* But option '-MDd' is not supported yet.
*/
#include <math.h>
#include <assert.h>
#include "Modules/_decimal/libmpdec/mpdecimal.h"
#include "Modules/_decimal/libmpdec/mpalloc.h"
#if defined(_DEBUG)
#if defined(_MSC_VER) && (defined(_M_IA64) || defined(_M_X64) || defined(_M_AMD64)) && 0
int __cdecl __control87_2 (unsigned int NewValue,
unsigned int Mask,
unsigned int *X86ControlWord,
unsigned int *Sse2ControlWord)
{
(void) X86ControlWord;
(void) Sse2ControlWord;
return _control87 (NewValue, Mask);
}
#endif
void mpd_del (mpd_t *dec)
{
if (mpd_isdynamic_data(dec))
mpd_free (dec->data);
if (mpd_isdynamic(dec))
mpd_free (dec);
}
void mpd_uint_zero (mpd_uint_t *dest, mpd_size_t len)
{
mpd_size_t i;
for (i = 0; i < len; i++)
dest[i] = 0;
}
int mpd_qresize (mpd_t *result, mpd_ssize_t nwords, uint32_t *status)
{
assert (!mpd_isconst_data(result)); /* illegal operation for a const */
assert (!mpd_isshared_data(result)); /* illegal operation for a shared */
assert (MPD_MINALLOC <= result->alloc);
nwords = (nwords <= MPD_MINALLOC) ? MPD_MINALLOC : nwords;
if (nwords == result->alloc)
return (1);
if (mpd_isstatic_data(result))
{
if (nwords > result->alloc)
return mpd_switch_to_dyn (result, nwords, status);
return (1);
}
return mpd_realloc_dyn (result, nwords, status);
}
#endif /* _DEBUG */
endef
define LZ_HACKS_C
/*
* Hacks around the link errors using 'clang-cl'; missing in < v8.
*/
#if defined(__clang__) && (__clang_major__ < 8)
unsigned char _BitScanReverse (unsigned long *_Index, unsigned long _Mask)
{
if (!_Mask)
return (0);
*_Index = (31 - __builtin_clzl (_Mask));
return (1);
}
unsigned char _BitScanForward (unsigned long *_Index, unsigned long _Mask)
{
if (!_Mask)
return (0);
*_Index = __builtin_ctzl (_Mask);
return (1);
}
#endif
endef
define CPP_FILTER_PY
import sys, os
empty_lines = 0
while True:
line = sys.stdin.readline()
if not line:
break
line = line.rstrip()
if line == "":
empty_lines += 1
continue
#
# MSVC or clang-cl 'line' directive
#
if line.startswith("#line") or line.startswith("# "):
line = line.replace (r"\\", "/")
print (line)
#
# Print a newline after a functions or structs
#
if line == "}" or line == "};":
print ("")
print ("Removed %d empty lines." % empty_lines, file=sys.stderr)
endef
define CHECK_FOR_UNUSED_LIBS_PY
#
# Check a MSVC .map-file for lines after a 'Unused libraries:'
#
import os, sys
ignore_libs = [ "oldnames.lib", "libcmt.lib" ]
class State():
IDLE = 0
UNUSED = 1
class Colour():
RED = WHITE = RESET = ""
try:
from colorama import init, Fore, Style
init()
Colour.RED = Fore.RED + Style.BRIGHT
Colour.WHITE = Fore.WHITE + Style.BRIGHT
Colour.RESET = Style.RESET_ALL
except:
pass
def report (map_file, unused):
num = len(unused)
plural = [ "library", "libraries" ]
if num > 0:
print ("%s%d unused %s in %s:%s" % (Colour.RED, num, plural[num > 1], map_file, Colour.RESET))
for u in sorted(unused):
print (" " + u)
print ("%sDone%s\n" % (Colour.WHITE, Colour.RESET))
def process_map (file, state):
unused_libs = []
f = open (file, "rt")
lines = f.readlines()
f.close()
for l in lines:
l = l.strip()
if l == "Unused libraries:":
state = State.UNUSED
continue
if state == State.UNUSED:
if l == "":
break
if os.path.basename (l).lower() not in ignore_libs:
unused_libs.append (l)
return unused_libs
map_file = sys.argv[1]
report (map_file, process_map(map_file, State.IDLE))
endef
PIP_WHL = $(word 1, $(wildcard Lib/ensurepip/_bundled/pip-*.whl))
SETUPTOOLS_WHL = $(word 1, $(wildcard Lib/ensurepip/_bundled/setuptools-*.whl))
_PIP_WHL = $(subst /,\,$(PIP_WHL))
_SETUPTOOLS_WHL = $(subst /,\,$(SETUPTOOLS_WHL))
_TCL_CORE_ROOT = $(subst /,\,$(TCL_CORE_ROOT))
whl_test:
$(call green_msg0, Found pip*.whl: '$(PIP_WHL)')
$(call green_msg0, Found setuptools*.whl: '$(SETUPTOOLS_WHL)')
$(call green_msg0, _PIP_WHL: '$(_PIP_WHL)')
$(call green_msg0, _SETUPTOOLS_WHL: '$(_SETUPTOOLS_WHL)')
$(call green_msg0, _TCL_CORE_ROOT: '$(_TCL_CORE_ROOT)')
#
# The shells from JPsoft.com handles a '^C' in a .bat file with the
# below 'on break ()' statement. The CMD crap does not.
#
_CMDPROC = if %_cmdproc. == 4NT. .or. %_cmdproc. == TCMD32. .or. \
%_cmdproc%. == TCC. .or. %_cmdproc. == TCCLE. \
on break (echo Quitting %+ quit)
define RUN_TESTS_BAT
@echo off
setlocal
set WSOCK_TRACE_LEVEL=0
$(_CMDPROC)
endef
#
# TODO: Rewrite this into a "py.exe -3 colorama-based-script.py"
#
define EMBEDDED_TESTS_BAT
::
:: This .bat-file will try to run all the embedded tests
:: and exit on the first failure. Otherwise it will say "Success! ..."
::
@echo off
setlocal
set WSOCK_TRACE_LEVEL=0
$(call echo_prog, $(BRIGHT_WHITE)Running $(words $(TESTEMBED_CASES)) '$<' test-cases.)
$(_CMDPROC)
set TESTPATH=$(REG_LIB_DIR);$(REG_DLLs_DIR)
set TESTHOME=$(REG_THIS_DIR)
set PYTHONPATH=%~dp0%\DLLs;%PYTHONPATH%
endef
define PYTHON_BAT_COMMON
@echo off
setlocal
set PROMPT=$$P$$G
$(_CMDPROC)
::
:: A 'set PYTHON_EXTRA_PATH=x;y;z' could be set from the outside.
::
set PYTHONHOME=%~dp0%
set PYTHONPATH=%PYTHONHOME%\DLLs;%PYTHONHOME%\$(_SETUPTOOLS_WHL);%PYTHONHOME%\$(_PIP_WHL);%PYTHON_EXTRA_PATH%
::
:: Do not write .pyc files.
::
:: set PYTHONDONTWRITEBYTECODE=1
::
:: Path for WinDbg and dbghelp.
::
set _NT_SYMBOL_PATH=%PYTHONHOME%\DLLs;%_NT_SYMBOL_PATH%
::
:: In case '$(PYTHON_DLL)' was linked to 'wsock_trace-$(CPU).lib', shut it up.
::
:: set WSOCK_TRACE_LEVEL=0
:: set WSOCK_DUMP_MODULES=0
:: set WSOCK_LUA_ENABLE=0
:: set USE_LUA=0
:: set TCLLIBPATH=%PYTHONHOME%\$(_TCL_CORE_ROOT)\lib\tcl8.6;%PYTHONHOME%\$(_TCL_CORE_ROOT)\library
::
:: In case a Python 'test*.py' wants to use 'Lib\distutils\msvccompiler.py'.
::
if exist libs\x64\python3.lib (
set LIBPATH=%PYTHONHOME%\libs\x64;%LIBPATH%
) else (
set LIBPATH=%PYTHONHOME%\libs;%LIBPATH%
)
::
:: Some script will invoke 'PC\*.bat' files which are rather CMD centric.
:: So set COMSPEC accordingly.
::
set COMSPEC=%WINDIR%\system32\cmd.exe
::
:: Invoke our 'python.exe' (or 'pythonw.exe') with all arguments
::
endef
#
# Stuff for updating the Registry while running 'install.bat':
#
REG_DOS_path = $(strip $(subst /,\\,$(realpath $(1))))
REG_THIS_DIR = $(call REG_DOS_path, .)
#
# Since 'python*.chm' may not exist yet
#
REG_PYTHON_CHM = $(REG_THIS_DIR)\\Python$(_PY_VER).chm
REG_IDLE_PYW = $(call REG_DOS_path, Lib/idlelib/idle.pyw)
REG_LIB_DIR = $(call REG_DOS_path, Lib)
REG_DLLs_DIR = $(call REG_DOS_path, DLLs)
define Python_REG
REGEDIT4
;
; DO NOT EDIT! This file was automatically generated)
; from $(realpath $(THIS_FILE)))
; at $(NOW). Edit that file instead.)
;
[$(top_key)]
"DisplayName"="Python $(PY_VER) ($(BITS)-bit, $(BUILDER) compiled)"
"SupportUrl"="http://www.python.org/"
"Version"="$(PY_VER_STR)"
"SysVersion"="$(PY_VER)"
"SysArchitecture"="$(BITS)bit"
[$(top_key)\Help]
[$(top_key)\Help\Main Python Documentation]
@="$(REG_PYTHON_CHM)"
[$(top_key)\Idle]
@="$(REG_IDLE_PYW)"
[$(top_key)\IdleShortcuts]
@=dword:00000001
[$(top_key)\InstalledFeatures]
"core_pdb"="$(PY_VER_STR)"
"core_d"="$(PY_VER_STR)"
"dev"="$(PY_VER_STR)"
"Shortcuts"="$(PY_VER_STR)"
"exe"="$(PY_VER_STR)"
"lib"="$(PY_VER_STR)"
"test"="$(PY_VER_STR)"
"doc_shortcut"="$(PY_VER_STR)"
"doc"="$(PY_VER_STR)"
"tools"="$(PY_VER_STR)"
"tcltk"="$(PY_VER_STR)"
"pip"="$(PY_VER_STR)"
[$(top_key)\InstallPath]
@="$(REG_THIS_DIR)\\"
"ExecutablePath"="$(REG_THIS_DIR)\\python.exe"
"WindowedExecutablePath"="$(REG_THIS_DIR)\\pythonw.exe"
;
; Put a '$$(call REG_DOS_path, Python3*.zip)' first?
;
[$(top_key)\PythonPath]
@="$(REG_LIB_DIR);$(REG_DLLs_DIR)"
endef
PY_EXE = $(subst /,\,$(realpath py.exe)) -$(PY_VER)-$(BITS)
define INSTALL_BAT
@echo off
$(call echo_prog, $(BRIGHT_GREEN)Creating Registry keys:)
reg import $(call REG_DOS_path, Python.reg) -reg:32 2> NUL
$(call echo_prog, $(BRIGHT_GREEN)\nTest sys.version:)
$(PY_EXE) -c "import sys; print (' ' + sys.version)"
$(call echo_prog, $(BRIGHT_GREEN)Test sysconfig:)
$(PY_EXE) -c "import sysconfig; print (' ' + sysconfig.get_platform())"
endef
#
# Some fixed dependencies:
#
# $(OBJ_DIR)/core/sre.obj: Modules/_sre/sre_constants.h Modules/_sre/sre_targets.h
# $(OBJ_DIR)/core/sha3module.obj: Modules/sha3module.c
#
# Use 'gcc' to create dependencies:
#
dep_replace = sed -e 's@\(.*\)\.o: @\n$$(OBJ_DIR)\/$(strip $(1))\1.obj: @'
dep_final_replace = -e 's@$(SQLITE3_ROOT)@$$(SQLITE3_ROOT)@g' \
-e 's@$(OPENSSL_ROOT)@$$(OPENSSL_ROOT)@g' \
-e 's@$(LZMA_ROOT)@$$(LZMA_ROOT)@g' \
-e 's@$(TCLTK_ROOT)@$$(TCLTK_ROOT)@g' \
-e 's@$(BZIP2_ROOT)@$$(BZIP2_ROOT)@g' \
-e 's@$(ZLIB_ROOT)@$$(ZLIB_ROOT)@g'
#
# Remove the generated 'Include/pyconfig.h' and '$(OBJ_DIR)/pythonnt_rc.h' from
# the dependencies as that would cause far too much to be rebuilt.
#
dep_final_replace += -e 's@Include/pyconfig.h @@g' \
-e 's@$(OBJ_DIR)/pythonnt_rc.h @@g'
#
# Pass these CFLAGS to 'gcc -MM':
# Filter out any MSVC/clang specific CFLAGS; only '-D*' and '-I*' are
# essential to dependency generation.
#
dep_CFLAGS = -MM -m$(BITS) --include Include/pyconfig.h -DDOING_CPP_PROCESSING $(filter -D% -I%, $(1))
#
# Make dependencies for a chunk of .c-files.
# Each chunk may need extra CFLAGS; like for 'Modules/_sqlite/*.c'.
#
# arg1: $(1): the list of .c-files.
# arg2: $(2): the extra CFLAGS for $(1).
# arg3: $(3): the .obj-file sub-directory (optional).
#
define create_deps
$(call white_msg, Generating dependencies for $(BRIGHT_GREEN)$(words $(1)) $(BRIGHT_WHITE)files...)
gcc $(call dep_CFLAGS, $(CFLAGS) $(3)) $(1) | $(call dep_replace, $(2)) >> .depend.tmp
@echo
endef
depend: make_dirs $(GENERATED) $(FROZEN_GENERATED)
$(call generate, .depend.tmp, #)
$(call create_deps, $(PC_SRC) $(OBJECTS_SRC) $(PARSER_SRC) $(PYTHON_SRC) $(MODULES_SRC), core/, -DPy_BUILD_CORE_BUILTIN)
$(call create_deps, $(BZIP2_SRC), bzip2/)
$(call create_deps, $(CTYPES_SRC), ctypes/, $(CTYPES_CFLAGS))
$(call create_deps, $(ELEMENTTREE_SRC), elementtree/, $(EXPAT_CFLAGS))
$(call create_deps, $(DECIMAL_C_SRC), decimal/, $(DECIMAL_CFLAGS))
$(call create_deps, $(LZMA_SRC), lzma/, $(LZMA_CFLAGS))
$(call create_deps, $(TKINTER_SRC),, $(TKINTER_CFLAGS))
$(call create_deps, $(ZLIB_SRC), zlib/, $(ZLIB_CFLAGS))
$(call create_deps, $(PYEXPAT_SRC), pyexpat/, $(EXPAT_CFLAGS))
$(call create_deps, $(_SQLITE3_SRC), _sqlite3/)
$(call create_deps, $(SQLITE3_SRC), sqlite3/)
sed $(dep_final_replace) < .depend.tmp > .depend.Windows
rm -f .depend.tmp
-include .depend.Windows
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment