Compilation of Flair Geoviewer with Cygwin

Hi everyone,

I am trying to compile Flair Geoviewer from the source code on Windows using Cygwin. I already have it working under WSL, but I would like to get a native Windows version too (partially because the WSL version opens in a weird window size and fonts due to my screen resolution I guess which will need some debugging).

In Cygwin, I have installed all the required dependencies including:

  • Python (with tkinter and numpy)
  • Tcl/Tk
  • X11

I also was able to compile and run Flair:

Unfortunately, I am running into errors related to M_PI not declared among other things including pthread_rwlock_unlock, bzero and rand48 methods not declared. Please see the screent output attached.

screen_output_no_preprocessor.txt (70.4 KB)

One thing that left only the rand48 method errors was (after searching and gpting) to add -D_USE_MATH_DEFINES to the compiler flags inside makefile (or with the make). Doing so results in the rand48 errors though.

screen_output_with_preprocessor.txt (2.7 KB)

Any help or suggestions on how to further resolve these issues would be greatly appreciated!

Thank you,

Dear @Ramzy1990

thanks to know for the -D_USE_MATH_DEFINES

It a bit strange all these messages since these functions are part of the POSIX.1-2008 standard

For the sincos() function you could try adding the define
#define _GNU_SOURCE
or replace the call inside the math/bmath.h
from

inline void bsincos(const double x, double* si, double* co)
{
	if (Abs(x)<2e-8) {
		*si = x;
		*co = (1-x/Sqrt2)*(1+x/Sqrt2);
	} else
		sincos(x, si, co);
	if (*si==1 || *si==-1) *co = 0;
	else
	if (*co==1 || *co==-1) *si = 0;
} // bsincos

to

inline void bsincos(const double x, double* si, double* co)
{
	if (Abs(x)<2e-8) {
		*si = x;
		*co = (1-x/Sqrt2)*(1+x/Sqrt2);
	} else {
        *si = sin(x);
        *co = cos(x);
    }
	if (*si==1 || *si==-1) *co = 0;
	else
	if (*co==1 || *co==-1) *si = 0;
} // bsincos

For the rand48 one option would to replace it
with (double)rand() / (double)RAND_MAX

1 Like

Thank you very much Vasilis and much appreciated!

Okay so the problem for random.h was in the following definition for CYGWIN inside the random header file:

#ifdef __ANDROID_API__
	// Apparently android has drand48 but not the re-entrant version
	#define HAS_RAND48
//	#define BASIC_RAND
// #elif defined(__MACH__) || defined(CYGWIN) || defined(ANDROID)
#elif defined(__MACH__) || defined(__CYGWIN__) || defined(ANDROID)
	#define HAS_RAND48
#endif

According to the following topic (and the cited list inside the topic), it should be __CYGWIN__ with two underscores preceding and following the keyword CYGWIN. This will make the logics related to HAS_RAND48 work as intended.

Also, for the sincos method, you can find it defined as such inside bmath.h:

#if defined(__APPLE__) || defined(ANDROID) || defined(__ANDROID_API__) || defined(CYGWIN)
inline void	sincos(const double x, double* ss, double* cc) { *ss = sin(x); *cc = cos(x);}

and yes indeed another CYGWIN to __CYGWIN__.

Now all errors are resolved when I re-compile again (after make clean) with the following options:
make CXXFLAGS="-D_GNU_SOURCE" or make CXXFLAGS="-D_USE_MATH_DEFINES"

but a new one appears! The following error:

In file included from ../data/meshdata.h:11,
                 from geometry.h:150,
                 from gregion.cc:14:
gregion.cc: In member function ‘unsigned int GRegion::boundaryCrossings(const Point&, const Point&, double*, Cache<CBody3D>&) const’:
gregion.cc:794:24: error: ‘body’ was not declared in this scope
  794 |                 assert(body != nullptr);        // we should always exit
      |                        ^~~~

which refers to the following location inside gregion.cc file:

// find distance to exit
DEBUG(GBody* body =)
zone->distance2Out(pos,dir, &tmin,tmax, cache);
assert(body != nullptr);	// we should always exit

but I changed it to:

GBody* body = zone->distance2Out(pos, dir, &tmin, tmax, cache);

And then after cleaning and re-compiling, this at last compiled, please see the following screen output. Please also advise if this DEBUG line was intended as it was.

screen_output_compilation.txt (26.2 KB)

With that done, I currently have the geoviwer.dll file and the usrbin2dvh.exe, meshtk.exe executables generated. I still have issue running flair-geoviwer, however! Although I did make install and the previous files are copied to flair install location (/usr/local/flair), but flair does not yet identify flair-geoviwer:

It seems of course we are already there and it is a matter of flair recognizing flair-geoviewer (although it is in the PATH), so any further instructions please?

