Skip to content

Commit 9aafbf5

Browse files
authored
Merge pull request #2 from virtualcell/poetry-native-build
move native-image build into poetry build
2 parents 7904b4f + 9b43b70 commit 9aafbf5

File tree

7 files changed

+143
-108
lines changed

7 files changed

+143
-108
lines changed

.github/workflows/main.yml

Lines changed: 30 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ jobs:
1313
steps:
1414
- name: Check out
1515
uses: actions/checkout@v4
16+
with:
17+
submodules: true
18+
fetch-depth: 2
1619

1720
- uses: actions/cache@v4
1821
with:
@@ -25,6 +28,17 @@ jobs:
2528

2629
- uses: abatilo/actions-poetry@v3
2730

31+
- name: setup graalvm for static native build
32+
uses: graalvm/setup-graalvm@v1
33+
with:
34+
java-version: "23"
35+
distribution: "graalvm-community"
36+
github-token: ${{ secrets.GITHUB_TOKEN }}
37+
components: "native-image"
38+
# native-image-musl: 'true' # Now semi-static by not including libc
39+
native-image-job-reports: "true"
40+
cache: "maven"
41+
2842
- name: Install python dependencies
2943
run: poetry install --no-interaction
3044

@@ -35,8 +49,8 @@ jobs:
3549
strategy:
3650
matrix: # python-version: ["3.9", "3.10", "3.11", "3.12"]
3751
python-version: ["3.11", "3.12"]
38-
# os: [macos-13, windows-latest, ubuntu-latest, macos-14]
39-
os: [ubuntu-latest, macos-14]
52+
os: [macos-13, windows-latest, ubuntu-latest, macos-14]
53+
# os: [ubuntu-latest, macos-14]
4054
fail-fast: false
4155
runs-on: ${{ matrix.os }}
4256
defaults:
@@ -66,50 +80,6 @@ jobs:
6680
native-image-job-reports: "true"
6781
cache: "maven"
6882

69-
- name: build entire project
70-
working-directory: vcell_submodule
71-
run: |
72-
mvn --batch-mode clean install dependency:copy-dependencies -DskipTests=true
73-
74-
- name: test, record, and build/install native library (ubuntu)
75-
working-directory: vcell-native
76-
run: |
77-
mvn --batch-mode clean install
78-
79-
java -agentlib:native-image-agent=config-output-dir=target/recording \
80-
-jar target/vcell-native-1.0-SNAPSHOT.jar \
81-
"src/test/resources/TinySpacialProject_Application0.xml" \
82-
"target/sbml-input"
83-
84-
mvn --batch-mode -P shared-dll package
85-
cp target/libvcell.so ../libvcell/_internal/libs
86-
if: ${{ startsWith(matrix.os, 'ubuntu') }}
87-
88-
- name: test, record, and build/install native library (macos)
89-
working-directory: vcell-native
90-
run: |
91-
mvn --batch-mode clean install
92-
93-
java -agentlib:native-image-agent=config-output-dir=target/recording \
94-
-jar target/vcell-native-1.0-SNAPSHOT.jar \
95-
"src/test/resources/TinySpacialProject_Application0.xml" \
96-
"target/sbml-input"
97-
98-
mvn --batch-mode -P shared-dll package
99-
cp target/libvcell.dylib ../libvcell/_internal/libs
100-
if: ${{ startsWith(matrix.os, 'macos') }}
101-
102-
- name: test, record, and build/install native library (windows)
103-
working-directory: vcell-native
104-
run: |
105-
mvn --batch-mode clean install
106-
107-
java -agentlib:native-image-agent=config-output-dir=target\recording -jar "target\vcell-native-1.0-SNAPSHOT.jar" "src\test\resources\TinySpacialProject_Application0.xml" "target\sbml-input"
108-
109-
mvn --batch-mode -P shared-dll package
110-
cp target/libvcell.dll ../libvcell/_internal/libs
111-
if: ${{ startsWith(matrix.os, 'windows') }}
112-
11383
- name: Install python dependencies
11484
run: poetry install --no-interaction
11585

