Merge pull request #218 from mesonbuild/gtkdoc

Basic gtkdoc support
pull/221/head
Jussi Pakkanen 9 years ago
commit 849786da14
  1. 7
      build.py
  2. 80
      gtkdochelper.py
  3. 12
      interpreter.py
  4. 32
      meson_install.py
  5. 27
      modules/gnome.py
  6. 3
      ninjabackend.py
  7. 4
      test cases/common/60 install script/meson.build
  8. 39
      test cases/frameworks/10 gtk-doc/doc/foobar-docs.sgml
  9. 9
      test cases/frameworks/10 gtk-doc/doc/meson.build
  10. 1
      test cases/frameworks/10 gtk-doc/doc/version.xml.in
  11. 15
      test cases/frameworks/10 gtk-doc/include/foo.h
  12. 13
      test cases/frameworks/10 gtk-doc/installed_files.txt
  13. 3
      test cases/frameworks/10 gtk-doc/meson.build

@ -72,7 +72,7 @@ class Build:
self.pot = []
self.subprojects = {}
self.pkgconfig_gens = []
self.install_script = None
self.install_scripts = []
self.install_dirs = []
def has_language(self, language):
@ -894,3 +894,8 @@ class PkgConfigGenerator():
self.description = description
self.version = version
self.filebase = filebase
class InstallScript:
def __init__(self, cmd_arr):
assert(isinstance(cmd_arr, list))
self.cmd_arr = cmd_arr

@ -0,0 +1,80 @@
#!/usr/bin/env python3
# Copyright 2015 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys, os
import subprocess
import shutil
def build_gtkdoc(source_root, build_root, doc_subdir, src_subdir, main_sgml, module):
abs_src = os.path.join(source_root, src_subdir)
abs_out = os.path.join(build_root, doc_subdir)
htmldir = os.path.join(abs_out, 'html')
subprocess.check_call(['gtkdoc-scan',
'--module=' + module,
'--source-dir=' + abs_src,
'--output-dir=.'], cwd=abs_out)
mkdb_cmd = ['gtkdoc-mkdb',
'--module=' + module,
'--output-format=xml',
'--sgml-mode',
'--source-dir=' + abs_src]
sgml_abs = os.path.join(source_root, doc_subdir, main_sgml)
if len(main_sgml) > 0:
mkdb_cmd.append('--main-sgml-file=' + sgml_abs)
subprocess.check_call(mkdb_cmd, cwd=abs_out)
shutil.rmtree(htmldir, ignore_errors=True)
try:
os.mkdir(htmldir)
except Exception:
pass
mkhtml_cmd = ['gtkdoc-mkhtml', module]
if len(main_sgml) > 0:
# Workaround for
# https://bugzilla.gnome.org/show_bug.cgi?id=753145
plainfile = os.path.split(sgml_abs)[1]
shutil.copy(sgml_abs, os.path.join(abs_out, plainfile))
mkhtml_cmd.append('../' + plainfile)
else:
mkhtml_cmd.append('../%s-docs.xml' % module)
subprocess.check_call(mkhtml_cmd, cwd=htmldir, shell=False)
subprocess.check_call(['gtkdoc-fixxref',
'--module=' + module,
'--module-dir=html'], cwd=abs_out)
def install_gtkdoc(build_root, doc_subdir, install_prefix, datadir, module):
source = os.path.join(build_root, doc_subdir, 'html')
final_destination = os.path.join(install_prefix, datadir, module)
shutil.rmtree(final_destination, ignore_errors=True)
shutil.copytree(source, final_destination)
if __name__ == '__main__':
# source_root = '/home/jpakkane/workspace/meson/test cases/frameworks/10 gtk-doc'
# build_root = '/home/jpakkane/workspace/meson/work area'
# doc_subdir = 'doc'
# src_subdir = 'include'
# module = 'foobar'
if len(sys.argv) != 7:
print(sys.argv)
print("Bad arguments.")
sys.exit(1)
(source_root, build_root, doc_subdir, src_subdir, main_sgml, module) = sys.argv[1:]
build_gtkdoc(source_root, build_root, doc_subdir, src_subdir, main_sgml, module)
if 'MESON_INSTALL_PREFIX' in os.environ:
if 'DESTDIR' in os.environ:
installdir = os.environ['DESTDIR'] + os.environ['MESON_INSTALL_PREFIX']
else:
installdir = os.environ['MESON_INSTALL_PREFIX']
install_gtkdoc(build_root, doc_subdir, installdir, 'share/gtk-doc/html', module)

