Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

Commit

Permalink
Build: Switch poetry->hatchling (#100)
Browse files Browse the repository at this point in the history
* migrate pyproject.toml
* Add C++ support
  • Loading branch information
iopapamanoglou authored Oct 24, 2024
1 parent 5ce6764 commit 930f60b
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 52 deletions.
12 changes: 7 additions & 5 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,18 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: '3.12'
#cache: 'poetry'
#cache: 'hatch'
- name: Install dependencies
run: |
python -m pip install poetry --upgrade pip
poetry install --with dev
python -m pip install hatch --upgrade pip
hatch env create test
- name: Lint with Ruff
run: poetry run ruff check --output-format=github .
run: hatch run ruff check --output-format=github .
#continue-on-error: true
- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v2
- name: Run pytest
run: poetry run pytest
run: hatch run test:pytest
#- name: Upload pytest test results
# uses: actions/upload-artifact@v4
# with:
Expand Down
127 changes: 80 additions & 47 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,63 +1,96 @@
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
# using scikit-build-core>0.9.3 disables editable mode
requires = ["hatchling", "scikit-build-core==0.9.2", "pybind11~=2.11.1"]
build-backend = "hatchling.build"

[tool.poetry.urls]
"Bug Tracker" = "https://github.com/atopile/faebryk/issues "


[tool.poetry]
[project]
name = "faebryk"
version = "4.1.1"
authors = ["ioannis_iteng <[email protected]>"]
readme = ["README.md", "LICENSE"]
license = "MIT"
version = "4.1.2"
authors = [{ name = "ioannis_iteng", email = "[email protected]" }]
description = "Open-source software-defined EDA"
readme = "README.md"
license = { file = "LICENSE" }
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
repository = "https://github.com/atopile/faebryk"
homepage = "https://github.com/atopile/faebryk"
requires-python = ">=3.12,<3.13"
dependencies = [
"networkx==3.3",
"numpy>=1.24.3,<3.0.0",
"scipy>=1.11.1,<=1.14.0",
"matplotlib~=3.7.1",
"sexpdata==1.0.2",
"black~=24.4.2",
"typing-extensions~=4.6.3",
"easyeda2kicad~=0.8.0",
"shapely~=2.0.1",
"freetype-py~=2.4.0",
"kicadcliwrapper~=1.0.0",
"dataclasses-json~=0.6.7",
"patool~=2.3.0",
"requests~=2.32.3",
"tortoise-orm~=0.21.3",
"rich~=13.7.1",
"typer>=0.12,<0.13",
"isort~=5.6.4",
"ruff>=0.6.4,<0.7.0",
"pint~=0.24.3",
"deprecated~=1.2.14",
"more-itertools~=10.4.0",
"psutil~=6.0.0",
]

[project.optional-dependencies]
dev = [
"pre-commit>=2.20,<4.0",
"pytest>=7.1.3,<9.0.0",
"viztracer~=0.16.3",
"pyinstrument~=4.7.1",
"gprof2dot~=2024.6.6",
"pytest-xdist~=3.6.1",
"dash~=2.18.1",
"dash_cytoscape~=1.0.2",
"pybind11~=2.11.1",
]
test = ["pytest>=7.1.3,<9.0.0", "pytest-xdist~=3.6.1", "pybind11~=2.11.1"]


[tool.poetry.scripts]
[project.scripts]
faebryk = "faebryk.tools.main:__main__"

[tool.poetry.dependencies]
python = "^3.12,<3.13" # max allowed version by scipy
networkx = "3.3"
numpy = ">=1.24.3,<3.0.0"
scipy = "^1.11.1,<=1.14.0"
matplotlib = "^3.7.1"
sexpdata = "1.0.2"
black = "^24.4.2"
typing-extensions = "^4.6.3"
easyeda2kicad = "^0.8.0"
shapely = "^2.0.1"
freetype-py = "^2.4.0"
kicadcliwrapper = "^1.0.0"
dataclasses-json = "^0.6.7"
patool = "^2.3.0"
requests = "^2.32.3"
tortoise-orm = "^0.21.3"
rich = "^13.7.1"
typer = { version = ">=0.9,<0.13", extras = ["all"] }
isort = "^5.6.4"
ruff = ">=0.6.4,<0.7.0"
pint = "^0.24.3"
deprecated = "^1.2.14"
more-itertools = "^10.4.0"
psutil = "^6.0.0"

[tool.poetry.group.dev.dependencies]
pre-commit = ">=2.20,<4.0"
pytest = ">=7.1.3,<9.0.0"
viztracer = "^0.16.3"
pyinstrument = "^4.7.1"
gprof2dot = "^2024.6.6"
pytest-xdist = "^3.6.1"
[project.urls]
"Homepage" = "https://github.com/atopile/faebryk"
"Bug Tracker" = "https://github.com/atopile/faebryk/issues"

[tool.hatch]

[tool.hatch.env]
#requires = ["hatch-pip-compile"]


[tool.hatch.envs.default]
#type = "pip-compile"
#pip-compile-resolver = "uv"
#pip-compile-installer = "uv"
#lock-filename = "locks/hatch.lock"
#pip-compile-verbose = true
#dependencies = ["faebryk[dev]"]

[tool.hatch.envs.test]
dependencies = ["faebryk[test]"]


[tool.hatch.build.targets.wheel]
packages = ["src/faebryk"]

[tool.hatch.build.targets.wheel.hooks.scikit-build]
experimental = true
cmake.source-dir = "src/faebryk/core/cpp"


[tool.pytest]
[tool.pytest.ini_options]
addopts = ["--import-mode=importlib", "--numprocesses=auto"]

Expand Down
8 changes: 8 additions & 0 deletions src/faebryk/core/cpp/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Language: Cpp
IndentWidth: 4
UseTab: Never
BreakConstructorInitializers: BeforeComma
ConstructorInitializerIndentWidth: 2
AllowShortFunctionsOnASingleLine: None
AllowShortLambdasOnASingleLine: None
ColumnLimit: 89
35 changes: 35 additions & 0 deletions src/faebryk/core/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 3.30)

