Skip to content
Snippets Groups Projects
Commit 1536e0f7 authored by Joseph Mirabel's avatar Joseph Mirabel
Browse files

Add doxygen -> C++ generation file.

parent f40713a2
No related branches found
No related tags found
No related merge requests found
#ifndef DOXYGEN_BOOST_DOC_HH
#define DOXYGEN_BOOST_DOC_HH
#ifndef DOXYGEN_DOC_HH
# error "You should have included doxygen.hh first."
#endif // DOXYGEN_DOC_HH
#include <boost/python.hpp>
namespace doxygen
{
namespace visitor
{
template <typename function_type>
struct member_func_impl : boost::python::def_visitor<member_func_impl<function_type> >
{
member_func_impl(const char* n, function_type f) : name(n), function(f) {}
template <class classT>
inline void visit(classT& c) const
{
c.def(name, function, doxygen::member_func_doc(function));
}
const char* name;
function_type function;
};
// TODO surprisingly, this does not work when defined here but it works when
// defined after the generated files are included.
template <typename function_type>
inline member_func_impl<function_type> member_func (const char* name, function_type function)
{
return member_func_impl<function_type>(name, function);
}
} // namespace visitor
} // namespace doxygen
#endif // DOXYGEN_BOOST_DOC_HH
#ifndef DOXYGEN_DOC_HH
#define DOXYGEN_DOC_HH
#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#ifndef DOXYGEN_DOC_MAX_NUMBER_OF_ARGUMENTS_IN_CONSTRUCTOR
#define DOXYGEN_DOC_MAX_NUMBER_OF_ARGUMENTS_IN_CONSTRUCTOR 10
#endif
namespace doxygen
{
template <typename _class>
struct class_doc_impl
{
static inline const char* run ()
{
return "";
}
};
template <typename _class>
inline const char* class_doc ()
{
return class_doc_impl<_class>::run();
}
template <typename FuncPtr>
inline const char* member_func_doc (FuncPtr)
{
return "";
}
#define DOXYGEN_DOC_DECLARE_CONSTRUCTOR(z,nargs,unused) \
template < \
typename Class \
BOOST_PP_COMMA_IF(nargs) \
BOOST_PP_ENUM_PARAMS(nargs, class Arg)> \
struct constructor_doc_##nargs##_impl { \
static inline const char* run () \
{ \
return ""; \
} \
}; \
\
template < \
typename Class \
BOOST_PP_COMMA_IF(nargs) \
BOOST_PP_ENUM_PARAMS(nargs, class Arg)> \
inline const char* constructor_doc () \
{ \
return constructor_doc_##nargs##_impl< \
Class \
BOOST_PP_COMMA_IF(nargs) \
BOOST_PP_ENUM_PARAMS(nargs, Arg)>::run(); \
}
BOOST_PP_REPEAT(DOXYGEN_DOC_MAX_NUMBER_OF_ARGUMENTS_IN_CONSTRUCTOR, DOXYGEN_DOC_DECLARE_CONSTRUCTOR, ~)
/*
template <typename Class>
inline const char* constructor_doc ()
{
return "";
}
*/
template <typename Class>
struct destructor_doc_impl
{
static inline const char* run ()
{
return "";
}
};
template <typename Class>
inline const char* destructor_doc ()
{
return destructor_doc_impl<Class>::run();
}
/* TODO class attribute can be handled by
template <typename Class, typename AttributeType>
const char* attribute_doc (AttributeType Class::* ptr)
{
// Body looks like
// if (ptr == &Class::attributeName)
// return "attrib documentation";
return "undocumented";
}
*/
} // namespace doxygen
#endif // DOXYGEN_DOC_HH
#!/usr/bin/python3
from __future__ import print_function
from lxml import etree
from os import path
from xml_docstring import XmlDocString
import sys
template_file_header = \
"""#ifndef DOXYGEN_AUTODOC_{header_guard}
#define DOXYGEN_AUTODOC_{header_guard}
#include "{path}/doxygen.hh"
"""
template_file_footer = \
"""
#endif // DOXYGEN_AUTODOC_{header_guard}
"""
template_class_doc = \
"""
template <{tplargs}>
struct class_doc_impl< {classname} >
{{
static inline const char* run ()
{{
return "{docstring}";
}}
}};"""
template_constructor_doc = \
"""
template <{tplargs}>
struct constructor_doc_{nargs}_impl< {classname_prefix}{comma}{argsstring} >
{{
static inline const char* run ()
{{
return "{docstring}";
}}
}};"""
template_destructor_doc = \
"""
template <{tplargs}>
struct destructor_doc_impl < {classname_prefix} >
{{
static inline const char* run ()
{{
return "{docstring}";
}}
}};"""
template_member_func_doc = \
"""
{template}inline const char* member_func_doc ({rettype} ({classname_prefix}*function_ptr) {argsstring})
{{{body}
return "";
}}"""
template_member_func_doc_body = \
"""
if (function_ptr == static_cast<{rettype} ({classname_prefix}*) {argsstring}>(&{classname_prefix}{membername}))
return "{docstring}";"""
template_static_func_doc = \
"""
{template}inline const char* member_func_doc ({rettype} (*function_ptr) {argsstring})
{{{body}
return "";
}}"""
template_static_func_doc_body = \
"""
if (function_ptr == static_cast<{rettype} (*) {argsstring}>(&{namespace}::{membername}))
return "{docstring}";"""
template_open_namespace = \
"""namespace {namespace} {{"""
template_close_namespace = \
"""}} // namespace {namespace}"""
template_include_intern = \
"""#include "{filename}"
"""
template_include_extern = \
"""#include <{filename}>
"""
def _templateParamToDict (param):
type = param.find('type')
declname = param.find('declname')
defname = param.find('defname')
# FIXME type may contain references in two ways:
# - the real param type
# - the name of the template argument is recognized as the name of a type...
if defname is None and declname is None:
typetext = type.text
for c in type.iter():
if c == type: continue
if c.text is not None: typetext += c.text
if c.tail is not None: typetext += c.tail
if typetext.startswith ("typename") or typetext.startswith ("class"):
s = typetext.split(maxsplit=1)
assert len(s) == 2
return { "type": s[0].strip(), "name": s[1].strip() }
else:
return { "type": type.text, "name": "" }
else:
assert defname.text == declname.text
return { "type": type.text, "name": defname.text }
def makeHeaderGuard (filename):
import os
return filename.upper().replace('.', '_').replace(os.path.sep, '_')
def format_description (brief, detailed):
b = [ el.text.strip() for el in brief .iter() if el.text ] if brief is not None else []
d = [ el.text.strip() for el in detailed.iter() if el.text ] if detailed is not None else []
text = "".join(b)
if d:
text += '\n' + "".join(d)
return text
class Reference(object):
def __init__ (self, index, id=None, name=None):
self.id = id
self.name = name
self.index = index
def xmlToType (self, node, array=None, parentClass=None, tplargs=None):
"""
- node:
- parentClass: a class
- tplargs: if one of the args is parentClass and no template arguments are provided,
set the template arguments to this value
- array: content of the sibling tag 'array'
"""
if node.text is not None:
t = node.text.strip()
else:
t = ""
for c in node.iterchildren():
if c.tag == "ref":
refid = c.attrib["refid"]
if parentClass is not None and refid == parentClass.id:
t += " " + parentClass.name
if c.tail is not None and c.tail.lstrip()[0] != '<':
t += tplargs
elif self.index.hasref(refid):
t += " " + self.index.getref(refid).name
else:
self.index.output.warn ("Unknown reference: ", c.text, refid)
t += " " + c.text.strip()
else:
if c.text is not None:
t += " " + c.text.strip()
if c.tail is not None:
t += " " + c.tail.strip()
if array is not None:
t += array.text
return t
# Only for function as of now.
class MemberDef(Reference):
def __init__ (self, index, memberdefxml, parent):
super().__init__ (index=index,
id = memberdefxml.attrib["id"],
name = memberdefxml.find("definition").text)
self.parent = parent
self.xml = memberdefxml
self.const = (memberdefxml.attrib['const']=="yes")
self.static = (memberdefxml.attrib['static']=="yes")
self.rettype = memberdefxml.find('type')
self.params = tuple( [ (param.find('type'), param.find('array')) for param in self.xml.findall("param") ] )
self.special = self.rettype.text is None and len(self.rettype.getchildren())==0
#assert self.special or len(self.rettype.text) > 0
self._templateParams (self.xml.find('templateparamlist'))
def _templateParams (self, tpl):
if tpl is not None:
self.template_params = tuple ([ _templateParamToDict(param) for param in tpl.iterchildren(tag="param") ])
else:
self.template_params = tuple()
def prototypekey (self):
prototype = (
self.xmlToType(self.rettype),
tuple( [ tuple(t.items()) for t in self.template_params ]),
tuple( [ self.xmlToType(param.find('type')) for param in self.xml.findall("param") ] ),
self.const,
)
return prototype
def s_prototypeArgs (self):
return "({0}){1}".format (self.s_args(), " const" if self.const else "")
def s_args (self):
# If the class is templated, check if one of the argument is the class itself.
# If so, we must add the template arguments to the class (if there is none)
if len(self.parent.template_params) > 0:
tplargs = " <" + ", ".join([ d['name'] for d in self.parent.template_params ]) + " > "
args = ", ".join(
[ self.xmlToType(type, array, parentClass=self.parent, tplargs=tplargs) for type,array in self.params])
else:
args = ", ".join([ self.xmlToType(type, array) for type, array in self.params])
return args
def s_tpldecl (self):
if len(self.template_params) == 0: return ""
return ", ".join([ d['type'] + " " + d['name'] for d in self.template_params ])
def s_rettype (self):
assert not self.special
return self.xmlToType(self.rettype)
def s_name (self):
return self.xml.find('name').text.strip()
def s_docstring (self):
return self.index.xml_docstring.getDocString (
self.xml.find('briefdescription'),
self.xml.find('detaileddescription'),
self.index.output)
def include (self):
import os.path
loc = self.xml.find('location')
# The location is based on $CMAKE_SOURCE_DIR. Remove first directory.
return loc.attrib['file'].split(os.path.sep,1)[1]
class CompoundBase(Reference):
def __init__ (self, compound, index):
self.compound = compound
self.filename = path.join (index.directory, compound.attrib["refid"]+".xml")
self.tree = etree.parse (self.filename)
self.definition = self.tree.getroot().find("compounddef")
super().__init__ (index,
id = self.definition.attrib['id'],
name = self.definition.find("compoundname").text)
class NamespaceCompound (CompoundBase):
def __init__ (self, *args):
super().__init__ (*args)
self.typedefs = []
self.enums = []
self.static_funcs = []
self.template_params = tuple()
# Add references
for section in self.definition.iterchildren("sectiondef"):
assert "kind" in section.attrib
kind = section.attrib["kind"]
if kind == "enum":
self.parseEnumSection (section)
elif kind == "typedef":
self.parseTypedefSection (section)
elif kind == "func":
self.parseFuncSection (section)
def parseEnumSection (self, section):
for member in section.iterchildren("memberdef"):
ref = Reference (index=self.index,
id=member.attrib["id"],
name= self.name + "::" + member.find("name").text)
self.index.registerReference (ref)
self.enums.append(member)
for value in member.iterchildren("enumvalue"):
ref = Reference (index=self.index,
id=value.attrib["id"],
name= self.name + "::" + member.find("name").text)
def parseTypedefSection (self, section):
for member in section.iterchildren("memberdef"):
ref = Reference (index=self.index,
id=member.attrib["id"],
name= self.name + "::" + member.find("name").text)
self.index.registerReference (ref)
self.typedefs.append(member)
def parseFuncSection (self, section):
for member in section.iterchildren("memberdef"):
self.static_funcs.append (MemberDef (self.index, member, self))
def innerNamespace (self):
return self.name
def write (self, output):
pass
class ClassCompound (CompoundBase):
def __init__ (self, *args):
super().__init__ (*args)
self.member_funcs = list()
self.static_funcs = list()
self.special_funcs = list()
self.attributes = list()
self.struct = (self.compound.attrib['kind'] == "struct")
self.public = (self.definition.attrib['prot'] == "public")
self.template_specialization = (self.name.find('<') > 0)
# Handle templates
self._templateParams (self.definition.find('templateparamlist'))
for memberdef in self.definition.iter(tag="memberdef"):
if memberdef.attrib['prot'] != "public":
continue
if memberdef.attrib['kind'] == "variable":
self._attribute (memberdef)
elif memberdef.attrib['kind'] == "typedef":
ref = Reference (index=self.index,
id=memberdef.attrib["id"],
name= self.name + "::" + memberdef.find("name").text)
self.index.registerReference (ref)
elif memberdef.attrib['kind'] == "enum":
ref = Reference (index=self.index,
id=memberdef.attrib["id"],
name= self.name + "::" + memberdef.find("name").text)
self.index.registerReference (ref)
for value in memberdef.iterchildren("enumvalue"):
ref = Reference (index=self.index,
id=value.attrib["id"],
name= self.name + "::" + memberdef.find("name").text)
self.index.registerReference (ref)
elif memberdef.attrib['kind'] == "function":
self._memberfunc (memberdef)
def _templateParams (self, tpl):
if tpl is not None:
self.template_params = tuple([ _templateParamToDict(param) for param in tpl.iterchildren(tag="param") ])
else:
self.template_params = tuple()
def _templateDecl (self):
if not hasattr(self, "template_params") or len(self.template_params) == 0:
return ""
return ", ".join([ d['type'] + " " + d['name'] for d in self.template_params ])
def _className (self):
if not hasattr(self, "template_params") or len(self.template_params) == 0:
return self.name
return self.name + " <" + ", ".join([ d['name'] for d in self.template_params ]) + " >"
def innerNamespace (self):
return self._className()
def _memberfunc (self, member):
m = MemberDef (self.index, member, self)
if m.special:
self.special_funcs.append (m)
elif m.static:
self.static_funcs.append (m)
else:
self.member_funcs.append (m)
def _writeClassDoc (self, output):
docstring = self.index.xml_docstring.getDocString (
self.definition.find('briefdescription'),
self.definition.find('detaileddescription'),
self.index.output)
if len(docstring) == 0: return
output.out (template_class_doc.format (
tplargs = self._templateDecl(),
classname = self._className(),
docstring = docstring,
))
def write (self, output):
if not self.public: return
if self.template_specialization:
output.warn ("Disable class {} because template argument are not resolved for templated class specialization.".format(self.name))
return
include = self.definition.find('includes')
output.open (include.text)
output.out (template_include_extern.format (filename=include.text))
output.out (template_open_namespace.format (namespace="doxygen"))
# Write class doc
self._writeClassDoc(output)
# Group member function by prototype
member_funcs = dict()
for m in self.member_funcs:
prototype = m.prototypekey()
if prototype in member_funcs:
member_funcs[prototype].append (m)
else:
member_funcs[prototype] = [ m, ]
classname_prefix = self._className() + "::"
for member in self.special_funcs:
docstring = member.s_docstring()
if len(docstring) == 0: continue
if member.s_name()[0] == '~':
output.out (template_destructor_doc.format (
tplargs = self._templateDecl(),
classname_prefix = self._className(),
docstring = docstring,
))
else:
output.out (template_constructor_doc.format (
tplargs = ", ".join([ d['type'] + " " + d['name'] for d in self.template_params + member.template_params ]),
nargs = len(member.params),
comma = ", " if len(member.params) > 0 else "",
classname_prefix = self._className(),
argsstring = member.s_args(),
docstring = docstring,
))
for prototype, members in member_funcs.items():
# remove undocumented members
documented_members = []
docstrings = []
for member in members:
docstring = member.s_docstring()
if len(docstring) == 0: continue
documented_members.append (member)
docstrings.append (docstring)
if len(documented_members) == 0: continue
body = "".join([
template_member_func_doc_body.format (
classname_prefix = classname_prefix,
membername = member.s_name(),
docstring = docstring,
rettype = member.s_rettype(),
argsstring = member.s_prototypeArgs(),
)
for member, docstring in zip(documented_members,docstrings) ])
member = members[0]
tplargs = ", ".join([ d['type'] + " " + d['name'] for d in self.template_params + member.template_params ])
output.out (template_member_func_doc.format (
template = "template <{}>\n".format (tplargs) if len(tplargs) > 0 else "",
rettype = member.s_rettype(),
classname_prefix = classname_prefix,
argsstring = member.s_prototypeArgs(),
body = body
))
output.out (template_close_namespace.format (namespace="doxygen"))
output.close()
def _attribute (self, member):
self.attributes.append (member)
class Index:
"""
This class is responsible for generating the list of all C++-usable documented elements.
"""
def __init__ (self, input, output):
self.tree = etree.parse (input)
self.directory = path.dirname (input)
self.xml_docstring = XmlDocString (self)
self.compounds = list()
self.references = dict()
self.output = output
def parseCompound (self):
for compound in self.tree.getroot().iterchildren ("compound"):
if compound.attrib['kind'] in ["class", "struct"]:
obj = ClassCompound (compound, self)
elif compound.attrib['kind'] == "namespace":
obj = NamespaceCompound (compound, self)
if obj.id not in self.compounds:
self.compounds.append (obj.id)
self.registerReference (obj)
def write (self):
# Header
from os.path import abspath, dirname
from time import asctime
self.output.open ("doxygen_xml_parser_for_cmake.hh")
self.output.out ("// Generated on {}".format (asctime()))
self.output.close()
# Implement template specialization for classes and member functions
for id in self.compounds:
compound = self.references[id]
compound.write(self.output)
self.output.open ("functions.h")
# Implement template specialization for static functions
static_funcs = dict()
prototypes = list()
includes = list()
for id in self.compounds:
compound = self.references[id]
for m in compound.static_funcs:
include = m.include()
if include not in includes:
includes.append (include)
docstring = m.s_docstring()
if len(docstring) == 0: continue
prototype = m.prototypekey()
if prototype in static_funcs:
static_funcs[prototype].append ( (m, docstring) )
else:
static_funcs[prototype] = [ (m, docstring) , ]
prototypes.append (prototype)
self.output.out (
"".join([ template_include_intern.format (filename=filename)
for filename in includes]))
self.output.out (template_open_namespace.format (namespace="doxygen"))
for prototype in prototypes:
member_and_docstring_s = static_funcs[prototype]
body = "".join([
template_static_func_doc_body.format (
namespace = member.parent.innerNamespace(),
membername = member.s_name(),
docstring = docstring,
rettype = member.s_rettype(),
argsstring = member.s_prototypeArgs(),
)
for member, docstring in member_and_docstring_s ])
member = member_and_docstring_s[0][0]
# TODO fix case of static method in templated class.
tplargs = ", ".join([ d['type'] + " " + d['name'] for d in member.parent.template_params + member.template_params ])
self.output.out (template_static_func_doc.format (
template = "template <{}>\n".format (tplargs) if len(tplargs) > 0 else "",
rettype = member.s_rettype(),
argsstring = member.s_prototypeArgs(),
body = body
))
self.output.out (template_close_namespace.format (namespace="doxygen"))
self.output.close ()
def registerReference (self, obj, overwrite=True):
if obj.id in self.references:
if obj.name != self.references[obj.id].name:
self.output.warn ("!!!! Compounds " + obj.id + " already exists.", obj.name, self.references[obj.id].name)
else:
self.output.warn ("Reference " + obj.id + " already exists.", obj.name)
if not overwrite: return
self.references[obj.id] = obj
def hasref (self, id):
return (id in self.references)
def getref (self, id):
return self.references[id]
class OutputStreams(object):
def __init__ (self, output_dir, warn, error, errorPrefix = ""):
self.output_dir = output_dir
self._out = None
self._warn = warn
self._err = error
self.errorPrefix = errorPrefix
self._created_files = dict()
def open (self, name):
assert self._out == None, "You did not close the previous file"
import os
fullname = os.path.join(self.output_dir, name)
dirname = os.path.dirname(fullname)
if not os.path.isdir (dirname): os.makedirs (dirname)
if name in self._created_files:
self._out = self._created_files[name]
else:
self._out = open(fullname, mode='w')
self._created_files[name] = self._out
# Header
self.out(template_file_header.format (
path = os.path.dirname(os.path.abspath(__file__)),
header_guard = makeHeaderGuard (name),
))
def close (self):
self._out = None
def writeFooterAndCloseFiles (self):
for n, f in self._created_files.items():
# Footer
self._out = f
self.out(template_file_footer.format(
header_guard = makeHeaderGuard (n),
))
f.close()
self._created_files.clear()
self._out = None
def out(self, *args):
print (*args, file=self._out)
def warn(self, *args):
print (self.errorPrefix, *args, file=self._warn)
def err(self, *args):
print (self.errorPrefix, *args, file=self._err)
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description='Process Doxygen XML documentation and generate C++ code.')
parser.add_argument('doxygen_index_xml', type=str, help='the Doxygen XML index.')
parser.add_argument('output_directory', type=str, help='the output directory.')
args = parser.parse_args()
index = Index (input = sys.argv[1],
output = OutputStreams (args.output_directory, sys.stdout, sys.stderr))
index.parseCompound()
index.write()
index.output.writeFooterAndCloseFiles()
assert index.output._out == None
class XmlDocString (object):
def __init__ (self, index):
self.index = index
self.tags = {
"para": self.para,
"ref": self.ref,
"briefdescription": self.otherTags,
"detaileddescription": self.otherTags,
"parameterlist": self.parameterlist,
"parameterdescription": self.otherTags,
"emphasis": self.emphasis,
"simplesect": self.simplesect,
}
self.unkwownTags = set()
self.unkwownReferences = dict()
self._linesep = "\\n\"\n\""
def clear (self):
self.lines = []
self.unkwownTags.clear()
self.unkwownReferences.clear()
def writeErrors (self, output):
ret = False
for t in self.unkwownTags:
output.warn ("Unknown tag: ", t)
ret = True
for ref,node in self.unkwownReferences.items():
output.warn ("Unknown reference: ", ref, node.text)
ret = True
return ret
def _write (self, str):
nlines=str.split(sep="\n")
if len(self.lines)==0:
self.lines += nlines
else:
self.lines[-1] += nlines[0]
self.lines += nlines[1:]
#self.lines += nlines[1:]
def _newline (self,n=1):
self.lines.extend (["",] * n)
def _clean(self):
s = 0
for l in self.lines:
if len(l.strip())==0: s+=1
else: break
e = len(self.lines)
for l in reversed(self.lines):
if len(l.strip())==0: e-=1
else: break
self.lines = self.lines[s:e]
def getDocString (self, brief, detailled, output):
self.clear()
if brief is not None:
self.visit (brief)
if detailled is not None and len(detailled.getchildren()) > 0:
if brief is not None: self._newline ()
self.visit (detailled)
from sys import stdout, stderr
self.writeErrors(output)
self._clean()
return self._linesep.join(self.lines)
def visit (self, node):
assert isinstance(node.tag, str)
tag = node.tag
if tag not in self.tags:
self.unknownTag (node)
else:
self.tags[tag](node)
def unknownTag (self, node):
self.unkwownTags.add (node.tag)
self.otherTags (node)
def otherTags (self, node):
if node.text:
self._write (node.text.strip())
for c in node.iterchildren():
self.visit (c)
if c.tail: self._write (c.tail.strip())
def emphasis (self, node):
self._write ("*")
self.otherTags(node)
self._write ("*")
def simplesect (self, node):
self._write (node.attrib["kind"].title()+": ")
self.otherTags (node)
def para (self, node):
if node.text: self._write (node.text)
for c in node.iterchildren():
self.visit (c)
if c.tail: self._write (c.tail)
self._newline()
def ref (self, node):
refid = node.attrib["refid"]
if self.index.hasref(refid):
self._write (self.index.getref(refid).name)
else:
self.unkwownReferences[refid] = node
self._write (node.text)
assert len(node.getchildren()) == 0
def parameterlist (self, node):
self._newline()
self._write (node.attrib["kind"].title())
self._newline()
for item in node.iterchildren("parameteritem"):
self.parameteritem (item)
def parameteritem (self, node):
indent = " "
self._write (indent + "- ")
# should contain two children
assert len(node.getchildren()) == 2
namelist = node.find ("parameternamelist")
desc = node.find ("parameterdescription")
sep = ""
for name in namelist.iterchildren("parametername"):
self._write (sep + name.text)
sep = ", "
self._write (" ")
self.visit (desc)
......@@ -44,7 +44,7 @@ INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/src")
INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}")
ADD_CUSTOM_TARGET(generate_doxygen_cpp_doc
COMMAND ${CMAKE_SOURCE_DIR}/cmake/doxygen/doxygen_xml_parser.py
COMMAND ${CMAKE_SOURCE_DIR}/doc/python/doxygen_xml_parser.py
${CMAKE_BINARY_DIR}/doc/doxygen-xml/index.xml
${CMAKE_CURRENT_BINARY_DIR}/doxygen_autodoc > ${CMAKE_CURRENT_BINARY_DIR}/doxygen_autodoc.log
BYPRODUCTS
......@@ -57,7 +57,7 @@ ADD_DEPENDENCIES(generate_doxygen_cpp_doc doc)
SET(${LIBRARY_NAME}_HEADERS
${CMAKE_CURRENT_BINARY_DIR}/doxygen_autodoc/doxygen_xml_parser_for_cmake.hh
fcl.hh
)
)
SET(${LIBRARY_NAME}_SOURCES
version.cc
......
......@@ -44,7 +44,7 @@
#include "doxygen_autodoc/hpp/fcl/math/transform.h"
#include "../cmake/doxygen/doxygen-boost.hh"
#include "../doc/python/doxygen-boost.hh"
using namespace boost::python;
using namespace hpp::fcl;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment