#2966: r.sim.water not working in 7.0.3 32bit and 64bit
-------------------------+-------------------------------------------------
Reporter: baharmon | Owner: grass-dev@…
Type: defect | Status: new
Priority: normal | Milestone: 7.0.4
Component: Raster | Version: 7.0.3
Resolution: | Keywords: r.sim.water, r.sim.erosion, SIMWE,
| MinGW-w64, compiling
CPU: All | Platform: MSWindows 8
-------------------------+-------------------------------------------------
Changes (by wenzeslaus):
* keywords: => r.sim.water, r.sim.erosion, SIMWE, MinGW-w64, compiling
* cpu: Unspecified => All
Comment:
It seems that it fails in between lines
[source:grass/trunk/raster/r.sim/r.sim.water/main.c?rev=68291#L303 303]
and [source:grass/trunk/raster/r.sim/r.sim.water/main.c?rev=68291#L325
325]:
{{{
#!c
mixx = conv * cellhd.west;
maxx = conv * cellhd.east;
miyy = conv * cellhd.south;
mayy = conv * cellhd.north;
stepx = cellhd.ew_res * conv;
stepy = cellhd.ns_res * conv;
step = (stepx + stepy) / 2.;
mx = cellhd.cols;
my = cellhd.rows;
x_orig = cellhd.west * conv;
y_orig = cellhd.south * conv;
xmin = 0.;
ymin = 0.;
xp0 = xmin + stepx / 2.;
yp0 = ymin + stepy / 2.;
xmax = xmin + stepx * (float)mx;
ymax = ymin + stepy * (float)my;
}}}
There is nothing special there except for the fact that the variables are
global defined, e.g. in
[source:grass/trunk/raster/r.sim/simlib/hydro.c#L73 simlib/hydro.c]:
{{{
#!c
double xmin, ymin, xmax, ymax;
double mayy, miyy, maxx, mixx;
}}}
and declared as `extern` in
[source:grass/trunk/raster/r.sim/simlib/waterglobs.h?rev=68291#L94
simlib/waterglobs.h], e.g.:
{{{
#!c
extern double xmin, ymin, xmax, ymax;
extern double mayy, miyy, maxx, mixx;
}}}
There should be nothing bad about these definitions but StackOverflow
explains that global variables, when placed in DLLs on MS Windows, are
different. [http://stackoverflow.com/questions/19373061 StackOverflow.
What happens to global and static variables in a shared library when it is
dynamically linked?]:
> In the case of Windows (.exe and .dll), the extern global variables are
not part of the exported symbols. In other words, different modules are in
no way aware of global variables defined in other modules. This means that
you will get linker errors if you try, for example, to create an
executable that is supposed to use an extern variable defined in a DLL,
because this is not allowed.
>
> In the case of Unix-like environments (like Linux), the dynamic
libraries, called "shared objects" with extension .so export all extern
global variables (or functions). In this case, if you do load-time linking
from anywhere to a shared object file, then the global variables are
shared, i.e., linked together as one. Basically, Unix-like systems are
designed to make it so that there is virtually no difference between
linking with a static or a dynamic library.
>
It further says that you must do the following ''to actually export a
global variable in Windows'':
{{{
#!c
#ifdef COMPILING_THE_DLL
#define MY_DLL_EXPORT extern "C" __declspec(dllexport)
#else
#define MY_DLL_EXPORT extern "C" __declspec(dllimport)
#endif
MY_DLL_EXPORT int my_global;
}}}
It further says that the syntax is ''similar to the function export/import
syntax'' which we are not using in GRASS except for few places (grep
reveals `mapcalc.tab.c`, `lz4.h`, `shapefil.h`, and `sqlp.tab.c`).
The `simlib` directory is compiled into a shared object file/dynamic
library (I have `libgrass_sim.so` in `dist.../lib`), so I assume the above
applies here, although the code should lead to linker error rather then
some failure during runtime (but that might apply just to MSVC compiler).
`r.sim.water` works in 7.0.2:
{{{
System Info
GRASS version: 7.0.2
GRASS SVN Revision: 66861
Build Date: 2015-11-19
Build Platform: i686-pc-mingw32
GDAL/OGR: 1.11.3
PROJ.4: 4.8.0
GEOS: 3.5.0
SQLite: 3.7.17
Python: 2.7.4
wxPython: 2.8.12.1
Platform: Windows-8-6.2.9200
> g.version -re
GRASS 7.0.2 (2015)
libgis Revision: 64733
libgis Date: 2015-02-25 01:56:29 +0100 (st, 25 2 2015)
...
}}}
So, it seems that it is related to transition from MinGW (32) to
MinGW-w64.
Based on the above I think that our options are (assuming we want to
support MS Windows):
1. use the (messy) `__declspec` in some way
2. modify the globals in `simlib` using functions instead of direct
access (approach used in the GRASS libraries?)
3. get rid of the global variables, use structures and function
parameters instead
4. copy (duplicate) the files into each module (r.sim.water and
r.sim.erosion)
5. use `simlib` as a static library
6. don't use `simlib` directory as a library, just compile object files
--
Ticket URL: <https://trac.osgeo.org/grass/ticket/2966#comment:4>
GRASS GIS <https://grass.osgeo.org>