Re: Sharing code between Nemiver and Anjuta



Hello,

Sébastien Granjoux <seb sfo free fr> a écrit:

I'm a developer of Anjuta and I will be interested to share more code
between Nemiver and Anjuta.

Great.  Thank you for considering this.

For the record, Jonathon Jongsma, the Nemiver co-maintainer had this
discussion with you guys a few years ago and it didn't went far,
mainly because we are in C++ and you guys are in C/GObject; in theory
it's thus easier for us to re-use your stuff, than the other way
around [1].

That being said, I am all for the principle of making our two projects
to get closer as I guess that can benefit our users.  I guess the
devil is going to be hidden in the practical details, but I suspect
hackers like hunting that devil until he flies back to hide in hell.

:-)

I don't know what could be shared between between both projects. We
could just write a common shared library wrapping gdb.

More on this later below.

But an important part of the code is the user interface so it would
be better if we can find a way to share this too.

For the UI, Nemiver uses gtkmm; in theory, that means that it's easier
for Nemiver to use UI elements from Anjuta than it is for Anjuta to
use UI elements from Nemiver.

It's not impossible for Anjuta to use UI elements from Nemiver, but I
think it's important to understand that the they are tied to the
nemiver::IDebugger (C++) interface of the debugger backend.  For
instance, the variable inspector widgets (e.g, local variable
inspector or expression monitor) for instance know how to react to
changes in the state of variables/expressions that the user queried
using the nemiver::IDebugger interface.  These widgets also let the
user edit the expressions etc.  That is why these widgets are passed
an instance of implementation of IDebugger at construction time.

In other words, using the UI of Nemiver means using its IDebugger
interface too, which amounts to what you referred to above as a
'shared library wrapping gdb'.

I think Nemiver is using GDL like Anjuta, but Anjuta wraps it so it is
not directly accessible. Every function in Anjuta is provided by
plugins, if Nemiver could load such plugin it would be easier to share
more code.

Actually we use gdlmm which -- as part of a gtkmm -- is a c++ wrapper
for GDL that provides strong compile-time type checking to the signals
we connect to, as well as a way to extend the widgets without banging
your head around the GObject macro-soup we all came to dislike too
often, and rightly so.

I think it is not easy and could take a quite long time but Anjuta
already have a integrated debugger so we have time.

Indeed.

Are there other people interested?

I'd be interested, of course.  But we'd need more people as my time is
limited, as is anyone else' time, I guess.  :-)

Jens Georg <mail jensge org> a écrit:

How about doing it the Unix way™ and use Nemiver as THE Anjuta debugger,
probably by providing some means of communication (D-Bus, ...) between
them?

Heh.  I wouldn't have proposed that myself, by fear of sounding maybe
unfriendly to my peers who have sunk so much of their time in the
current Anjuta's debugger  :-)

More seriously though, just speaking for Nemiver, I wouldn't go for an
IPC based way to do this.  I'd rather embed the relevant Nemiver bits
via a C++ library.  If you guys still don't want to switch to c++,
then it'll take devising a C/GObject wrapper around that library.

But really, maybe you guys should consider switching progressively to
C++.  If even GCC did it, I think it can be possible for Anjuta.  

I will gently argue for this point throughout this message even though
I am fully aware that I am not part of your project and thus won't be
the one doing the work.

I am doing this b/c I feel that ultimately, if done right, it might
help you guys in terms of maintainability of the code (while keeping
code speed and size in check), and it might help our users because
they get a less crashy and leaky tool in the end.

Johannes Schmid <jhs jsschmid de> a écrit:

I though about this a while and indeed it could work in some way:

* Anjuta would start a nemiver instance with some kind of --no-gui
option that would provide the backend for gdb and the dbus interface

* The dbus interface would work in two ways:
 - Anjuta would sent commands to nemiver like it does to gdb at the
moment. It would also very for certain information (Info about
variables, breakpoints etc.)
 - Nemiver would itself sent some command to anjuta like the current
