[GRASS-dev] Standalone GUI modules: Makefile

Hi devs,

before asking for help I will introduce you to the topic. In r52629
[1] I tried to implement the idea of standalone GUI modules for Map
Swipe. These modules should be similar to wxGUI components but they
are intended to be launched in the same way as standard modules.

The implementation is simple. You create a file file similar to a file
for python script. But you start wx application and set up the wxGUI
component. As an example you can see mapswipe/g.gui.mapswipe.py which
you can run like this:

g.gui.mapswipe first=map_before second=map_after

The standalone window is the same as you get from the main menu in the
main GUI. You probably see the advantages of this approach. The GUI
will be forced to be more modular and the modularity will be
maintained because users can actually use the standalone modules. The
main idea is to make GUI to be more like the rest of GRASS. The best
part is that this can easily coexist with the idea of one big main GUI
application.

Now, I'm asking for help with Makefile for this module. Martin helped
me a lot in identifying what has to be done and he prepared the
Makefile [2]. But this Makefile need to be generalized in order to
avoid code duplication. I'm not able to do it so I'm asking you to
help.

Basically, the necessary steps are:

1. copy the g.gui.modulename.py to scripts and create standard module
documentation (then you can run g.gui.mapswipe and g.manual
g.gui.mapswipe)

2. remove tmp file with documentation (to behave as a wxGUI component)

3. create wxGUI component documentation (then you can run g.manual
wxGUI.MapSwipe)

Module directory has to be added to gui/wxpython/Makefile in order to
call make in wxGUI module directory (mapswipe in this case). This is
of course expected. However, that is the third directory name
occurrence in this Makefile. Some clever solution is needed here too.

Everything is open for a discussion so the Makefile tasks may change.
But I hope that the current solution is good enough to be fully
implemented (this means, please, help with the Makefile).

You can study the current solution from the sources [3]. The latest
changes were: moving a documentation, renaming the main.py file and
the Makefile (r53733-r53737).

Vaclav

[1] http://trac.osgeo.org/grass/changeset/52629
[2] http://trac.osgeo.org/grass/browser/grass/trunk/gui/wxpython/mapswipe/Makefile?rev=53737
[3] http://trac.osgeo.org/grass/browser/grass/trunk/gui/wxpython/mapswipe/

Vaclav Petras wrote:

Now, I'm asking for help with Makefile for this module. Martin helped
me a lot in identifying what has to be done and he prepared the
Makefile [2]. But this Makefile need to be generalized in order to
avoid code duplication. I'm not able to do it so I'm asking you to
help.

If you want to avoid duplication, it would help to avoid giving each
module two distinct names (e.g. g.gui.mapswipe and MapSwipe).

A prefix or suffix can be handled easily enough, but the case
conversion is more awkward. make doesn't have a function for case
conversion, and using $(shell ...) is inefficient and relies upon the
existence of a utility such as "tr".

If one can't be generated automatically from the other, then we'd need
to implement a table, as is done for library names in Grass.make.
"mapswipe" can be generated from "MapSwipe" (at the cost of running an
external command), but we can't do the reverse. Also, if one form uses
camel-case while the other use underscores, it gets more complicated.

Basically: how important is it for each module to have a WXPGM
distinct from PGM?

--
Glynn Clements <glynn@gclements.plus.com>

On 10 November 2012 19:22, Glynn Clements <glynn@gclements.plus.com> wrote:

Vaclav Petras wrote:

Now, I'm asking for help with Makefile for this module. Martin helped
me a lot in identifying what has to be done and he prepared the
Makefile [2]. But this Makefile need to be generalized in order to
avoid code duplication. I'm not able to do it so I'm asking you to
help.

If you want to avoid duplication, it would help to avoid giving each
module two distinct names (e.g. g.gui.mapswipe and MapSwipe).

A prefix or suffix can be handled easily enough, but the case
conversion is more awkward. make doesn't have a function for case
conversion, and using $(shell ...) is inefficient and relies upon the
existence of a utility such as "tr".

If one can't be generated automatically from the other, then we'd need
to implement a table, as is done for library names in Grass.make.
"mapswipe" can be generated from "MapSwipe" (at the cost of running an
external command), but we can't do the reverse. Also, if one form uses
camel-case while the other use underscores, it gets more complicated.

Basically: how important is it for each module to have a WXPGM
distinct from PGM?

Hmm, it is not so important. The main reason is that we need two
manual pages. One for module (g.gui.mapswipe.html) and one for
component (wxGUI.MapSwipe.html).

To simplify things, we can use name wxGUI.g.gui.mapswipe.html. But I
don't like "wxGUI.g.gui" part. Naming convention should lead to nice
names. wxGUI.mapswipe.html would be nice (mapswipe is also the
directory name).

