Skip to content

Commit d5275c1

Browse files
authored
Merge pull request #11 from ababak/dev
Building wheels
2 parents dd2702f + f2e22ca commit d5275c1

File tree

5 files changed

+137
-85
lines changed

5 files changed

+137
-85
lines changed
Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1-
name: Build and Publish Wheels Test
1+
name: Build and Publish Test Wheels
22

33
on:
4+
# push:
5+
# tags:
6+
# - "v*.*.*"
47
workflow_dispatch:
58
inputs:
69
tag:
710
description: 'Version tag to use (e.g. v1.2.3)'
811
required: true
912
default: ''
10-
13+
1114
jobs:
1215
build_wheels:
1316
name: Build Universal Wheel
@@ -22,31 +25,35 @@ jobs:
2225
with:
2326
python-version: '3.9'
2427

25-
- name: Install dependencies
28+
- name: Update pip
2629
run: |
2730
python -m pip install --upgrade pip
28-
pip install wheel setuptools toml
29-
30-
- name: Build extensions using Docker
31-
run: |
32-
python setup.py build_ext
33-
31+
pip install wheel setuptools build toml
32+
3433
- name: Build universal wheel
3534
run: |
36-
python setup.py bdist_wheel
35+
python -m build --wheel
3736
3837
- name: Upload wheel as artifact
39-
uses: actions/upload-artifact@v3
38+
uses: actions/upload-artifact@v4
4039
with:
4140
name: wheel
4241
path: dist/*.whl
42+
43+
publish:
44+
name: Publish to TestPyPI
45+
needs: build_wheels
46+
runs-on: ubuntu-latest
47+
48+
steps:
49+
- name: Download wheel artifacts
50+
uses: actions/download-artifact@v4
51+
with:
52+
name: wheel
53+
path: dist
4354

44-
# - name: Publish to PyPI
45-
# uses: pypa/gh-action-pypi-publish@release/v1
46-
# with:
47-
# password: ${{ secrets.PYPI_API_TOKEN }}
4855
- name: Publish to TestPyPI
4956
uses: pypa/gh-action-pypi-publish@release/v1
5057
with:
5158
repository-url: https://test.pypi.org/legacy/
52-
password: ${{ secrets.PYPI_TEST_API_TOKEN }}
59+
password: ${{ secrets.PYPI_TEST_API_TOKEN }}

.github/workflows/build-wheels.yml

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,35 @@ jobs:
2525
with:
2626
python-version: '3.9'
2727

28-
- name: Install dependencies
28+
- name: Update pip
2929
run: |
3030
python -m pip install --upgrade pip
31-
pip install wheel setuptools toml
32-
33-
- name: Build extensions using Docker
34-
run: |
35-
python setup.py build_ext
31+
pip install wheel setuptools build toml
3632
3733
- name: Build universal wheel
3834
run: |
39-
python setup.py bdist_wheel
35+
python -m build
4036
4137
- name: Upload wheel as artifact
42-
uses: actions/upload-artifact@v3
38+
uses: actions/upload-artifact@v4
4339
with:
4440
name: wheel
4541
path: dist/*.whl
4642

47-
# - name: Publish to PyPI
48-
# uses: pypa/gh-action-pypi-publish@release/v1
49-
# with:
50-
# password: ${{ secrets.PYPI_API_TOKEN }}
51-
- name: Publish to TestPyPI
43+
publish:
44+
name: Publish to PyPI
45+
needs: build_wheels
46+
runs-on: ubuntu-latest
47+
48+
steps:
49+
- name: Download wheel artifacts
50+
uses: actions/download-artifact@v4
51+
with:
52+
name: wheel
53+
path: dist
54+
55+
- name: Publish to PyPI
5256
uses: pypa/gh-action-pypi-publish@release/v1
5357
with:
54-
repository-url: https://test.pypi.org/legacy/
55-
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
58+
password: ${{ secrets.PYPI_API_TOKEN }}
59+

README.md

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,51 @@
1-
[![Docker Image CI](https://github.com/ababak/cgcpp/actions/workflows/docker-image.yml/badge.svg?branch=v1.7.0)](https://github.com/ababak/cgcpp/actions/workflows/docker-image.yml)
1+
[![Docker Image CI](https://github.com/ababak/cgcpp/actions/workflows/docker-image.yml/badge.svg)](https://github.com/ababak/cgcpp/actions/workflows/docker-image.yml)
2+
3+
# Computer Graphics C++ (cgcpp)
4+
A universal C++ solution for common needs in computer graphics software.
5+
6+
### Supported Environments
7+
- **Python & Boost Versions** (Windows):
8+
- Python 3.9, Boost 1.76.0
9+
- Python 3.10, Boost 1.80.0
10+
- Python 3.11, Boost 1.82.0
11+
- Python 3.12, Boost 1.85.0
12+
- **Autodesk Maya** (Windows):
13+
- Maya 2023: Python 3.9, Boost 1.76.0
14+
- Maya 2024: Python 3.10, Boost 1.80.0
15+
- Maya 2025: Python 3.11, Boost 1.82.0
16+
- Maya 2026: Python 3.11, Boost 1.85.0
17+
- **SideFX Houdini** (Windows):
18+
- Houdini 19.5: Python 3.9, Boost 1.76.0
19+
- Houdini 20.0: Python 3.10, Boost 1.80.0
20+
- Houdini 20.5: Python 3.11, Boost 1.82.0
21+
22+
Support for additional platforms and DCC applications may be added in the future.
23+
24+
### Features
25+
- **Isolated builds** inside a Docker container for a predictable environment
26+
- **Python-C++ integration** to call C++ functions from Python
27+
- **Dynamic library reloading** (updates libraries on each new call)
28+
- **Python exception handling** from C++
29+
30+
## Installation
31+
Install in your Windows Python virtual environment:
232

3-
# Computer Graphics C++ (cgcpp)
4-
A universal solution for common needs in C++ in computer graphics software.
5-
6-
### Supports
7-
- Python 3.9, Boost 1.76.0 on Windows
8-
- Python 3.10, Boost 1.80.0 on Windows
9-
- Python 3.11, Boost 1.82.0 on Windows
10-
- Python 3.12, Boost 1.85.0 on Windows
11-
- Autodesk Maya 2023-2026 on Windows *(Python 3.9 and Boost 1.76.0 in Maya 2023, Python 3.10 and Boost 1.80.0 in Maya 2024, Python 3.11 and Boost 1.82.0 in Maya 2025, Python 3.11 and Boost 1.85.0 in Maya 2026)*
12-
- SideFX Houdini 19.5-20.5 on Windows *(Python 3.9 and Boost 1.76.0 in Houdini 19.5, Python 3.10 and Boost 1.80.0 in Houdini 20.0, Python 3.11 and Boost 1.82.0 in Houdini 20.5)*
13-
14-
Support for other platforms and other DCC applications may come later.
15-
16-
### Features
17-
- Build inside a docker container (isolated predictable environment)
18-
- Call library C++ functions from Python
19-
- Dynamically reload modified libraries (each new call reloads the library and alows it to be updated)
20-
- Throw Python exceptions from C++
33+
python -m pip install git+https://github.com/ababak/cgcpp.git
2134

22-
## Installation
23-
Install in your Windows Python virtual environment:
35+
or
2436

25-
python -m pip install git+https://github.com/ababak/cgcpp.git
37+
pip install cgcpp
2638

27-
## Build the examples
39+
## Building Examples
2840

2941
mkdir out
3042
python -m cgcpp examples/source_exception --out ./out
3143
python -m cgcpp examples/source_maya --out ./out --maya
3244
python -m cgcpp examples/source_houdini --out ./out --houdini
3345

34-
Make sure you have Maya and Houdini versions installed in default locations that correspond to versions listed in `CMakeLists.txt`
46+
Ensure you have Maya and Houdini installed in their default locations as specified in `CMakeLists.txt`
3547

36-
## Test built examples
48+
## Testing Built Examples
3749
Should throw `AttributeError: Some error` exception:
3850

3951
python -c 'import cgcpp;cgcpp.call(lib="out/lib_exception", func="call")'

pyproject.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ Homepage = "https://github.com/ababak/cgcpp"
1212
Repository = "https://github.com/ababak/cgcpp.git"
1313

1414
[build-system]
15-
requires = ["setuptools>=61.0", "wheel", "toml"]
15+
requires = ["setuptools>=61.0", "wheel", "build", "toml"]
1616
build-backend = "setuptools.build_meta"
1717

1818
[tool.setuptools.packages.find]
19-
where = ["source/"]
19+
where = ["source"]
20+
21+
# [tool.setuptools.package-data]
22+
# "*" = ["*.*"] # <-- this changed

setup.py

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
(c) Andriy Babak 2021
33
44
date: 28/05/2021
5-
modified: 04/04/2025 11:01:38
5+
modified: 04/04/2025 15:32:12
66
77
Author: Andriy Babak
88
e-mail: ababak@gmail.com
@@ -12,6 +12,7 @@
1212
"""
1313

1414
import os
15+
import shutil
1516
import subprocess
1617
from pathlib import Path
1718

@@ -29,6 +30,9 @@ def get_version() -> str:
2930

3031

3132
VERSION = get_version()
33+
ROOT_PATH = Path(__file__).parent.absolute()
34+
SOURCE_PATH = ROOT_PATH / "source"
35+
BUILD_PATH = ROOT_PATH / "build"
3236

3337

3438
class BdistWheelCommand(bdist_wheel):
@@ -46,12 +50,6 @@ def get_tag(self):
4650
return impl, abi, plat
4751

4852

49-
class CMakeExtension(setuptools.Extension):
50-
def __init__(self, name, sourcedir=""):
51-
setuptools.Extension.__init__(self, name, sources=[])
52-
self.sourcedir = Path(sourcedir).absolute()
53-
54-
5553
class CMakeBuild(build_ext):
5654
"""
5755
Build CMake using docker image
@@ -61,56 +59,84 @@ class CMakeBuild(build_ext):
6159
DOCKER_IMAGE = f"ababak/cgcpp:{'.'.join(VERSION.split('.')[:2])}"
6260

6361
def run(self):
62+
"""Prepare the Docker image and run the build."""
63+
# Check if Docker is installed
6464
try:
6565
out = subprocess.check_output([self.DOCKER_APP, "--version"])
6666
except OSError:
6767
extensions = ", ".join(e.name for e in self.extensions)
6868
raise RuntimeError(
6969
f"Docker must be installed to build the following extensions: {extensions}"
7070
)
71+
# Check if the image is available
7172
out = subprocess.check_output(
7273
[self.DOCKER_APP, "images", "-q", self.DOCKER_IMAGE]
7374
)
7475
if not out:
75-
print(f'Building docker image "{self.DOCKER_IMAGE}"...')
76-
docker_args = [
77-
self.DOCKER_APP,
78-
"build",
79-
# "--rm",
80-
"-t",
81-
self.DOCKER_IMAGE,
82-
".",
83-
]
84-
subprocess.check_call(docker_args)
85-
for ext in self.extensions:
86-
self.build_extension(ext)
76+
# Try to pull the image from Docker Hub
77+
try:
78+
print(f'Trying to pull the docker image "{self.DOCKER_IMAGE}"...')
79+
out = subprocess.check_output(
80+
[self.DOCKER_APP, "pull", self.DOCKER_IMAGE]
81+
)
82+
print(f'Pulled the docker image "{self.DOCKER_IMAGE}"...')
83+
except subprocess.CalledProcessError:
84+
# If the image is not available, build it from the Dockerfile
85+
print(f'Building docker image "{self.DOCKER_IMAGE}"...')
86+
docker_args = [
87+
self.DOCKER_APP,
88+
"build",
89+
# "--rm",
90+
"-t",
91+
self.DOCKER_IMAGE,
92+
".",
93+
]
94+
subprocess.check_call(docker_args)
95+
super().run()
8796

8897
def build_extension(self, ext):
89-
extdir = Path(self.get_ext_fullpath(ext.name)).parent.absolute()
90-
if not extdir.exists():
91-
os.makedirs(extdir)
92-
sourcedir = ext.sourcedir
98+
staging_path = Path(self.get_ext_fullpath(ext.name)).parent.absolute()
99+
if not staging_path.exists():
100+
os.makedirs(staging_path)
101+
# relative_file_path = Path(dirpath).relative_to(SOURCE_PATH)
102+
# source_path = dirpath
103+
# destination_path = (staging_path / relative_file_path).parent
104+
# for i, j in ext.__dict__.items():
105+
# print(f"{i} = {j}")
106+
print("staging_path", staging_path)
107+
sdir = Path(__file__).parent
108+
sources_path = os.path.commonpath(ext.sources)
109+
source_dir = sdir / sources_path
110+
print("sdir", sdir)
111+
print("source_dir", source_dir)
93112
print(f'Building extension "{ext.name}" using "{self.DOCKER_IMAGE}"...')
94113
docker_args = [
95114
self.DOCKER_APP,
96115
"run",
97116
"--rm",
98117
"-v",
99-
f"{sourcedir}:c:/source:ro",
118+
f"{source_dir}:c:/source:ro",
100119
"-v",
101-
f"{extdir}:c:/out",
120+
f"{staging_path}:c:/out",
102121
self.DOCKER_IMAGE,
103122
]
104123
subprocess.check_call(docker_args)
105124

106125

107126
# Configuration.
108127
setuptools.setup(
109-
ext_modules=[CMakeExtension("cgcpp/lib_loader", "source_lib_loader")],
128+
ext_modules=[
129+
setuptools.Extension(
130+
"cgcpp.lib_loader",
131+
sources=[
132+
"source_lib_loader/lib_loader.cpp",
133+
"source_lib_loader/CMakeLists.txt",
134+
],
135+
)
136+
],
110137
cmdclass={
111138
"build_ext": CMakeBuild,
112139
"bdist_wheel": BdistWheelCommand,
113140
},
114-
include_package_data=True,
115141
zip_safe=False,
116142
)

0 commit comments

Comments
 (0)