line that we are at or things like that.

Again, I'd rather go for a using a library that uses the Nemiver
internals.  It'll take some designing of the library interface, but
then we'll need this design process for the dbus interface anyway.
Thus I think we cannot really do away with the design burden.  But I
suspect the gain of the library approach (versus dbus) would be speed,
size, and "agility".

Sébastien Granjoux <seb sfo free fr> a écrit:

Le 09/06/2013 20:53, Johannes Schmid a écrit :
How about doing it the Unix way™ and use Nemiver as THE Anjuta debugger,
probably by providing some means of communication (D-Bus, ...) between
them?

We are already interfaced with gdb using the Unix way and it's not so
easy because they are quite some information to exchange. We can use
Nemiver as an additional layer it will be a bit better but I don't
think it will be very different from the current gdb machine
interface.

The interface that Nemiver uses to interact with the debugger backend
is nemiver::IDebugger.  You can see an example of it in this small
regression test at:

    https://git.gnome.org/browse/nemiver/tree/tests/test-disassemble.cc

Start reading from the 'test_main' function.  What that test does is
to load an implementation (that knows how to use GDB) of the IDebugger
interface, set callback functions that get called upon meaning events
reported by the IDebugger interface, load a small program, set a
breakpoint in the main function of the program, execute the program
under the supervision of GDB; when the breakpoint is hit, this
regression test disassembles 20 instructions around the breakpoint.

Moreover it needs quite some changes in Nemiver, I don't know if
someone on Nemiver side want to do it.

Yes, I think it'll need some changes, indeed.  It'll need to ironing
out of some idiosyncrasies from the interface.  And if you don't want
to switch to C++ for the Anjuta core, I guess it'll need some major
C/GOBject wrapping.  It's doable, but I don't fancy doing that myself
because I don't think that holds much value, ultimately -- and it's a
lot of work.  I won't oppose the inclusion of such a library, of
course.

I am of the belief that switching to C++ instead would be a better use
of our hacking time and energy :-)

It's not planned now but I will be interested to share some widgets

Just curious, what widget exactly?

and I don't think we can do it the Unix way.

If by "Unix way", you mean using IPC, I definitely agree.


Jens Georg <mail jensge org> a écrit:

Hubert Figuière <hub figuiere net> a écrit:


You mean you are ready to use C++ in Anjuta code base?

Good question.

Sébastien Granjoux <seb sfo free fr> a écrit:


Le 05/06/2013 22:33, Hubert Figuière a écrit :

[...]

You mean you are ready to use C++ in Anjuta code base?

That's an issue but that's fine for me. I think C++ has some
advantages comparing to C.

Indeed.

But the minimal common denominator for Gtk is still C and I don't
see it changing.

Hmmh, actually, not exactly.  We are using Gtk+, yes, but only through
Gtkmm.  We do seldom use C/Gtk, for some widget that are not yet
wrapped by Gtkmm, but that belongs to exceptional cases, and I'd like
that to stay that way.

I am not pushing for Gtkmm for religious reasons.  Rather, it's
ultimately to have a code base that crashes and leaks less, without
having to spend "big" amounts of time doing testing.

James Liggett <jrliggett cox net> a écrit:

But, Anjuta has always used C whenever possible, and it's generally been
a policy of ours to stick to it to keep the codebase consistent. It
might be worthwhile to consider moving the entire Anjuta codebase to an
OO language like C++ so we can take advantage of its features and keep
the code consistent.

Amen brother.  Note that OO is not the only paradigm that you guys
would benefit from.

For instance, having the compiler tell you straight away that the
"data" argument that you passed to your signal handler is of the wrong
type (for instance, after you did some refactoring) is a huge
improvement over silently overlooking that until you users experiment
the inevitable resulting crash down the way is a *huge* selling point
in my book.  And having that, while sitting on the giant shoulders of
C, in such a way that you can just copy-paste code from C code bases,
compile it and use is w/o *needing* to wrap feels like another silver
bullet.  And of course, we can rely on a mature and versatile
toolchain these days.