Anyway, I thing that it is worth to have two manual pages (and thus
two identifiers), one for module and one for component integrated to
wxGUI. The later one is without the generated part so the user is not
disturbed by the command line things when he is using GUI. Another
argument for the GUI-only manual page is the list of wxGUI components
where are these components listed by their long (user visible) names
(Map Swipe).

In conclusion, I agree that translating one to another is too
complicated. However, we can give up the camel case (which is used
only in manual) and derive one name from another just by substitution
(PGM=g.gui.$WXPGM). In this case, we can have two identifiers for two
(similar but different) manual pages which are needed to satisfy all
users. And finally, if we agree on two manual pages, we need the rule
for the Makefile.

Vaclav

Vaclav Petras wrote:

> Basically: how important is it for each module to have a WXPGM
> distinct from PGM?
>
Hmm, it is not so important. The main reason is that we need two
manual pages. One for module (g.gui.mapswipe.html) and one for
component (wxGUI.MapSwipe.html).

To simplify things, we can use name wxGUI.g.gui.mapswipe.html. But I
don't like "wxGUI.g.gui" part. Naming convention should lead to nice
names. wxGUI.mapswipe.html would be nice (mapswipe is also the
directory name).

Prefixes and suffixes can be added and removed easily enough, so
having g.gui.mapswipe.html and wxGUI.mapswipe.html is straightforward.

So if you have a subdirectory for modules, you could do e.g.:

MODULES := $(patsubst g.gui.%.py,%,$(wildcard g.gui.*.py))
CMDHTML := $(patsubst %,$(HTMLDIR)/g.gui.%.html,$(MODULES))
GUIHTML := $(patsubst %,$(HTMLDIR)/wgGUI.%.html,$(MODULES))
PYFILES := $(patsubst %,$(SCRIPTDIR)/g.gui.%,$(MODULES))

default: $(CMDHTML) $(GUIHTML) $(PYFILES)

$(HTMLDIR)/g.gui.%.html: g.gui.%.html g.gui.%.tmp.html | $(HTMLDIR)
  $(PYTHON) $(GISBASE)/tools/mkhtml.py g.gui.$* $(GRASS_VERSION_DATE) > $@

$(HTMLDIR)/wxGUI.%.html: g.gui.%.html | $(HTMLDIR)
  $(INSTALL_DATA) $< $@

g.gui.%.tmp.html: $(SCRIPTDIR)/g.gui.%.py
  $(call htmldesc,$<,$@)

$(SCRIPTDIR)/g.gui.%.py: g.gui.%.py | $(SCRIPTDIR)
  $(INSTALL) $< $@

--
Glynn Clements <glynn@gclements.plus.com>

Hi,

2012/11/12 Glynn Clements <glynn@gclements.plus.com>:

So if you have a subdirectory for modules, you could do e.g.:

MODULES := $(patsubst g.gui.%.py,%,$(wildcard g.gui.*.py))
CMDHTML := $(patsubst %,$(HTMLDIR)/g.gui.%.html,$(MODULES))
GUIHTML := $(patsubst %,$(HTMLDIR)/wgGUI.%.html,$(MODULES))
PYFILES := $(patsubst %,$(SCRIPTDIR)/g.gui.%,$(MODULES))

[...]

to avoid that this issue remains unsolved, I took liberty to commit
suggested solution as GuiScript.make (r54150). Ideally Html.make could
be included to avoid copying htmldesc routine and rules for installing
images.

Thanks for a review in advance, Martin

--
Martin Landa <landa.martin gmail.com> * http://geo.fsv.cvut.cz/~landa

Martin Landa wrote:

> So if you have a subdirectory for modules, you could do e.g.:
>
> MODULES := $(patsubst g.gui.%.py,%,$(wildcard g.gui.*.py))
> CMDHTML := $(patsubst %,$(HTMLDIR)/g.gui.%.html,$(MODULES))
> GUIHTML := $(patsubst %,$(HTMLDIR)/wgGUI.%.html,$(MODULES))
> PYFILES := $(patsubst %,$(SCRIPTDIR)/g.gui.%,$(MODULES))

[...]

to avoid that this issue remains unsolved, I took liberty to commit
suggested solution as GuiScript.make (r54150). Ideally Html.make could
be included to avoid copying htmldesc routine and rules for installing
images.

Html.make should be included, and variables and rules which are
defined there should be removed from GuiScript.make.

--
Glynn Clements <glynn@gclements.plus.com>

Hi,

2012/12/3 Glynn Clements <glynn@gclements.plus.com>:

Html.make should be included, and variables and rules which are
defined there should be removed from GuiScript.make.

sure, unfortunately it doesn't work without any extra care. When
Html.make is included than

`g.gui.%.tmp.html` from GuiScript is ignored and `%.tmp.html` from
Html.make is used instead.

Martin

--
Martin Landa <landa.martin gmail.com> * http://geo.fsv.cvut.cz/~landa

Martin Landa wrote:

