[GRASS-dev] GRASS 6.4.2RC1 planning

Hi devs,

I would suggest to prepare GRASS 6.4.2RC1 over the next days in
order to make a final release in October possible. I can take care
of the RC preparation.

Objections?

Markus

this would be a good time as I can get it tested by volunteers on MSWindows in class, especially the things that are not working well in 6.4.1

Helena

On Sep 27, 2011, at 9:22 AM, Markus Neteler wrote:

Hi devs,

I would suggest to prepare GRASS 6.4.2RC1 over the next days in
order to make a final release in October possible. I can take care
of the RC preparation.

Objections?

Markus
_______________________________________________
grass-dev mailing list
grass-dev@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/grass-dev

2011/9/27 Markus Neteler <neteler@osgeo.org>:

I would suggest to prepare GRASS 6.4.2RC1 over the next days in
order to make a final release in October possible. I can take care
of the RC preparation.

+1

Martin

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

Markus N wrote:

I would suggest to prepare GRASS 6.4.2RC1 over the next days in
order to make a final release in October possible. I can take care
of the RC preparation.

.wonderful.

Objections?

the main thing I'd like to see get done before rc1 is an answer on
the double call to $(MAKE) if INST_NOW=y is passed to Grass.make.

AFAICT that's the only thing left blocking g.extension[.sh] from finally
working with the Ubuntu & Debian packages by users without the full
source tree installed.

https://trac.osgeo.org/grass/browser/grass/branches/develbranch_6/include/Make/Grass.make.in#L388

(the first time $(MAKE) is called the module is successfully created in
the $MAPSET/.tmp/ dirs. but then it tries to run $(MAKE) again a second
time, but put things in the install dir where the user doesn't have write
permission)

also hoping that the 65 and 70 wingrass nightly builds come back to life
to further test #1452 (wingrass broken datum trans. selection in the wx
loc'n wiz [not sure if it is a symptom of the broken epsg file currently
in proj 4.7.1svn or not]).

thanks,
Hamish

Hamish wrote:

the main thing I'd like to see get done before rc1 is an answer on
the double call to $(MAKE) if INST_NOW=y is passed to Grass.make.

AFAICT that's the only thing left blocking g.extension[.sh] from finally
working with the Ubuntu & Debian packages by users without the full
source tree installed.

https://trac.osgeo.org/grass/browser/grass/branches/develbranch_6/include/Make/Grass.make.in#L388

(the first time $(MAKE) is called the module is successfully created in
the $MAPSET/.tmp/ dirs. but then it tries to run $(MAKE) again a second
time, but put things in the install dir where the user doesn't have write
permission)

So don't set INST_NOW=y; just set ARCH_DISTDIR explicitly. Or if, for
some reason, you must use INST_NOW=y, set ARCH_INSTDIR to the desired
installation directory.

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

Hamish wrote:
> the main thing I'd like to see get done before rc1 is an answer on
> the double call to $(MAKE) if INST_NOW=y is passed to Grass.make.
>
> AFAICT that's the only thing left blocking g.extension[.sh] from
> finally working with the Ubuntu & Debian packages by users
> without the full source tree installed.

...

> (the first time $(MAKE) is called the module is successfully created in
> the $MAPSET/.tmp/ dirs. but then it tries to run $(MAKE) again a second
> time, but put things in the install dir where the user doesn't have
> write permission)

Glynn:

So don't set INST_NOW=y;

Without that it fails almost immediately.

just set ARCH_DISTDIR explicitly.

It already was.

Or if, for some reason, you must use INST_NOW=y, set ARCH_INSTDIR to
the desired installation directory.

some progress: I had been setting UNIX_BIN, but by setting ARCH_BINDIR
instead it is now working from the ubuntu command line with just the
grass+grass-dev package installed. Some scripts and C modules tested,
I'm sure there are more issues but for now it seems ok.

one that failed was d.barb, it failed looking for -lfreetype, although
libfreetype6.so.* is found in /usr/lib. but not the static lib which
ships with the libfreetype6-dev package. After install the freetype -dev
package it built ok. d.barb only uses R_text(), not freetype directly, so
I'm not sure if that's to be expected or not.
?

