8000 gh-93939: Build C extensions without setup.py by tiran · Pull Request #94474 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-93939: Build C extensions without setup.py #94474

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 14, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
gh-93939: Build C extensions without setup.py
  • Loading branch information
tiran committed Jul 13, 2022
commit 7b40b31a34ebea4f58356ef29d2a84eacfd0a06c
97 changes: 0 additions & 97 deletions Lib/_bootsubprocess.py

This file was deleted.

9 changes: 9 additions & 0 deletions Lib/test/test_descr.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
except ImportError:
_testcapi = None

try:
import xxsubtype
except ImportError:
xxsubtype = None


class OperatorsTest(unittest.TestCase):

Expand Down Expand Up @@ -299,6 +304,7 @@ def test_explicit_reverse_methods(self):
self.assertEqual(float.__rsub__(3.0, 1), -2.0)

@support.impl_detail("the module 'xxsubtype' is internal")
@unittest.skipIf(xxsubtype is None, "requires xxsubtype module")
def test_spam_lists(self):
# Testing spamlist operations...
import copy, xxsubtype as spam
Expand Down Expand Up @@ -343,6 +349,7 @@ def foo(self): return 1
self.assertEqual(a.getstate(), 42)

@support.impl_detail("the module 'xxsubtype' is internal")
@unittest.skipIf(xxsubtype is None, "requires xxsubtype module")
def test_spam_dicts(self):
# Testing spamdict operations...
import copy, xxsubtype as spam
Expand Down Expand Up @@ -1600,6 +1607,7 @@ def test_refleaks_in_classmethod___init__(self):
self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10)

@support.impl_detail("the module 'xxsubtype' is internal")
@unittest.skipIf(xxsubtype is None, "requires xxsubtype module")
def test_classmethods_in_c(self):
# Testing C-based class methods...
import xxsubtype as spam
Expand Down Expand Up @@ -1683,6 +1691,7 @@ def test_refleaks_in_staticmethod___init__(self):
self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10)

@support.impl_detail("the module 'xxsubtype' is internal")
@unittest.skipIf(xxsubtype is None, "requires xxsubtype module")
def test_staticmethods_in_c(self):
# Testing C-based static methods...
import xxsubtype as spam
Expand Down
59 changes: 10 additions & 49 deletions Makefile.pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,6 @@ ENSUREPIP= @ENSUREPIP@
LIBMPDEC_A= Modules/_decimal/libmpdec/libmpdec.a
LIBEXPAT_A= Modules/expat/libexpat.a

# OpenSSL options for setup.py so sysconfig can pick up AC_SUBST() vars.
OPENSSL_INCLUDES=@OPENSSL_INCLUDES@
OPENSSL_LIBS=@OPENSSL_LIBS@
OPENSSL_LDFLAGS=@OPENSSL_LDFLAGS@
OPENSSL_RPATH=@OPENSSL_RPATH@

# Module state, compiler flags and linker flags
# Empty CFLAGS and LDFLAGS are omitted.
# states:
Expand Down Expand Up @@ -582,9 +576,10 @@ LIBEXPAT_HEADERS= \

# Default target
all: @DEF_MAKE_ALL_RULE@
build_all: check-clean-src $(BUILDPYTHON) platform oldsharedmods sharedmods \
gdbhooks Programs/_testembed scripts
build_wasm: check-clean-src $(BUILDPYTHON) platform oldsharedmods python-config
build_all: check-clean-src $(BUILDPYTHON) platform oldsharedmods \
gdbhooks Programs/_testembed scripts checksharedmods
build_wasm: check-clean-src $(BUILDPYTHON) platform oldsharedmods \
python-config checksharedmods

