From 6b122ef8102717f869ed925d1777b48221ddc67e Mon Sep 17 00:00:00 2001 From: Tim Paine <3105306+timkpaine@users.noreply.github.com> Date: Thu, 9 Jan 2025 19:37:09 -0500 Subject: [PATCH 1/3] Expand CI, enable windows testing --- .copier-answers.yml | 2 +- .github/workflows/build.yml | 18 +++++++++++++----- Makefile | 2 +- hatch_cpp/plugin.py | 7 +++++-- hatch_cpp/structs.py | 7 ++----- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/.copier-answers.yml b/.copier-answers.yml index 3e3d361..f3bd003 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,6 +1,6 @@ # Changes here will be overwritten by Copier _commit: 81e8acd -_src_path: git@github.com:python-project-templates/base.git +_src_path: https://github.com/python-project-templates/base.git add_extension: python email: t.paine154@gmail.com github: python-project-templates diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d9a8ac7..b5df3cb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,8 +29,8 @@ jobs: strategy: matrix: - os: [ubuntu-latest, macos-latest] - python-version: ["3.9"] + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v4 @@ -56,7 +56,15 @@ jobs: - name: Test run: make coverage - + if: matrix.os != 'windows-latest' + + - name: Test + run: | + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + make coverage + shell: cmd + if: matrix.os == 'windows-latest' + - name: Upload test results (Python) uses: actions/upload-artifact@v4 with: @@ -68,7 +76,7 @@ jobs: uses: EnricoMi/publish-unit-test-result-action@v2 with: files: '**/junit.xml' - if: matrix.os == 'ubuntu-latest' + if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.9' - name: Upload coverage uses: codecov/codecov-action@v5 @@ -82,4 +90,4 @@ jobs: with: name: dist-${{matrix.os}} path: dist - if: matrix.os == 'ubuntu-latest' + if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.9' diff --git a/Makefile b/Makefile index 627b57c..1473fb6 100644 --- a/Makefile +++ b/Makefile @@ -99,7 +99,7 @@ deep-clean: ## clean everything from the repository git clean -fdx clean: ## clean the repository - rm -rf .coverage coverage cover htmlcov logs build dist *.egg-info + rm -rf .coverage coverage cover htmlcov logs build dist *.egg-info hatch_cpp/tests/*/dist hatch_cpp/tests/*/build hatch_cpp/tests/*/*/*.so hatch_cpp/tests/*/*/*.pyd ############################################################################################ diff --git a/hatch_cpp/plugin.py b/hatch_cpp/plugin.py index fb88301..0ce6f53 100644 --- a/hatch_cpp/plugin.py +++ b/hatch_cpp/plugin.py @@ -43,10 +43,13 @@ def initialize(self, version: str, _: dict[str, t.Any]) -> None: libraries = [HatchCppLibrary(**library_kwargs) for library_kwargs in library_kwargs] platform = HatchCppPlatform.default() if config.toolchain == "raw": - # g++ basic-project/basic.cpp -I. -I/opt/homebrew/opt/python@3.11/Frameworks/Python.framework/Versions/3.11/include/python3.11/ -undefined dynamic_lookup -fPIC -shared -o extension.so build_plan = HatchCppBuildPlan(libraries=libraries, platform=platform) build_plan.generate() - build_plan.execute(verbose=config.verbose) + if config.verbose: + for command in build_plan.commands: + self._logger.info(command) + build_plan.execute() + # build_kwargs = config.build_kwargs # if version == "editable": # build_kwargs = config.editable_build_kwargs or build_kwargs diff --git a/hatch_cpp/structs.py b/hatch_cpp/structs.py index ccfab16..0412aef 100644 --- a/hatch_cpp/structs.py +++ b/hatch_cpp/structs.py @@ -117,8 +117,7 @@ def get_flags(self, library: HatchCppLibrary) -> str: flags += " " + " ".join(f"/LIBPATH:{lib}" for lib in library.library_dirs) flags += " " + " ".join(f"/D{macro}" for macro in library.define_macros) flags += " " + " ".join(f"/U{macro}" for macro in library.undef_macros) - flags += f" /Fo{library.name}.obj" - flags += f" /Fe{library.name}.pyd" + flags += f" /Fo{library.name}.pyd" # clean while flags.count(" "): flags = flags.replace(" ", " ") @@ -138,9 +137,7 @@ def generate(self): self.commands.append(f"{self.platform.cc} {' '.join(library.sources)} {flags}") return self.commands - def execute(self, verbose: bool = True): + def execute(self): for command in self.commands: - if verbose: - print(f"Running command: {command}") system(command) return self.commands From b7cbb9905816a5528faf51312d44965a5887a05b Mon Sep 17 00:00:00 2001 From: Tim Paine <3105306+timkpaine@users.noreply.github.com> Date: Thu, 9 Jan 2025 22:45:01 -0500 Subject: [PATCH 2/3] Test importing built library --- .gitignore | 5 +++++ hatch_cpp/plugin.py | 1 + hatch_cpp/structs.py | 30 ++++++++++++++++++++------- hatch_cpp/tests/test_project_basic.py | 8 ++++++- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index a090202..858d10c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,12 @@ __pycache__/ *$py.class # C extensions +*.a *.so +*.obj +*.dll +*.exp +*.lib # Distribution / packaging .Python diff --git a/hatch_cpp/plugin.py b/hatch_cpp/plugin.py index 0ce6f53..0de620f 100644 --- a/hatch_cpp/plugin.py +++ b/hatch_cpp/plugin.py @@ -49,6 +49,7 @@ def initialize(self, version: str, _: dict[str, t.Any]) -> None: for command in build_plan.commands: self._logger.info(command) build_plan.execute() + build_plan.cleanup() # build_kwargs = config.build_kwargs # if version == "editable": diff --git a/hatch_cpp/structs.py b/hatch_cpp/structs.py index 0412aef..cc9c99c 100644 --- a/hatch_cpp/structs.py +++ b/hatch_cpp/structs.py @@ -2,7 +2,8 @@ from dataclasses import dataclass, field from os import environ, system -from sys import platform as sys_platform +from pathlib import Path +from sys import executable, platform as sys_platform from sysconfig import get_path from typing import Literal @@ -80,7 +81,7 @@ def default() -> HatchCppPlatform: raise Exception(f"Unrecognized toolchain: {CC}, {CXX}") return HatchCppPlatform(cc=CC, cxx=CXX, platform=platform, toolchain=toolchain) - def get_flags(self, library: HatchCppLibrary) -> str: + def get_compile_flags(self, library: HatchCppLibrary) -> str: flags = "" if self.toolchain == "gcc": flags = f"-I{get_path('include')}" @@ -109,20 +110,28 @@ def get_flags(self, library: HatchCppLibrary) -> str: elif self.toolchain == "msvc": flags = f"/I{get_path('include')} " flags += " ".join(f"/I{d}" for d in library.include_dirs) - flags += " /LD" flags += " " + " ".join(library.extra_compile_args) flags += " " + " ".join(library.extra_link_args) flags += " " + " ".join(library.extra_objects) - flags += " " + " ".join(f"{lib}.lib" for lib in library.libraries) - flags += " " + " ".join(f"/LIBPATH:{lib}" for lib in library.library_dirs) flags += " " + " ".join(f"/D{macro}" for macro in library.define_macros) flags += " " + " ".join(f"/U{macro}" for macro in library.undef_macros) - flags += f" /Fo{library.name}.pyd" + flags += " /EHsc /DWIN32 /LD" + flags += f" /Fo:{library.name}.obj" + flags += f" /Fe:{library.name}.pyd" + flags += " /link /DLL" + if (Path(executable).parent / "libs").exists(): + flags += f" /LIBPATH:{str(Path(executable).parent / 'libs')}" + flags += " " + " ".join(f"{lib}.lib" for lib in library.libraries) + flags += " " + " ".join(f"/LIBPATH:{lib}" for lib in library.library_dirs) # clean while flags.count(" "): flags = flags.replace(" ", " ") return flags + def get_link_flags(self, library: HatchCppLibrary) -> str: + flags = "" + return flags + @dataclass class HatchCppBuildPlan(object): @@ -133,7 +142,7 @@ class HatchCppBuildPlan(object): def generate(self): self.commands = [] for library in self.libraries: - flags = self.platform.get_flags(library) + flags = self.platform.get_compile_flags(library) self.commands.append(f"{self.platform.cc} {' '.join(library.sources)} {flags}") return self.commands @@ -141,3 +150,10 @@ def execute(self): for command in self.commands: system(command) return self.commands + + def cleanup(self): + if self.platform.platform == "win32": + for library in self.libraries: + temp_obj = Path(f"{library.name}.obj") + if temp_obj.exists(): + temp_obj.unlink() diff --git a/hatch_cpp/tests/test_project_basic.py b/hatch_cpp/tests/test_project_basic.py index b70fff5..03de9f9 100644 --- a/hatch_cpp/tests/test_project_basic.py +++ b/hatch_cpp/tests/test_project_basic.py @@ -1,7 +1,8 @@ from os import listdir +from pathlib import Path from shutil import rmtree from subprocess import check_output -from sys import platform +from sys import path, platform class TestProject: @@ -20,3 +21,8 @@ def test_basic(self): assert "extension.pyd" in listdir("hatch_cpp/tests/test_project_basic/basic_project") else: assert "extension.so" in listdir("hatch_cpp/tests/test_project_basic/basic_project") + here = Path(__file__).parent / "test_project_basic" + path.insert(0, str(here)) + import basic_project.extension + + assert basic_project.extension.hello() == "A string" From b33981d94c10dc5cc1a01e1e72e814480f9db86b Mon Sep 17 00:00:00 2001 From: Tim Paine <3105306+timkpaine@users.noreply.github.com> Date: Fri, 10 Jan 2025 10:47:38 -0500 Subject: [PATCH 3/3] =?UTF-8?q?Bump=20version:=200.1.0=20=E2=86=92=200.1.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hatch_cpp/__init__.py | 2 +- pyproject.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hatch_cpp/__init__.py b/hatch_cpp/__init__.py index 3dc1f76..485f44a 100644 --- a/hatch_cpp/__init__.py +++ b/hatch_cpp/__init__.py @@ -1 +1 @@ -__version__ = "0.1.0" +__version__ = "0.1.1" diff --git a/pyproject.toml b/pyproject.toml index c9344a7..451b580 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ authors = [{name = "the hatch-cpp authors", email = "t.paine154@gmail.com"}] description = "Hatch plugin for C++ builds" readme = "README.md" license = { text = "Apache-2.0" } -version = "0.1.0" +version = "0.1.1" requires-python = ">=3.9" keywords = [ "hatch", @@ -59,7 +59,7 @@ Repository = "https://github.com/python-project-templates/hatch-cpp" Homepage = "https://github.com/python-project-templates/hatch-cpp" [tool.bumpversion] -current_version = "0.1.0" +current_version = "0.1.1" commit = true tag = false pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy