After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 592311 - GObject IDL (needed for sane cross compilation)
GObject IDL (needed for sane cross compilation)
Status: RESOLVED INVALID
Product: glib
Classification: Platform
Component: gobject
2.31.x
Other All
: Normal enhancement
: ---
Assigned To: gtkdev
gtkdev
: 604556 663287 685298 (view as bug list)
Depends on:
Blocks: 696773
 
 
Reported: 2009-08-19 10:28 UTC by Emmanuele Bassi (:ebassi)
Modified: 2015-03-13 16:55 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Example emulator solution to cross compiling (8.70 KB, patch)
2012-10-10 18:59 UTC, Nicolas Dufresne (ndufresne)
none Details | Review

Description Emmanuele Bassi (:ebassi) 2009-08-19 10:28:21 UTC
currently, GObject-Introspection does not work when cross-compiling for different architectures.

apart from bug 560282 there's also the issue of g-ir-scanner dlopen()-ing a module in python: the problem is that the g-ir-scanner scanner binary ends up calling imp.load_module() on the code you're trying to compile. Since the arch you're running on (say 64 bit) might not equal the arch you're compiling for (say 32 bit), you get an error. there is no way importing the module in python is going to work when cross compiling.

the question is: why does g-ir-scanner have to do that? and can g-ir-scanner get the same information from, say, the output from binutils?
Comment 1 Colin Walters 2009-08-19 14:37:21 UTC
We need to load the code so we can get information on properties, signals, inheritance hierarchy, etc.  See:

http://git.gnome.org/cgit/gobject-introspection/tree/girepository/gdump.c

Now, there are a few different approaches.  The easiest one would be to ship a copy of the .gir in the tarballs, and have that be used as the data source if cross compiling.
Comment 2 Richard Purdie 2009-08-19 16:29:25 UTC
I work quite heavily with build systems, particularly cross compiling ones and see a lot of demand for building unreleased software straight from the source control system for testing/development purposes. Shipping the .gir file wouldn't help those use cases, or the one of a developer wanting to build/develop their own software cross platform.

Is there a more difficult but comprehensive way to solve this problem?
Comment 3 Johan (not receiving bugmail) Dahlin 2009-08-19 19:22:50 UTC
An alternative approach would be to extract that information from the source via a parser that knows enough about GObject to know about properties etc. It wouldn't be foolproof though, as some default property values cannot easily be abstracted. Not to mention that C parser g-ir-scanner would have to be extended considerably or ported to another parser such as clang.
Comment 4 Colin Walters 2009-08-19 19:48:12 UTC
[posting my comment, even though Johan beat me to essentially saying the same thing, mine is a bit more elaborated]

In the long term, ideally we could have C authors write comments that we scan, rather than calling the various functions like g_signal_new, g_object_class_install_property, g_boxed_type_register_static, etc.  

This is a *lot* of work though, and really depends on having introspection integrated deeply into GLib, and having the relevant library "ported".


It might be possible to use static code analysis to recognize invocations the above functions.  I think that's feasible, but again definitely not trivial.  Probably the right intermediate-term approach though.  

To code this, I'd just export a hook function from scannerlexer.y that exports a whole function parse tree to C.  Then we could do some heuristics on the function; scan through the tree for e.g. an invocation of g_boxed_type_register_static.  Once we see that, check that the arguments to the function are all things we recognize (in this case, we just need the first string argument).

Likewise for recognizing invocations of g_signal_new.  

