From 146fd754cadbfcaf062696067160792ca5a8fb18 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 11 May 2023 18:15:05 -0400 Subject: [PATCH] fix: ninja wasn't being used if present (#310) Also adds a way to test downstream packages manually. --------- Signed-off-by: Henry Schreiner --- .../getting_started/fortran/CMakeLists.txt | 2 +- .../getting_started/fortran/pyproject.toml | 4 ++ noxfile.py | 72 +++++++++++++++++++ pyproject.toml | 2 +- src/scikit_build_core/build/wheel.py | 4 +- src/scikit_build_core/builder/generator.py | 6 +- tests/packages/fortran_example/CMakeLists.txt | 2 +- tests/test_fortran.py | 16 +++++ 8 files changed, 103 insertions(+), 5 deletions(-) diff --git a/docs/examples/getting_started/fortran/CMakeLists.txt b/docs/examples/getting_started/fortran/CMakeLists.txt index 237e94af..caadb140 100644 --- a/docs/examples/getting_started/fortran/CMakeLists.txt +++ b/docs/examples/getting_started/fortran/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.15...3.26) +cmake_minimum_required(VERSION 3.17.2...3.26) project(${SKBUILD_PROJECT_NAME} LANGUAGES C Fortran) find_package( diff --git a/docs/examples/getting_started/fortran/pyproject.toml b/docs/examples/getting_started/fortran/pyproject.toml index e0f74782..cf998e51 100644 --- a/docs/examples/getting_started/fortran/pyproject.toml +++ b/docs/examples/getting_started/fortran/pyproject.toml @@ -6,3 +6,7 @@ build-backend = "scikit_build_core.build" name = "example" version = "0.0.1" dependencies = ["numpy"] + +[tool.scikit-build] +ninja.minimum-version = "1.10" +cmake.minimum-version = "3.17.2" diff --git a/noxfile.py b/noxfile.py index 84ba56f5..cc848625 100644 --- a/noxfile.py +++ b/noxfile.py @@ -114,3 +114,75 @@ def test_doc_examples(session: nox.Session, example: str) -> None: session.chdir(f"docs/examples/getting_started/{example}") session.install(".", "--config-settings=cmake.verbose=true") session.run("python", "../test.py") + + +@nox.session(reuse_venv=True) +def downstream(session: nox.Session) -> None: + """ + Build a downstream project. + """ + + # If running in manylinux: + # docker run --rm -v $PWD:/sk -w /sk -t quay.io/pypa/manylinux2014_x86_64:latest \ + # pipx run --system-site-packages nox -s downstream -- https://github.com/... + # (requires tomli, so allowing access to system-site-packages) + + if sys.version_info < (3, 11): + import tomli as tomllib + else: + import tomllib + + parser = argparse.ArgumentParser() + parser.add_argument("project", help="A project to build") + parser.add_argument("--subdir", help="A subdirectory to build") + args, remaining = parser.parse_known_args(session.posargs) + + tmp_dir = Path(session.create_tmp()) + proj_dir = tmp_dir / "_".join(args.project.split("/")) + + session.install("build", "hatch-vcs", "hatchling") + session.install(".[pyproject]", "--no-build-isolation") + + if proj_dir.is_dir(): + session.chdir(proj_dir) + session.run("git", "pull", external=True) + else: + session.run( + "git", + "clone", + args.project, + *remaining, + proj_dir, + "--recurse-submodules", + external=True, + ) + session.chdir(proj_dir) + + # Read and strip requirements + pyproject_toml = Path("pyproject.toml") + with pyproject_toml.open("rb") as f: + pyproject = tomllib.load(f) + requires = [ + x + for x in pyproject["build-system"]["requires"] + if "scikit-build-core" not in x.replace("_", "-") + ] + if not shutil.which("ninja"): + requires.append("ninja") + if not shutil.which("cmake"): + requires.append("cmake") + if requires: + session.install(*requires) + + if args.subdir: + session.chdir(args.subdir) + + session.run( + "python", + "-m", + "build", + "--no-isolation", + "--skip-dependency-check", + "--wheel", + ".", + ) diff --git a/pyproject.toml b/pyproject.toml index 922910df..15d29405 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -237,7 +237,7 @@ exclude = [] [tool.ruff.per-file-ignores] "tests/**" = ["T20"] -"noxfile.py" = ["T20"] +"noxfile.py" = ["T20", "TID251"] "src/scikit_build_core/resources/*.py" = ["PTH", "ARG002"] "src/scikit_build_core/_compat/**.py" = ["TID251"] "tests/conftest.py" = ["TID251"] diff --git a/src/scikit_build_core/build/wheel.py b/src/scikit_build_core/build/wheel.py index a373f7d5..7138becb 100644 --- a/src/scikit_build_core/build/wheel.py +++ b/src/scikit_build_core/build/wheel.py @@ -182,7 +182,9 @@ def _build_wheel_impl( generator = builder.config.env.get( "CMAKE_GENERATOR", - "MSVC" if sysconfig.get_platform().startswith("win") else "Unknown", + "MSVC" + if sysconfig.get_platform().startswith("win") + else "Default generator", ) rich_print( f"[green]***[/green] [bold]Building project with [blue]{generator}[/blue]..." diff --git a/src/scikit_build_core/builder/generator.py b/src/scikit_build_core/builder/generator.py index 95e525f0..0424ba8a 100644 --- a/src/scikit_build_core/builder/generator.py +++ b/src/scikit_build_core/builder/generator.py @@ -80,7 +80,11 @@ def set_environment_for_gen( "win" ): # Non-MSVC Windows platforms require Ninja - env.setdefault("CMAKE_GENERATOR", "Ninja") + default = "Ninja" + + # Try Ninja if it is available, even if make is CMake default + if default == "Unix Makefiles": + default = "Ninja" if env.get("CMAKE_GENERATOR", default or "Ninja") == "Ninja": min_ninja = Version(ninja_settings.minimum_version) diff --git a/tests/packages/fortran_example/CMakeLists.txt b/tests/packages/fortran_example/CMakeLists.txt index 12817014..62ba67bd 100644 --- a/tests/packages/fortran_example/CMakeLists.txt +++ b/tests/packages/fortran_example/CMakeLists.txt @@ -1,5 +1,5 @@ # setup project ### -cmake_minimum_required(VERSION 3.15...3.24) +cmake_minimum_required(VERSION 3.17.2...3.24) project( fibby diff --git a/tests/test_fortran.py b/tests/test_fortran.py index 122ec63f..aee88825 100644 --- a/tests/test_fortran.py +++ b/tests/test_fortran.py @@ -5,8 +5,14 @@ from pathlib import Path import pytest +from packaging.version import Version from scikit_build_core.build import build_wheel +from scikit_build_core.program_search import ( + best_program, + get_cmake_programs, + get_ninja_programs, +) np = pytest.importorskip("numpy") @@ -14,6 +20,10 @@ FORTRAN_EXAMPLE = DIR / "packages/fortran_example" +cmake_info = best_program(get_cmake_programs(), minimum_version=Version("3.17.2")) +ninja_info = best_program(get_ninja_programs(), minimum_version=Version("1.10")) + + @pytest.mark.compile() @pytest.mark.configure() @pytest.mark.fortran() @@ -22,6 +32,12 @@ sysconfig.get_platform().startswith("win"), reason="No reasonable Fortran compiler for MSVC", ) +@pytest.mark.skipif( + cmake_info is None, reason="CMake needs to be 3.17.2+ to support Fortran with Ninja" +) +@pytest.mark.skipif( + ninja_info is None, reason="Ninja needs to be 1.10+ to support Fortran with CMake" +) def test_pep517_wheel(tmp_path, monkeypatch, virtualenv): dist = tmp_path / "dist" dist.mkdir()