This looks like it will fail if there are spaces in the path names:

make MODULE_TOPDIR="$GISBASE" \
   ARCH_INC="-I$GISBASE/include -I${MYINST_DIR}/include -I$TMPDIR/$DIST_DIR/include" \
   ARCH_LIBPATH="-L$GISBASE/lib -L${MYINST_DIR}/lib -L$TMPDIR/$DIST_DIR/lib" \

any hints on how to better quote ARCH_INC and ARCH_LIBPATH components?

thanks,
Hamish

Hamish wrote:

one that failed was d.barb, it failed looking for -lfreetype, although
libfreetype6.so.* is found in /usr/lib.

That won't help; it would have to be using -lfreetype6 rather than
-lfreetype.

but not the static lib which
ships with the libfreetype6-dev package. After install the freetype -dev
package it built ok. d.barb only uses R_text(), not freetype directly, so
I'm not sure if that's to be expected or not.

Has FreeType been updated since the base GRASS package was built?

I don't see anything about d.barb which looks different to any other
d.* module.

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

Hamish wrote:

> So don't set INST_NOW=y;

Without that it fails almost immediately.

In what way?

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

Hamish wrote:

[I missed this part in my previous reply.]

This looks like it will fail if there are spaces in the path names:

make MODULE_TOPDIR="$GISBASE" \
   ARCH_INC="-I$GISBASE/include -I${MYINST_DIR}/include -I$TMPDIR/$DIST_DIR/include" \
   ARCH_LIBPATH="-L$GISBASE/lib -L${MYINST_DIR}/lib -L$TMPDIR/$DIST_DIR/lib" \

any hints on how to better quote ARCH_INC and ARCH_LIBPATH components?

Single quotes:

make MODULE_TOPDIR="$GISBASE" \
   ARCH_INC="'-I$GISBASE/include' '-I${MYINST_DIR}/include' '-I$TMPDIR/$DIST_DIR/include'" \
   ARCH_LIBPATH="'-L$GISBASE/lib' '-L${MYINST_DIR}/lib' '-L$TMPDIR/$DIST_DIR/lib'" \

This approach will work so long as the variable is only used within
commands. The value (which doesn't include the outer-most double
quotes) will be substituted verbatim (including the single quotes)
into the command which is passed to the shell.

Make itself doesn't have any quoting mechanism, so you can't have
spaces in any path which is used as part of a target or prerequisite,
or an "include" directive, or which is processed by make functions
(patsubst, wildcard, etc).

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

Hamish wrote:
> one that failed was d.barb, it failed looking for
-lfreetype, although libfreetype6.so.* is found in /usr/lib.

That won't help; it would have to be using -lfreetype6
rather than -lfreetype.

sorry my mistake, /usr/lib/libfreetype.so.6* exists from the main
debian package, while /usr/lib/libfreetype.so and *.a come from
the -dev package.

so -lfreetype can't be found, but once the -dev package is
installed and the addon module does build it seems to pick up
the non-dev one:

$ ldd d.barb | grep freetype
    libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0x00601000)

could resetting $ARCH_LIBPATH make it somehow forget to look in
/usr/lib/ or follow ld.so.conf?

not a critical problem, just confused,
Hamish

Hamish wrote:

> This looks like it will fail if there are spaces in
> the path names:

[...]
Glynn wrote:

Single quotes:

make MODULE_TOPDIR="$GISBASE" \
ARCH_INC="'-I$GISBASE/include'
'-I${MYINST_DIR}/include' '-I$TMPDIR/$DIST_DIR/include'" \
ARCH_LIBPATH="'-L$GISBASE/lib'
'-L${MYINST_DIR}/lib' '-L$TMPDIR/$DIST_DIR/lib'" \

This approach will work so long as the variable is only
used within commands. The value (which doesn't include the
outer-most double quotes) will be substituted verbatim
(including the single quotes) into the command which is passed
to the shell.

thanks, applied in devbr6, ...

Make itself doesn't have any quoting mechanism, so you can't
have spaces in any path which is used as part of a target or
prerequisite, or an "include" directive, or which is processed
by make functions (patsubst, wildcard, etc).

