Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate Python wheels in CI #1317

Merged
merged 37 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
37d9190
Use scikit-build-core to create a PyPI package (wheels + sdist)
JeanChristopheMorinPerso Apr 9, 2023
b9d3acf
Add new GH Actions workflow to build the wheels
JeanChristopheMorinPerso Apr 10, 2023
bcffe4e
Fix stdlib install
JeanChristopheMorinPerso Apr 10, 2023
bf105f1
Set MACOSX_DEPLOYMENT_TARGET to 10.13
JeanChristopheMorinPerso Apr 10, 2023
47396ff
Remove Python 3.11. We would need a newer Pybind11
JeanChristopheMorinPerso Apr 10, 2023
446e427
Reorganize workflow to build from sdist and disable MaterialXTest
JeanChristopheMorinPerso Apr 10, 2023
764315f
Fix pip install command
JeanChristopheMorinPerso Apr 10, 2023
057d018
Only run on 3.10 to speed up testing
JeanChristopheMorinPerso Apr 10, 2023
1980eae
Fix tests again...
JeanChristopheMorinPerso Apr 10, 2023
333d147
Re-enable all Python versions
JeanChristopheMorinPerso Apr 10, 2023
62d65b5
Minor spelling
jstone-lucasfilm Apr 10, 2023
54369db
Re-enable MATERIALX_BUILD_RENDER
JeanChristopheMorinPerso Apr 11, 2023
911f7c8
Add Python 3.11 to build matrix
jstone-lucasfilm Apr 25, 2023
d0b05a3
Add Python 3.11 to build matrix
jstone-lucasfilm Apr 25, 2023
f0b32fb
Update Python version range
jstone-lucasfilm Apr 25, 2023
8bc9f26
Simplify list of build exclusions
jstone-lucasfilm Apr 25, 2023
6b0dcfa
Minor workflow clarifications
jstone-lucasfilm Apr 26, 2023
669d7d4
Remove OCIO from Python build
jstone-lucasfilm Apr 26, 2023
3e71487
Minor naming updates
jstone-lucasfilm Apr 28, 2023
4252d6a
Update tests
JeanChristopheMorinPerso Jun 3, 2023
009c5ef
Get python package version from CMake
JeanChristopheMorinPerso Jun 3, 2023
aa175f4
Fix tests on Windows
JeanChristopheMorinPerso Jun 4, 2023
e0be564
Merge branch 'main' into python_packaging
jstone-lucasfilm Jun 13, 2023
aaab1cd
Merge branch 'main' into python_packaging
jstone-lucasfilm Jul 12, 2023
43c3fe9
Update script syntax
jstone-lucasfilm Jul 12, 2023
3e69d80
Use original concurrency rules in main
jstone-lucasfilm Jul 13, 2023
bb9804e
Merge branch 'main' into python_packaging
jstone-lucasfilm Jul 24, 2023
97ad91f
Merge branch 'main' into python_packaging
jstone-lucasfilm Aug 4, 2023
d1f7001
move mtx_skbuild_plugin.py into python folder
JeanChristopheMorinPerso Aug 4, 2023
6b4db09
Make sure there is no RPATH on Linux and macOS wheels
JeanChristopheMorinPerso Aug 5, 2023
a1c783e
Merge branch 'main' into python_packaging
jstone-lucasfilm Aug 17, 2023
ae2cae5
Remove TODO
jstone-lucasfilm Aug 18, 2023
6a8c7f9
Allow concurrent builds for now
jstone-lucasfilm Aug 18, 2023
5f98f72
Merge branch 'main' into python_packaging
jstone-lucasfilm Aug 18, 2023
2cade13
Minor spacing update
jstone-lucasfilm Aug 22, 2023
f775f6f
Remove forward slash for consistency
jstone-lucasfilm Aug 22, 2023
8f6a05f
Merge branch 'main' into python_packaging
jstone-lucasfilm Aug 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
name: python

on:
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
workflow_dispatch:

jobs:
# Generate the sdist first. We'll use it to create the wheels.
# https://packaging.python.org/en/latest/flow#the-source-distribution-sdist
sdist:
name: Generate Source Distribution
runs-on: ubuntu-latest
outputs:
sdist_filename: ${{ steps.generate.outputs.filename }}

steps:
- uses: actions/checkout@v3

- uses: actions/setup-python@v4
with:
python-version: 3.11

