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/*"))