# Check that the source is clean when building out of source.
check-clean-src:
Expand Down Expand Up @@ -726,22 +721,6 @@ $(srcdir)/Modules/_blake2/blake2s_impl.c: $(srcdir)/Modules/_blake2/blake2b_impl
$(PYTHON_FOR_REGEN) $(srcdir)/Modules/_blake2/blake2b2s.py
$(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py -f $@

# Build the shared modules
# Under GNU make, MAKEFLAGS are sorted and normalized; the 's' for
# -s, --silent or --quiet is always the first char.
# Under BSD make, MAKEFLAGS might be " -s -v x=y".
# Ignore macros passed by GNU make, passed after --
sharedmods: $(PYTHON_FOR_BUILD_DEPS) pybuilddir.txt @LIBMPDEC_INTERNAL@ @LIBEXPAT_INTERNAL@
@case "`echo X $$MAKEFLAGS | sed 's/^X //;s/ -- .*//'`" in \
*\ -s*|s*) quiet="-q";; \
*) quiet="";; \
esac; \
echo "$(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \
$(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build"; \
$(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \
$(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build


# Build static library
$(LIBRARY): $(LIBRARY_OBJS)
-rm -f $@
Expand Down Expand Up @@ -832,10 +811,6 @@ python.worker.js: $(srcdir)/Tools/wasm/python.worker.js
# Build static libmpdec.a
LIBMPDEC_CFLAGS=@LIBMPDEC_CFLAGS@ $(PY_STDMODULE_CFLAGS) $(CCSHARED)

# for setup.py
DECIMAL_CFLAGS=@LIBMPDEC_CFLAGS@
DECIMAL_LDFLAGS=@LIBMPDEC_LDFLAGS@

# "%.o: %c" is not portable
Modules/_decimal/libmpdec/basearith.o: $(srcdir)/Modules/_decimal/libmpdec/basearith.c $(LIBMPDEC_HEADERS) $(PYTHON_HEADERS)
$(CC) -c $(LIBMPDEC_CFLAGS) -o $@ $(srcdir)/Modules/_decimal/libmpdec/basearith.c
Expand Down Expand Up @@ -890,10 +865,6 @@ $(LIBMPDEC_A): $(LIBMPDEC_OBJS)
# Build static libexpat.a
LIBEXPAT_CFLAGS=@LIBEXPAT_CFLAGS@ $(PY_STDMODULE_CFLAGS) $(CCSHARED)

# for setup.py
EXPAT_CFLAGS=@LIBEXPAT_CFLAGS@
EXPAT_LDFLAGS=@LIBEXPAT_LDFLAGS@

Modules/expat/xmlparse.o: $(srcdir)/Modules/expat/xmlparse.c $(LIBEXPAT_HEADERS) $(PYTHON_HEADERS)
$(CC) -c $(LIBEXPAT_CFLAGS) -o $@ $(srcdir)/Modules/expat/xmlparse.c

Expand All @@ -919,7 +890,8 @@ oldsharedmods: $(SHAREDMODS) pybuilddir.txt
fi; \
done

checksharedmods: oldsharedmods sharedmods $(PYTHON_FOR_BUILD_DEPS)
# dependency on BUILDPYTHON ensures that the target is run last
checksharedmods: oldsharedmods $(PYTHON_FOR_BUILD_DEPS) $(BUILDPYTHON)
@$(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/Tools/scripts/check_extension_modules.py

Modules/Setup.local:
Expand All @@ -942,7 +914,7 @@ Makefile Modules/config.c: Makefile.pre \
$(SHELL) $(MAKESETUP) -c $(srcdir)/Modules/config.c.in \
-s Modules \
Modules/Setup.local \
@MODULES_SETUP_STDLIB@ \
Modules/Setup.stdlib \
Modules/Setup.bootstrap \
$(srcdir)/Modules/Setup
@mv config.c Modules
Expand Down Expand Up @@ -1762,7 +1734,7 @@ altinstall: commoninstall

commoninstall: check-clean-src @FRAMEWORKALTINSTALLFIRST@ \
altbininstall libinstall inclinstall libainstall \
sharedinstall oldsharedinstall altmaninstall \
oldsharedinstall altmaninstall \
@FRAMEWORKALTINSTALLLAST@

# Install shared libraries enabled by Setup
Expand Down Expand Up @@ -2252,17 +2224,6 @@ libainstall: all scripts
else true; \
fi
A93C
# Install the dynamically loadable modules
# This goes into $(exec_prefix)
sharedinstall: all
$(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/setup.py install \
--prefix=$(prefix) \
--install-scripts=$(BINDIR) \
--install-platlib=$(DESTSHARED) \
--root=$(DESTDIR)/
-rm $(DESTDIR)$(DESTSHARED)/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py
-rm -r $(DESTDIR)$(DESTSHARED)/__pycache__

# Here are a couple of targets for MacOSX again, to install a full
# framework-based Python. frameworkinstall installs everything, the
# subtargets install specific parts. Much of the actual work is offloaded to
Expand Down Expand Up @@ -2536,10 +2497,10 @@ update-config:
Python/thread.o: @THREADHEADERS@ $(srcdir)/Python/condvar.h

# Declare targets that aren't real files
.PHONY: all build_all build_wasm sharedmods check-clean-src
.PHONY: all build_all build_wasm check-clean-src
.PHONY: oldsharedmods checksharedmods test quicktest
.PHONY: install altinstall oldsharedinstall bininstall altbininstall
.PHONY: maninstall libinstall inclinstall libainstall sharedinstall
.PHONY: maninstall libinstall inclinstall libainstall
.PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure
.PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools
.PHONY: frameworkaltinstallunixtools recheck clean clobber distclean
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
C extension modules are now built by ``configure`` and ``make``
instead of :mod:`distutils` and ``setup.py``.
2 changes: 1 addition & 1 deletion Modules/Setup
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ PYTHONPATH=$(COREPYTHONPATH)
#xx xxmodule.c
#xxlimited xxlimited.c
#xxlimited_35 xxlimited_35.c
xxsubtype xxsubtype.c # Required for the test suite to pass!
#xxsubtype xxsubtype.c

# Testing

Expand Down
1 change: 1 addition & 0 deletions Modules/Setup.stdlib.in
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@
############################################################################
# Test modules

@MODULE_XXSUBTYPE_TRUE@xxsubtype xxsubtype.c
@MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c
@MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c
@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c
Expand Down
1 change: 0 additions & 1 deletion Python/stdlib_module_names.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 3 additions & 8 deletions Tools/scripts/check_extension_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,11 @@ class ModuleChecker:
pybuilddir_txt = "pybuilddir.txt"

setup_files = (
SRC_DIR / "Modules/Setup",
# see end of configure.ac
"Modules/Setup.local",
"Modules/Setup.bootstrap",
"Modules/Setup.stdlib",
"Modules/Setup.bootstrap",
SRC_DIR / "Modules/Setup",
)

def __init__(self, cross_compiling: bool = False, strict: bool = False):
Expand Down Expand Up @@ -308,12 +309,6 @@ def get_sysconfig_modules(self) -> Iterable[ModuleInfo]:
MODBUILT_NAMES: modules in *static* block
MODSHARED_NAMES: modules in *shared* block
MODDISABLED_NAMES: modules in *disabled* block

Modules built by setup.py addext() have a MODULE_{modname}_STATE entry,
but are not listed in MODSHARED_NAMES.

Modules built by old-style setup.py add() have neither a MODULE_{modname}
entry nor an entry in MODSHARED_NAMES.
"""
moddisabled = set(sysconfig.get_config_var("MODDISABLED_NAMES").split())
if self.cross_compiling:
Expand Down
11 changes: 0 additions & 11 deletions Tools/scripts/generate_stdlib_module_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

SRC_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
STDLIB_PATH = os.path.join(SRC_DIR, 'Lib')
SETUP_PY = os.path.join(SRC_DIR, 'setup.py')

IGNORE = {
'__init__',
Expand Down Expand Up @@ -64,15 +63,6 @@ def list_packages(names):
names.add(name)


# Extension modules built by setup.py
def list_setup_extensions(names):
cmd = [sys.executable, SETUP_PY, "-q", "build", "--list-module-names"]
output = subprocess.check_output(cmd)
output = output.decode("utf8")
extensions = output.splitlines()
names |= set(extensions)


# Built-in and extension modules built by Modules/Setup*
# includes Windows and macOS extensions.
def list_modules_setup_extensions(names):
Expand Down Expand Up @@ -103,7 +93,6 @@ def list_frozen(names):
def list_modules():
names = set(sys.builtin_module_names)
list_modules_setup_extensions(names)
list_setup_extensions(names)
list_packages(names)
list_python_modules(names)
list_frozen(names)
Expand Down
4 changes: 2 additions & 2 deletions Tools/ssl/multissltests.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ def recompile_pymods(self):
env["LD_RUN_PATH"] = self.lib_dir

log.info("Rebuilding Python modules")
cmd = [sys.executable, os.path.join(PYTHONROOT, "setup.py"), "build"]
cmd = ["make", "oldsharedmods", "checksharedmods"]
self._subprocess_call(cmd, env=env)
self.check_imports()

Expand Down Expand Up @@ -472,7 +472,7 @@ def main():
start = datetime.now()

if args.steps in {'modules', 'tests'}:
for name in ['setup.py', 'Modules/_ssl.c']:
for name in ['Makefile.pre.in', 'Modules/_ssl.c']:
if not os.path.isfile(os.path.join(PYTHONROOT, name)):
parser.error(
"Must be executed from CPython build dir"
Expand Down
Loading
0