- name: Install Build Command
run: python -m pip install build

- name: Generate Sdist
id: generate
run: |
python -m build -s . --outdir dist
echo "filename=$(ls dist)" >> "$GITHUB_OUTPUT"

- name: Upload Sdist
uses: actions/upload-artifact@v3
with:
name: sdist
path: ./dist/*.tar.gz

# Create the wheels. It'll use the sdist to confirm that we can compile MaterialX from the sdist.
# https://packaging.python.org/en/latest/flow#the-built-distributions-wheels
wheels:
name: Generate Wheel
runs-on: ${{ matrix.os }}
needs: ['sdist']
strategy:
fail-fast: false
matrix:
python-version: ['37', '38', '39', '310', '311']
os: ['ubuntu-latest', 'macos-latest', 'windows-latest']

steps:
- name: Download Sdist
uses: actions/download-artifact@v3
with:
name: sdist
path: sdist

- name: Build Wheel
# https://cibuildwheel.readthedocs.io/en/stable/
uses: pypa/[email protected]
with:
# Build from the sdist. We want to make sure it's valid and works as expected.
package-dir: ${{ github.workspace }}/sdist/${{ needs.sdist.outputs.sdist_filename }}
output-dir: wheels
env:
CIBW_BUILD: 'cp${{ matrix.python-version }}-*'
CIBW_SKIP: '*musllinux*'
CIBW_ARCHS: 'auto64'
# https://github.com/pypa/manylinux
# manylinux2014 is CentOS 7 based. Which means GCC 10 and glibc 2.17.
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
CIBW_BEFORE_ALL_LINUX: yum install -y libXt-devel
CIBW_BEFORE_ALL_MACOS: sudo xcode-select -switch /Applications/Xcode_13.4.app
CIBW_BUILD_VERBOSITY: 1
CIBW_ENVIRONMENT: CMAKE_BUILD_PARALLEL_LEVEL=2
# CIBW_BUILD_FRONTEND: build # https://github.com/pypa/build
MACOSX_DEPLOYMENT_TARGET: '10.15'

- name: Upload Wheel
uses: actions/upload-artifact@v3
with:
name: wheels
path: ./wheels/*.whl

test:
name: Test Wheel
needs: ['wheels']
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
os: ['ubuntu-latest', 'macos-latest', 'windows-latest']

steps:
- uses: actions/checkout@v3

- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Download Wheels
uses: actions/download-artifact@v3
with:
name: wheels
path: wheels

- name: Install Wheel
run: python -m pip install MaterialX --find-links wheels --no-index

- name: Python Tests
shell: bash
run: |
set -e
python python/MaterialXTest/main.py
jstone-lucasfilm marked this conversation as resolved.
Show resolved Hide resolved
python python/MaterialXTest/genshader.py
python python/Scripts/mxformat.py ./resources/Materials/TestSuite/stdlib/upgrade --yes --upgrade
python python/Scripts/mxvalidate.py ./resources/Materials/Examples/StandardSurface/standard_surface_marble_solid.mtlx --stdlib --verbose
python python/Scripts/mxdoc.py --docType md ./libraries/pbrlib/pbrlib_defs.mtlx
python python/Scripts/mxdoc.py --docType html ./libraries/bxdf/standard_surface.mtlx
python python/Scripts/generateshader.py ./resources/Materials/Examples/StandardSurface --target glsl
python python/Scripts/generateshader.py ./resources/Materials/Examples/StandardSurface --target osl
python python/Scripts/generateshader.py ./resources/Materials/Examples/StandardSurface --target mdl
python python/Scripts/generateshader.py ./resources/Materials/Examples/StandardSurface --target msl
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
build
dist
64 changes: 39 additions & 25 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ if (MATERIALX_BUILD_JS)
endif()
endif()

project(MaterialX)
project(MaterialX VERSION ${MATERIALX_LIBRARY_VERSION})

option(MATERIALX_BUILD_PYTHON "Build the MaterialX Python package from C++ bindings. Requires Python 3.6 or greater." OFF)
option(MATERIALX_BUILD_VIEWER "Build the MaterialX Viewer." OFF)
Expand Down Expand Up @@ -101,6 +101,12 @@ set(MATERIALX_OSL_BINARY_OSLC "" CACHE FILEPATH "Full path to the OSL compiler b
set(MATERIALX_OSL_BINARY_TESTRENDER "" CACHE FILEPATH "Full path to the OSL test render binary.")
set(MATERIALX_OSL_INCLUDE_PATH "" CACHE PATH "Full path to OSL shader includes (e.g. 'stdosl.h').")

set(MATERIALX_PYTHON_FOLDER_NAME "python/MaterialX" CACHE INTERNAL "Folder name to user for installing the Python library.")

if(SKBUILD)
set(MATERIALX_PYTHON_FOLDER_NAME "MaterialX")
endif()

# Helpers for MDL validation
if (MATERIALX_BUILD_GEN_MDL)
set(MATERIALX_MDLC_EXECUTABLE "" CACHE FILEPATH "Full path to the mdlc binary.")
Expand Down Expand Up @@ -207,6 +213,12 @@ set(MATERIALX_SAME_DIR_RPATH "${RPATH_RELATIVE_SYMBOL};${CMAKE_INSTALL_PREFIX}/$
set(MATERIALX_UP_ONE_RPATH "${RPATH_RELATIVE_SYMBOL}/../${MATERIALX_INSTALL_LIB_PATH};${MATERIALX_SAME_DIR_RPATH}")
# For linking to libraries where source is two directories deep, ie: "MATX/python/MaterialX/../../lib"
set(MATERIALX_UP_TWO_RPATH "${RPATH_RELATIVE_SYMBOL}/../../${MATERIALX_INSTALL_LIB_PATH};${MATERIALX_SAME_DIR_RPATH}")
if(SKBUILD)
# When building the Python wheels, we don't want to set any RPATH because
# we want to wheel to be self-contained. We don't want any interference from
# external paths.
set(MATERIALX_UP_TWO_RPATH "${RPATH_RELATIVE_SYMBOL}")
endif()

# Adjust compiler settings
if(MSVC)
Expand Down Expand Up @@ -300,7 +312,7 @@ if(MATERIALX_BUILD_RENDER)
if(MATERIALX_BUILD_GRAPH_EDITOR)
add_subdirectory(source/MaterialXGraphEditor)
endif()
if(MATERIALX_INSTALL_RESOURCES)
if(MATERIALX_INSTALL_RESOURCES AND NOT SKBUILD)
add_subdirectory(resources)
endif()
endif()
Expand Down Expand Up @@ -335,26 +347,28 @@ if(${CMAKE_VERSION} VERSION_GREATER "3.6.2")
endif()

# Install root-level documents
install(FILES LICENSE CHANGELOG.md README.md THIRD-PARTY.md
DESTINATION .)

set(MATERIALX_GEN_CONFIG_PATH "${MATERIALX_INSTALL_LIB_PATH}/cmake/${CMAKE_PROJECT_NAME}")

include(CMakePackageConfigHelpers)
configure_package_config_file(cmake/modules/MaterialXConfig.cmake.in
${CMAKE_BINARY_DIR}/cmake/${CMAKE_PROJECT_NAME}Config.cmake
INSTALL_DESTINATION "${MATERIALX_GEN_CONFIG_PATH}"
PATH_VARS CMAKE_INSTALL_PREFIX CMAKE_PROJECT_NAME)
write_basic_package_version_file(${CMAKE_BINARY_DIR}/cmake/${CMAKE_PROJECT_NAME}ConfigVersion.cmake
VERSION ${MATERIALX_LIBRARY_VERSION}
COMPATIBILITY AnyNewerVersion)

# Install the auto-generated CMake configuration files:

install(EXPORT MaterialX
DESTINATION "${MATERIALX_GEN_CONFIG_PATH}"
FILE ${CMAKE_PROJECT_NAME}Targets.cmake)

install(FILES "${CMAKE_BINARY_DIR}/cmake/${CMAKE_PROJECT_NAME}ConfigVersion.cmake"
"${CMAKE_BINARY_DIR}/cmake/${CMAKE_PROJECT_NAME}Config.cmake"
DESTINATION "${MATERIALX_GEN_CONFIG_PATH}")
if(NOT SKBUILD)
install(FILES LICENSE CHANGELOG.md README.md THIRD-PARTY.md
DESTINATION .)

set(MATERIALX_GEN_CONFIG_PATH "${MATERIALX_INSTALL_LIB_PATH}/cmake/${CMAKE_PROJECT_NAME}")

include(CMakePackageConfigHelpers)
configure_package_config_file(cmake/modules/MaterialXConfig.cmake.in
${CMAKE_BINARY_DIR}/cmake/${CMAKE_PROJECT_NAME}Config.cmake
INSTALL_DESTINATION "${MATERIALX_GEN_CONFIG_PATH}"
PATH_VARS CMAKE_INSTALL_PREFIX CMAKE_PROJECT_NAME)
write_basic_package_version_file(${CMAKE_BINARY_DIR}/cmake/${CMAKE_PROJECT_NAME}ConfigVersion.cmake
VERSION ${MATERIALX_LIBRARY_VERSION}
COMPATIBILITY AnyNewerVersion)

# Install the auto-generated CMake configuration files:

install(EXPORT MaterialX
DESTINATION "${MATERIALX_GEN_CONFIG_PATH}"
FILE ${CMAKE_PROJECT_NAME}Targets.cmake)

install(FILES "${CMAKE_BINARY_DIR}/cmake/${CMAKE_PROJECT_NAME}ConfigVersion.cmake"
"${CMAKE_BINARY_DIR}/cmake/${CMAKE_PROJECT_NAME}Config.cmake"
DESTINATION "${MATERIALX_GEN_CONFIG_PATH}")
endif()
24 changes: 15 additions & 9 deletions libraries/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
DESTINATION "${MATERIALX_INSTALL_STDLIB_PATH}" MESSAGE_NEVER
PATTERN "CMakeLists.txt" EXCLUDE
PATTERN "pbrlib_genosl_impl.*" EXCLUDE)

if (MATERIALX_OSL_LEGACY_CLOSURES)
set(PBRLIB_SUFFIX "legacy")
else()
set(PBRLIB_SUFFIX "mtlx")
endif()

install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/pbrlib/genosl/pbrlib_genosl_impl.${PBRLIB_SUFFIX}"
DESTINATION "${MATERIALX_INSTALL_STDLIB_PATH}/pbrlib/genosl/" RENAME pbrlib_genosl_impl.mtlx)
if(NOT SKBUILD)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
DESTINATION "${MATERIALX_INSTALL_STDLIB_PATH}"
PATTERN "CMakeLists.txt" EXCLUDE
PATTERN "pbrlib_genosl_impl.*" EXCLUDE)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/pbrlib/genosl/pbrlib_genosl_impl.${PBRLIB_SUFFIX}"
DESTINATION "${MATERIALX_INSTALL_STDLIB_PATH}/pbrlib/genosl/" RENAME pbrlib_genosl_impl.mtlx)
endif()

set(MATERIALX_PYTHON_LIBRARIES_PATH "${MATERIALX_PYTHON_FOLDER_NAME}/${MATERIALX_INSTALL_STDLIB_PATH}")
if(SKBUILD)
set(MATERIALX_PYTHON_LIBRARIES_PATH "${SKBUILD_PLATLIB_DIR}/MaterialX/libraries")
endif()

install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
DESTINATION "python/MaterialX/${MATERIALX_INSTALL_STDLIB_PATH}"
DESTINATION "${MATERIALX_PYTHON_LIBRARIES_PATH}"
PATTERN "CMakeLists.txt" EXCLUDE
PATTERN "pbrlib_genosl_impl.*" EXCLUDE)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/pbrlib/genosl/pbrlib_genosl_impl.${PBRLIB_SUFFIX}"
DESTINATION "python/MaterialX/${MATERIALX_INSTALL_STDLIB_PATH}/pbrlib/genosl/" RENAME pbrlib_genosl_impl.mtlx)
DESTINATION "${MATERIALX_PYTHON_LIBRARIES_PATH}/pbrlib/genosl/" RENAME pbrlib_genosl_impl.mtlx)
78 changes: 78 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
[build-system]
# Use a fixed version because we use an experimental feature
# (a custom plugin) and for now that functionality has
# no compatibility promises.
requires = ["scikit-build-core==0.4.4"]
build-backend = "scikit_build_core.build"

[project]
name = "MaterialX"
dynamic = ["version"]

authors = [
{ name="Contributors to the MaterialX project", email="[email protected]" },
]
readme = "README.md"
requires-python = ">=3.6"

classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
]

[project.urls]
"Homepage" = "https://materialx.org"
"Source" = "https://github.com/AcademySoftwareFoundation/MaterialX"
"Bug Tracker" = "https://github.com/AcademySoftwareFoundation/MaterialX/issues"

[project.scripts]
baketextures = "MaterialX._scripts.baketextures:main"
jstone-lucasfilm marked this conversation as resolved.
Show resolved Hide resolved
generateshader = "MaterialX._scripts.generateshader:main"
genmdl = "MaterialX._scripts.genmdl:main"
mxdoc = "MaterialX._scripts.mxdoc:main"
mxupdate = "MaterialX._scripts.mxupdate:main"
mxvalidate = "MaterialX._scripts.mxvalidate:main"
translateshader = "MaterialX._scripts.translateshader:main"
writenodegraphs = "MaterialX._scripts.writenodegraphs:main"

[tool.scikit-build]
cmake.minimum-version = "3.18"
cmake.verbose = false
cmake.build-type = "Release"

# Enable experimental features if any are available
# In this case we need custom local plugin to get
# the project version from cmake.
experimental = true
metadata.version.provider = "mtx_skbuild_plugin"
metadata.version.provider-path = "./python"

# Uncoment when developing locally to enable inplace builds.
# build-dir = "build/"

logging.level = "DEBUG"

# Since the python package doesn't live in a standard directory
# in the source (i.e ./src or ./), we need to manually specify
# where the package is.
wheel.packages = ["python/MaterialX"]

sdist.exclude = [
"/build",
"/dist",
"/resources",
"/javascript",
"/documents",
"/.github",
"MANIFEST.in"
]

[tool.scikit-build.cmake.define]
MATERIALX_BUILD_SHARED_LIBS = 'OFF' # Be explicit
MATERIALX_BUILD_PYTHON = 'ON'
MATERIALX_TEST_RENDER = 'OFF'
jstone-lucasfilm marked this conversation as resolved.
Show resolved Hide resolved
MATERIALX_WARNINGS_AS_ERRORS = 'ON'
MATERIALX_BUILD_TESTS = 'OFF'
# TODO: How could we harmonize this variable with SKBUILD?
MATERIALX_INSTALL_PYTHON = 'OFF'
25 changes: 16 additions & 9 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
set(SETUP_PY_IN "${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in")
set(SETUP_PY "${CMAKE_INSTALL_PREFIX}/python/setup.py")

configure_file(${SETUP_PY_IN} ${SETUP_PY})
if(NOT SKBUILD)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/MaterialX" DESTINATION "python" MESSAGE_NEVER)
jstone-lucasfilm marked this conversation as resolved.
Show resolved Hide resolved
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/Scripts" DESTINATION "python" MESSAGE_NEVER)
endif()

install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/MaterialX" DESTINATION "python" MESSAGE_NEVER)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/Scripts" DESTINATION "python" MESSAGE_NEVER)
if(SKBUILD)
install(
DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/Scripts/"
DESTINATION "${MATERIALX_PYTHON_FOLDER_NAME}/_scripts"
PATTERN "README.md" EXCLUDE
)
endif()

if(MATERIALX_PYTHON_OCIO_DIR)
if(NOT EXISTS "${MATERIALX_PYTHON_OCIO_DIR}/config.ocio")
message(WARNING "No file named config.ocio was found in the given OCIO directory.")
endif()
install(DIRECTORY "${MATERIALX_PYTHON_OCIO_DIR}/" DESTINATION "python/MaterialX/config/" MESSAGE_NEVER)
install(DIRECTORY "${MATERIALX_PYTHON_OCIO_DIR}/" DESTINATION "${MATERIALX_PYTHON_FOLDER_NAME}/config/" MESSAGE_NEVER)
endif()

if(MATERIALX_INSTALL_PYTHON AND PYTHON_EXECUTABLE)
install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} install clean --all)" MESSAGE_NEVER)
if(MATERIALX_INSTALL_PYTHON AND PYTHON_EXECUTABLE AND NOT SKBUILD)
set(SETUP_PY "${CMAKE_INSTALL_PREFIX}/python/setup.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in" "${SETUP_PY}")
install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} install clean --all)")
jstone-lucasfilm marked this conversation as resolved.
Show resolved Hide resolved
endif()
2 changes: 2 additions & 0 deletions python/MaterialX/_scripts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This directory is empty buit it's used when packaging the Python library.
the files in ../../Scripts will be copied inside.
1 change: 1 addition & 0 deletions python/MaterialX/_scripts/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Only required for entry-points.
Loading