One tricky thing here is avoiding cases where these things are created at runtime, but those should be very few.
Comment 5 Colin Walters 2009-08-19 19:49:52 UTC
But again though I understand the desire for building from git, practically speaking using a .gir generated on another machine should work relatively well.
Comment 6 Johan (not receiving bugmail) Dahlin 2009-12-14 17:08:59 UTC
*** Bug 604556 has been marked as a duplicate of this bug. ***
Comment 7 Koen Kooi 2010-01-23 11:34:53 UTC
So could people start shipping .gir files in tarballs to get at least support for crosscompiling releases?
Comment 8 Richard Purdie 2010-01-23 22:56:27 UTC
Are the .gir files architecture independent?
Comment 9 Emmanuele Bassi (:ebassi) 2010-01-24 03:15:38 UTC
(In reply to comment #8)
> Are the .gir files architecture independent?

yes, or at least: they should be.
Comment 10 Colin Walters 2011-03-29 15:21:42 UTC
Coming back to this, I think we shouldn't ship the .gir in the tarballs; all we need to ship is the private gdump.xml file, which is what requires running the code and breaks on cross compiling.

We would still do the source code scanning.
Comment 11 Colin Walters 2011-03-29 15:26:00 UTC
Note this only kicks the can slightly down the road; we're back to the problem when building from git.  I'm hesistant to recommend committing this to git because it'd be a conflict-fest.

I don't see how to solve this without converting consuming libraries to use at least a partial IDL.

We wouldn't have to go all the way to a full IDL; it could be something like:

gobject-gen --prefix=myobj --code

which would generate a .c file with property/signal definitions you could #include.

Actually in this world, g-ir-scanner could even do this, so we flip things entirely around.  g-ir-scanner would run *first* and generate .c/.h fragments that get #included, and generate the .gir.

This would also nicely move us along towards a full IDL future.
Comment 12 Colin Walters 2011-04-07 20:46:36 UTC
Reassigning this to gobject.  So I am looking at writing glib-genobject which takes a partial IDL.  I think this could actually be a nice improvement.

In practice, if your object has any nontrivial signals, we already force you to write a separate foo.list file and pass it to glib-genmarshal.  Thus there's already precedent for requiring a compile-time tool in a separate language.  Taking that a bit farther, let me sketch out some syntax for glib-genobject:

Put in a file named "shell-global.gobj":

# Property definitions  (# is the comment syntax for .gobj files)
# Note that we generate the nick from the name by replacing - with
# a space and uppercasing each word (i doubt anyone would need an override
# for this).  We take the first line from the docs as the blurb.
# This is for backwards compatibility

/**
 * ShellGlobal:overlay-group:
 *
 * Actor holding objects that appear above the desktop contents
 */
property object(CLUTTER_TYPE_ACTOR) overlay-group

/**
 * ShellGlobal:screen
 *
 * Metacity screen object for the shell
 */
property object(META_TYPE_SCREEN) screen

# We default to read-only.  Other keywords would be "writable" and "construct":
# Here's GApplicationCommandLine's "platform-data" property:

property writable construct variant("a{sv}") platform-data { NULL }

The last value is the default.  Here's a boolean one:

property boolean is-remote { FALSE }

# Signals:

signal void xdnd-position-changed (int, int) run-last;

# Okay, that's a bit too easy, let's try a more complex one from GActionGroup:

signal void action-added (string) run-last detailed struct(GActionGroupInterface, action_added)

# end examples

So how do you use this in code?  Basically, glib-genobj myobj.gobj -o myobj-gobj.c


/* myobj.c */

#include "myobj.h"
#include "myobj-gobj.c"

static void
my_obj_class_init (MyObjClass *class)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (class);

  gobject_class->get_property = my_obj_class_get_property;

  GOBJ_IMPL_MY_OBJ_CLASS_INIT (class)
}

The generated myobj-gobj.c code includes a macro which expands to all the C code.

Okay, so you're asking - how is this different from GOB ( http://www.jirka.org/gob.html ) ?  Basically, we are only targeting replacing the GType data - we're not trying to make it all single file.  The single file thing has a huge impact on debugging with gdb, etc.

We're also far away from Vala, which is a full programming language.

Other details - what about enums, boxeds, classes and interfaces?  Enums are already covered by glib-mkenums; we get all the data we need from the headers.

For boxeds, scanning for G_DEFINE_BOXED_TYPE should work.

Likewise for objects and interfaces, I *think* we may be able to just scan the .c file for G_DEFINE_TYPE and G_DEFINE_INTERFACE; i.e. hard require use of that macro in the introspection scanner.  G_DEFINE_TYPE_WITH_CODE would have to be restricted to G_IMPLEMENT_INTERFACE.
Comment 13 Yeti 2011-12-19 22:30:36 UTC
Please don't do this.