# if not defined, set default
if(NOT DEFINED EDITABLE)
set(EDITABLE 0)
endif()

add_definitions(-DEDITABLE=${EDITABLE})

if(${EDITABLE})
set(PROJECT_NAME faebryk_core_cpp_editable)
else()
set(PROJECT_NAME faebryk_core_cpp)
endif()

# boilerplate ----------------------------------------------------------
project(${PROJECT_NAME} LANGUAGES CXX)
set(PYBIND11_FINDPYTHON ON)
find_package(pybind11 CONFIG REQUIRED)

# configure ------------------------------------------------------------
set(CMAKE_CXX_STANDARD 20)
# turn on optimization
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
# TODO remove
# enable debug symbols
set(CMAKE_BUILD_TYPE Debug)

# source files ---------------------------------------------------------
include_directories(${CMAKE_SOURCE_DIR}/include)
set(SOURCE_FILES src/main.cpp)

# build ----------------------------------------------------------------
pybind11_add_module(${PROJECT_NAME} ${SOURCE_FILES})
install(TARGETS ${PROJECT_NAME} DESTINATION .)
86 changes: 86 additions & 0 deletions src/faebryk/core/cpp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# This file is part of the faebryk project
# SPDX-License-Identifier: MIT

import logging
import pathlib
import shutil
import site
from typing import Callable

logger = logging.getLogger(__name__)


# Check if installed as editable
def is_editable_install():
site_packages = site.getsitepackages()
return not any((pathlib.Path(sp) / "faebryk").exists() for sp in site_packages)


def compile_and_load():
"""
Forces C++ to compile into faebryk_core_cpp_editable module which is then loaded
into _cpp.
"""
import subprocess
import sys

cpp_dir = pathlib.Path(__file__).parent
build_dir = cpp_dir / "build"

# check for cmake binary existing
if not shutil.which("cmake"):
raise RuntimeError(
"cmake not found, needed for compiling c++ code in editable mode"
)

pybind11_dir = subprocess.check_output(
["python", "-m", "pybind11", "--cmakedir"],
text=True,
).strip()

# force recompile
# subprocess.run(["rm", "-rf", str(build_dir)], check=True)

subprocess.run(
[
"cmake",
"-S",
str(cpp_dir),
"-B",
str(build_dir),
"-DEDITABLE=1",
f"-DCMAKE_PREFIX_PATH={pybind11_dir}",
],
check=True,
)
subprocess.run(
[
"cmake",
"--build",
str(build_dir),
],
check=True,
)

if not build_dir.exists():
raise RuntimeError("build directory not found")

sys.path.append(str(build_dir))
global _cpp
import faebryk_core_cpp_editable as _cpp # type: ignore


if is_editable_install():
logger.warning("faebryk is installed as editable package, compiling c++ code")
compile_and_load()
else:
# check whether module is available
try:
import faebryk_core_cpp as _cpp # type: ignore # noqa: E402
except ImportError:
logger.warning("faebryk_core_cpp module not found, assuming editable mode")
compile_and_load()


# Re-export c++ with type hints
add: Callable[[int, int], int] = _cpp.add
29 changes: 29 additions & 0 deletions src/faebryk/core/cpp/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* This file is part of the faebryk project
* SPDX-License-Identifier: MIT
*/

#include <pybind11/pybind11.h>

// check if c++20 is used
#if __cplusplus < 202002L
#error "C++20 is required"
#endif

namespace py = pybind11;

int add(int i, int j) {
return i + j;
}

#if EDITABLE
#define PYMOD(m) PYBIND11_MODULE(faebryk_core_cpp_editable, m)
#warning "EDITABLE"
#else
#define PYMOD(m) PYBIND11_MODULE(faebryk_core_cpp, m)
#endif

PYMOD(m) {
m.doc() = "faebryk core c++ module";

m.def("add", &add, "A function that adds two numbers");
}
8 changes: 8 additions & 0 deletions test/core/cpp/test_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file is part of the faebryk project
# SPDX-License-Identifier: MIT

from faebryk.core.cpp import add


def test_add():
assert add(1, 2) == 3

0 comments on commit 930f60b

Please sign in to comment.