diff --git a/.ci/aarch64_linux/aarch64_wheel_ci_build.py b/.ci/aarch64_linux/aarch64_wheel_ci_build.py index d4afea81ac0b..51578fbfb775 100755 --- a/.ci/aarch64_linux/aarch64_wheel_ci_build.py +++ b/.ci/aarch64_linux/aarch64_wheel_ci_build.py @@ -372,7 +372,7 @@ if __name__ == "__main__": else: print("build pytorch without mkldnn backend") - os.system(f"cd /pytorch; {build_vars} python3 setup.py bdist_wheel") + os.system(f"cd /pytorch; {build_vars} python3 -m build --wheel --no-isolation") if enable_cuda: print("Updating Cuda Dependency") filename = os.listdir("/pytorch/dist/") diff --git a/.ci/aarch64_linux/build_aarch64_wheel.py b/.ci/aarch64_linux/build_aarch64_wheel.py index 52525f14460d..37fc488c5b3c 100755 --- a/.ci/aarch64_linux/build_aarch64_wheel.py +++ b/.ci/aarch64_linux/build_aarch64_wheel.py @@ -442,7 +442,7 @@ def build_torchvision( if host.using_docker(): build_vars += " CMAKE_SHARED_LINKER_FLAGS=-Wl,-z,max-page-size=0x10000" - host.run_cmd(f"cd vision && {build_vars} python3 setup.py bdist_wheel") + host.run_cmd(f"cd vision && {build_vars} python3 -m build --wheel --no-isolation") vision_wheel_name = host.list_dir("vision/dist")[0] embed_libgomp(host, use_conda, os.path.join("vision", "dist", vision_wheel_name)) @@ -497,7 +497,7 @@ def build_torchdata( if host.using_docker(): build_vars += " CMAKE_SHARED_LINKER_FLAGS=-Wl,-z,max-page-size=0x10000" - host.run_cmd(f"cd data && {build_vars} python3 setup.py bdist_wheel") + host.run_cmd(f"cd data && {build_vars} python3 -m build --wheel --no-isolation") wheel_name = host.list_dir("data/dist")[0] embed_libgomp(host, use_conda, os.path.join("data", "dist", wheel_name)) @@ -553,7 +553,7 @@ def build_torchtext( if host.using_docker(): build_vars += " CMAKE_SHARED_LINKER_FLAGS=-Wl,-z,max-page-size=0x10000" - host.run_cmd(f"cd text && {build_vars} python3 setup.py bdist_wheel") + host.run_cmd(f"cd text && {build_vars} python3 -m build --wheel --no-isolation") wheel_name = host.list_dir("text/dist")[0] embed_libgomp(host, use_conda, os.path.join("text", "dist", wheel_name)) @@ -614,7 +614,7 @@ def build_torchaudio( host.run_cmd( f"cd audio && export FFMPEG_ROOT=$(pwd)/third_party/ffmpeg && export USE_FFMPEG=1 \ && ./packaging/ffmpeg/build.sh \ - && {build_vars} python3 setup.py bdist_wheel" + && {build_vars} python3 -m build --wheel --no-isolation" ) wheel_name = host.list_dir("audio/dist")[0] @@ -726,7 +726,7 @@ def start_build( print("Building PyTorch wheel") build_opts = "" if pytorch_build_number is not None: - build_opts += f" --build-number {pytorch_build_number}" + build_opts += f" -C--build-option=--build-number={pytorch_build_number}" # Breakpad build fails on aarch64 build_vars = "USE_BREAKPAD=0 " if branch == "nightly": @@ -747,7 +747,8 @@ def start_build( print("build pytorch with mkldnn+acl backend") build_vars += " USE_MKLDNN=ON USE_MKLDNN_ACL=ON" host.run_cmd( - f"cd $HOME/pytorch && export ACL_ROOT_DIR=$HOME/ComputeLibrary && {build_vars} python3 setup.py bdist_wheel{build_opts}" + f"cd $HOME/pytorch && export ACL_ROOT_DIR=$HOME/ComputeLibrary && " + f"{build_vars} python3 -m build --wheel --no-isolation{build_opts}" ) print("Repair the wheel") pytorch_wheel_name = host.list_dir("pytorch/dist")[0] @@ -763,7 +764,7 @@ def start_build( else: print("build pytorch without mkldnn backend") host.run_cmd( - f"cd pytorch && {build_vars} python3 setup.py bdist_wheel{build_opts}" + f"cd pytorch && {build_vars} python3 -m build --wheel --no-isolation{build_opts}" ) print("Deleting build folder") diff --git a/.ci/docker/build.sh b/.ci/docker/build.sh index 8672fae2bbdd..db5ef3ff3e03 100755 --- a/.ci/docker/build.sh +++ b/.ci/docker/build.sh @@ -452,12 +452,3 @@ elif [ "$HAS_TRITON" = "yes" ]; then echo "expecting triton to not be installed, but it is" exit 1 fi - -# Sanity check cmake version. Executorch reinstalls cmake and I'm not sure if -# they support 4.0.0 yet, so exclude them from this check. -CMAKE_VERSION=$(drun cmake --version) -if [[ "$EXECUTORCH" != *yes* && "$CMAKE_VERSION" != *4.* ]]; then - echo "CMake version is not 4.0.0:" - drun cmake --version - exit 1 -fi diff --git a/.ci/docker/common/install_triton.sh b/.ci/docker/common/install_triton.sh index f48140952c3a..1b68e3c24783 100755 --- a/.ci/docker/common/install_triton.sh +++ b/.ci/docker/common/install_triton.sh @@ -66,15 +66,15 @@ if [ -n "${UBUNTU_VERSION}" ] && [ -n "${GCC_VERSION}" ] && [[ "${GCC_VERSION}" # Triton needs at least gcc-9 to build apt-get install -y g++-9 - CXX=g++-9 conda_run python setup.py bdist_wheel + CXX=g++-9 conda_run python -m build --wheel --no-isolation elif [ -n "${UBUNTU_VERSION}" ] && [ -n "${CLANG_VERSION}" ]; then # Triton needs which surprisingly is not available with clang-9 toolchain add-apt-repository -y ppa:ubuntu-toolchain-r/test apt-get install -y g++-9 - CXX=g++-9 conda_run python setup.py bdist_wheel + CXX=g++-9 conda_run python -m build --wheel --no-isolation else - conda_run python setup.py bdist_wheel + conda_run python -m build --wheel --no-isolation fi # Copy the wheel to /opt for multi stage docker builds diff --git a/.ci/docker/requirements-ci.txt b/.ci/docker/requirements-ci.txt index a0aed290a210..0504d9e76e1b 100644 --- a/.ci/docker/requirements-ci.txt +++ b/.ci/docker/requirements-ci.txt @@ -10,6 +10,11 @@ boto3==1.35.42 #Pinned versions: 1.19.12, 1.16.34 #test that import: +build==1.3.0 +#Description: A simple, correct Python build frontend. +#Pinned versions: 1.3.0 +#test that import: + click #Description: Command Line Interface Creation Kit #Pinned versions: @@ -106,10 +111,10 @@ networkx==2.8.8 #Pinned versions: 2.8.8 #test that import: functorch -ninja==1.11.1.3 +ninja==1.11.1.4 #Description: build system. Used in some tests. Used in build to generate build #time tracing information -#Pinned versions: 1.11.1.3 +#Pinned versions: 1.11.1.4 #test that import: run_test.py, test_cpp_extensions_aot.py,test_determination.py numba==0.55.2 ; python_version == "3.10" and platform_machine != "s390x" @@ -373,7 +378,7 @@ dataclasses_json==0.6.7 #Pinned versions: 0.6.7 #test that import: -cmake==4.0.0 +cmake==3.31.6 #Description: required for building tlparse==0.4.0 diff --git a/.ci/manywheel/build_common.sh b/.ci/manywheel/build_common.sh index 4c268befb30e..b84268fd1289 100644 --- a/.ci/manywheel/build_common.sh +++ b/.ci/manywheel/build_common.sh @@ -142,7 +142,7 @@ time CMAKE_ARGS=${CMAKE_ARGS[@]} \ EXTRA_CAFFE2_CMAKE_FLAGS=${EXTRA_CAFFE2_CMAKE_FLAGS[@]} \ BUILD_LIBTORCH_CPU_WITH_DEBUG=$BUILD_DEBUG_INFO \ USE_NCCL=${USE_NCCL} USE_RCCL=${USE_RCCL} USE_KINETO=${USE_KINETO} \ - python setup.py bdist_wheel -d /tmp/$WHEELHOUSE_DIR + python -m build --wheel --no-isolation --outdir /tmp/$WHEELHOUSE_DIR echo "Finished setup.py bdist at $(date)" # Build libtorch packages diff --git a/.ci/pytorch/build.sh b/.ci/pytorch/build.sh index 1c88554c2af9..c08d9fce9039 100755 --- a/.ci/pytorch/build.sh +++ b/.ci/pytorch/build.sh @@ -290,13 +290,13 @@ else WERROR=1 python setup.py clean - WERROR=1 python setup.py bdist_wheel + WERROR=1 python -m build --wheel --no-isolation else python setup.py clean if [[ "$BUILD_ENVIRONMENT" == *xla* ]]; then source .ci/pytorch/install_cache_xla.sh fi - python setup.py bdist_wheel + python -m build --wheel --no-isolation fi pip_install_whl "$(echo dist/*.whl)" diff --git a/.ci/pytorch/macos-build.sh b/.ci/pytorch/macos-build.sh index d7447e7d4858..c01efda11ea6 100755 --- a/.ci/pytorch/macos-build.sh +++ b/.ci/pytorch/macos-build.sh @@ -36,11 +36,11 @@ fi print_cmake_info if [[ ${BUILD_ENVIRONMENT} == *"distributed"* ]]; then # Needed for inductor benchmarks, as lots of HF networks make `torch.distribtued` calls - USE_DISTRIBUTED=1 USE_OPENMP=1 WERROR=1 python setup.py bdist_wheel + USE_DISTRIBUTED=1 USE_OPENMP=1 WERROR=1 python -m build --wheel --no-isolation else # Explicitly set USE_DISTRIBUTED=0 to align with the default build config on mac. This also serves as the sole CI config that tests # that building with USE_DISTRIBUTED=0 works at all. See https://github.com/pytorch/pytorch/issues/86448 - USE_DISTRIBUTED=0 USE_OPENMP=1 MACOSX_DEPLOYMENT_TARGET=11.0 WERROR=1 BUILD_TEST=OFF USE_PYTORCH_METAL=1 python setup.py bdist_wheel --plat-name macosx_11_0_arm64 + USE_DISTRIBUTED=0 USE_OPENMP=1 MACOSX_DEPLOYMENT_TARGET=11.0 WERROR=1 BUILD_TEST=OFF USE_PYTORCH_METAL=1 python -m build --wheel --no-isolation -C--build-option=--plat-name=macosx_11_0_arm64 fi if which sccache > /dev/null; then print_sccache_stats diff --git a/.ci/pytorch/test.sh b/.ci/pytorch/test.sh index 316eea7c073e..2dec0ce0d50f 100755 --- a/.ci/pytorch/test.sh +++ b/.ci/pytorch/test.sh @@ -1415,7 +1415,7 @@ EOF pip3 install -r requirements.txt # shellcheck source=./common-build.sh source "$(dirname "${BASH_SOURCE[0]}")/common-build.sh" - python setup.py bdist_wheel --bdist-dir="base_bdist_tmp" --dist-dir="base_dist" + python -m build --wheel --no-isolation -C--build-option=--bdist-dir="base_bdist_tmp" --outdir "base_dist" python -mpip install base_dist/*.whl echo "::endgroup::" diff --git a/.ci/pytorch/win-test-helpers/arm64/build_pytorch.ps1 b/.ci/pytorch/win-test-helpers/arm64/build_pytorch.ps1 index 29b3e913439c..a165f2a222ca 100644 --- a/.ci/pytorch/win-test-helpers/arm64/build_pytorch.ps1 +++ b/.ci/pytorch/win-test-helpers/arm64/build_pytorch.ps1 @@ -70,7 +70,7 @@ sccache --zero-stats sccache --show-stats # Build the wheel -python setup.py bdist_wheel +python -m build --wheel --no-build-isolation if ($LASTEXITCODE -ne 0) { exit 1 } # Install the wheel locally diff --git a/.ci/pytorch/win-test-helpers/build_pytorch.bat b/.ci/pytorch/win-test-helpers/build_pytorch.bat index 67d156922192..427566ff7823 100644 --- a/.ci/pytorch/win-test-helpers/build_pytorch.bat +++ b/.ci/pytorch/win-test-helpers/build_pytorch.bat @@ -130,7 +130,7 @@ if "%USE_CUDA%"=="1" ( :: Print all existing environment variable for debugging set -python setup.py bdist_wheel +python -m build --wheel --no-isolation if errorlevel 1 goto fail if not errorlevel 0 goto fail sccache --show-stats diff --git a/.ci/pytorch/windows/arm64/build_pytorch.bat b/.ci/pytorch/windows/arm64/build_pytorch.bat index 3363a2d08846..b5c2ef65b84a 100644 --- a/.ci/pytorch/windows/arm64/build_pytorch.bat +++ b/.ci/pytorch/windows/arm64/build_pytorch.bat @@ -48,7 +48,7 @@ sccache --zero-stats sccache --show-stats :: Call PyTorch build script -python setup.py bdist_wheel -d "%PYTORCH_FINAL_PACKAGE_DIR%" +python -m build --wheel --no-isolation --outdir "%PYTORCH_FINAL_PACKAGE_DIR%" :: show sccache stats sccache --show-stats diff --git a/.ci/pytorch/windows/internal/install_python.bat b/.ci/pytorch/windows/internal/install_python.bat index 84d0f9caccef..86626e15fbc4 100644 --- a/.ci/pytorch/windows/internal/install_python.bat +++ b/.ci/pytorch/windows/internal/install_python.bat @@ -28,5 +28,5 @@ start /wait "" python-amd64.exe /quiet InstallAllUsers=1 PrependPath=0 Include_t if errorlevel 1 exit /b 1 set "PATH=%CD%\Python\Scripts;%CD%\Python;%PATH%" -%PYTHON_EXEC% -m pip install --upgrade pip setuptools packaging wheel +%PYTHON_EXEC% -m pip install --upgrade pip setuptools packaging wheel build if errorlevel 1 exit /b 1 diff --git a/.ci/pytorch/windows/internal/setup.bat b/.ci/pytorch/windows/internal/setup.bat index 71056540464c..34a5140cb1ee 100644 --- a/.ci/pytorch/windows/internal/setup.bat +++ b/.ci/pytorch/windows/internal/setup.bat @@ -86,7 +86,7 @@ copy /Y "%LIBTORCH_PREFIX%-%PYTORCH_BUILD_VERSION%.zip" "%PYTORCH_FINAL_PACKAGE_ goto build_end :pytorch -%PYTHON_EXEC% setup.py bdist_wheel -d "%PYTORCH_FINAL_PACKAGE_DIR%" +%PYTHON_EXEC% -m build --wheel --no-isolation --outdir "%PYTORCH_FINAL_PACKAGE_DIR%" :build_end IF ERRORLEVEL 1 exit /b 1 diff --git a/.ci/pytorch/windows/setup_build.bat b/.ci/pytorch/windows/setup_build.bat index dbdc9891324c..a7addd5d712d 100644 --- a/.ci/pytorch/windows/setup_build.bat +++ b/.ci/pytorch/windows/setup_build.bat @@ -18,7 +18,7 @@ if "%DESIRED_PYTHON%" == "3.9" %PYTHON_EXEC% -m pip install numpy==2.0.2 cmake %PYTHON_EXEC% -m pip install pyyaml %PYTHON_EXEC% -m pip install mkl-include mkl-static -%PYTHON_EXEC% -m pip install boto3 ninja typing_extensions setuptools==72.1.0 +%PYTHON_EXEC% -m pip install boto3 requests ninja typing_extensions setuptools==72.1.0 where cmake.exe diff --git a/.ci/wheel/build_wheel.sh b/.ci/wheel/build_wheel.sh index 2d5f4d30b4c8..6123e8abc8c0 100755 --- a/.ci/wheel/build_wheel.sh +++ b/.ci/wheel/build_wheel.sh @@ -143,7 +143,8 @@ case $desired_python in RENAME_WHEEL=false ;; 3.13t) - echo "Using 3.13 deps" + echo "Using 3.13t deps" + mac_version='macosx-11.0-arm64' NUMPY_PINNED_VERSION="==2.1.0" RENAME_WHEEL=false ;; @@ -185,11 +186,11 @@ export USE_QNNPACK=OFF export BUILD_TEST=OFF pushd "$pytorch_rootdir" -echo "Calling setup.py bdist_wheel at $(date)" +echo "Calling -m build --wheel --no-isolation at $(date)" -_PYTHON_HOST_PLATFORM=${mac_version} ARCHFLAGS="-arch arm64" python setup.py bdist_wheel -d "$whl_tmp_dir" --plat-name "${mac_version//[-.]/_}" +_PYTHON_HOST_PLATFORM=${mac_version} ARCHFLAGS="-arch arm64" python -m build --wheel --no-isolation --outdir "$whl_tmp_dir" -C--plat-name="${mac_version//[-.]/_}" -echo "Finished setup.py bdist_wheel at $(date)" +echo "Finished -m build --wheel --no-isolation at $(date)" if [[ $package_type != 'libtorch' ]]; then echo "delocating wheel dependencies" diff --git a/.github/requirements/pip-requirements-macOS.txt b/.github/requirements/pip-requirements-macOS.txt index 5fc26302a0ad..ef27f2ea20b4 100644 --- a/.github/requirements/pip-requirements-macOS.txt +++ b/.github/requirements/pip-requirements-macOS.txt @@ -1,4 +1,5 @@ boto3==1.35.42 +build==1.2.2.post1 cmake==3.27.* expecttest==0.3.0 fbscribelogger==0.1.7 diff --git a/pyproject.toml b/pyproject.toml index 69ece31e0a98..46fbdda22b70 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ requires = [ # 70.1.0: min version for integrated bdist_wheel command from wheel package # 77.0.0: min version for SPDX expression support for project.license - "setuptools>=70.1.0,<80.0", + "setuptools>=70.1.0", "cmake>=3.27", "ninja", "numpy", diff --git a/requirements-build.txt b/requirements-build.txt index 2009ddb658ed..85923ae39cbd 100644 --- a/requirements-build.txt +++ b/requirements-build.txt @@ -1,5 +1,5 @@ # Build System requirements -setuptools>=70.1.0,<80.0 # setuptools develop deprecated on 80.0 +setuptools>=70.1.0 cmake>=3.27 ninja numpy diff --git a/test/cpp_extensions/python_agnostic_extension/test/test_python_agnostic.py b/test/cpp_extensions/python_agnostic_extension/test/test_python_agnostic.py index 58a8dafb305a..95ca8638ab92 100644 --- a/test/cpp_extensions/python_agnostic_extension/test/test_python_agnostic.py +++ b/test/cpp_extensions/python_agnostic_extension/test/test_python_agnostic.py @@ -28,7 +28,7 @@ class TestPythonAgnostic(TestCase): shutil.rmtree(cls.dist_dir) # Build the wheel - wheel_cmd = [sys.executable, "setup.py", "bdist_wheel"] + wheel_cmd = [sys.executable, "-m", "build", "--wheel", "--no-isolation"] return_code = shell(wheel_cmd, cwd=cls.extension_root, env=os.environ) if return_code != 0: raise RuntimeError("python_agnostic bdist_wheel failed to build") @@ -39,7 +39,7 @@ class TestPythonAgnostic(TestCase): ) @unittest.skipIf(not IS_LINUX, "test requires linux tools ldd and nm") def test_extension_is_python_agnostic(self, device): - # For this test, run_test.py will call `python setup.py bdist_wheel` in the + # For this test, run_test.py will call `python -m build --wheel --no-isolation` in the # cpp_extensions/python_agnostic_extension folder, where the extension and # setup calls specify py_limited_api to `True`. To approximate that the # extension is indeed python agnostic, we test diff --git a/test/run_test.py b/test/run_test.py index e2dece333891..d8bd65c4e95c 100755 --- a/test/run_test.py +++ b/test/run_test.py @@ -837,7 +837,7 @@ def _test_cpp_extensions_aot(test_directory, options, use_ninja): "--root", "./install", ] - wheel_cmd = [sys.executable, "-m", "pip", "wheel", ".", "-w", "./dist"] + wheel_cmd = [sys.executable, "-m", "build", "--wheel", "--no-isolation"] return_code = shell(install_cmd, cwd=cpp_extensions_test_dir, env=shell_env) if return_code != 0: return return_code diff --git a/tools/packaging/build_wheel.py b/tools/packaging/build_wheel.py index 10c4516a3280..dad2d8084967 100644 --- a/tools/packaging/build_wheel.py +++ b/tools/packaging/build_wheel.py @@ -20,7 +20,6 @@ logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) ROOT_PATH = Path(__file__).absolute().parent.parent.parent -SETUP_PY_PATH = ROOT_PATH / "setup.py" REQUIREMENTS_PATH = ROOT_PATH / "requirements.txt" PYPROJECT_TOML_PATH = ROOT_PATH / "pyproject.toml" @@ -143,18 +142,27 @@ class Builder: def __init__(self, interpreter: str) -> None: self.interpreter = interpreter - def setup_py(self, cmd_args: list[str]) -> bool: - return ( - run_cmd([self.interpreter, str(SETUP_PY_PATH), *cmd_args]).returncode == 0 - ) - - def bdist_wheel(self, destination: str) -> bool: + def build_wheel(self, destination: str) -> bool: logger.info("Running bdist_wheel -d %s", destination) - return self.setup_py(["bdist_wheel", "-d", destination]) + return ( + run_cmd( + [ + self.interpreter, + "-m", + "build", + "--wheel", + "--no-isolation", + "--outdir", + destination, + str(ROOT_PATH), + ] + ).returncode + == 0 + ) def clean(self) -> bool: logger.info("Running clean") - return self.setup_py(["clean"]) + return run_cmd([self.interpreter, "setup.py", "clean"]).returncode == 0 def install_requirements(self) -> None: logger.info("Installing requirements") @@ -234,7 +242,7 @@ def main() -> None: start_time = time.time() - builder.bdist_wheel(args.destination) + builder.build_wheel(args.destination) end_time = time.time()