@ -722,10 +722,10 @@ class MesonMain(InterpreterObject):
'current_build_dir' : self.current_build_dir_method,
'source_root' : self.source_root_method,
'build_root' : self.build_root_method,
'set_install_script' : self.set_install_script_method,
'add_install_script' : self.add_install_script_method,
})
def set_install_script_method(self, args, kwargs):
def add_install_script_method(self, args, kwargs):
if len(args) != 1:
raise InterpreterException('Set_install_script takes exactly one argument.')
check_stringlist(args)
@ -734,7 +734,7 @@ class MesonMain(InterpreterObject):
self.interpreter.subdir, scriptbase)
if not os.path.isfile(scriptfile):
raise InterpreterException('Can not find install script %s.' % scriptbase)
self.build.install_script = scriptfile
self.build.install_scripts.append(build.InstallScript([scriptfile]))
def current_source_dir_method(self, args, kwargs):
src = self.interpreter.environment.source_dir
@ -909,6 +909,12 @@ class Interpreter():
outvalues.append(self.module_method_callback(v))
elif isinstance(v, build.GeneratedList):
outvalues.append(GeneratedListHolder(v))
elif isinstance(v, build.RunTarget):
if v.name in self.build.targets:
raise InterpreterException('Tried to create target %s which already exists.' % v.name)
self.build.targets[v.name] = v
elif isinstance(v, build.InstallScript):
self.build.install_scripts.append(v)
else:
print(v)
raise InterpreterException('Module returned a value of unknown type.')

@ -29,7 +29,7 @@ class InstallData():
self.data = []
self.po_package_name = ''
self.po = []
self.install_script = None
self.install_scripts = []
self.install_subdirs = []
def do_install(datafilename):
@ -119,26 +119,28 @@ def install_headers(d):
shutil.copystat(fullfilename, outfilename)
def run_install_script(d):
if d.install_script is None:
return
env = {'MESON_SOURCE_ROOT' : d.source_dir,
'MESON_BUILD_ROOT' : d.build_dir,
'MESON_INSTALL_PREFIX' : d.prefix
}
script = d.install_script
print('Running custom install script %s' % script)
suffix = os.path.splitext(script)[1].lower()
if platform.system().lower() == 'windows' and suffix != '.bat':
first_line = open(script).readline().strip()
if first_line.startswith('#!'):
commands = first_line[2:].split('#')[0].strip().split()
commands[0] = shutil.which(commands[0].split('/')[-1])
if commands[0] is None:
raise RuntimeError("Don't know how to run script %s." % script)
script = commands + [script]
child_env = os.environ.copy()
child_env.update(env)
subprocess.check_call(script, env=child_env)
for i in d.install_scripts:
script = i.cmd_arr[0]
print('Running custom install script %s' % script)
suffix = os.path.splitext(script)[1].lower()
if platform.system().lower() == 'windows' and suffix != '.bat':
first_line = open(script).readline().strip()
if first_line.startswith('#!'):
commands = first_line[2:].split('#')[0].strip().split()
commands[0] = shutil.which(commands[0].split('/')[-1])
if commands[0] is None:
raise RuntimeError("Don't know how to run script %s." % script)
final_command = commands + [script] + i.cmd_arr[1:]
else:
final_command = i.cmd_arr
subprocess.check_call(final_command, env=child_env)
def is_elf_platform():
platname = platform.system().lower()