The DEBUG(x) macro normally is only activated if you compile with make DEBUG=yes
In debug mode then the assert() statements are also active. In your case it seems that the assert() is taken into account despite the DEBUG was not set to on.
In any case the assert(() was just a for testing you can safely comment out both lines
DEBUG(GBody* body =)
and the
assert(body != nullptr);

Once you create the geoviewer.dll try the following from the terminal. Start python and execute

$ python
Python 3.12.7 (main, Feb  4 2025, 14:46:03) [GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import geoviewer

if you don’t get any error then it should work.

If from the terminal you can load geoviewer but flair cannot find it, then probably you need to set the LD_LIBRARYPATH environment variable or configure the directory to be accepted as having dynamic libraries with the ldconfig
program

Many years ago flair + geoviewer was working under cygwin, but its been like a decade that I did not try it

1 Like

Thank you again, Vasilis! Sounds good and I commented out the debug lines.

And beautiful check for the geoviewer module, indeed there is an error loading the library inside the /usr/local/flair (but not inside the location where geoviewer is compiled):

$ python
Python 3.9.16 (main, Mar  8 2023, 22:47:22)
[GCC 11.3.0] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import geoviewer
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: Permission denied
>>>

I added executions permissions to geoviewer.dll file and this is now working:

I think it is related to the following line in the makefile when it is copied:
install -m 644 $(SOLIB) $(ROOT)$(DESTDIR)

Thank you very much for Flair, Vasilis!

Could you please provide me the changes you made and what you modified in the system, so I can include them in the standard distribution for the future

1 Like

Yes of course! Here are the changes I made which are minimal (using diff):

--- ./original/flair-geoviewer-3.4/geometry/gregion.cc	2025-02-24 04:30:05.000000000 -0500
+++ flair-geoviewer-3.4/geometry/gregion.cc	2025-03-17 13:22:55.964774200 -0400
@@ -787,9 +787,10 @@
 		*tlength -= tmin;		// tally negative enter distance
 
 		// find distance to exit
-		DEBUG(GBody* body =)
-		zone->distance2Out(pos,dir, &tmin,tmax, cache);
-		assert(body != nullptr);	// we should always exit
+		// DEBUG(GBody* body =)
+		// zone->distance2Out(pos,dir, &tmin,tmax, cache);
+          // GBody* body = zone->distance2Out(pos, dir, &tmin, tmax, cache);
+		// assert(body != nullptr);	// we should always exit
 
 		*tlength += tmin;		// tally positive exit distance


--- ./original/flair-geoviewer-3.4/makefile	2025-02-24 04:30:05.000000000 -0500
+++ flair-geoviewer-3.4/makefile	2025-03-17 13:28:49.013431300 -0400
@@ -332,7 +332,7 @@
 install: $(SOLIB)
 	mkdir -p $(ROOT)$(DESTDIR)
 	mkdir -p $(ROOT)$(DESTDIR)/fonts
-	install -m 644 $(SOLIB) $(ROOT)$(DESTDIR)
+	install -m 744 $(SOLIB) $(ROOT)$(DESTDIR)
 	install -m 755 $(AUXPRGS) $(ROOT)$(DESTDIR)
 	for f in AUTHORS BUGS README LICENSE; do \
 		install -m 644 $$f $(ROOT)$(DESTDIR)/$$f.$(NAME); \


--- ./original/flair-geoviewer-3.4/math/bmath.h	2025-02-24 04:30:05.000000000 -0500
+++ flair-geoviewer-3.4/math/bmath.h	2025-03-17 12:41:35.437004100 -0400
@@ -142,7 +142,7 @@
 	printf("%s -> %30.30f (%g) %llx\n", #val, _my_val, _my_val, *(unsigned long long *)&_my_val);\
 } while (0)
 
-#if defined(__APPLE__) || defined(ANDROID) || defined(__ANDROID_API__) || defined(CYGWIN)
+#if defined(__APPLE__) || defined(ANDROID) || defined(__ANDROID_API__) || defined(__CYGWIN__)
 inline void	sincos(const double x, double* ss, double* cc) { *ss = sin(x); *cc = cos(x);}
 inline double	exp10(const double x)	{ return exp(x*Ln10);  }
 inline float	exp10f(const float x)	{ return expf(x*Ln10); }


--- ./original/flair-geoviewer-3.4/math/random.h	2023-09-28 08:48:10.000000000 -0400
+++ flair-geoviewer-3.4/math/random.h	2025-03-17 12:41:33.518809700 -0400
@@ -24,7 +24,8 @@
 	// Apparently android has drand48 but not the re-entrant version
 	#define HAS_RAND48
 //	#define BASIC_RAND
-#elif defined(__MACH__) || defined(CYGWIN) || defined(ANDROID)
+#elif defined(__MACH__) || defined(__CYGWIN__) || defined(ANDROID)
 	#define HAS_RAND48
 #endif
 

And then to use either -D_GNU_SOURCE or -D_USE_MATH_DEFINES when compiling.

1 Like