Merge pull request #808 from thiblahute/gtkdoc

Fix various gtkdoc issues
This commit is contained in:
Jussi Pakkanen 2016-09-28 17:03:58 -04:00 committed by GitHub
commit 0a4957627a
2 changed files with 184 additions and 83 deletions

View File

@ -16,7 +16,7 @@
functionality such as gobject-introspection and gresources.''' functionality such as gobject-introspection and gresources.'''
from .. import build from .. import build
import os, sys import os
import subprocess import subprocess
from ..mesonlib import MesonException from ..mesonlib import MesonException
from .. import dependencies from .. import dependencies
@ -94,12 +94,13 @@ class GnomeModule:
return stdout.split('\n')[:-1] return stdout.split('\n')[:-1]
def get_link_args(self, state, lib, depends): def get_link_args(self, state, lib, depends=None):
link_command = ['-l%s' % lib.name] link_command = ['-l%s' % lib.name]
if isinstance(lib, build.SharedLibrary): if isinstance(lib, build.SharedLibrary):
link_command += ['-L%s' % link_command += ['-L%s' %
os.path.join(state.environment.get_build_dir(), os.path.join(state.environment.get_build_dir(),
lib.subdir)] lib.subdir)]
if depends:
depends.append(lib) depends.append(lib)
return link_command return link_command
@ -107,8 +108,6 @@ class GnomeModule:
if not include_dirs: if not include_dirs:
return [] return []
build_to_src = os.path.relpath(state.environment.get_source_dir(),
state.environment.get_build_dir())
dirs_str = [] dirs_str = []
for incdirs in include_dirs: for incdirs in include_dirs:
if hasattr(incdirs, "held_object"): if hasattr(incdirs, "held_object"):
@ -124,14 +123,72 @@ class GnomeModule:
basedir = dirs.get_curdir() basedir = dirs.get_curdir()
for d in dirs.get_incdirs(): for d in dirs.get_incdirs():
expdir = os.path.join(basedir, d) expdir = os.path.join(basedir, d)
srctreedir = os.path.join(build_to_src, expdir) srctreedir = os.path.join(state.environment.get_source_dir(), expdir)
dirs_str += ['%s%s' % (prefix, expdir), buildtreedir = os.path.join(state.environment.get_build_dir(), expdir)
dirs_str += ['%s%s' % (prefix, buildtreedir),
'%s%s' % (prefix, srctreedir)] '%s%s' % (prefix, srctreedir)]
for d in dirs.get_extra_build_dirs(): for d in dirs.get_extra_build_dirs():
dirs_str += ['%s%s' % (prefix, d)] dirs_str += ['%s%s' % (prefix, d)]
return dirs_str return dirs_str
def get_dependencies_flags(self, deps, state, depends=None):
cflags = set()
ldflags = set()
gi_includes = set()
if not isinstance(deps, list):
deps = [deps]
for dep in deps:
if hasattr(dep, 'held_object'):
dep = dep.held_object
if isinstance(dep, dependencies.InternalDependency):
cflags.update(self.get_include_args( state, dep.include_directories))
for lib in dep.libraries:
ldflags.update(self.get_link_args(state, lib.held_object, depends))
libdepflags = self.get_dependencies_flags(lib.held_object.get_external_deps(), state, depends)
cflags.update(libdepflags[0])
ldflags.update(libdepflags[1])
gi_includes.update(libdepflags[2])
extdepflags = self.get_dependencies_flags(dep.ext_deps, state, depends)
cflags.update(extdepflags[0])
ldflags.update(extdepflags[1])
gi_includes.update(extdepflags[2])
for source in dep.sources:
if isinstance(source.held_object, GirTarget):
gi_includes.update([os.path.join(state.environment.get_build_dir(),
source.held_object.get_subdir())])
# This should be any dependency other than an internal one.
elif isinstance(dep, dependencies.Dependency):
cflags.update(dep.get_compile_args())
for lib in dep.get_link_args():
if (os.path.isabs(lib) and
# For PkgConfigDependency only:
getattr(dep, 'is_libtool', False)):
ldflags.update(["-L%s" % os.path.dirname(lib)])
libname = os.path.basename(lib)
if libname.startswith("lib"):
libname = libname[3:]
libname = libname.split(".so")[0]
lib = "-l%s" % libname
# Hack to avoid passing some compiler options in
if lib.startswith("-W"):
continue
ldflags.update([lib])
if isinstance(dep, dependencies.PkgConfigDependency):
girdir = dep.get_variable("girdir")
if girdir:
gi_includes.update([girdir])
elif isinstance(dep, (build.StaticLibrary, build.SharedLibrary)):
for incd in dep.get_include_dirs():
cflags.update(incd.get_incdirs())
else:
mlog.log('dependency %s not handled to build gir files' % dep)
continue
return cflags, ldflags, gi_includes
def generate_gir(self, state, args, kwargs): def generate_gir(self, state, args, kwargs):
if len(args) != 1: if len(args) != 1:
raise MesonException('Gir takes one argument') raise MesonException('Gir takes one argument')
@ -221,52 +278,10 @@ class GnomeModule:
deps = [deps] deps = [deps]
deps = (girtarget.get_all_link_deps() + girtarget.get_external_deps() + deps = (girtarget.get_all_link_deps() + girtarget.get_external_deps() +
deps) deps)
for dep in deps: cflags, ldflags, gi_includes = self.get_dependencies_flags(deps, state, depends)
if hasattr(dep, 'held_object'): scan_command += list(cflags) + list(ldflags)
dep = dep.held_object for i in gi_includes:
if isinstance(dep, dependencies.InternalDependency): scan_command += ['--add-include-path=%s' % i]
scan_command += self.get_include_args(
state,
dep.include_directories)
for lib in dep.libraries:
scan_command += self.get_link_args(state, lib.held_object,
depends)
for source in dep.sources:
if isinstance(source.held_object, GirTarget):
scan_command += [
"--add-include-path=%s" % (
os.path.join(state.environment.get_build_dir(),
source.held_object.get_subdir()),
)
]
# This should be any dependency other than an internal one.
elif isinstance(dep, dependencies.Dependency):
scan_command += dep.get_compile_args()
for lib in dep.get_link_args():
if (os.path.isabs(lib) and
# For PkgConfigDependency only:
getattr(dep, 'is_libtool', False)):
scan_command += ["-L%s" % os.path.dirname(lib)]
libname = os.path.basename(lib)
if libname.startswith("lib"):
libname = libname[3:]
libname = libname.split(".so")[0]
lib = "-l%s" % libname
# Hack to avoid passing some compiler options in
if lib.startswith("-W"):
continue
scan_command += [lib]
if isinstance(dep, dependencies.PkgConfigDependency):
girdir = dep.get_variable("girdir")
if girdir:
scan_command += ["--add-include-path=%s" % (girdir, )]
elif isinstance(dep, (build.StaticLibrary, build.SharedLibrary)):
for incd in dep.get_include_dirs():
scan_command += incd.get_incdirs()
else:
mlog.log('dependency %s not handled to build gir files' % dep)
continue
inc_dirs = kwargs.pop('include_directories', []) inc_dirs = kwargs.pop('include_directories', [])
if not isinstance(inc_dirs, list): if not isinstance(inc_dirs, list):
@ -377,12 +392,40 @@ class GnomeModule:
'--modulename=' + modulename] '--modulename=' + modulename]
args += self.unpack_args('--htmlargs=', 'html_args', kwargs) args += self.unpack_args('--htmlargs=', 'html_args', kwargs)
args += self.unpack_args('--scanargs=', 'scan_args', kwargs) args += self.unpack_args('--scanargs=', 'scan_args', kwargs)
args += self.unpack_args('--scanobjsargs=', 'scanobjs_args', kwargs)
args += self.unpack_args('--gobjects-types-file=', 'gobject_typesfile', kwargs, state)
args += self.unpack_args('--fixxrefargs=', 'fixxref_args', kwargs) args += self.unpack_args('--fixxrefargs=', 'fixxref_args', kwargs)
args += self.unpack_args('--html-assets=', 'html_assets', kwargs, state)
args += self.unpack_args('--content-files=', 'content_files', kwargs, state)
args += self.unpack_args('--installdir=', 'install_dir', kwargs, state)
args += self.get_build_args(kwargs, state)
res = [build.RunTarget(targetname, command[0], command[1:] + args, [], state.subdir)] res = [build.RunTarget(targetname, command[0], command[1:] + args, [], state.subdir)]
if kwargs.get('install', True): if kwargs.get('install', True):
res.append(build.InstallScript(command + args)) res.append(build.InstallScript(command + args))
return res return res
def get_build_args(self, kwargs, state):
args = []
cflags, ldflags, gi_includes = self.get_dependencies_flags(kwargs.get('dependencies', []), state)
inc_dirs = kwargs.get('include_directories', [])
if not isinstance(inc_dirs, list):
inc_dirs = [inc_dirs]
for incd in inc_dirs:
if not isinstance(incd.held_object, (str, build.IncludeDirs)):
raise MesonException(
'Gir include dirs should be include_directories().')
cflags.update(self.get_include_args(state, inc_dirs))
if cflags:
args += ['--cflags=%s' % ' '.join(cflags)]
if ldflags:
args += ['--ldflags=%s' % ' '.join(ldflags)]
compiler = state.environment.coredata.compilers.get('c')
if compiler:
args += ['--cc=%s' % ' '.join(compiler.get_exelist())]
args += ['--ld=%s' % ' '.join(compiler.get_linker_exelist())]
return args
def gtkdoc_html_dir(self, state, args, kwarga): def gtkdoc_html_dir(self, state, args, kwarga):
if len(args) != 1: if len(args) != 1:
raise MesonException('Must have exactly one argument.') raise MesonException('Must have exactly one argument.')
@ -392,18 +435,24 @@ class GnomeModule:
return os.path.join('share/gtkdoc/html', modulename) return os.path.join('share/gtkdoc/html', modulename)
def unpack_args(self, arg, kwarg_name, kwargs): def unpack_args(self, arg, kwarg_name, kwargs, expend_file_state=None):
try: if kwarg_name not in kwargs:
return []
new_args = kwargs[kwarg_name] new_args = kwargs[kwarg_name]
if not isinstance(new_args, list): if not isinstance(new_args, list):
new_args = [new_args] new_args = [new_args]
args = []
for i in new_args: for i in new_args:
if not isinstance(i, str): if expend_file_state and isinstance(i, mesonlib.File):
raise MesonException('html_args values must be strings.') i = os.path.join(expend_file_state.environment.get_build_dir(), i.subdir, i.fname)
except KeyError: elif not isinstance(i, str):
return[] raise MesonException(kwarg_name + ' values must be strings.')
if len(new_args) > 0: args.append(i)
return [arg + '@@'.join(new_args)]
if args:
return [arg + '@@'.join(args)]
return [] return []
def gdbus_codegen(self, state, args, kwargs): def gdbus_codegen(self, state, args, kwargs):