> Html.make should be included, and variables and rules which are
> defined there should be removed from GuiScript.make.

sure, unfortunately it doesn't work without any extra care. When
Html.make is included than

`g.gui.%.tmp.html` from GuiScript is ignored and `%.tmp.html` from
Html.make is used instead.

Right. It's supposed to choose the most-specific match (the one with
the shortest stem), but that was broken in 3.81; it just uses the
first match.

Placing the pattern rule for g.gui.%.tmp.html before Html.make is
included should avoid the issue.

--
Glynn Clements <glynn@gclements.plus.com>

Hi,

2012/12/3 Glynn Clements <glynn@gclements.plus.com>:

`g.gui.%.tmp.html` from GuiScript is ignored and `%.tmp.html` from
Html.make is used instead.

Right. It's supposed to choose the most-specific match (the one with
the shortest stem), but that was broken in 3.81; it just uses the
first match.

Placing the pattern rule for g.gui.%.tmp.html before Html.make is
included should avoid the issue.

thanks for the clarification. Unfortunately placing Html.make after
`g.gui.%.tmp.html` doesn't seems to help.

Martin

--
Martin Landa <landa.martin gmail.com> * http://geo.fsv.cvut.cz/~landa

Martin Landa wrote:

> Placing the pattern rule for g.gui.%.tmp.html before Html.make is
> included should avoid the issue.

thanks for the clarification. Unfortunately placing Html.make after
`g.gui.%.tmp.html` doesn't seems to help.

The attached version works for me with make 3.82. I don't have 3.81 to
test with, but I would have thought that there would be some
formulation which results in g.gui.%.tmp.html being preferred over
%.tmp.html.

If there isn't, the common definitions (htmldesc, IMGSRC, IMGDST) and
pattern rules ($(HTMLDIR)/%.png, $(HTMLDIR)/%.jpg) should be moved to
a separate file which can then be included from both Html.make and
GuiScript.make.

--
Glynn Clements <glynn@gclements.plus.com>

(attachments)

GuiScript.make (981 Bytes)

Hi,

2012/12/5 Glynn Clements <glynn@gclements.plus.com>:

The attached version works for me with make 3.82. I don't have 3.81 to
test with, but I would have thought that there would be some
formulation which results in g.gui.%.tmp.html being preferred over
%.tmp.html.

unfortunately it's not working with make 3.81.

If there isn't, the common definitions (htmldesc, IMGSRC, IMGDST) and
pattern rules ($(HTMLDIR)/%.png, $(HTMLDIR)/%.jpg) should be moved to
a separate file which can then be included from both Html.make and
GuiScript.make.

seems to be an option. Martin

--
Martin Landa <landa.martin gmail.com> * http://geo.fsv.cvut.cz/~landa

Hi,

2012/12/5 Martin Landa <landa.martin@gmail.com>:

If there isn't, the common definitions (htmldesc, IMGSRC, IMGDST) and
pattern rules ($(HTMLDIR)/%.png, $(HTMLDIR)/%.jpg) should be moved to
a separate file which can then be included from both Html.make and
GuiScript.make.

seems to be an option. Martin

OK, done r54199. Martin

--
Martin Landa <landa.martin gmail.com> * http://geo.fsv.cvut.cz/~landa

Martin Landa wrote:

>> If there isn't, the common definitions (htmldesc, IMGSRC, IMGDST) and
>> pattern rules ($(HTMLDIR)/%.png, $(HTMLDIR)/%.jpg) should be moved to
>> a separate file which can then be included from both Html.make and
>> GuiScript.make.
>
> seems to be an option. Martin

OK, done r54199. Martin

Note that the current approach is incompatible with parallel builds.

If g.gui.%.html and wxGUI.%.html are built concurrently, the latter
may try to delete the g.gui.%.tmp.html file while the former is using
it.

One solution is to modify mkhtml.py to allow the inclusion of the
.tmp.html file to be suppressed. Another is to explicitly order the
builds, e.g.:

  guiscript: $(IMGDST) $(PYFILES)
    $(MAKE) $(CMDHTML)
    -rm -f g.gui.*.tmp.html
    $(MAKE) $(GUIHTML)

  .PHONY: guiscript

--
Glynn Clements <glynn@gclements.plus.com>

2012/12/5 Glynn Clements <glynn@gclements.plus.com>:

One solution is to modify mkhtml.py to allow the inclusion of the
.tmp.html file to be suppressed. Another is to explicitly order the
builds, e.g.:

        guiscript: $(IMGDST) $(PYFILES)
                $(MAKE) $(CMDHTML)
                -rm -f g.gui.*.tmp.html
                $(MAKE) $(GUIHTML)

        .PHONY: guiscript

right, second solution applied in r54213. Martin

--
Martin Landa <landa.martin gmail.com> * http://geo.fsv.cvut.cz/~landa