as there will be spaces in both the C:\Program Files\ for the
grass include headers and C:\Documents and Settings\ for the
build ($MAPSET/.tmp/) + install target, I guess for wingrass
in cases where the default path names have been used the best we
can do is to ensure that when it fails, it fails gracefully.

Hamish

Glynn:

> > So don't set INST_NOW=y;

Hamish:

> Without that it fails almost immediately.

Glynn:

In what way?

hmm, maybe setting ARCH_BINDIR fixed that now.

also, don't know if it really matters, but:

[...]
make htmlscript scriptstrings
[...]
.../1470.0/dist.i686/scripts/r.surf.volcano --html-description < /dev/null | grep -v '</body>\|</html>' > r.surf.volcano.tmp.html ; true ; fi
ERROR: G_getenv(): Variable LOCATION_NAME not set
[...]
...g.parser -t r.surf.volcano | sed s/\"/\\\\\"/g | sed 's/.*/_("&")/' > /usr/lib/grass64/locale/scriptstrings/r.surf.volcano_to_translate.c ; true
/bin/sh: cannot create /usr/lib/grass64/locale/scriptstrings/r.surf.volcano_to_translate.c: Directory nonexistent
ERROR: G_getenv(): Variable LOCATION_NAME not set

Hamish

Hamish wrote:

> > one that failed was d.barb, it failed looking for
> -lfreetype, although libfreetype6.so.* is found in /usr/lib.
>
> That won't help; it would have to be using -lfreetype6
> rather than -lfreetype.

sorry my mistake, /usr/lib/libfreetype.so.6* exists from the main
debian package, while /usr/lib/libfreetype.so and *.a come from
the -dev package.

so -lfreetype can't be found, but once the -dev package is
installed and the addon module does build it seems to pick up
the non-dev one:

$ ldd d.barb | grep freetype
    libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0x00601000)

could resetting $ARCH_LIBPATH make it somehow forget to look in
/usr/lib/ or follow ld.so.conf?

When the linker is passed -lfoo, it looks for libfoo.so or libfoo.a in
the library path (typically /usr/lib plus any directories specified by
-L switches). It will not look for libfoo.so.<something>.

libfoo.so would normally be a symlink to the actual library, which
will have a version number appended to it (e.g. libfoo.so.6).

If it finds libfoo.so (a shared library), and that library contains an
embedded "soname" (e.g. libfoo.so.6), the soname will be embedded into
the executable. Otherwise the orignal library name (e.g. libfoo.so)
will be embedded into the executable.

The loader uses whichever name is embedded in the executable to find
the library.

IOW, the unversioned symlink (libfoo.so) is only required for linking.
Loading (i.e. running) an executable only requires the library proper.
This is why the unversioned symlink is normally only included in the
-dev package.

In general, you can't build programs which use a library without the
library's -dev package.

While d.barb doesn't actually use the freetype library directly, 6.x's
Grass.make says otherwise:

  DRIVERLIB = -l$(DRIVER_LIBNAME) $(GISLIB) $(FTLIB) $(ICONVLIB)
  ...
  RASTERLIB = -l$(RASTER_LIBNAME) $(PNGDRIVERLIB) $(PSDRIVERLIB) $(DRIVERLIB) $(GISLIB)

I.e. anything which links against $(RASTERLIB) will end up with
$(FTLIB) in the link command. If libfreetype.so or libfreetype.a
doesn't exist, the command will fail (in spite of the fact that the
library isn't actually required, insofar as the absence of the library
won't result in the executable having any unresolved symbols).

7.0 doesn't have this problem. There, Grass.make doesn't include the
dependencies in the various FOOLIB variables unless you opt to use
static libraries (--disable-shared).

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

Hamish wrote:

also, don't know if it really matters, but:

[...]
make htmlscript scriptstrings
[...]
.../1470.0/dist.i686/scripts/r.surf.volcano --html-description < /dev/null | grep -v '</body>\|</html>' > r.surf.volcano.tmp.html ; true ; fi
ERROR: G_getenv(): Variable LOCATION_NAME not set

Does 6.x include demolocation in the installation?

The actual command is:

