import tempfile
from .glibtransformer import IntrospectionBinary
+from .utils import get_libtool_command
# bugzilla.gnome.org/558436
# Compile a binary program which is then linked to a library
# we want to introspect, in order to call its get_type functions.
-_PROGRAM_TEMPLATE = '''/* This file is generated, do not edit */
+_PROGRAM_TEMPLATE = """/* This file is generated, do not edit */
#include <glib.h>
#include <girepository.h>
#include <string.h>
GOptionContext *context;
GError *error = NULL;
+ if (!g_thread_supported ()) g_thread_init (NULL);
g_type_init ();
- g_thread_init (NULL);
+
+ %(init_sections)s
context = g_option_context_new ("");
g_option_context_add_main_entries (context, entries, "girepository-1.0");
g_option_context_add_group (context, g_irepository_get_option_group ());
if (!g_option_context_parse (context, &argc, &argv, &error))
{
- g_printerr ("introspect failed (%d,%d): %s\\n",
+ g_printerr ("introspect failed (%%d,%%d): %%s\\n",
error->domain, error->code,
error->message);
return 1;
}
return 0;
}
-'''
+"""
class CompilerError(Exception):
def __init__(self, options, get_type_functions):
self._options = options
self._get_type_functions = get_type_functions
- self._tmpdir = tempfile.mkdtemp('', 'tmp-introspect')
+ # We have to use the current directory to work around Unix
+ # sysadmins who mount /tmp noexec
+ self._tmpdir = tempfile.mkdtemp('', 'tmp-introspect', dir=os.getcwd())
self._compiler_cmd = os.environ.get('CC', 'gcc')
- self._linker_cmd = os.environ.get('LD', self._compiler_cmd)
+ self._linker_cmd = os.environ.get('CC', self._compiler_cmd)
self._pkgconfig_cmd = os.environ.get('PKG_CONFIG', 'pkg-config')
self._uninst_srcdir = os.environ.get(
# Public API
def run(self):
- print ' GEN ' + self._options.output
+ tpl_args = {}
+ tpl_args['init_sections'] = "\n".join(self._options.init_sections)
+
c_path = self._generate_tempfile('.c')
f = open(c_path, 'w')
- f.write(_PROGRAM_TEMPLATE)
+ f.write(_PROGRAM_TEMPLATE % tpl_args)
# We need to reference our get_type functions to make sure they are
# pulled in at the linking stage if the library is a static library
# rather than a shared library.
- for func in self._get_type_functions:
- f.write("extern GType " + func + "(void);\n")
- f.write("GType (*GI_GET_TYPE_FUNCS_[])(void) = {\n")
- first = True
- for func in self._get_type_functions:
- if first:
- first = False
- else:
- f.write(",\n")
- f.write(" " + func)
- f.write("\n};\n")
-
+ if len(self._get_type_functions) > 0:
+ for func in self._get_type_functions:
+ f.write("extern GType " + func + "(void);\n")
+ f.write("GType (*GI_GET_TYPE_FUNCS_[])(void) = {\n")
+ first = True
+ for func in self._get_type_functions:
+ if first:
+ first = False
+ else:
+ f.write(",\n")
+ f.write(" " + func)
+ f.write("\n};\n")
f.close()
o_path = self._generate_tempfile('.o')
stdout=subprocess.PIPE)
return proc.communicate()[0].split()
- def _use_libtool_infection(self):
- libtool_infection = not self._options.nolibtool
- if not libtool_infection:
- return None
-
- libtool_path = self._options.libtool_path
- if libtool_path:
- # Automake by default sets:
- # LIBTOOL = $(SHELL) $(top_builddir)/libtool
- # To be strictly correct we would have to parse shell. For now
- # we simply split().
- return libtool_path.split(' ')
-
- try:
- subprocess.check_call(['libtool', '--version'])
- except subprocess.CalledProcessError, e:
- # If libtool's not installed, assume we don't need it
- return None
-
- return ['libtool']
-
def _compile(self, output, *sources):
- args = [self._compiler_cmd]
- if self._compiler_cmd == 'gcc':
+ # Not strictly speaking correct, but easier than parsing shell
+ args = self._compiler_cmd.split()
+ # Do not add -Wall when using init code as we do not include any
+ # header of the library being introspected
+ if self._compiler_cmd == 'gcc' and not self._options.init_sections:
args.append('-Wall')
pkgconfig_flags = self._run_pkgconfig('--cflags')
if self._uninst_srcdir:
args.append('-I' + os.path.join(self._uninst_srcdir,
'girepository'))
args.extend(pkgconfig_flags)
+ cflags = os.environ.get('CFLAGS')
+ if (cflags):
+ for iflag in cflags.split():
+ args.append(iflag)
for include in self._options.cpp_includes:
args.append('-I' + include)
args.extend(['-c', '-o', output])
def _link(self, output, *sources):
args = []
- libtool = self._use_libtool_infection()
+ libtool = get_libtool_command(self._options)
if libtool:
args.extend(libtool)
args.append('--mode=link')
args.extend([self._linker_cmd, '-o', output])
+ cflags = os.environ.get('CFLAGS')
+ if (cflags):
+ for iflag in cflags.split():
+ args.append(iflag)
+
# Make sure to list the library to be introspected first since it's
# likely to be uninstalled yet and we want the uninstalled RPATHs have
# priority (or we might run with installed library that is older)
# hack for building GIRepository.gir, skip -lgirepository-1.0 since
# libgirepository-1.0.la is not in current directory and we refer to it
# explicitly below anyway
- if (not uninst_builddir or
- self._options.libraries[0] != 'girepository-1.0'):
- # We only use the first library; assume others are "custom"
- # libraries like from gir-repository. Right now those don't define
- # new GTypes, so we don't need to introspect them.
- args.append('-l' + self._options.libraries[0])
+ for library in self._options.libraries:
+ if (uninst_builddir and
+ self._options.libraries[0] == 'girepository-1.0'):
+ continue
+ if library.endswith(".la"): # explicitly specified libtool library
+ args.append(library)
+ else:
+ args.append('-l' + library)
# hack for building gobject-introspection itself
if uninst_builddir: