Building MaterialX via Python¶

See the Github repo where the notebook for this is hosted. The repo can be forkded / cloned and modified as desired.

The following is a simple example of building MaterialX from within Python. It assumes each step will be run once for cloning, and the build step done as many times as needed. A test of the build is done by running a MaterialX executable.

Note that this is example is written for a Windows build. Suitable build setup can be done for Linux and Mac as well.

Setup¶

Use OS and subprocess to run commands. Cache the root directory so we can return to it as needed

In [ ]:
import os
import subprocess
import sys

rootdir = os.getcwd()
print('Root folder: ', rootdir)
Root folder:  d:\Work\materialx\buildMaterialX
In [ ]:
def printLog(logfile):
    f = open(logfile, 'r')
    print(f.read())
    f.close()

Clone the Repo¶

This will clone the ASWF repo into a subfolder called MaterialX:

In [ ]:
print('Cloning MaterialX...')
os.chdir(rootdir)
result = os.system('git clone https://github.com/AcademySoftwareFoundation/MaterialX.git > clone.log 2>&1')
print('Finished clone: %s' % ('Success' if result == 0 else 'Failed'))
if result != 0:
    printLog('clone.log')
Cloning MaterialX...
Finished clone: Failed
fatal: destination path 'MaterialX' already exists and is not an empty directory.

Get Submodules¶

Go to the MaterialX folder and get the submodules

In [ ]:
os.chdir(rootdir)
os.chdir('MaterialX')

print('Get submodules...')
result = os.system('git submodule update --init --recursive > submodule.log 2>&1')
print('Finished getting submodules:', result)
if result != 0:
    printLog('submodule.log')
Get submodules...
Finished getting submodules: 0

Create a "build" folder¶

In [ ]:
os.chdir(rootdir)
os.chdir('MaterialX')
if not os.path.exists('build'):
    os.mkdir('build')

os.chdir('build')
print('Build folder is: ', os.getcwd())
Build folder is:  d:\Work\materialx\buildMaterialX\MaterialX\build

Setup Platform / OS Build¶

As required platform / OS pre-requisites should be installed.

For example for Linux see this page which will be required when running a Codespace on remote host. gcc should already be installed but can be checked using by running gcc -v

In [ ]:
# Pre-build setup for Linux
if sys.platform == 'linux':
    os.system('sudo apt-get update')
    os.system('sudo apt-get install xorg-dev mesa-utils')

Setup Build Configuration MaterialX¶

Go to the build folder and run CMake to set up build configuration.

In [ ]:
os.chdir(rootdir)
os.chdir('MaterialX')
os.chdir('build')

# Build setup
buildSetupCmd = 'cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON  -DMATERIALX_BUILD_VIEWER=ON -DMATERIALX_BUILD_GRAPH_EDITOR=ON -DMATERIALX_BUILD_PYTHON=ON -DMATERIALX_WARNINGS_AS_ERRORS=ON'

# Check the current OS for build setup options
osOptions = ''
if sys.platform == 'win32':
    osOptions = ' -G "Visual Studio 16 2019" -A "x64" -DCMAKE_BUILD_TYPE=RelWithDebInfo ' 
# else check if linux
elif sys.platform == 'linux':
    osOptions = ''
else:
    osOptions = ''

result = os.system(buildSetupCmd + osOptions + ' -S .. > buildsetup.log 2>&1')
print('Finished build setup: %s' % ('Success' if result == 0 else 'Failed'))
printLog('buildsetup.log')
Finished build setup: Success
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19045.
-- Setting namespace to 'MaterialX_v1_38_9'
-- NanoGUI v0.2.0 
-- NanoGUI: using OpenGL backend.
-- NanoGUI: building static library.
-- Using Win32 for window creation
-- NanoGUI: not building the Python plugin.
CMake Deprecation Warning at source/MaterialXGraphEditor/External/Glfw/CMakeLists.txt:1 (cmake_minimum_required):
  Compatibility with CMake < 3.5 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value or use a ...<max> suffix to tell
  CMake that the project does not need compatibility with older versions.


-- Using Win32 for window creation
CMake Deprecation Warning at source/PyMaterialX/External/PyBind11/CMakeLists.txt:8 (cmake_minimum_required):
  Compatibility with CMake < 3.5 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value or use a ...<max> suffix to tell
  CMake that the project does not need compatibility with older versions.


-- pybind11 v2.10.4 
CMake Warning (dev) at source/PyMaterialX/External/PyBind11/tools/FindPythonLibsNew.cmake:98 (find_package):
  Policy CMP0148 is not set: The FindPythonInterp and FindPythonLibs modules
  are removed.  Run "cmake --help-policy CMP0148" for policy details.  Use
  the cmake_policy command to set the policy and suppress this warning.

Call Stack (most recent call first):
  source/PyMaterialX/External/PyBind11/tools/pybind11Tools.cmake:50 (find_package)
  source/PyMaterialX/External/PyBind11/tools/pybind11Common.cmake:180 (include)
  source/PyMaterialX/External/PyBind11/CMakeLists.txt:208 (include)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Configuring done (0.5s)