Anyone who wants to do different things while registering signals/properties or abstract them in a different way, i.e. anyone doing anything actually *interesting*, would be left out in cold.

I do not have any problem with the requirement to provide separate parseable definitions for signals and properties. It sort of makes sense and I can decide how to provide them (which includes generating them from something else in a manner I have control of).

What I cannot do is giving g-ir control over what code ends up in my class init functions.
Comment 14 Kevin Fox 2012-07-16 18:52:46 UTC
Would qemu be a good solution here? You could run g-ir-scanner in a tiny vm so it can do the dump. It wouldn't be very fast, but it wouldn't have to happen very often. If you are cross compiling, you probably have qemu installed anyway to do testing.
Comment 15 Koen Kooi 2012-07-16 19:15:46 UTC
Qemu is not a good solution because it isn't available for all architectures.
Comment 16 Olivier Crête 2012-08-17 20:38:09 UTC
What about just building a second copy of the library for the host architecture in the case of cross-compiling?
Comment 17 Nicolas Dufresne (ndufresne) 2012-08-29 16:38:11 UTC
(In reply to comment #16)
> What about just building a second copy of the library for the host architecture
> in the case of cross-compiling?

The .typeglib is a binary format and is architecture dependent. If I understood correctly, it is because of the way it is generated and read back.

Just a mention that I managed to cross-compile this using qemu, I'm trying to figure-out if it would be possible to include the required hooks, because while not all architecture are supported by Qemu, this remains the only existing solution.

Overall, the first issue is that the build rely on a python module (_giscanner.so) which gets cross-compiled for the platform, this can be worked around by compiling it for the build architecture. Then, a cross compiled program has to be run on target to generate the dump.xml file, this includes the properties and types introspection data. Finally, from this file and the GIR, a .typelib is being compiled with g-ir-compiler, which does not give the same result depending on which architecture it runs on.

My current approach is to specify a prebuilt _giscanner.so during configure phase, and run the dump program and compiler through qemu (using a wrapper script to bypass libtool). I also had to change a bit the python script to allow setting custom pkg-config command and add support for LDFLAGS.

Let me know if it's worth uploading this patch here.
Comment 18 Colin Walters 2012-09-05 22:27:29 UTC
(In reply to comment #17)

> The .typeglib is a binary format and is architecture dependent. If I understood
> correctly, it is because of the way it is generated and read back.

Mmm...it's architecture dependent because it only has machine-dependent types like int32, guint64; there is no "int".

> Just a mention that I managed to cross-compile this using qemu, I'm trying to
> figure-out if it would be possible to include the required hooks, because while
> not all architecture are supported by Qemu, this remains the only existing
> solution.

I'd be happy to look at a patch.  It's very likely to be a conflict-fest with the outstanding mingw32 and MSVC work =/

After 3.6?

> My current approach is to specify a prebuilt _giscanner.so during configure
> phase, and run the dump program and compiler through qemu (using a wrapper
> script to bypass libtool). I also had to change a bit the python script to
> allow setting custom pkg-config command and add support for LDFLAGS.

Hmm.  Is it too hard to add a Makefile which builds _giscanner-host.so ?
 
> Let me know if it's worth uploading this patch here.

Of course!  I can't promise anything without seeing it...but I can tell you other people are interested in it.
Comment 19 Colin Walters 2012-10-02 14:29:57 UTC
*** Bug 685298 has been marked as a duplicate of this bug. ***
Comment 20 Nicolas Dufresne (ndufresne) 2012-10-10 18:59:15 UTC
Created attachment 226193 [details] [review]
Example emulator solution to cross compiling

I have not mark this as a patch, basically because it's not a proper patch. This patch adds a series of hook and small fixes to allow cross compiling using qemu.

To use this patch, you first need to compile a build platform version of the scanner python module:

configure
make _giscanner.la
cp .libs/_giscanner.so _giscanner.x86_64.so
make distclean

And then setup cross compiling environment and emulator command. (Clearly this can be automated and cleanup. But that was the time I had to figure this out)

# setup some env
export EMULATOR_CMD="qemu-mipsel -E D_LIBRARY_PATH=.libs:$stage/lib:$prefix/lib -L $stage"
export EMULATOR=./emulate.sh
./configure --host=...
make _giscanner.la
# Workaround python module not built for the right platform
cp _giscanner.x86_64.so .libs/_giscanner.so
make
make install

Hope this will help some people to workaround the issue.
Comment 21 Colin Walters 2012-10-27 15:56:43 UTC
*** Bug 663287 has been marked as a duplicate of this bug. ***
Comment 22 Kouhei Sutou 2013-02-10 07:09:28 UTC
Is there any progress about this?

I want to compile GObject Introspection for Windows on Debian GNU/Linux sid with MinGW-w64.

I am a member of the Ruby-GNOME2 project. The project released Ruby bindings for GTK+ 3 named Ruby/GTK3. The bindings ship GTK+ 3 Windows binary that is compiled on Debian GNU/Linux. So Ruby/GTK3 can be used without compilation on Windows.

The project also wants to provide Ruby bindings for GObject Introspection with GObject Introspection Windows binary. (Ruby bindings for GObject Introspection, named Ruby/GObjectIntrospection, works well on Linux.)

So I'm interested in this topic.
Comment 23 Tomas Frydrych 2013-04-02 13:02:46 UTC
I am working on Yocto support for g-i. Using Qemu this is not that hard a problem to solve, and not using Qemu, well, there's been little progress in the nearly 4 years this bug exists :)
Comment 24 Colin Walters 2013-04-10 11:59:29 UTC
(In reply to comment #23)
> I am working on Yocto support for g-i.

Do you have any links to patches?  A high level summary of the current state?

And thanks a ton for working on this!
Comment 25 Tomas Frydrych 2013-04-15 08:29:53 UTC
I got it pretty much working, the Yocto meta-gir repo is at https://github.com/Guacamayo/meta-gir

A bunch of patches, none of them upstreamable, is in https://github.com/Guacamayo/meta-gir/tree/master/meta-gir/recipes-gir/g-ir/files; there are some things that could be done upstream to make things easier: 

 * configure options to make it possible to build the tools, the lib and the typlibs separately,

 * not running pkg-config in makefiles,

 * extra command line args to g-ir-scanner to enable use of wrappers in place of ldd and when executing the product (see the use-*.patch files).

There are some issues that cannot be sensibly addressed here, such as the limitations of 'pkg-config --variable', which does not do sysroot fix up, so a sed script has to be run on configure.ac when cross compiling to get the paths right (pkg-config needs a --path=VARIABLE option, which would work like --variable but do sysroot fix up the same way it happens for --libs and --cflags).
Comment 26 Colin Walters 2013-04-15 13:04:00 UTC
(In reply to comment #25)
> I got it pretty much working, the Yocto meta-gir repo is at
> https://github.com/Guacamayo/meta-gir
> 
> A bunch of patches, none of them upstreamable, 

=( 

But why would you do all this work and not even have a git checkout and attempt to get stuff upstream? =(  Damn OE default of building from tarballs... 

So take as an example:
https://github.com/Guacamayo/meta-gir/blob/master/meta-gir/recipes-gir/g-ir/files/configure-introspection.patch

Can't we just wrap this in AS_IF([test x$cross_compiling = xyes],  ?

> There are some issues that cannot be sensibly addressed here, such as the
> limitations of 'pkg-config --variable', which does not do sysroot fix up, so a
> sed script has to be run on configure.ac when cross compiling to get the paths
> right (pkg-config needs a --path=VARIABLE option, which would work like
> --variable but do sysroot fix up the same way it happens for --libs and
> --cflags).

Makes sense.  Though honestly, I don't understand the point of AC_PATH_PROG() and pkg-config --variable=binary .  It's just easier to search $PATH at runtime, and I can't think of why hardcoding the path would help anyone.
Comment 27 Tomas Frydrych 2013-04-15 14:07:42 UTC
> But why would you do all this work and not even have a git checkout and attempt
> to get stuff upstream? =(  Damn OE default of building from tarballs... 

To make g-ir cross-compile is, unfortunately, not a matter of a few trivial patches, but a fairly substantial refactoring of the build system and rethink of the way in which it is set up, and even then you will not get something that 'Just Cross Compiles(TM)', not least because of the awkwardness of the scanner tool. The meta-gir patches are a minimal and OE-specific workaround for the way the g-ir build system is set up. If there is an impetus to refactor the g-ir build system to make it a bit friendlier for cross compilation, I can look into it.

> So take as an example:
> https://github.com/Guacamayo/meta-gir/blob/master/meta-gir/recipes-gir/g-ir/files/configure-introspection.patch
> 
> Can't we just wrap this in AS_IF([test x$cross_compiling = xyes],  ?

It would serve no useful purpose on it's own, you need to hack the makefiles alonside, e.g., https://github.com/Guacamayo/meta-gir/blob/master/meta-gir/recipes-gir/g-ir/files/fixup-gir-build.patch and other patches.


> Makes sense.  Though honestly, I don't understand the point of AC_PATH_PROG()
> and pkg-config --variable=binary .  It's just easier to search $PATH at
> runtime, and I can't think of why hardcoding the path would help anyone.

Searching $PATH is very fragile, the only robust ways of ensuring you are calling the correct tool is to either have a tool prefix, as is done with compilers and such, or to specify the full path.
Comment 28 Colin Walters 2013-04-15 14:27:02 UTC
(In reply to comment #27)
> > But why would you do all this work and not even have a git checkout and attempt
> > to get stuff upstream? =(  Damn OE default of building from tarballs... 
> 
> To make g-ir cross-compile is, unfortunately, not a matter of a few trivial
> patches, but a fairly substantial refactoring of the build system and rethink
> of the way in which it is set up,

Right, I understand that.  But there's likely parts of it that can go upstream cleanly, and even for the "non upstreamable" parts I'd definitely consider maintaining an alternative set of Makefiles or scripts in the tree.

> If there is an impetus to refactor the g-ir
> build system to make it a bit friendlier for cross compilation, I can look into
> it.

Definitely!  Not least because I want g-i to work well for OE, but also because I want it to work for mingw32 cross builds.

> Searching $PATH is very fragile, the only robust ways of ensuring you are
> calling the correct tool is to either have a tool prefix, as is done with
> compilers and such, or to specify the full path.

Hmm.  I was burned in the OE context by something doing AC_PATH_PROG(bison) and that found bison-native's path in the sysroot, which ended up being embedded in a generated binary for the target, which obviously failed at runtime.  Maybe that's an unusual case.

Anyways, if you find the time, please do consider turning whatever patches you can into "git format-patch" style and submit them here.  Failing that I can look at doing it myself at some point, but it'll likely only happen once I get to the point of having an autobuilt glib (not g-i) for mingw32 in the GNOME infrastructure.
Comment 29 Allison Karlitskaya (desrt) 2013-04-16 13:00:52 UTC
vapi anybody?

Seriously... if someone invents a new IDL format that's not vapi, I'm going to be upset.
Comment 30 nuthankumar 2014-06-26 16:09:54 UTC
I am trying to build this project,

https://github.com/Guacamayo/meta-gir

but i get an error saying ERROR: can't resolve libraries to shared libraries: gobject-2.0, glib-2.0

ERROR: can't resolve libraries to shared libraries: gobject-2.0, glib-2.0
make[2]: *** [GLib-2.0.gir] Error 1
make[2]: Leaving directory
`/home/ignite/sbox2/rootfs/rfs-raspbian/home/pi/gobject-introspection-1.34.2'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory
`/home/ignite/sbox2/rootfs/rfs-raspbian/home/pi/gobject-introspection-1.34.2'
make: *** [all] Error 2

Can anyone help to solve this problem?
Comment 31 Emmanuele Bassi (:ebassi) 2014-06-26 16:15:49 UTC
bugzilla is not a help forum; please, ask the Guacamayo developers/maintainers.
Comment 32 Allison Karlitskaya (desrt) 2015-03-13 16:55:28 UTC
Bug 696773 is addressing the real issue here, which is how to make gobject-introspection work in cross-compiling situations.  An IDL is probably not part of the solution to that problem and this bug has spun wildly off topic, so I'm going to close it now.