@@ -134,13 +104,27 @@ jobs:
134104
steps:
135105
- name: Check out
136106
uses: actions/checkout@v4
107+
with:
108+
submodules: true
109+
fetch-depth: 2
137110

138111
- uses: actions/setup-python@v5
139112
with:
140113
python-version: "3.11"
141114

142115
- uses: abatilo/actions-poetry@v3
143116

117+
- name: setup graalvm for static native build
118+
uses: graalvm/setup-graalvm@v1
119+
with:
120+
java-version: "23"
121+
distribution: "graalvm-community"
122+
github-token: ${{ secrets.GITHUB_TOKEN }}
123+
components: "native-image"
124+
# native-image-musl: 'true' # Now semi-static by not including libc
125+
native-image-job-reports: "true"
126+
cache: "maven"
127+
144128
- name: Install python dependencies
145129
run: poetry install --no-interaction
146130

Lines changed: 35 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,34 @@
11
name: release-main
22

33
on:
4+
workflow_dispatch:
45
release:
56
types: [published]
67
branches: [main]
78

89
jobs:
9-
publish:
10+
build:
1011
strategy:
11-
matrix: # python-version: ["3.9", "3.10", "3.11", "3.12"]
12+
matrix:
13+
# python-version: ["3.9", "3.10", "3.11", "3.12"]
1214
python-version: ["3.11", "3.12"]
13-
# os: [macos-13, windows-latest, ubuntu-latest, macos-14]
14-
os: [ubuntu-latest, macos-14]
15+
os: [macos-13, windows-latest, ubuntu-latest, macos-14]
16+
# os: [ubuntu-latest, macos-14]
1517
fail-fast: false
1618
runs-on: ${{ matrix.os }}
1719
defaults:
1820
run:
1921
shell: bash
22+
2023
steps:
2124
- name: Check out
2225
uses: actions/checkout@v4
2326
with:
2427
submodules: true
2528
fetch-depth: 2
2629

27-
28-
- uses: actions/setup-python@v5
30+
- name: Set up Python
31+
uses: actions/setup-python@v5
2932
with:
3033
python-version: ${{ matrix.python-version }}
3134

@@ -42,50 +45,6 @@ jobs:
4245
native-image-job-reports: "true"
4346
cache: "maven"
4447

45-
- name: build entire project
46-
working-directory: vcell_submodule
47-
run: |
48-
mvn --batch-mode clean install dependency:copy-dependencies -DskipTests=true
49-
50-
- name: test, record, and build/install native library (ubuntu)
51-
working-directory: vcell-native
52-
run: |
53-
mvn --batch-mode clean install
54-
55-
java -agentlib:native-image-agent=config-output-dir=target/recording \
56-
-jar target/vcell-native-1.0-SNAPSHOT.jar \
57-
"src/test/resources/TinySpacialProject_Application0.xml" \
58-
"target/sbml-input"
59-
60-
mvn --batch-mode -P shared-dll package
61-
cp target/libvcell.so ../libvcell/_internal/libs
62-
if: ${{ startsWith(matrix.os, 'ubuntu') }}
63-
64-
- name: test, record, and build/install native library (macos)
65-
working-directory: vcell-native
66-
run: |
67-
mvn --batch-mode clean install
68-
69-
java -agentlib:native-image-agent=config-output-dir=target/recording \
70-
-jar target/vcell-native-1.0-SNAPSHOT.jar \
71-
"src/test/resources/TinySpacialProject_Application0.xml" \
72-
"target/sbml-input"
73-
74-
mvn --batch-mode -P shared-dll package
75-
cp target/libvcell.dylib ../libvcell/_internal/libs
76-
if: ${{ startsWith(matrix.os, 'macos') }}
77-
78-
- name: test, record, and build/install native library (windows)
79-
working-directory: vcell-native
80-
run: |
81-
mvn --batch-mode clean install
82-
83-
java -agentlib:native-image-agent=config-output-dir=target\recording -jar "target\vcell-native-1.0-SNAPSHOT.jar" "src\test\resources\TinySpacialProject_Application0.xml" "target\sbml-input"
84-
85-
mvn --batch-mode -P shared-dll package
86-
cp target/libvcell.dll ../libvcell/_internal/libs
87-
if: ${{ startsWith(matrix.os, 'windows') }}
88-
8948
- name: Install python dependencies
9049
run: poetry install --no-interaction
9150

