Import('env')
import os
import os.path
import sys
def run_doxygen(target, source, env):
os.environ['PATH']=env['ENV']['PATH']
env.Execute("doxygen --version")
env.Execute("doxygen "+source[0].abspath)
def print_doxygen(target, source, env):
print "running doxygen"
def print_generate_doxygen(target, source, env):
print "generating doxygen configuration"
def print_generate_doxygen_header(target, source, env):
print "generating doxygen header ", target[0].path
def make_defs(target, source, env):
os.environ['PATH']=env['ENV']['PATH']
env.Execute("grep -v \"#include\" "+source[0].abspath+"| cpp -C -DIMP_DOXYGEN -dM - | grep -v \"define __\" > "+target[0].abspath)
def print_make_defs(target, source, env):
print "running cpp ", str(target), str(source)
def make_output(nodes):
return " "+"\\\n ".join(['"'+x.abspath+'"' for x in nodes])
def generate_doxygen_header(target, source, env):
print "generate header from ", source[0].path
infile = file(source[0].path, 'r')
outfile= file(target[0].path, 'w')
for l in infile:
if l.find("DOXYGEN STUFF GOES HERE") != -1:
outfile.write('\n')
# Older doxygen versions use a PHP search engine instead of JS
if env['DOXYGEN_VERSION'] >= (1,6,0):
outfile.write("""
""");
else:
outfile.write(l)
# Generate doxygen.conf from doxygen.conf.in
def generate_doxygen(target, source, env):
print "generating doxygen.conf"
infile = file(source[0].path, 'r')
outfile = file(target[0].path, 'w')
source_path= os.path.split(os.path.split(os.path.split(source[0].abspath)[0])[0])[0]
target_path= os.path.split(os.path.split(os.path.split(target[0].abspath)[0])[0])[0]
print >> outfile, "# Auto-generated by SConscript; do NOT edit directly!"
print >> outfile, "# Edit %s instead\n" % source[0].path
examples=[]
inputs=[]
images=[]
dots=[]
has_dot=str(source[1].get_contents())
for s in source[2:]:
ss= str(s)
if ss.endswith(".png"):
images.append(s)
else:
put=False
if ss.find('example') !=-1 and not ss.endswith(".dox"):
examples.append(s)
put=True
if ss.endswith(".dox") \
or ss.endswith(".h"):
inputs.append(s)
put=True
elif ss.endswith(".py"):
put=True
if ss.find("/_") ==-1 or ss.endswith("__init__.py"):
inputs.append(s)
elif ss.endswith(".dot"):
dots.append(s)
put = True
elif ss.endswith(".def"):
put = True
elif ss.endswith("header.txt"):
put = True
if not put:
print >> sys.stderr, "Warning, do not know what to do with the file "+ ss
for line in infile:
if '@IMP_IMAGES@' in line:
outfile.write(make_output(images))
elif '@INPUTS@' in line:
outfile.write(make_output(inputs))
elif '@IMP_EXAMPLES@' in line:
outfile.write(make_output(examples))
elif '@IMP_DOTS@' in line:
outfile.write(make_output(dots))
elif '@IMP_SOURCE_PATH@' in line:
outfile.write(line.replace('@IMP_SOURCE_PATH@', source_path))
elif '@IMP_TARGET_PATH@' in line:
outfile.write(line.replace('@IMP_TARGET_PATH@', target_path))
elif '@IMP_ENABLED_SECTIONS@' in line:
if has_dot == "True":
outfile.write(line.replace('@IMP_ENABLED_SECTIONS@', "graphs"))
else:
outfile.write("")
elif '@IMP_HAS_DOT@' in line:
if has_dot=="True":
outfile.write(line.replace('@IMP_HAS_DOT@', 'YES'))
else:
outfile.write(line.replace('@IMP_HAS_DOT@', 'NO'))
elif not line.startswith('#'):
outfile.write(line)
infile.close()
outfile.close()
def generate_example_index(target, source, env):
print "generating index"
outfile= open(target[0].abspath, "w")
print >> outfile, """/** \page examples IMP Examples
Each modules has its own set of examples demonstrating how to use the features of that particular module."""
for p in source:
contents= open(p.abspath, "r").read()
# rather dumb, I think
name= contents[contents.find("\page")+6:].split(" ")[0]
print >> outfile, " - \\ref "+name +"\n"
print >> outfile, "*/"
print "done generating examples"
if not env['doxygen']:
print "Warning: IMP documentation requires doxygen."
Return
env.Append(BUILDERS = {'RunDoxygen': Builder(action=env.Action(run_doxygen,
print_doxygen))})
env.Append(BUILDERS = {'MakeDefs': Builder(action=env.Action(make_defs,
make_defs))})
docdir = env.GetInstallDirectory('docdir', 'html')
# Install all files from 'dox' directory into the 'docdir' directory (cannot
# use env.InstallAs() right now, due to scons bug #1751)
input_files=Glob("#/examples/README") +Glob("#/examples/*/README")\
+Glob("#/examples/*.py") +Glob("#/examples/*/*.py")\
+Glob("#/examples/*.cpp") +Glob("#/examples/*/*.cpp")
env.Append(BUILDERS = {'GenerateDoxygen': Builder(action=env.Action(generate_doxygen,
print_generate_doxygen))})
env.Append(BUILDERS = {'GenerateDoxygenHeader': Builder(action=env.Action(generate_doxygen_header,
print_generate_doxygen_header))})
env.Append(BUILDERS = {'GenerateExamples': Builder(action=generate_example_index)})
modexamples = Glob("#/modules/*/examples/generated/examples.dox",
ondisk=False) \
+ ['#/kernel/examples/generated/examples.dox']
example_index = env.GenerateExamples("generated/all_examples.dox", modexamples)
rawheaders=[]
for h in Glob("#/build/include/*.h", ondisk=False) \
+ Glob("#/build/include/IMP/*.h", ondisk=False) \
+ Glob("#/build/include/IMP/*/*.h", ondisk=False):
if h.path.find("internal")==-1:
rawheaders.append(h)
headers=[]
config=[]
# leftover from attempt to get things to work with 1.6.1.
macros=[]
for h in rawheaders:
if h.path.endswith('macros.h'):
macros.append(h)
elif h.path.endswith('config.h'):
config.append(h)
else:
headers.append(h)
headers= config+macros+headers
macrodef=[]
for m in macros:
nm='generated/' + m.abspath[m.abspath.rfind("/")+1:]+".def"
#print nm
macrodef.append(env.MakeDefs(source=m, target=nm))
sources = headers + macrodef+ Glob("#/kernel/doc/*.dox") + [example_index] \
+ Glob("#/doc/*.dox") \
+ Glob("#/modules/*/doc/*.dox") \
+ Glob("#/modules/*/examples/*.xml") \
+ Glob("#/modules/*/examples/*/*.xml") \
+ Glob("#/kernel/doc/generated/*.dox") \
+ Glob("#/modules/*/doc/generated/*.dox") + modexamples \
+ Glob("#/modules/*/doc/*.dot") + Glob("#/kernel/doc/*.dot")
if env['IMP_PROVIDE_PYTHON']:
for p in env.get('IMP_PYTHON_DOCS', []):
sources += Glob("#/build/lib/IMP/"+p+"/*.py", ondisk=False) \
+ Glob("#/build/lib/IMP/"+p+"/*/*.py", ondisk=False)
examples= Glob("#/modules/example/src/*.cpp") + Glob("#/build/include/IMP/example/*.h")\
+ Glob("#/modules/*/examples/*.py") + Glob("#/modules/*/examples/*/*.py")\
+ Glob("#/modules/*/examples/*.cpp") + Glob("#/modules/*/examples/*/*.cpp")\
+ Glob("#/modules/*/examples/generated/*.html") \
+ Glob("#/modules/*/examples/*/generated/*.html")\
+ Glob("#/kernel/examples/*.py") + Glob("#/kernel/examples/*/*.py")\
+ Glob("#/kernel/examples/*.cpp") + Glob("#/kernel/examples/*/*.cpp")\
+ Glob("#/kernel/examples/generated/*.html") \
+ Glob("#/kernel/examples/*/generated/*.html")\
+ Glob("#/modules/*/doc/*.dox") + Glob("#/modules/*/doc/*/*.dox")\
+ Glob("#/modules/*/doc/*.png") + Glob("#/modules/*/doc/*/*.png")\
+ Glob("#/modules/*/doc/*.html") + Glob("#/modules/*/doc/*/*.html")\
+ Glob("#/kernel/doc/*.dox") + Glob("#/kernel/doc/*/*.dox")\
+ Glob("#/kernel/doc/*.png") + Glob("#/kernel/doc/*/*.png")\
+ Glob("#/kernel/doc/*.html") + Glob("#/kernel/doc/*/*.html")\
#sources.sort()
examples.sort()
doxyheader= env.GenerateDoxygenHeader(target=["#/doc/doxygen/generated/header.txt"],
source=["#/website/header.txt"])
env.Alias('doxygen-header', doxyheader)
doxconf=env.GenerateDoxygen("doxygen.conf", ["doxygen.conf-in", env.Value(env['dot'])] +sources+examples)
env.Depends(doxconf, ['#/build/include'])
dox = env.RunDoxygen("#/build/doc/html/index.html", ["doxygen.conf"]+sources+[doxyheader])
env.Depends(dox, '#/doc/doxygen/doxypy.py')
env.Requires(dox, env.Alias("doc-files"))
install=env.Command(Dir(env.subst(docdir)), dox,
"install -d $TARGET && cp -r ${SOURCE.dir}/* $TARGET")
env.Alias('doc-install', install)
env.Alias('doc', dox)
env.Requires(install, env.Alias('doc'))
Clean(dox, Glob("#/build/doc/html/*"))