htmldesc = \
  GISRC=$(RUN_GISRC) \
  GISBASE=$(RUN_GISBASE) \
  PATH="$(BIN):$$PATH" \
  $(LD_LIBRARY_PATH_VAR)="$(BIN):$(ARCH_LIBDIR):$($(LD_LIBRARY_PATH_VAR))" \
  LC_ALL=C $(1) --html-description < /dev/null | grep -v '</body>\|</html>' > $(PGM).tmp.html ; true

where $(1) is the full path to the program.

GISRC needs to point at a valid $GISRC file (valid insofar as it
contains settings for GISDBASE, LOCATION_NAME and MAPSET). In 7.0,
this is:

RUN_GISRC = $(GISBASE)/demolocation/.grassrc$(GRASS_VERSION_MAJOR)$(GRASS_VERSION_MINOR)

[...]
...g.parser -t r.surf.volcano | sed s/\"/\\\\\"/g | sed 's/.*/_("&")/' > /usr/lib/grass64/locale/scriptstrings/r.surf.volcano_to_translate.c ; true
/bin/sh: cannot create /usr/lib/grass64/locale/scriptstrings/r.surf.volcano_to_translate.c: Directory nonexistent

The resulting C file is used by "make -C locale pot" to make the .pot
files (the untranslated message catalogues, containing the strings
which require translation), which are then translated ... by humans.

In order for add-ons to get translations, we'd need to have "make pot"
(from locale/Makefile) scan the add-ons source tree as well as the
main source tree, so that any localisable strings are included in the
.pot files from which the translators work. The translations would
then end up as part of the main GRASS distribution.

I don't think that there's any realistic mechanism for add-ons to have
their own message catalogues. Particularly for scripts, where it's
g.parser's message catalogue (i.e. "grassmods.mo") which is used.

About the only thing which we can do about the above error is to
modify the corresponding rule (in Script.make) to check that the
destination directory exists before running the command.

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

Hamish wrote:

> Make itself doesn't have any quoting mechanism, so you can't
> have spaces in any path which is used as part of a target or
> prerequisite, or an "include" directive, or which is processed
> by make functions (patsubst, wildcard, etc).

as there will be spaces in both the C:\Program Files\ for the
grass include headers and C:\Documents and Settings\ for the
build ($MAPSET/.tmp/) + install target, I guess for wingrass
in cases where the default path names have been used the best we
can do is to ensure that when it fails, it fails gracefully.

The default is to put everything under C:\OSGeo4W. If you want to use
e.g. C:\Program Files, you need to ensure that only 8.3 pathnames are
used.

Also, AFAICT the installer doesn't attempt to fix ${prefix} to match
the actual installation directory, so if the user chooses a different
location, Platform.make will be wrong.

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

Glynn wrote:

> > Make itself doesn't have any quoting mechanism, so you
> > can't have spaces in any path which is used as part of
> > a target or prerequisite, or an "include" directive, or
> > which is processed by make functions (patsubst, wildcard,
> > etc).

Hamish:

> as there will be spaces in both the C:\Program Files\ for the
> grass include headers and C:\Documents and Settings\ for the
> build ($MAPSET/.tmp/) + install target,

Glynn:

The default is to put everything under C:\OSGeo4W. If you
want to use e.g. C:\Program Files, you need to ensure that
only 8.3 pathnames are used.

I'm hoping (perhaps in vain) to get this going for end-users
without the full development stack in place. I wonder how hard
it would be to write a small C or python program which could
convert the string to an 8.3 pathname, as %%~sFoo might do in a
batch file? so we could build in something like:
if [ -n "$MSYS" ] ; then
    MAPSET_DIR_safe=`g.dosname path="$MAPSET_DIR"`
fi

Python os.lib 1-liner?

It may be that for WinGrass we end up just shipping an addons
collection installer with them all pre-built, but I think it is
worth a bit of effort to see how far we can get with g.extension.

for now I've added a warning to the script in devbr6 so that it
sends out a warning if it detects a space.

Also, AFAICT the installer doesn't attempt to fix ${prefix}
to match the actual installation directory, so if the user
chooses a different location, Platform.make will be wrong.

right; not really sure how to do an 'sed -i' at install time
with the nsi installer tools. fwiw in the last days I've done
that replacement in Debian's git packaging rules repo, for future
ubuntu and debian packages.