Sébastien Granjoux <seb sfo free fr> a écrit:


Le 06/06/2013 21:06, Johannes Schmid a écrit :
Well yes and no. Our policy is to keep the core libs (libanjuta) in C
while plugins can (in theory) use any language and in practice can use
C, Vala, C++ (though there is no wrapper around libanjuta) and in theory
any language that supports gobject-introspection.

I fully agree with this.


I don't see an issue when using C++ code in anjuta but I would like to
avoid duplicating code between nemiver and anjuta because it is a pain
to maintain. That could mean two things

The current debugger plugin in Anjuta has roughly the same function
than Nemiver (I think Nemiver is a bit better) and has no code in
common. I think the only common code is GDL which can be used by
Nemiver.

As I said above, Nemiver use GDL already, through gdlmm.

* export the common functionality into some kind of library (can be part
of the nemiver sources)
* 1:1 copy of some nemiver sources into the anjuta codebase (like done
with scintilla). This is less prefered but might be easier to start with

I'm not convinced that it's less work to use Nemiver code than to
duplicate it in Anjuta and I see C++ as a disadvantage for this. But I
can be wrong. Moreover I think it's much more interesting to try to
use Nemiver code than rewriting it in C. So, I would prefer to try the
first, cleaner, solution.

Yeah.  Assuming we can devise a library for the stuff you guys find
worthwile, if there is value for Nemiver to use that library, I'd be
glad to have a library external to Nemiver, that Nemiver depends on.
Anjuta could then depend on that same library, too.


Sébastien Granjoux <seb sfo free fr> a écrit:

I have get Nemiver, compiled it and started to read the code. I
describe below my first view of Nemiver code. It includes my own
opinion, so please correct me if I have misunderstood something or if
you disagree.



The architecture is very similar to Anjuta. There is a main function
which is loading plugins (DynamicModule for Nemiver) which are
responsible for providing the functions. There is a common library
which is named libnemivercommon instead of libanjuta. Like in Anjuta,
the debugger is splitted in two modules: one responsible for the GUI
and one which wraps gdb (libgdbmod).

Nemiver is indeed organized around dynmods (short name for
DynamicModule s).  A dynmod exposes an interface that is a C++ header
that contains classes that are only pure interfaces, or classes with
inline functions only.

A user codebase doesn't have to 'link' with the dynmod explicitly.

Rather, it links with libnemivercommon *only*.  In the code, it says
somewhere "load the dynmod "foo" that provides and implementation of
the interface I".  libnemivercommon knows how to load that dynmod
using dlopen-fu and checks that it indeed provides an implementation
for that interface I.

Once the dynmod is loaded, the user codebase just uses the interface
I.  Note that there is no IDL here, no code generation, etc.  I is a
C++ interface.  I did this voluntarily to minimize cruft and maximize
maintainability.  At this point, I am not really interested in, e.g,
dynmods written in dynamic languages.  I am not opposed to these, but
really, what I wanted first was a graphical debugger that would be
fast, robust and would use reasonable amounts of memory.

The main difference is that Nemiver is written in C++ and is using its
own types while Anjuta is using GLib. By example there is a
nemiver::Object which is a very simple version of GObject or
DynModIface which is replacing GInterface.

Yes, I am not a fan of GObject at the application development level
because the macro soup that comes with it makes it too error prone,
leading to a more crashy user experience than I'd like to accommodate.

:-)

Nemiver thus defines a lot of ad-hoc types.  It's as easy as doing
class foo : some_base class {};  No GObject boilerplate shit.  But we
do use a lot of libstdc++ and gtkmm types, too.

Nemiver is using GLib and Gtk, by example, GModule for loading its
module but it's completely hidden at the lowest level. So it cannot be
used as a GLib library. I think that GObject introspection is not
working on Nemiver libraries, by example.