@@ -104,8 +63,15 @@ jobs:
10463
env:
10564
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
10665
RELEASE_VERSION: ${{ steps.vars.outputs.tag }}
66+
67+
- name: Setup tmate
68+
if: failure()
69+
uses: mxschmitt/action-tmate@v3
70+
with:
71+
limit-access-to-actor: true
72+
10773
deploy-docs:
108-
needs: publish
74+
needs: build
10975
runs-on: ubuntu-latest
11076
steps:
11177
- name: Check out
@@ -114,5 +80,23 @@ jobs:
11480
- name: Set up the environment
11581
uses: ./.github/actions/setup-poetry-env
11682

83+
- name: Set up Python
84+
uses: actions/setup-python@v5
85+
with:
86+
python-version: ${{ matrix.python-version }}
87+
88+
- uses: abatilo/actions-poetry@v3
89+
90+
- name: setup graalvm for static native build
91+
uses: graalvm/setup-graalvm@v1
92+
with:
93+
java-version: "23"
94+
distribution: "graalvm-community"
95+
github-token: ${{ secrets.GITHUB_TOKEN }}
96+
components: "native-image"
97+
# native-image-musl: 'true' # Now semi-static by not including libc
98+
native-image-job-reports: "true"
99+
cache: "maven"
100+
117101
- name: Deploy documentation
118102
run: poetry run mkdocs gh-deploy --force

build.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import os
2+
import shutil
3+
import subprocess
4+
import sys
5+
from pathlib import Path
6+
7+
8+
def run_command(command, cwd=None):
9+
result = subprocess.run(command, shell=True, cwd=cwd, check=True, text=True)
10+
if result.returncode != 0:
11+
sys.exit(result.returncode)
12+
13+
14+
def main():
15+
root_dir = Path(__file__).resolve().parent
16+
vcell_submodule_dir = root_dir / "vcell_submodule"
17+
vcell_native_dir = root_dir / "vcell-native"
18+
libvcell_lib_dir = root_dir / "libvcell" / "lib"
19+
20+
# Ensure the libvcell/lib directory exists
21+
libvcell_lib_dir.mkdir(parents=True, exist_ok=True)
22+
23+
# Build VCell Java project from submodule
24+
run_command("mvn --batch-mode clean install -DskipTests", cwd=vcell_submodule_dir)
25+
26+
# fail if both JAVA_HOME and GRAALVM_HOME are not set
27+
if "JAVA_HOME" not in os.environ and "GRAALVM_HOME" not in os.environ:
28+
print("JAVA_HOME or GRAALVM_HOME environment variable must be set")
29+
sys.exit(1)
30+
31+
# Check if native-image is installed
32+
if not shutil.which("native-image"):
33+
print("native-image could not be found")
34+
sys.exit(1)
35+
36+
# Build vcell-native as Java
37+
run_command("mvn --batch-mode clean install", cwd=vcell_native_dir)
38+
39+
# Run with native-image-agent to record configuration for native-image
40+
run_command(
41+
"java -agentlib:native-image-agent=config-output-dir=target/recording "
42+
"-jar target/vcell-native-1.0-SNAPSHOT.jar "
43+
"src/test/resources/TinySpacialProject_Application0.xml "
44+
"target/sbml-input",
45+
cwd=vcell_native_dir,
46+
)
47+
48+
# Build vcell-native as native shared object library
49+
run_command("mvn package -P shared-dll", cwd=vcell_native_dir)
50+
51+
# Copy the shared library to libvcell/lib
52+
for ext in ["so", "dylib", "dll"]:
53+
shared_lib = vcell_native_dir / f"target/libvcell.{ext}"
54+
if shared_lib.exists():
55+
shutil.copy(shared_lib, libvcell_lib_dir / f"libvcell.{ext}")
56+
57+
58+
if __name__ == "__main__":
59+
main()