-- Generating done (2.1s)
-- Build files have been written to: D:/Work/materialx/buildMaterialX/MaterialX/build

Build MaterialX¶

In [ ]:
os.chdir(rootdir)
os.chdir('MaterialX')
os.chdir('build')
result = os.system('cmake --build . --target install --config RelWithDebInfo > build.log 2>&1')
print('Finished build: %s' % ('Success' if result == 0 else 'Failed'))
printLog('build.log')
Finished build: Success
Microsoft (R) Build Engine version 16.11.2+f32259642 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.

  glfw_objects.vcxproj -> D:\Work\materialx\buildMaterialX\MaterialX\build\source\MaterialXView\external\NanoGUI\ext\glfw\src\glfw_objects.dir\RelWithDebInfo\glfw_objects.lib
  MaterialXCore.vcxproj -> D:\Work\materialx\buildMaterialX\MaterialX\build\lib\RelWithDebInfo\MaterialXCore.lib
  MaterialXFormat.vcxproj -> D:\Work\materialx\buildMaterialX\MaterialX\build\lib\RelWithDebInfo\MaterialXFormat.lib
  MaterialXGenShader.vcxproj -> D:\Work\materialx\buildMaterialX\MaterialX\build\lib\RelWithDebInfo\MaterialXGenShader.lib
  ...
  PyMaterialXGenMsl.vcxproj -> D:\Work\materialx\buildMaterialX\MaterialX\build\bin\RelWithDebInfo\PyMaterialXGenMsl.cp310-win_amd64.pyd
  PyMaterialXGenOsl.vcxproj -> D:\Work\materialx\buildMaterialX\MaterialX\build\bin\RelWithDebInfo\PyMaterialXGenOsl.cp310-win_amd64.pyd
  PyMaterialXRender.vcxproj -> D:\Work\materialx\buildMaterialX\MaterialX\build\bin\RelWithDebInfo\PyMaterialXRender.cp310-win_amd64.pyd
  PyMaterialXRenderGlsl.vcxproj -> D:\Work\materialx\buildMaterialX\MaterialX\build\bin\RelWithDebInfo\PyMaterialXRenderGlsl.cp310-win_amd64.pyd
  PyMaterialXRenderOsl.vcxproj -> D:\Work\materialx\buildMaterialX\MaterialX\build\bin\RelWithDebInfo\PyMaterialXRenderOsl.cp310-win_amd64.pyd
  1>
  -- Install configuration: "RelWithDebInfo"
  -- Up-to-date: D:/Work/materialx/buildMaterialX/MaterialX/build/installed/./LICENSE
  -- Up-to-date: D:/Work/materialx/buildMaterialX/MaterialX/build/installed/./CHANGELOG.md
  -- Up-to-date: D:/Work/materialx/buildMaterialX/MaterialX/build/installed/./README.md
  ...
  -- Up-to-date: D:/Work/materialx/buildMaterialX/MaterialX/build/installed/python/MaterialX/PyMaterialXRenderOsl.lib
  -- Up-to-date: D:/Work/materialx/buildMaterialX/MaterialX/build/installed/python/MaterialX/PyMaterialXRenderOsl.cp310-win_amd64.pyd
  running install
  D:\Work\materialx\buildMaterialX\.venv\lib\site-packages\setuptools\command\install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
    warnings.warn(
  D:\Work\materialx\buildMaterialX\.venv\lib\site-packages\setuptools\command\easy_install.py:144: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.
    warnings.warn(
  running bdist_egg
  running egg_info
  writing MaterialX.egg-info\PKG-INFO
  writing dependency_links to MaterialX.egg-info\dependency_links.txt
  writing top-level names to MaterialX.egg-info\top_level.txt
  reading manifest file 'MaterialX.egg-info\SOURCES.txt'
  writing manifest file 'MaterialX.egg-info\SOURCES.txt'
  installing library code to build\bdist.win-amd64\egg
  running install_lib
  running build_py
  creating build
  creating build\lib
  creating build\lib\MaterialX
  copying MaterialX\colorspace.py -> build\lib\MaterialX
  copying MaterialX\datatype.py -> build\lib\MaterialX
  copying MaterialX\main.py -> build\lib\MaterialX
  copying MaterialX\__init__.py -> build\lib\MaterialX
  copying MaterialX\MANIFEST.in -> build\lib\MaterialX
  copying MaterialX\PyMaterialXCore.cp310-win_amd64.pyd -> build\lib\MaterialX
  copying MaterialX\PyMaterialXCore.lib -> build\lib\MaterialX
  copying MaterialX\PyMaterialXFormat.cp310-win_amd64.pyd -> build\lib\MaterialX
  copying MaterialX\PyMaterialXFormat.lib -> build\lib\MaterialX
  copying MaterialX\PyMaterialXGenGlsl.cp310-win_amd64.pyd -> build\lib\MaterialX
  copying MaterialX\PyMaterialXGenGlsl.lib -> build\lib\MaterialX
  ...
  copying build\lib\MaterialX\PyMaterialXRenderOsl.cp310-win_amd64.pyd -> build\bdist.win-amd64\egg\MaterialX
  copying build\lib\MaterialX\PyMaterialXRenderOsl.lib -> build\bdist.win-amd64\egg\MaterialX
  creating build\bdist.win-amd64\egg\MaterialX\_scripts
  copying build\lib\MaterialX\_scripts\README.md -> build\bdist.win-amd64\egg\MaterialX\_scripts
  copying build\lib\MaterialX\_scripts\__init__.py -> build\bdist.win-amd64\egg\MaterialX\_scripts
  copying build\lib\MaterialX\__init__.py -> build\bdist.win-amd64\egg\MaterialX
  byte-compiling build\bdist.win-amd64\egg\MaterialX\colorspace.py to colorspace.cpython-310.pyc
  byte-compiling build\bdist.win-amd64\egg\MaterialX\datatype.py to datatype.cpython-310.pyc
  byte-compiling build\bdist.win-amd64\egg\MaterialX\main.py to main.cpython-310.pyc
  byte-compiling build\bdist.win-amd64\egg\MaterialX\_scripts\__init__.py to __init__.cpython-310.pyc
  byte-compiling build\bdist.win-amd64\egg\MaterialX\__init__.py to __init__.cpython-310.pyc
  creating build\bdist.win-amd64\egg\EGG-INFO
  copying MaterialX.egg-info\PKG-INFO -> build\bdist.win-amd64\egg\EGG-INFO
  copying MaterialX.egg-info\SOURCES.txt -> build\bdist.win-amd64\egg\EGG-INFO
  copying MaterialX.egg-info\dependency_links.txt -> build\bdist.win-amd64\egg\EGG-INFO
  copying MaterialX.egg-info\not-zip-safe -> build\bdist.win-amd64\egg\EGG-INFO
  copying MaterialX.egg-info\top_level.txt -> build\bdist.win-amd64\egg\EGG-INFO
  writing build\bdist.win-amd64\egg\EGG-INFO\native_libs.txt
  creating 'dist\MaterialX-1.38.9-py3.10.egg' and adding 'build\bdist.win-amd64\egg' to it
  removing 'build\bdist.win-amd64\egg' (and everything under it)
  Processing MaterialX-1.38.9-py3.10.egg
  removing 'd:\work\materialx\buildmaterialx\.venv\lib\site-packages\MaterialX-1.38.9-py3.10.egg' (and everything under it)
  creating d:\work\materialx\buildmaterialx\.venv\lib\site-packages\MaterialX-1.38.9-py3.10.egg
  Extracting MaterialX-1.38.9-py3.10.egg to d:\work\materialx\buildmaterialx\.venv\lib\site-packages
  MaterialX 1.38.9 is already the active version in easy-install.pth
  
  Installed d:\work\materialx\buildmaterialx\.venv\lib\site-packages\materialx-1.38.9-py3.10.egg
  Processing dependencies for MaterialX==1.38.9
  Finished processing dependencies for MaterialX==1.38.9
  running clean
  removing 'build\lib' (and everything under it)
  removing 'build\bdist.win-amd64' (and everything under it)
  'build\scripts-3.10' does not exist -- can't clean it
  removing 'build'

Test MaterialX¶

Run a few tests to check that the build was successful:

  1. Run Python script to generate shader code
  2. Run MaterialX Graph Editor
In [ ]:
# Runr the generateshader.py script on one of the example materials
os.chdir(rootdir)
os.chdir('MaterialX')
result = os.system('python python/Scripts/generateShader.py resources/Materials/Examples/StandardSurface/standard_surface_glass_tinted.mtlx > genshader.log 2>&1')
printLog('genshader.log')
---------- Generate code for file:  resources/Materials/Examples/StandardSurface/standard_surface_glass_tinted.mtlx --------------------
- Set up CMS ...
- Set up Units ...
- Shader output path: d:\Work\materialx\buildMaterialX\MaterialX\resources\Materials\Examples\StandardSurface
-- Generate code for node: GlassTinted
--- Wrote pixel shader to: d:\Work\materialx\buildMaterialX\MaterialX\resources\Materials\Examples\StandardSurface/GlassTinted.glsl.frag
--- Wrote vertex shader to: d:\Work\materialx\buildMaterialX\MaterialX\resources\Materials\Examples\StandardSurface/GlassTinted.glsl.vert
--- Validation passed for node: GlassTinted

In [ ]:
# Run the MaterialX Editor from the install location
os.chdir(rootdir)
cmd = 'MaterialX/build/installed/bin/MaterialXGraphEditor.exe'
if os.path.exists(cmd):
    result = subprocess.Popen([cmd, '-c 1'], stdout = subprocess.PIPE)
else:
    print('MaterialXGraphEditor.exe not found')