from __future__ import print_function
import sys, os, argparse, shutil, subprocess, tempfile, platform, stat
def _getModules(sourceRoot):
modules = []
topLevel = []
for p in os.listdir(sourceRoot):
if os.path.basename(p).startswith('.'):
continue
path = os.path.join(sourceRoot, p)
if os.path.isdir(path):
topLevel.append(path)
path = os.path.join(os.path.join(sourceRoot, p), 'plugin/')
if os.path.isdir(path):
topLevel.append(path)
for t in topLevel:
for p in os.listdir(t):
if os.path.basename(p).startswith('.'):
continue
elif os.path.basename(p).startswith('CMakeFiles'):
continue
elif os.path.basename(p).startswith('testenv'):
continue
path = os.path.join(os.path.join(sourceRoot, t), p)
if os.path.isdir(path):
modules.append(path)
return modules
def _generateDocs(pxrSourceRoot, thirdSourceRoot, pxrBuildRoot, installLoc,
doxygenBin, dotBin):
docsLoc = os.path.join(installLoc, 'src/modules')
if not os.path.exists(docsLoc):
os.makedirs(docsLoc)
modules = _getModules(pxrSourceRoot)
modules.extend(_getModules(thirdSourceRoot))
for mod in modules:
target = os.path.join(docsLoc, os.path.basename(mod))
if os.path.exists(target):
def _removeReadOnly(func, path, exc):
try:
os.chmod(path, stat.S_IWRITE)
func(path)
except Exception as exc:
print("Failed to remove %s: %s" % (path, str(exc)),
file=sys.stderr)
shutil.rmtree(target, onerror=_removeReadOnly)
shutil.copytree(mod, target)
pxrMod = os.path.join(docsLoc, 'pxr')
if not os.path.exists(pxrMod):
os.makedirs(pxrMod)
pxrHeaderSrc = os.path.join(pxrBuildRoot, 'include', 'pxr', 'pxr.h')
pxrHeaderDest = os.path.join(pxrMod, 'pxr.h')
if os.path.exists(pxrHeaderDest):
os.remove(pxrHeaderDest)
shutil.copyfile(pxrHeaderSrc, pxrHeaderDest)
doxyConfigSrc = os.path.join(pxrBuildRoot, 'Doxyfile')
doxyConfigDest = os.path.join(docsLoc, 'usd', 'Doxyfile')
if os.path.exists(doxyConfigDest):
os.remove(doxyConfigDest)
shutil.copyfile(doxyConfigSrc, doxyConfigDest)
os.chdir(installLoc)
cmd = [doxygenBin, doxyConfigDest]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
output = proc.communicate()[0]
if proc.wait() != 0:
print(output.replace('\r\n', '\n'), file=sys.stderr)
sys.exit('Error: doxygen failed to complete; '
'exit code %d.' % proc.returncode)
def _checkPath(path, ident, perm):
if not os.path.exists(path):
sys.exit('Error: file path %s (arg=%s) '
'does not exist, exiting.' % (path,ident))
elif not os.access(path, perm):
permString = '-permission'
if perm == os.W_OK:
permString = 'write'+permString
elif perm == os.R_OK:
permString = 'read'+permString
elif perm == os.X_OK:
permString = 'execute'+permString
sys.exit('Error: insufficient permission for path %s, '
'%s required.' % (path, permString))
def _generateInstallLoc(installRoot):
installPath = os.path.join(installRoot, 'docs')
if not os.path.exists(installPath):
os.mkdir(installPath)
return installPath
if __name__ == "__main__":
p = argparse.ArgumentParser(description="Generate USD documentation.")
p.add_argument("source", help="The path to the pxr source root.")
p.add_argument("third_source", help="The path to the third_party source root.")
p.add_argument("build", help="The path to the build directory root.")
p.add_argument("install", help="The install root for generated docs.")
p.add_argument("doxygen", help="The path to the doxygen executable.")
p.add_argument("dot", help="The path to the dot executable.")
args = p.parse_args()
_checkPath(args.source, 'source', os.R_OK)
_checkPath(args.third_source, 'third_source', os.R_OK)
_checkPath(args.build, 'build', os.R_OK)
_checkPath(args.install, 'install', os.W_OK)
_checkPath(args.doxygen, 'doxygen', os.X_OK)
_checkPath(args.dot, 'dot', os.X_OK)
installPath = _generateInstallLoc(args.install)
_generateDocs(args.source, args.third_source, args.build, installPath,
args.doxygen, args.dot)