libvcell/_internal/libs/.gitignore

Lines changed: 0 additions & 4 deletions
This file was deleted.

libvcell/_internal/native_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def _load_library(self) -> ctypes.CDLL:
2020
if lib_ext is None:
2121
raise OSError(f"Unsupported operating system: {system}")
2222

23-
libs_dir = files(libvcell).joinpath("_internal/libs")
23+
libs_dir = files(libvcell).joinpath("lib")
2424
if not libs_dir.is_dir():
2525
raise OSError(f"Could not find the shared library directory {libs_dir}")
2626

pyproject.toml

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
[build-system]
2+
requires = ["setuptools", "wheel"]
3+
build-backend = "setuptools.build_meta"
4+
15
[tool.poetry]
26
name = "libvcell"
3-
version = "0.0.1"
7+
version = "0.0.2"
48
description = "This is a python package which wraps a subset of VCell Java code as a native python package."
59
authors = ["Jim Schaff <[email protected]>"]
610
repository = "https://github.com/virtualcell/libvcell"
@@ -10,13 +14,16 @@ packages = [
1014
{include = "libvcell"}
1115
]
1216
include = [
13-
{path="libvcell/_internal/libs/*", format="wheel"}
17+
{path="libvcell/lib/libvcell*", format="wheel"}
1418
]
1519

1620
[tool.poetry.dependencies]
1721
python = ">=3.9,<4.0"
1822
pydantic = "^2.10.6"
1923

24+
[tool.poetry.build]
25+
script = "build.py"
26+
2027
[tool.poetry.group.dev.dependencies]
2128
pytest = "^7.2.0"
2229
pytest-cov = "^4.0.0"
@@ -30,9 +37,12 @@ mkdocs = "^1.6.1"
3037
mkdocs-material = "^9.5.50"
3138
mkdocstrings = {extras = ["python"], version = "^0.27.0"}
3239

33-
[build-system]
34-
requires = ["poetry-core>=1.0.0"]
35-
build-backend = "poetry.core.masonry.api"
40+
[tool.cibuildwheel]
41+
build = "cp311-manylinux_x86_64 cp311-macosx_x86_64 cp311-macosx_arm64 cp311-win_amd64"
42+
skip = "cp36-* cp37-* cp38-* cp310-*"
43+
44+
[tool.setuptools.package-data]
45+
libvcell = ["lib/*"]
3646

3747
[tool.mypy]
3848
files = ["libvcell", "tests"]
@@ -85,6 +95,8 @@ lint.ignore = [
8595
"E731",
8696
# avoid specifiying long messages outside the exception class
8797
"TRY003",
98+
# S602 `subprocess` call with `shell=True` identified, security issue
99+
"S602",
88100
]
89101

90102
[tool.ruff.format]

scripts/build_native.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ java -agentlib:native-image-agent=config-output-dir=target/recording \
4040
mvn package -P shared-dll
4141

4242
# install vcell-native as shared object library
43-
cp target/libvcell.dylib "$ROOT_DIR/libvcell/_internal/libs/libvcell.dylib"
43+
cp target/libvcell.dylib "$ROOT_DIR/libvcell/lib/libvcell.dylib"

0 commit comments

Comments
 (0)