@ -16,7 +16,7 @@
functionality such as gobject-introspection and gresources.'''
import build
import os
import os, sys
import subprocess
from coredata import MesonException
import mlog
@ -176,6 +176,31 @@ class GnomeModule:
target_g = build.CustomTarget(targetname, state.subdir, kwargs)
return target_g
def gtkdoc(self, state, args, kwargs):
if len(args) != 1:
raise MesonException('Gtkdoc must have one positional argument.')
modulename = args[0]
if not isinstance(modulename, str):
raise MesonException('Gtkdoc arg must be string.')
if not 'src_dir' in kwargs:
raise MesonException('Keyword argument src_dir missing.')
main_sgml = kwargs.get('main_sgml', '')
if not isinstance(main_sgml, str):
raise MesonException('Main sgml keyword argument must be a string.')
src_dir = kwargs['src_dir']
targetname = modulename + '-doc'
command = os.path.normpath(os.path.join(os.path.split(__file__)[0], "../gtkdochelper.py"))
args = [state.environment.get_source_dir(),
state.environment.get_build_dir(),
state.subdir,
os.path.normpath(os.path.join(state.subdir, src_dir)),
main_sgml,
modulename]
res = [build.RunTarget(targetname, command, args, state.subdir)]
if kwargs.get('install', True):
res.append(build.InstallScript([command] + args))
return res
def gdbus_codegen(self, state, args, kwargs):
if len(args) != 2:
raise MesonException('Gdbus_codegen takes two arguments, name and xml file.')

@ -431,8 +431,7 @@ class NinjaBackend(backends.Backend):
d.man.append(i)
def generate_custom_install_script(self, d):
d.install_script = self.build.install_script
d.install_scripts = self.build.install_scripts
def generate_header_install(self, d):
incroot = self.environment.get_includedir()

@ -1,8 +1,8 @@
project('custom install script', 'c')
if meson.get_compiler('c').get_id() == 'msvc'
meson.set_install_script('myinstall.bat')
meson.add_install_script('myinstall.bat')
else
meson.set_install_script('myinstall.sh')
meson.add_install_script('myinstall.sh')
endif
executable('prog', 'prog.c', install : true)

@ -0,0 +1,39 @@
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY version SYSTEM "version.xml">
]>
<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
<bookinfo>
<title>Foolib Reference Manual</title>
<releaseinfo>
for Foobar &version;
</releaseinfo>
<authorgroup>
<author>
<firstname>Jonny</firstname>
<surname>Example</surname>
<affiliation>
<address>
<email>unknown@example.com</email>
</address>
</affiliation>
</author>
</authorgroup>
<copyright>
<year>2015</year>
<holder>Foobar corporation holdings ltd</holder>
</copyright>
</bookinfo>
<reference id="foobar">
<title>Foobar library</title>
<partintro>
<para>
This part documents Foobar libs.
</para>
</partintro>
<xi:include href="xml/foo.xml"/>
</reference>
</book>

@ -0,0 +1,9 @@
gnome = import('gnome')
cdata = configuration_data()
cdata.set('VERSION', '1.0')
configure_file(input : 'version.xml.in',
output : 'version.xml',
configuration : cdata)
gnome.gtkdoc('foobar', src_dir : '../include', main_sgml : 'foobar-docs.sgml', install : true)

@ -0,0 +1,15 @@
#pragma once
/**
* FooIndecision:
* @FOO_MAYBE: Something maybe
* @FOO_POSSIBLY: Something possible
*
* The indecision type.
**/
typedef enum {
FOO_MAYBE,
FOO_POSSIBLY,
} FooIndecision;

@ -0,0 +1,13 @@
usr/share/gtk-doc/html/foobar/foobar.devhelp2
usr/share/gtk-doc/html/foobar/foobar-foo.html
usr/share/gtk-doc/html/foobar/foobar.html
usr/share/gtk-doc/html/foobar/home.png
usr/share/gtk-doc/html/foobar/index.html
usr/share/gtk-doc/html/foobar/index.sgml
usr/share/gtk-doc/html/foobar/left-insensitive.png
usr/share/gtk-doc/html/foobar/left.png
usr/share/gtk-doc/html/foobar/right-insensitive.png
usr/share/gtk-doc/html/foobar/right.png
usr/share/gtk-doc/html/foobar/style.css
usr/share/gtk-doc/html/foobar/up-insensitive.png
usr/share/gtk-doc/html/foobar/up.png

@ -0,0 +1,3 @@
project('gtkdoctest', 'c')
subdir('doc')
Loading…
Cancel
Save