Skip to content

Commit 10e8f85

Browse files
committed
Add support for standalone USD compilation
1 parent 58e300e commit 10e8f85

File tree

12 files changed

+413
-14
lines changed

12 files changed

+413
-14
lines changed

.github/scripts/houdini.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ def get_sidefx_platform():
4747
return "macos"
4848
elif current_platform == "Linux":
4949
return "linux"
50-
else:
51-
return ""
50+
raise Exception(f"Platform not supported: {current_platform}")
51+
5252

5353

5454
def download_sidefx_product_release(dir_path, release):

.github/scripts/maya.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def download_file(download_file_path, download_url):
6060

6161

6262
def get_autodesk_platform():
63-
"""Get the active platform usable for SideFX platform API calls
63+
"""Get the active platform usable for Autodesk platform API calls
6464
Returns:
6565
str: The active platform
6666
"""
@@ -71,8 +71,7 @@ def get_autodesk_platform():
7171
return "MacOS"
7272
elif current_platform == "Linux":
7373
return "Linux"
74-
else:
75-
return ""
74+
raise Exception(f"Platform not supported: {current_platform}")
7675

7776

7877
def get_autodesk_maya_usd_sdk_releases(platform_name, maya_version):
@@ -128,7 +127,7 @@ def install_autodesk_product(product, version, dependency_dir_path):
128127
Args:
129128
product (str): The target product name (e.g. maya, etc.)
130129
version (str|None): The target product version (e.g. 2024.4, etc.)
131-
install_dir_path (str): The install dir path.
130+
dependency_dir_path (str): The install dir path.
132131
"""
133132
autodesk_maya_version = version
134133
python_version = MAYA_PYTHON_VERSION_MAPPING[version]
@@ -271,12 +270,12 @@ def install_autodesk_product(product, version, dependency_dir_path):
271270