If we are going to use ${GRASS_ADDON_PATH[0]} as a sort of
GRASS_ADDON_BASE dir, I wonder if we should add each dir in the
$GRASS_ADDON_PATH + ./man/ + `manpath` in a $MANPATH as part of
init.sh? Not sure how to get the html pages automatically
registered into the system, although Martin's and/or William's
enhancements may already have solved that.

Hamish

ps- not ignoring g.extension.py, just not bothering to port over
all these little experiments until we've settled on the best
approach.

Also, AFAICT the installer doesn't attempt to fix ${prefix}
to match the actual installation directory, so if the user
chooses a different location, Platform.make will be wrong.

right; not really sure how to do an 'sed -i' at install time
with the nsi installer tools.

as I remember correctly, there are some routines in the nsis-installer which
are able to do this.

which lines should be adapted by the nsis-installer?

best regards
Helmut

--
View this message in context: http://osgeo-org.1803224.n2.nabble.com/GRASS-6-4-2RC1-planning-tp6835951p6843285.html
Sent from the Grass - Dev mailing list archive at Nabble.com.

Hamish wrote:

I wonder how hard
it would be to write a small C or python program which could
convert the string to an 8.3 pathname, as %%~sFoo might do in a
batch file? so we could build in something like:
if [ -n "$MSYS" ] ; then
    MAPSET_DIR_safe=`g.dosname path="$MAPSET_DIR"`
fi

Python os.lib 1-liner?

  >>> win32api.GetShortPathName(r'c:\Program Files (x86)\Python27')
  'c:\\PROGRA~2\\Python27'

> Also, AFAICT the installer doesn't attempt to fix ${prefix}
> to match the actual installation directory, so if the user
> chooses a different location, Platform.make will be wrong.

right; not really sure how to do an 'sed -i' at install time
with the nsi installer tools.

One option is to move the variables containing the paths (prefix,
GRASS_HOME, and RUN_GISBASE) to a separate file, e.g. Paths.make.
Then, the installer could replace that file in its entirety, rather
than having to modify specific lines in Platform.make.

OTOH, most of those variables aren't particularly relevant for
building add-ons. E.g. If you're building against an installed GRASS,
RUN_GISBASE probably needs to point to the installed version, not the
source tree.

Actually, some of them might need to be split, in the same way that
7.0 has ARCH_LIBDIR and BASE_LIBDIR. ARCH_LIBDIR is where
freshly-compiled libraries should be stored, BASE_LIBDIR is where
existing GRASS libraries are found. For a normal build, both of these
point to dist.<arch>/lib; when building add-ons, ARCH_LIBDIR points at
the add-ons source tree, BASE_LIBDIR points at the installed GRASS.

RUN_GISBASE is used mainly to set PYTHONPATH (RUN_GISBASE uses Windows
syntax rather than MSys syntax). If you're building an add-on which
includes some Python modules and a script which imports both add-on
modules and stock grass.{script,lib} modules, PYTHONPATH will need to
include both sets of directories.

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

--- On Thu, 9/29/11, Helmut Kudrnovsky <hellik@web.de> wrote:
Glynn:

>> Also, AFAICT the installer doesn't attempt to fix ${prefix}
>> to match the actual installation directory, so if the user
>> chooses a different location, Platform.make will be wrong.

Hamish:

> right; not really sure how to do an 'sed -i' at install
> timewith the nsi installer tools.

Helmut:

as I remember correctly, there are some routines in the
nsis-installer which are able to do this.

which lines should be adapted by the nsis-installer?

GRASS_HOME and RUN_GISBASE

(to respond to Glynn's suggestion to split the files: not a
general solution, but: can these values be overridden on the
command line at runtime using g.extension's prefix= answer?
at least that would help for g.extension)

here's the sed I used to replace it with "/usr/lib/grass64"
on debian:

        # adjust from build-server build dir to end-user's install dir
        sed -i -e "s+^\(GRASS_HOME*=\) .*+\1 /usr/lib/$(BASE_NAME)+" \
                -e "s+^\(RUN_GISBASE*=\) .*+\1 /usr/lib/$(BASE_NAME)+" \
                debian/tmp/usr/lib/$(BASE_NAME)/include/Make/Platform.make