Correct.  No (GObject) introspection.  If someone plans to write a
wrapper library, it'll need either to be done by hand, or use an
ad-hoc auto-generation thingy of some sort.

* I think we can try to use the gdb module (libgdbmod) of Nemiver. I
think it's a bit better than Anjuta gdb plugin but the main advantage
is that the interface is well defined. We need a wrapper to convert
GObject into Nemiver object and the opposite though. Is there someone
interested to work on it on Nemiver side?

As I implied above, what the client consumes is not libgdbmod.  It's
rather the interface it exposes, which is nemiver::IDebugger.

I am not interested in consuming GObject at the application level in
Nemiver because from where I sit today, and seeing all the advantages
we are experiences from using a C++ interface like IDebugger, I hardly
see any value in going back to something as low level as GObject.

I'd like to hear opinions that would proved me wrong, though.

I suppose this wrapper could be generated more or less automatically
by some scripts like it is done for GObject C++ bindings.

Just curious; there are scripts that generate C/GObject wrappers from
a C++ interface?

What do you mean by GObject C++ bindings?

At the beginning, I have imagined that we could use the GObject C++
bindings but I think it will not work because Nemiver uses its own
classes.

Do you see another solution?

As I don't understand what you mean by GObject C++ bindings, I guess
I'll wait for your answer to my question above.

But, I tend to think that a C/GObject library that would wrap
nemiver::IDebugger would need to be hand crafted.  Automation is not
everything; the wrapper's interface will need to be properly designed
as well.


* Nemiver is split in quite a lots of libraries, by example the
parsing of gdb output is compiled in a separated library. It is
possible to use them but again the issue is that there are written in
C++. I think writing a wrapper is less interesting for such smaller
libraries unless it can be generated automatically.

That, or switch to C++ in Anjuta's core.  :-)

* Another possibility is to do it in the opposite way, I mean write
something in C using GObject and use it in Nemiver.

And get something that is more error prone, probably takes more source
code (e.g, handling strings in C vs using std::string, for a quick
shot) just to achieve the same result.  And the result won't even be
faster.

Really, unless I get some strong arguments about what we'll get as
technical superiority and robustness from within Nemiver by doing
this, I fear I won't buy much into getting back to C/GObject for
something that we /already/ have in C++ and is doing the job.

I am not against using C, mind you.  My willingness to re-use C is
what got me in this C++ business in the first place.  :-) But to me,
up to a certain point, the more C++ I can use at application level,
the better.

In this direction, the wrapper can be generated more or less
automatically. Is there some parts of Anjuta that would be useful
for Nemiver? Or do you have ideas of something those can be written
in C and used by both programs?

Oh, I sure would be glad to use some C code for stuff Nemiver doesn't
do yet, and that Anjuta does.  I don't think of anything in particular
yet, though.

* If we continue the previous idea at its limit, we can wrap all
Anjuta plugins to use them in Nemiver and transform Nemiver in a full
IDE. I add this as a possibility but I don't think it worths it. What
do you think?

Haha  :-)

Emacs is the ILE (integrated Life Environment) where I live so, as a
programmer, I am not really interested in hacking on an IDE.  But a
graphical debugger (that I launch from within Emacs everyday), I can
hack on.  :-)

Joking aside, I'd vote for Anjuta to be THE IDE in GNOME.  Really.
You guys know the problem domain, and you know it well.

I'd just wish Anjuta to be in full-blown C++ and see you guys enjoy a
less crashy and leaky life, happily and easily re-using whatever C or
C++ code base you come across and find worthwhile ;-)

* Finally, the last remaining usage of Nemiver code could be just to
read it and see what can be learned from it and re-implement it in
Anjuta. The function of both programs overlaps and the architecture is
quite similar so we have faced the same issues.

This works as well.

Cheers.

[1] http://osdir.com/ml/ide.anjuta.devel/2006-10/msg00051.html


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]