View File

@ -30,7 +30,16 @@ parser.add_argument('--mainfile', dest='mainfile')
parser.add_argument('--modulename', dest='modulename') parser.add_argument('--modulename', dest='modulename')
parser.add_argument('--htmlargs', dest='htmlargs', default='') parser.add_argument('--htmlargs', dest='htmlargs', default='')
parser.add_argument('--scanargs', dest='scanargs', default='') parser.add_argument('--scanargs', dest='scanargs', default='')
parser.add_argument('--scanobjsargs', dest='scanobjsargs', default='')
parser.add_argument('--gobjects-types-file', dest='gobject_typesfile', default='')
parser.add_argument('--fixxrefargs', dest='fixxrefargs', default='') parser.add_argument('--fixxrefargs', dest='fixxrefargs', default='')
parser.add_argument('--ld', dest='ld', default='')
parser.add_argument('--cc', dest='cc', default='')
parser.add_argument('--ldflags', dest='ldflags', default='')
parser.add_argument('--cflags', dest='cflags', default='')
parser.add_argument('--content-files', dest='content_files', default='')
parser.add_argument('--html-assets', dest='html_assets', default='')
parser.add_argument('--installdir', dest='install_dir')
def gtkdoc_run_check(cmd, cwd): def gtkdoc_run_check(cmd, cwd):
p = subprocess.Popen(cmd, cwd=cwd, p = subprocess.Popen(cmd, cwd=cwd,
@ -45,15 +54,49 @@ def gtkdoc_run_check(cmd, cwd):
raise MesonException('\n'.join(err_msg)) raise MesonException('\n'.join(err_msg))
def build_gtkdoc(source_root, build_root, doc_subdir, src_subdir, def build_gtkdoc(source_root, build_root, doc_subdir, src_subdir,
main_file, module, html_args, scan_args, fixxref_args): main_file, module, html_args, scan_args, fixxref_args,
gobject_typesfile, scanobjs_args, ld, cc, ldflags, cflags,
html_assets, content_files):
print("Building documentation for %s" % module)
abs_src = os.path.join(source_root, src_subdir) abs_src = os.path.join(source_root, src_subdir)
doc_src = os.path.join(source_root, doc_subdir)
abs_out = os.path.join(build_root, doc_subdir) abs_out = os.path.join(build_root, doc_subdir)
htmldir = os.path.join(abs_out, 'html') htmldir = os.path.join(abs_out, 'html')
content_files += [main_file]
sections = os.path.join(doc_src, module + "-sections.txt")
if os.path.exists(sections):
content_files.append(sections)
# Copy files to build directory
for f in content_files:
f_abs = os.path.join(doc_src, f)
shutil.copyfile(f_abs, os.path.join(
abs_out, os.path.basename(f_abs)))
shutil.rmtree(htmldir, ignore_errors=True)
try:
os.mkdir(htmldir)
except Exception:
pass
for f in html_assets:
f_abs = os.path.join(doc_src, f)
shutil.copyfile(f_abs, os.path.join(htmldir, os.path.basename(f_abs)))
scan_cmd = ['gtkdoc-scan', scan_cmd = ['gtkdoc-scan',
'--module=' + module, '--module=' + module,
'--source-dir=' + abs_src] + scan_args '--source-dir=' + abs_src] + scan_args
gtkdoc_run_check(scan_cmd, abs_out) gtkdoc_run_check(scan_cmd, abs_out)
if gobject_typesfile:
scanobjs_cmd = ['gtkdoc-scangobj'] + scanobjs_args + [gobject_typesfile,
'--module=' + module, '--cflags=' + cflags, '--ldflags=' + ldflags]
gtkdoc_run_check(scanobjs_cmd, abs_out)
# Make docbook files # Make docbook files
if main_file.endswith('sgml'): if main_file.endswith('sgml'):
modeflag = '--sgml-mode' modeflag = '--sgml-mode'
@ -62,20 +105,15 @@ def build_gtkdoc(source_root, build_root, doc_subdir, src_subdir,
mkdb_cmd = ['gtkdoc-mkdb', mkdb_cmd = ['gtkdoc-mkdb',
'--module=' + module, '--module=' + module,
'--output-format=xml', '--output-format=xml',
'--expand-content-files=',
modeflag, modeflag,
'--source-dir=' + abs_src] '--source-dir=' + abs_src]
main_abs = os.path.join(source_root, doc_subdir, main_file)
if len(main_file) > 0: if len(main_file) > 0:
# Yes, this is the flag even if the file is in xml. # Yes, this is the flag even if the file is in xml.
mkdb_cmd.append('--main-sgml-file=' + main_file) mkdb_cmd.append('--main-sgml-file=' + main_file)
gtkdoc_run_check(mkdb_cmd, abs_out) gtkdoc_run_check(mkdb_cmd, abs_out)
# Make HTML documentation # Make HTML documentation
shutil.rmtree(htmldir, ignore_errors=True)
try:
os.mkdir(htmldir)
except Exception:
pass
mkhtml_cmd = ['gtkdoc-mkhtml', mkhtml_cmd = ['gtkdoc-mkhtml',
'--path=' + abs_src, '--path=' + abs_src,
module, module,
@ -109,11 +147,16 @@ def run(args):
scanargs = options.scanargs.split('@@') scanargs = options.scanargs.split('@@')
else: else:
scanargs = [] scanargs = []
if len(options.scanobjsargs) > 0:
scanobjsargs = options.scanobjsargs.split('@@')
else:
scanobjsargs = []
if len(options.fixxrefargs) > 0: if len(options.fixxrefargs) > 0:
fixxrefargs = options.fixxrefargs.split('@@') fixxrefargs = options.fixxrefargs.split('@@')
else: else:
fixxrefargs = [] fixxrefargs = []
build_gtkdoc(options.sourcedir, build_gtkdoc(
options.sourcedir,
options.builddir, options.builddir,
options.subdir, options.subdir,
options.headerdir, options.headerdir,
@ -121,16 +164,25 @@ def run(args):
options.modulename, options.modulename,
htmlargs, htmlargs,
scanargs, scanargs,
fixxrefargs) fixxrefargs,
options.gobject_typesfile,
scanobjsargs,
options.ld,
options.cc,
options.ldflags,
options.cflags,
options.html_assets.split('@@') if options.html_assets else [],
options.content_files.split('@@') if options.content_files else [])
if 'MESON_INSTALL_PREFIX' in os.environ: if 'MESON_INSTALL_PREFIX' in os.environ:
install_dir = options.install_dir if options.install_dir else options.modulename
destdir = os.environ.get('DESTDIR', '') destdir = os.environ.get('DESTDIR', '')
installdir = destdir_join(destdir, os.environ['MESON_INSTALL_PREFIX']) installdir = destdir_join(destdir, os.environ['MESON_INSTALL_PREFIX'])
install_gtkdoc(options.builddir, install_gtkdoc(options.builddir,
options.subdir, options.subdir,
installdir, installdir,
'share/gtk-doc/html', 'share/gtk-doc/html',
options.modulename) install_dir)
return 0 return 0
if __name__ == '__main__': if __name__ == '__main__':