Hamish

Hamish,

GRASS_HOME and RUN_GISBASE

(to respond to Glynn's suggestion to split the files: not a
general solution, but: can these values be overridden on the
command line at runtime using g.extension's prefix= answer?
at least that would help for g.extension)

here's the sed I used to replace it with "/usr/lib/grass64"
on debian:

       # adjust from build-server build dir to end-user's install dir
       sed -i -e "s+^\(GRASS_HOME*=\) .*+\1 /usr/lib/$(BASE_NAME)+" \
               -e "s+^\(RUN_GISBASE*=\) .*+\1 /usr/lib/$(BASE_NAME)+" \
               debian/tmp/usr/lib/$(BASE_NAME)/include/Make/Platform.make

[sorry no sed-expert here on my side]

checked with nightly build WinGRASS-6.4.SVN-r48555-1-Setup.exe, installation
folder is C:\Program Files\GRASS 6.4.SVN\ (german winvista32-box)

following left overs from the osgeo4w-build-environment of the
wingrass-installer

C:\Program Files\GRASS 6.4.SVN\include\Make\Platform.make

  [...]
  prefix = /c/OSGeo4W/apps/grass
  exec_prefix = ${prefix}
  ARCH = i686-pc-mingw32
  UNIX_BIN = /c/OSGeo4W/bin
  INST_DIR = ${prefix}/grass-6.4.2svn
  [...]
  # GRASS dirs
  GRASS_HOME = /c/OSGeo4W/apps/grass/grass-6.4.2svn
  RUN_GISBASE = /c/OSGeo4W/apps/grass/grass-6.4.2svn
  RUN_GISRC =
${ARCH_DISTDIR}/demolocation/.grassrc${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}
  [...]
  CPPFLAGS = -I/c/OSGeo4W/include
  CFLAGS1 = -g -O2
  CXXFLAGS1 = -g -O2
  INCLUDE_DIRS = -I/c/OSGeo4W/include
  
  COMPILE_FLAGS = $(CPPFLAGS) $(CFLAGS1) $(INCLUDE_DIRS)
  COMPILE_FLAGS_CXX = $(CPPFLAGS) $(CXXFLAGS1) $(INCLUDE_DIRS)
  LINK_FLAGS = -Wl,--export-dynamic,--enable-runtime-pseudo-reloc
-L/c/OSGeo4W/lib -L/osgeo4w/usr/src/grass64_release/mswindows/osgeo4w/lib
  
  gdal/OGR
  GDALLIBS = /c/OSGeo4W/lib/gdal_i.lib
  GDALCFLAGS = -I/c/OSGeo4W/include
  USE_GDAL = 1
  USE_OGR = 1
  
  #GEOS
  GEOSLIBS = /c/OSGeo4W/lib/geos_c_i.lib -lgeos_c_i
  GEOSCFLAGS = -I/c/OSGeo4W/include
  USE_GEOS = 1
  
  #FreeType:
  FTINC = -I/c/OSGeo4W/include/freetype2
  FTLIB = -lfreetype
  
  proj.4:
  PROJINC = $(GDALCFLAGS)
  PROJLIB = -lproj
  NAD2BIN = /c/OSGeo4W/bin/nad2bin
  PROJSHARE = /c/OSGeo4W/share/proj
  
C:\Program Files\GRASS 6.4.SVN\include\Make\Grass.make

  [...]
  # GRASS global directories and constants
  # platform specific dirs
  ARCH_DISTDIR = /c/OSGeo4W/apps/grass/grass-6.4.2svn
  ARCH_BINDIR = /c/OSGeo4W/bin
  ERRORLOG = $(GRASS_HOME)/error.log
  [...]

maybe you could indicate which of mentioned osgeo4w-leftovers should be
changed.
that would be helpful changing the nsis-installer

best regards
Helmut

--
View this message in context: http://osgeo-org.1803224.n2.nabble.com/GRASS-6-4-2RC1-planning-tp6835951p6848892.html
Sent from the Grass - Dev mailing list archive at Nabble.com.