272271
def create_autodesk_maya_artifact(artifact_src, artifact_dst, artifact_prefix, artifact_product_name, dependency_dir_path):
273272
"""Create a .zip artifact based on the source directory content.
274-
The output name will have will end in the houdini build name.
273+
The output name will have will end in the Maya build name.
275274
276275
Args:
277276
artifact_src (str): The source directory
278277
artifact_dst (str): The target directory
279-
artifact_prefix (str): The file name prefix, the suffix will be the Houdini build name
278+
artifact_prefix (str): The file name prefix, the suffix will be the Maya build name
280279
artifact_product_name (str): The file name product name.
281280
This defines the Maya product name, e.g. like 'maya'
282281
dependency_dir_path (str): The dependency install directory path.

.github/scripts/standalone.py

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
import argparse
2+
import logging
3+
import os
4+
import platform
5+
import requests
6+
import shutil
7+
import subprocess
8+
import json
9+
10+
11+
USD_COMPILED_DOWNLOAD_URL = {
12+
"25.05": {
13+
"Windows": "https://developer.nvidia.com/downloads/USD/usd_binaries/25.05/usd.py311.windows-x86_64.usdview.release-0.25.05-25f3d3d8.zip",
14+
"Linux": "https://developer.nvidia.com/downloads/USD/usd_binaries/25.05/usd.py311.manylinux_2_35_x86_64.usdview.release@0.25.05-25f3d3d8.zip"
15+
},
16+
"24.11": {
17+
"Windows": "https://developer.nvidia.com/downloads/USD/usd_binaries/24.11/usd.py311.windows-x86_64.usdview.release-0.24.11-4d81dd85.zip",
18+
"Linux": "https://developer.nvidia.com/downloads/USD/usd_binaries/24.11/usd.py311.manylinux_2_35_x86_64.usdview.release-0.24.11-4d81dd85.zip"
19+
}
20+
}
21+
SEVENZIP_WINDOWS_DOWNLOAD_URL = {
22+
"2301": "https://www.7-zip.org/a/7z2401-x64.exe"
23+
}
24+
25+
26+
logging.basicConfig(format="%(asctime)s %(message)s", datefmt="%m/%d/%Y %I:%M:%S %p", level=logging.INFO)
27+
28+
29+
def download_file(download_file_path, download_url):
30+
"""Download the release to the directory
31+
Args:
32+
download_file_path (str): The target file
33+
download_url (str): The download url
34+
Returns:
35+
str: The file path of the downloaded file
36+
"""
37+
# Download file
38+
download_dir_path = os.path.dirname(download_file_path)
39+
if not os.path.exists(download_dir_path):
40+
os.makedirs(download_dir_path)
41+
request = requests.get(download_url, stream=True)
42+
if request.status_code == 200:
43+
with open(download_file_path, "wb") as download_file:
44+
request.raw.decode_content = True
45+
shutil.copyfileobj(request.raw, download_file)
46+
else:
47+
raise Exception("Error downloading file | {}".format(download_url))
48+
return download_file_path
49+
50+
51+
def get_standalone_platform():
52+
"""Get the active platform usable for SideFX platform API calls
53+
Returns:
54+
str: The active platform
55+
"""
56+
current_platform = platform.system()
57+
if current_platform == "Windows" or current_platform.startswith("CYGWIN"):
58+
return "Windows"
59+
elif current_platform == "Linux":
60+
return "Linux"
61+
raise Exception(f"Platform not supported: {current_platform}")
62+
63+
64+
def install_standalone_product(product, version, dependency_dir_path):
65+
"""Install a standalone USD release
66+
Args:
67+
version (str|None): The target product version (e.g. 2024.4, etc.)
68+
dependency_dir_path (str): The install dir path.
69+
"""
70+
71+
# Directories
72+
download_dir_path = os.path.join(dependency_dir_path, "download")
73+
install_dir_path = os.path.join(dependency_dir_path, "install")
74+
if os.path.exists(download_dir_path):
75+
shutil.rmtree(download_dir_path)
76+
if os.path.exists(install_dir_path):
77+
shutil.rmtree(install_dir_path)
78+
os.makedirs(download_dir_path)
79+
os.makedirs(install_dir_path)
80+
81+
sevenZip_dir_name = "7zip"
82+
sevenZip_download_dir_path = os.path.join(download_dir_path, sevenZip_dir_name)
83+
sevenZip_install_dir_path = os.path.join(install_dir_path, sevenZip_dir_name)
84+
85+
usd_standalone_dir_name = "usd_standalone"
86+
usd_standalone_download_dir_path = os.path.join(download_dir_path, usd_standalone_dir_name)
87+
usd_standalone_install_dir_path = os.path.join(install_dir_path, usd_standalone_dir_name)
88+
89+
config_file_path = os.path.join(install_dir_path, "config.json")
90+
91+
standalone_platform = get_standalone_platform()
92+
93+
# USD
94+
usd_standalone_download_url = USD_COMPILED_DOWNLOAD_URL[version][standalone_platform]
95+
usd_standalone_download_file_path = os.path.join(usd_standalone_download_dir_path, "usd_standalone.zip")
96+
logging.info("Downloading USD Build {}".format(version))
97+
download_file(usd_standalone_download_file_path, usd_standalone_download_url)
98+
logging.info("Extracting USD Build")
99+
if standalone_platform == "Windows":
100+
# 7Zip
101+
serverZip_version = "2301"
102+
serverZip_download_url = SEVENZIP_WINDOWS_DOWNLOAD_URL[serverZip_version]
103+
serverZip_download_file_path = os.path.join(sevenZip_download_dir_path, "7zip.exe")
104+
logging.info("Downloading 7zip (Build {})".format(serverZip_version))
105+
download_file(serverZip_download_file_path, serverZip_download_url)
106+
logging.info("Installing 7zip")
107+
command = [serverZip_download_file_path, "/S", "/D={}".format(sevenZip_install_dir_path)]
108+
process = subprocess.check_call(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
109+
serverZip_exe_file_path = os.path.join(sevenZip_install_dir_path, "7z.exe")
110+
# Unzip
111+
command = [serverZip_exe_file_path, "x", usd_standalone_download_file_path, "-o{}".format(usd_standalone_install_dir_path)]
112+
process = subprocess.check_call(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
113+
elif standalone_platform == "Linux":
114+
# Unzip
115+
command = ["7z", "x", f"-o{usd_standalone_install_dir_path}", usd_standalone_download_file_path]
116+
process = subprocess.check_call(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
117+
118+
# Store configuration
119+
python_version = os.path.basename(usd_standalone_download_url).split(".")[1]
120+
with open(config_file_path, "w") as config_file:
121+
config = {
122+
"python": python_version,
123+
"usd": version,
124+
}
125+
json.dump(config, config_file)
126+
127+
128+
def create_standalone_artifact(artifact_src, artifact_dst, artifact_prefix, artifact_product_name, dependency_dir_path):
129+
"""Create a .zip artifact based on the source directory content.
130+
The output name will have will end in the houdini build name.
131+
132+
Args:
133+
artifact_src (str): The source directory
134+
artifact_dst (str): The target directory
135+
artifact_prefix (str): The file name prefix, the suffix will be the Houdini build name
136+
artifact_product_name (str): The file name product name.
137+
This defines the Maya product name, e.g. like 'maya'
138+
dependency_dir_path (str): The dependency install directory path.
139+
Returns:
140+
str: The artifact file path
141+
"""
142+
install_dir_path = os.path.join(dependency_dir_path, "install")
143+
config_file_path = os.path.join(install_dir_path, "config.json")
144+
with open(config_file_path, "r") as config_file:
145+
config = json.load(config_file)
146+
147+
usd_version = config["usd"]
148+
python_version = config["python"]
149+
standalone_platform = get_standalone_platform()
150+
artifact_file_path = os.path.join(
151+
artifact_dst, f"{artifact_prefix}_{artifact_product_name}-{usd_version}-{python_version}-{standalone_platform}"
152+
)
153+
artifact_dir_path = os.path.dirname(artifact_file_path)
154+
if not os.path.exists(artifact_dir_path):
155+
os.makedirs(artifact_dir_path)
156+
shutil.make_archive(artifact_file_path, "zip", artifact_src)
157+
158+
159+
if __name__ == "__main__":
160+
# Parse args
161+
parser = argparse.ArgumentParser()
162+
parser.add_argument("--install", action="store_true", help="Install the standalone pre-compiled USD build")
163+
parser.add_argument(
164+
"--install_standalone_product_name",
165+
help="Standalone product name to install. If not provided, fallback to the default.",
166+
)
167+
parser.add_argument(
168+
"--install_standalone_product_version",
169+
help="USD product version to install.",
170+
)
171+
parser.add_argument(
172+
"--install_directory",
173+
help="The installation directory.",
174+
)
175+
parser.add_argument("--artifact", action="store_true", help="Create artifact")
176+
parser.add_argument("--artifact_src", help="Artifact source directory")
177+
parser.add_argument("--artifact_dst", help="Artifact target directory")
178+
parser.add_argument("--artifact_prefix", help="Artifact name prefix")
179+
parser.add_argument("--artifact_product_name", help="Artifact product name")
180+
args = parser.parse_args()
181+
# Execute
182+
# Install precompiled standalone USD with headers
183+
if args.install:
184+
install_standalone_product(
185+
args.install_standalone_product_name,
186+
args.install_standalone_product_version,
187+
args.install_directory
188+
)
189+
# Create artifact tagged with stand build name (expects standalone USD build to be installed via the above install command)
190+
if args.artifact:
191+
create_standalone_artifact(
192+
args.artifact_src, args.artifact_dst, args.artifact_prefix, args.artifact_product_name, args.install_directory
193+
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
set USD_STANDALONE_ROOT=%cd%\dependency\install\usd_standalone
2+
set AR_DCC_NAME=STANDALONE
3+
set AR_RESOLVER_NAME=%1
4+
cmake . -B build -G %2 -A x64 -T %3
5+
cmake --build build --clean-first --config Release
6+
cmake --install build
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
repo_root=$(cd .; pwd)
2+
export USD_STANDALONE_ROOT=$repo_root/dependency/install/usd_standalone
3+
export AR_DCC_NAME=STANDALONE
4+
export AR_RESOLVER_NAME=$1
5+
cmake . -B build && cmake --build build --clean-first
6+
cmake --install build
7+
ctest -VV --test-dir build # Run tests

0 commit comments

Comments
 (0)