Monday, July 31, 2017

Building Harbour

Almost unbelievable!
Let's build the "(xBASE) Clipper" compiler for Solaris 11.3!
But let me do a correction ;-), let's build the Harbour or simply HB for short.
Yes, Harbour seems to be one of the finest next-step Clipper substitutes.
If you know nothing about xBASE language, get to know it.

NOTE
The xBASE language is originally and essentially procedural, not object-oriented. But the case for object-orientation is not a real impediment if modularity is well exploited. Originally, there's no SQL and the database is made of a bunch of data-files (.DBF) and index-files, which can be shared over the network with adequate file and record locking support. Essentially, databases are file-record based. The language is reasonably flexible and there's a nice support for (kind of forms-based and menu-driven) console applications (sometimes even with mouse support). Roughly, one could say it's more powerful (more modern and much easier) than COBOL, sufficiently low-level as COBOL can't ever be and much more resourceful on the UI aspect (although it could be purely BATCH). Well, and much, much more.
Why Harbour, one could reasonably ask?
Isn't that a dead or outdated development option from the 80s?
We're living on the 21st century! Why care about something 35 years old?

Nowadays I would say that the main favorable argument is SIMPLICITY.
But not only that. It's PRACTICAL, EFFICIENT and RESOURCEFUL.
As anything else, it's not a perfect and universal solution.
But it excels in its niche and it's easy to learn and use.
The possibilities it still offers outweighs its age.
And it now runs natively under Solaris 11.3!
Check the About Harbour web page.

NOTE
I would risk to say that one interesting deployment of xBASE with Harbour would be for on-line or batch networked console applications modules running on "text-only" (minimal non-GUI systems such as Solaris 11 text-installs) boxes for supporting industrial plants IT infrastructure on tough environments.
The Harbour Project has been trying to bring in many enhancements, as well as many new features, such as GUI support with Qt integration, some object orientation support and more:











 
NOTE
It may be important to mention that most libraries have both options of being static or dynamic. So, the there's no concern about code bloats or exaggerated consumption of resources. Furthermore, it's not constrained by the inherent DOS limitations and idiosyncrasies (it's a new world, it's UNIX and it can be Solaris).
But it's not necessarily a wonderful world right from the start. Although a remarkable work and effort, as being free and open-source, the Harbour Project naturally lacks some "minor' finishing works, specially in website and documentation update and maintenance, as well as to source-code level deployment and build support and documentation. Particularly related to Solaris, currently, there are a few issues that haave to be manually adjusted (hacked) at first. The source-code deployment doesn't use a standard GNU - Build Automation and this brings difficulties in getting to know something different. I confess I don't have enough time to get to know all the details of Harbour's particular build process, but I'd summarize it as a mix of GNU and some inter-wined xBASE coding. I may have missed some points on how to properly deal with it, but I suspect that these points are actually bugs or shortcomings that would have to be addressed in the future. These difficulties did not prevent me from successfully build and use the current version.

NOTE
By the way, currently, there may be some confusion about versions. The main page says that the latest stable is 3.0.0 but the link points to version 3.2.0dev (just look at ./include/hbver.h macros). But there's also a fork to version 3.4.0. Anyway, for now, I'll stick to the main page version, 3.2.0dev.
As I said, the build process is "unusual" and the documentation and general detection support seems scarce or needing more work and improvement. Due to all that I'll start with just the 32-bits scenario. I'll develop this post so that in the end for targeting 64-bits it will be just a matter of substituting 32 with 64 or, if you prefer, substituting 64 for 32 where applicable :-D

For learning how to build, one would certainly try to start from the web-page README or from the (roughly equivalent) ./READ.md file (by the way, .MD are MarkDown files frequently used with GitHub, but I don't care). In fact, there's not much there for a Solaris build, except for a few confirmations that minimum requirements are fulfilled, there's a bunch of environment variables to drive the build and installation and that you should use gmake or gmake install. But be aware that there are a few pitfalls; it's not that straightforward with respect to a Solaris build environment. I would say that the main value of this post is precisely the attempt to guide the whole build process in a more hassle-free approach.

Beyond GCC, other pre-requisites are (at least):


To get started, going manually or by customizing a script such as the one demonstrated at GNU - Build preparation post, create the underlying ZFS support using the same approach previously described in other "Building-series" posts of mine, for instance: Building Qt 4.8.7. In the end, it will become something similar to:

$ DS=.../software/hb
$ zfs list -o name -t all -r $DS |sed 's,$DS,...,'
NAME
...

.../hb-3.2.0
.../hb-3.2.0@source
.../hb-3.2.0-gnu32
.../hb-3.2.0-gnu32@start
.../hb-3.2.0-gnu32@build
.../hb-3.2.0-gnu64
.../hb-3.2.0-gnu64@start
.../hb-3.2.0-gnu64@build


The -gnuXX datasets are clones from @source. The @start snapshot is particularly important as an eventual reset point. Before creating it some manual fixes (hacks) to the extracted source-code tarball must be applied. There's no @config snapshots due to the building process differences from the standard GNU - Build Automation. Here, the @build snapshot is more than ever of just good-practice style.

The final resting place (and state) of the built modules will be similar to:
(pre-created as well, but as root, due to the /opt mountpoint)

$ DS=.../hb-3.2.0
$ zfs list -o name,mountpoint -t all -r $DS
NAME                         MOUNTPOINT
.../hb-3.2.0
                 /opt/hb-3.2.0
.../hb-3.2.0/gnu32           /opt/hb-3.2.0/gnu32
...
/hb-3.2.0/gnu32@release
.../hb-3.2.0/gnu64           /opt/hb-3.2.0/gnu64 
.../hb-3.2.0/gnu64@release

Now, I'll refer to a source-script (setenv) such as the one demonstrated at GNU - Build preparation post, with the following additions / customizations (located at ~/software/hb):

...

#
# Other PATH and PKG_CONFIG_PATH settings.
# Put entries in reverse order of dependency.

# (following my PATH building suggestion) 
#

extend-env /opt/qt-4.8.7
extend-env /opt/sqlite-3.19.3

extend-env /opt/tcl-8.5.19
extend-env /opt/automake-1.15
extend-env /opt/autoconf-2.69

extend-env /opt/m4-1.4.18
extend-env /opt/libtool-2.4.6


...

#
# To be appended to the end of the setenv source-script
#

export HB_INSTALL_PREFIX=/opt/hb-3.2.0/gnu$BITS
  
export HB_COMPILER=gcc
export HB_USER_CFLAGS="$CFLAGS -R$HB_INSTALL_PREFIX/lib"
export HB_USER_DFLAGS="$HB_USER_CFLAGS"

export HB_USER_LDFLAGS="$HB_USER_CFLAGS"

export HB_BUILD_DYN=yes
export HB_INSTALL_DYN=yes

export HB_BUILD_CONTRIB=yes
export HB_BUILD_CONTRIB_DYN=yes

export HB_INSTALL_MAN=""

export HB_WITH_ODBC=/usr/include/odbc
export HB_WITH_SQLITE3=/opt/sqlite-3.19.3/gnu$BITS/include
export HB_WITH_GD=/usr/include/gd2
export HB_WITH_BZIP2=/usr/include

export HB_WITH_QT=/opt/qt-4.8.7/gnu$BITS/include
export HB_QTPATH=/opt/qt-4.8.7/gnu$BITS/bin


Now proceed to the fixes (hacks) to cope with GCC 4.8.2 and Solaris 11.3:

1) The layout of the HB_INSTALL_PREFIX tree is suboptimal. There are hard-coded subdirectories named harbour which can be inconvenient. I won't fix it, but I'll circumvent them as to my preference as follows:

$ cd ~/software/hb/hb-3.2.0-gnu32
$ diff /tmp/original-global.mk ./config/global.mk

492a493,505 
> ifeq ($(HB_HOST_PLAT),sunos)
> ifneq ($(findstring amd64,$(shell isainfo -k)),)
> HB_HOST_CPU := x86_64
> ifneq ($(filter $(HB_USER_CFLAGS),-m64),)
> HB_CPU := x86_64
> else
> ifneq ($(filter $(HB_USER_CFLAGS),-m32),)
> HB_CPU := x86
> endif
> endif
> endif
> endif


1820c1833
< ifeq ($(HB_SYSLOC),yes)
---
> # ifeq ($(HB_SYSLOC),yes)
 

1822c1835
< endif
---
> # endif


1852,1853c1865,1866
<             LIBPOSTFIX := $(LIBPOSTFIX)$(DIRSEP)harbour
<             INCPOSTFIX := $(DIRSEP)harbour

---
>             LIBPOSTFIX :=
>             INCPOSTFIX :=


1889c1902
<          export HB_INSTALL_DOC :=

        $(HB_INSTALL_PREFIX)$(DIRSEP)share$(DIRSEP)doc$(DIRSEP)harbour
---
>          export HB_INSTALL_DOC :=

         $(HB_INSTALL_PREFIX)$(DIRSEP)share$(DIRSEP)doc

1896c1909
<          ifeq ($(HB_SYSLOC),yes)
---
> #         ifeq ($(HB_SYSLOC),yes)
1898c1911
<          endif
---
> #         endif


1908c1921
<             export HB_INSTALL_ETC :=

          $(HB_INSTALL_PREFIX)$(DIRSEP)etc$(DIRSEP)harbour
---
>             export HB_INSTALL_ETC :=

          $(HB_INSTALL_PREFIX)$(DIRSEP)etc

1916c1929
<          ifneq ($(findstring |/opt/harbour,|$(HB_INSTALL_PREFIX)),)
---
> #         ifneq ($(findstring |/opt/harbour,|$(HB_INSTALL_PREFIX)),)


1918,1920c1931,1933
<          else
<             export HB_INSTALL_CONTRIB :=

          $(HB_INSTALL_PREFIX)$(DIRSEP)share$(DIRSEP)harbour$(DIRSEP)contrib
<          endif

---
> #         else
> #            export HB_INSTALL_CONTRIB :=

            $(HB_INSTALL_PREFIX)$(DIRSEP)share$(DIRSEP)harbour$(DIRSEP)contrib
> #         endif

In case the above diff output gets difficult or somehow inconsistent, here's an attempt to present the above changes (hacks) in a different way:

 493 ifeq ($(HB_HOST_PLAT),sunos)
 494    ifneq ($(findstring amd64,$(shell isainfo -k)),)
 495       HB_HOST_CPU := x86_64
 496       ifneq ($(filter $(HB_USER_CFLAGS),-m64),)
 497          HB_CPU := x86_64
 498       else
 499          ifneq ($(filter $(HB_USER_CFLAGS),-m32),)
 500             HB_CPU := x86
 501          endif
 502       endif
 503    endif
 504 endif
 505
 506 ifeq ($(HB_INIT_DONE),)
 507    $(info ! HB_HOST_PLAT: ...
 508 endif


1827 export HB_SYSLOC
1828
1829 ifneq ($(HB_INSTALL_PREFIX),)
1830
1831    ifeq ($(HB_BUILD_SHARED),)
1832       ifneq ($(HB_PLATFORM_UNIX),)
1833 #         ifeq ($(HB_SYSLOC),yes)
1834             export HB_BUILD_SHARED := yes
1835 #         endif
1836       endif
1837    endif


1863       else
1864          ifneq ($(findstring |/opt,|$(HB_INSTALL_PREFIX)),)
1865             LIBPOSTFIX :=
1866             INCPOSTFIX :=
1867          else
1868             LIBPOSTFIX :=
1869          endif
1870       endif
1871    endif
1872    endif


1897    # Standard name: DOCDIR
1898    ifeq ($(HB_INSTALL_DOC),)
1899       ifeq ($(HB_PLATFORM_UNIX),)
1900          export HB_INSTALL_DOC := ...
1901       else
1902          export HB_INSTALL_DOC :=

                 $(HB_INSTALL_PREFIX)$(DIRSEP)share$(DIRSEP)doc
1903       endif
1904    endif


1905    # Standard name: MANDIR
1906    ifeq ($(HB_INSTALL_MAN),)
1907       # Do not set man dir for non-*nix targets
1908       ifneq ($(HB_PLATFORM_UNIX),)
1909 #         ifeq ($(HB_SYSLOC),yes)
1910             export HB_INSTALL_MAN :=

                    $(HB_INSTALL_PREFIX)$(DIRSEP)share$(DIRSEP)man
1911 #         endif
1912       endif
1913    endif


1914    # Standard name: ETCDIR
1915    ifeq ($(HB_INSTALL_ETC),)
1916       # Do not set doc dir for non-*nix targets
1917       ifneq ($(HB_PLATFORM_UNIX),)
1918          ifeq ($(HB_PLATFORM),darwin)
1919             export HB_INSTALL_ETC := ...
1920          else
1921             export HB_INSTALL_ETC :=

                    $(HB_INSTALL_PREFIX)$(DIRSEP)etc
1922          endif
1923       endif
1924    endif


1925    ifeq ($(HB_INSTALL_CONTRIB),)
1926       ifeq ($(HB_PLATFORM_UNIX),)
1927          export HB_INSTALL_CONTRIB := $(HB_INSTALL_PREFIX)$(DIRSEP)contrib
1928       else
1929 #         ifneq ($(findstring |/opt/harbour,|$(HB_INSTALL_PREFIX)),)
1930             export HB_INSTALL_CONTRIB :=

                    $(HB_INSTALL_PREFIX)$(DIRSEP)contrib
1931 #         else
1932 #            export HB_INSTALL_CONTRIB := ...
1933 #         endif
1934       endif
1935    endif

2) In ./include/hbdefs.h,
after line 637, insert the following fix for the correct endianess detection:

...
637 #define HB_DBLFL_PREC_FACTOR 1.0000000000000002;
638
639 #if defined(__BYTE_ORDER__)
640
641   #if defined(__ORDER_LITTLE_ENDIAN__)

642
643     #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
644       #define HB_LITTLE_ENDIAN
645     #endif
646
647   #elif defined(__ORDER_BIG_ENDIAN__)

648
649     #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
650       #define HB_BIG_ENDIAN
651     #endif
652
653   #elif defined(__ORDER_PDP_ENDIAN__ )

654
655     #if __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__
656       #define HB_PDP_ENDIAN
657     #endif
658
659   #endif
660
661 #endif
662

...

NOTE
How did I get to the above fix?
By noting the following GCC 4.8.2 preprocessor defines:
$ gcc -dM -E - < /dev/null |egrep '(ORDER|ENDIAN)'
#define __ORDER_LITTLE_ENDIAN__ 1234
#define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__
#define __ORDER_PDP_ENDIAN__ 3412
#define __ORDER_BIG_ENDIAN__ 4321
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__

For fixing the hbmk2's default cpu setting (see the bottom of this post) I'll have to (approximately) adjust ./utils/hbmk2/hbmk2.prg as follows:

12955    CASE HBMK_ISCOMP( "gcc|icc|clang|sunpro|diab|pcc|tcc" )
12956       /* TOFIX: This is not necessarily correct, since these inherit the
12957                 default CPU architecture from OS default, by and large,
12958                 and targets can be overridden using user options. */
12959       #ifdef __ARCH64BIT__
12960       RETURN "x86_64"
12961       #else
12962       RETURN "x86"
12963       #endif

Take the @start snapshot:
$ zfs snapshot $DS/hb-3.2.0-gnu32@start


Now proceed to the "main build":

$ source ../setenv 32
...

$ gmake
...

And proceed to the "flawed" installation:

NOTE
The following command is just "su", not "su -".
This is important and a limitation of the Harbour "make system".
$ su
# gmake install
...

# ^D

On both previous steps there will be a few unexpected errors:
hbmk2[hbgd]: Exit code: 7: failed in final assembly (linker or library manager)
hbmk2[hbziparc]: Exit code: 7: failed in final assembly (linker or library manager)
hbmk2[sddodbc]: Exit code: 7: failed in final assembly (linker or library manager)
hbmk2[sddsqlt3]: Exit code: 7: failed in final assembly (linker or library manager)
And there will be other expected harmless "warnings":
hbmk2[gtalleg]: Exit code: 10: dependency missing or disabled
hbmk2[hbfbird]: Exit code: 10: dependency missing or disabled
hbmk2[hbfimage]: Exit code: 10: dependency missing or disabled
hbmk2[hbmagic]: Exit code: 10: dependency missing or disabled
hbmk2[hbmysql]: Exit code: 10: dependency missing or disabled
hbmk2[hbpgsql]: Exit code: 10: dependency missing or disabled
hbmk2[sddfb]: Exit code: 10: dependency missing or disabled
hbmk2[sddmy]: Exit code: 10: dependency missing or disabled
hbmk2[sddoci]: Exit code: 10: dependency missing or disabled
hbmk2[sddpg]: Exit code: 10: dependency missing or disabled

hbmk2[gtwvg]: Exit code: 50: stop requested
hbmk2[hbblat]: Exit code: 50: stop requested
hbmk2[hbwin]: Exit code: 50: stop requested
hbmk2[libhpdf]: Exit code: 50: stop requested
hbmk2[lzf]: Exit code: 50: stop requested
hbmk2[minilzo]: Exit code: 50: stop requested
hbmk2[minizip]: Exit code: 50: stop requested
hbmk2[mxml]: Exit code: 50: stop requested
hbmk2[rddads]: Exit code: 50: stop requested
hbmk2[tinymt]: Exit code: 50: stop requested
hbmk2[xdiff]: Exit code: 50: stop requested
Naturally, the priority is to address the unexpected errors.
For now, I gave up trying to understand the Harbour "make system".
I'll consider it some sort of bug, because AFAIK I could manually fix it.

As root make sure you place the all dynamic libraries in the right location (the lib subdir of the HB_INSTALL_PREFIX). AFAIK I couldn't get it working just via the environment variables!

$ env |grep HB
HB_BUILD_CONTRIB_DYN=yes
HB_WITH_SQLITE3=/opt/sqlite-3.19.3/gnu32/include
HB_WITH_GD=/usr/include/gd2
HB_BUILD_CONTRIB=yes
HB_USER_CFLAGS=-m32 -march=core2 -std=gnu89
HB_WITH_ODBC=/usr/include/odbc
HB_INSTALL_DYN=yes
HB_BUILD_DYN=yes
HB_WITH_QT=/opt/qt-4.8.7/gnu32/include
HB_INSTALL_PREFIX=/opt/hb-3.2.0/gnu32
HB_COMPILER=gcc
HB_INSTALL_MAN=
HB_QTPATH=/opt/qt-4.8.7/gnu32/bin


$ export HB=$(pwd)
$ su
# cd $HB_INSTALL_PREFIX/lib 

# (cd $HB/lib/sunos/gcc; gtar cf /tmp/libs1.tar *.so*)
# gtar xf /tmp/libs1.tar

# (cd $HB/bin/sunos/gcc; gtar cf /tmp/libs2.tar *.so*)
# gtar xf /tmp/libs2.tar


# ^D

NOTE
You could gather the previous privileged (#) commands on a script because they will have to be repeated later. For instance:
#!/bin/bash

if [[ -z $HB_INSTALL_PREFIX ]]
then
  echo HB_INSTALL_PREFIX not set!
  exit 1
fi

if [[ -z $HB ]]
then
  echo HB not set!
  exit 1
fi

echo From $HB/bin and $HB/lib to $HB_INSTALL_PREFIX/lib

cd $HB_INSTALL_PREFIX/lib

(cd $HB/lib/sunos/gcc; gtar cf /tmp/libs1.tar *.so*)
gtar xf /tmp/libs1.tar

(cd $HB/bin/sunos/gcc; gtar cf /tmp/libs2.tar *.so*)
gtar xf /tmp/libs2.tar

rm /tmp/libs1.tar /tmp/libs2.tar
 Then, manually build the libraries that have failed in the automatic build:
 
$ export PATH=$HB_INSTALL_PREFIX/bin:$PATH
$ echo $PATH
/opt/hb-3.2.0/gnu32/bin:/opt/libtool-2.4.6/gnu32/bin:/opt/m4-1.4.18/gnu32/bin:/opt/autoconf-2.69/gnu32/bin:/opt/automake-1.15/gnu32/bin:/opt/tcl-8.5.19/gnu32/bin:/opt/sqlite-3.19.3/gnu32/bin:/opt/qt-4.8.7/gnu32/bin:/usr/gnu/bin:/usr/bin:/usr/sbin


$ cd $HB/contrib
$ INCLUDE_FIX="$(pwd)/rddsql"

$ ../bin/sunos/gcc/hbmk2 -cflag=-I"$INCLUDE_FIX" \
  -width=0 -autohbm- @hbpre -inc -hbdyn \
  sddsqlt3/sddsqlt3.hbp @hbpost sddsqlt3/sddsqlt3.hbc
hbmk2: Processing environment options: -comp=gcc
hbmk2: Dependency 'sqlite3' found: /opt/sqlite-3.19.3/gnu32/include (3.19.3)
hbmk2: Compiling...
hbmk2: Creating dynamic library... ../bin/sunos/gcc/libsddsqlt3.so.3.2.0
hbmk2: Created symbolic link ../bin/sunos/gcc/libsddsqlt3.so to libsddsqlt3.so.3.2.0
hbmk2: Created symbolic link ../bin/sunos/gcc/libsddsqlt3.so.3.2 to libsddsqlt3.so.3.2.0


$ ../bin/sunos/gcc/hbmk2 -cflag=-I"$INCLUDE_FIX" \
  -width=0 -autohbm- @hbpre -inc -hbdyn \
  sddodbc/sddodbc.hbp @hbpost sddodbc/sddodbc.hbc
hbmk2: Processing environment options: -comp=gcc
hbmk2: Dependency 'odbc' found: /usr/include/odbc
hbmk2: Compiling...
hbmk2: Creating dynamic library... ../bin/sunos/gcc/libsddodbc.so.3.2.0
hbmk2: Created symbolic link ../bin/sunos/gcc/libsddodbc.so to libsddodbc.so.3.2.0
hbmk2: Created symbolic link ../bin/sunos/gcc/libsddodbc.so.3.2 to libsddodbc.so.3.2.0


$ ../bin/sunos/gcc/hbmk2 \
  -width=0 -autohbm- @hbpre -inc -hbdyn \
  hbziparc/hbziparc.hbp @hbpost hbziparc/hbziparc.hbc
hbmk2: Processing environment options: -comp=gcc
hbmk2: Compiling Harbour sources...
hbmk2: Compiling...
hbmk2: Creating dynamic library... ../bin/sunos/gcc/libhbziparc.so.3.2.0
hbmk2: Created symbolic link ../bin/sunos/gcc/libhbziparc.so to libhbziparc.so.3.2.0
hbmk2: Created symbolic link ../bin/sunos/gcc/libhbziparc.so.3.2 to libhbziparc.so.3.2.0


$ ../bin/sunos/gcc/hbmk2 \
  -width=0 -autohbm- @hbpre -inc -hbdyn \
  hbgd/hbgd.hbp @hbpost hbgd/hbgd.hbc
hbmk2: Processing environment options: -comp=gcc
hbmk2: Dependency 'gd' found: /usr/include/gd2
hbmk2: Compiling Harbour sources...
hbmk2: Compiling...
hbmk2: Creating dynamic library... ../bin/sunos/gcc/libhbgd.so.3.2.0
hbmk2: Created symbolic link ../bin/sunos/gcc/libhbgd.so to libhbgd.so.3.2.0
hbmk2: Created symbolic link ../bin/sunos/gcc/libhbgd.so.3.2 to libhbgd.so.3.2.0


Maybe (double-check the build logs) it can be necessary to:

$ export HB_WITH_BZIP2=/usr/include

$ ../bin/sunos/gcc/hbmk2 \
  -width=0 -autohbm- @hbpre -inc hbbz2/hbbz2.hbp @hbpost
hbmk2: Processing environment options: -comp=gcc
hbmk2: Dependency 'bzip2' found: /usr/include
hbmk2: Compiling...
hbmk2: Creating static library... ../lib/sunos/gcc/libhbbz2.a


$ ../bin/sunos/gcc/hbmk2 \
  -width=0 -autohbm- @hbpre -inc -hbdyn hbbz2/hbbz2.hbp @hbpost hbbz2/hbbz2.hbc
hbmk2: Processing environment options: -comp=gcc
hbmk2: Dependency 'bzip2' found: /usr/include
hbmk2: Compiling...
hbmk2: Creating dynamic library... ../bin/sunos/gcc/libhbbz2.so.3.2.0
hbmk2: Created symbolic link ../bin/sunos/gcc/libhbbz2.so to libhbbz2.so.3.2.0
hbmk2: Created symbolic link ../bin/sunos/gcc/libhbbz2.so.3.2 to libhbbz2.so.3.2.0


NOTE
Again, you could gather the previous commands on a script just for convenience or maybe multiple builds targets. For instance:
#!/bin/bash

if [[ -z $HB_INSTALL_PREFIX ]] 
then
  echo HB_INSTALL_PREFIX not set!
  exit 1
fi

if [[ -z $HB ]] 
then
  echo HB not set!
  exit 1
fi

echo
echo Fixing libraries from $HB/contrib
echo

export PATH=$HB_INSTALL_PREFIX/bin:$PATH

cd $HB/contrib
INCLUDE_FIX="$(pwd)/rddsql"

echo sddsqlt3
../bin/sunos/gcc/hbmk2 -cflag=-I"$INCLUDE_FIX" \
-width=0 -autohbm- @hbpre -inc -hbdyn \
sddsqlt3/sddsqlt3.hbp @hbpost sddsqlt3/sddsqlt3.hbc

echo

echo sddodbc
../bin/sunos/gcc/hbmk2 -cflag=-I"$INCLUDE_FIX" \
-width=0 -autohbm- @hbpre -inc -hbdyn \
sddodbc/sddodbc.hbp @hbpost sddodbc/sddodbc.hbc

echo

echo hbziparc
../bin/sunos/gcc/hbmk2 \
-width=0 -autohbm- @hbpre -inc -hbdyn \
hbziparc/hbziparc.hbp @hbpost hbziparc/hbziparc.hbc

echo

echo hbgd
../bin/sunos/gcc/hbmk2 \
-width=0 -autohbm- @hbpre -inc -hbdyn \
hbgd/hbgd.hbp @hbpost hbgd/hbgd.hbc

echo

echo hbbz2
../bin/sunos/gcc/hbmk2 \
-width=0 -autohbm- @hbpre -inc hbbz2/hbbz2.hbp @hbpost
../bin/sunos/gcc/hbmk2 \
-width=0 -autohbm- @hbpre -inc -hbdyn hbbz2/hbbz2.hbp @hbpost
Take the @build snapshot:

$ zfs snapshot $DS/hb-3.2.0-gnu32@build

Repeat the manual library copying step to ensure that the manually build libraries also get copied to $HB_INSTALL_PREFIX/lib.

$ cd $HB
$ su
# cd $HB_INSTALL_PREFIX/lib


# (cd $HB/lib/sunos/gcc; gtar cf /tmp/libs1.tar *.so*)
# gtar xf /tmp/libs1.tar

# (cd $HB/bin/sunos/gcc; gtar cf /tmp/libs2.tar *.so*)
# gtar xf /tmp/libs2.tar


And in addition, fix a few more things:

# cd ..

# rm bin/*.so*

# cat contrib/hbexpat/hbexpat.hbc
...

# libs=3rd/expat/expat.hbc          comment this line!

# mv bin/hbrun{,-bin}
# touch bin/hbrun
# chmod a+x bin/hbrun
# vim bin/hbrun
# cat bin/hbrun
#!/bin/bash
HB=/opt/hb-3.2.0/gnu32
LD_LIBRARY_PATH=$HB/lib $HB/bin/hbrun-bin $*


NOTE
Once more you could gather commands on a script for added convenience, in this case, for the hbrun "invoke fix" via LD_LIBRARY_PATH (or you could take more time in trying to find out how to pass an -R option to the hbrun make step, how knows if at ./contrib/hbrun/hbrun.hbp). For instance:
#!/bin/bash

if [[ -z $HB_INSTALL_PREFIX ]] 
then
  echo HB_INSTALL_PREFIX not set!
  exit 1
fi

cd $HB_INSTALL_PREFIX

#
# Harbour Shell / Script Runner (hbssr)
#
cat >bin/hbssr <<EOF
#!/bin/bash
HB=$HB_INSTALL_PREFIX
LD_LIBRARY_PATH=\$HB/lib \$HB/bin/hbrun \$*
EOF

chmod a+x bin/hbssr
Take the final snapshot:

# zfs snapshot .../hb-3.2.0/gnu32@release

At last, HB_INSTALL_PREFIX will look as follows:

# tree -d -L 2 $HB_INSTALL_PREFX
/opt/hb-3.2.0/gnu32
├── bin
├── contrib
│ ├── gtqtc
│ ├── hbamf
│ ├── hbblink
│ ├── hbbz2
│ ├── hbbz2io
│ ├── hbcairo
│ ├── hbcomio
│ ├── hbcomm
│ ├── hbct
│ ├── hbcups
│ ├── hbcurl
│ ├── hbexpat
│ ├── hbformat
│ ├── hbfoxpro
│ ├── hbfship
│ ├── hbgd
│ ├── hbgs
│ ├── hbgt
│ ├── hbgzio
│ ├── hbhpdf
│ ├── hbhttpd
│ ├── hblzf
│ ├── hbmemio
│ ├── hbmisc
│ ├── hbmlzo
│ ├── hbmxml
│ ├── hbmzip
│ ├── hbnetio
│ ├── hbnf
│ ├── hbodbc
│ ├── hboslib
│ ├── hbpipeio
│ ├── hbsms
│ ├── hbsqlit3
│ ├── hbssl
│ ├── hbtcpio
│ ├── hbtest
│ ├── hbtinymt
│ ├── hbtip
│ ├── hbtpathy
│ ├── hbunix
│ ├── hbxdiff
│ ├── hbxpp
│ ├── hbzebra
│ ├── hbziparc
│ ├── rddbm
│ ├── rddsql
│ ├── sddodbc
│ ├── sddsqlt3
│ └── xhb
├── etc
├── include
├── lib
└── share
  ├── doc
  └── man
58 directories

Of particularly interest are the libraries:
(some just static, some both static and dynamic)

# ls -lho $HB_INSTALL_PREFIX/lib |grep harbour
lrwxrwxrwx   ... lib/libharbour.so -> libharbour.so.3.2.0
lrwxrwxrwx   ... lib/libharbour.so.3.2 -> libharbour.so.3.2.0
-rwxr-xr-x   ... lib/libharbour.so.3.2.0


and in general:

# ls -lho $HB_INSTALL_PREFIX/lib |egrep "lib.*\.(a|so)*"

-rw-r--r--   ... lib/lib___.a
lrwxrwxrwx   ... lib/lib___.so -> lib___.so.3.2.0
lrwxrwxrwx   ... lib/lib___.so.3.2 -> lib___.so.3.2.0
-rwxr-xr-x   ... lib/lib___.so.3.2.0

...

And to the best of my understanding that's the essential start-up!
Welcome to xBASE under Solaris 11.3!

# $HB_INSTALL_PREFIX/bin/hbtest
Harbour Regression Test Suite
Copyright (c) 1999-2016, Viktor Szakats
http://harbour-project.org/
------------------------------------------------------------
      Version: Harbour 3.2.0dev (r1705200225)
     Compiler: GNU C 4.8.2 (32-bit)
           OS: SunOS 5.11 i86pc
   Date, Time: 2017-07-31 22:32:02
Shortcut opt.: On
     Switches:  
============================================================
R No.  Line         TestCall()          -> Result | Expected
------------------------------------------------------------
============================================================
Test calls passed:       4861 ( 100.00 % )
Test calls failed:          0 ( 0.00 % )
                   ----------
            Total:       4861 ( Time elapsed: 0.19 seconds )


# $HB_INSTALL_PREFIX/bin/hbmk2 -build
Harbour 3.2.0dev (r1705200225)
Copyright (c) 1999-2016, http://harbour-project.org/

Harbour Build Info
---------------------------
Version: Harbour 3.2.0dev (r1705200225)
Compiler: GNU C 4.8.2 (32-bit)
Platform: SunOS 5.11 i86pc
PCode version: 0.3
ChangeLog last entry: 2017-05-20 02:25 UTC Viktor Szakats ...
ChangeLog ID: 731297e3d5b89d9f4304719560cd95f87ba1e239
Built on: Jul 30 2017 18:05:56
Extra C compiler options: 

     -m32 -march=core2 -std=gnu89 -R/opt/hb-3.2.0/gnu32/lib
Extra linker options:
     -m32 -march=core2 -std=gnu89 -R/opt/hb-3.2.0/gnu32/lib
Build options: (Clipper 5.3b) (Clipper 5.x undoc)
---------------------------


At first I thought I had possible issues. But after further investigations the apparent inconsistency of having a lib under lib in dynprefix was of no concern. See the following output:

# $HB_INSTALL_PREFIX/bin/hbmk2 --hbinfo
{

  "platform":"sunos",
  "compiler":"gcc",
  "cpu":"x86",
  "buildname":"",
  "targetname":".adhoc.",
  "targettype":"hbexe",
  "dynprefix":"/opt/hb-3.2.0/gnu32/lib/lib",
  "dynsuffix":"",
  "inc":"no",
  "hbctree":""
}

For dynprefix that's not an issue because although dynprefix clearly contains a path, it's not a path, but just a string prefix (including the initial "lib" of the file-name) of some full library located in $HB_INSTALL_PREFIX/lib/.

As a very first personal examples, check these out:

$ cd /tmp

$ cat sample.prg 
PROCEDURE main
  SET CURSOR OFF
  CLEAR SCREEN
  msg_justify( MAXROW()/2, "Hello, world!" )
  msg_justify( ROW()+1, "Press any key to exit!" )
  INKEY(0)
  CLEAR SCREEN
  SET CURSOR ON
  RETURN

FUNCTION msg_justify
  PARAMETERS row, msg
  @ row, ( MAXCOL() - LEN(msg) )/2 SAY msg
  RETURN


$ $HB_INSTALL_PREFIX/bin/hbmk2 /tmp/sample.prg
Harbour 3.2.0dev (r1705200225)
Copyright (c) 1999-2016, http://harbour-project.org/
Compiling '/tmp/sample.prg'...
Lines 20, Functions/Procedures 2
Generating C source output to '/var/tmp/...'... Done.


$ ./sample
(did you notice the graphics mouse cursor under a $TERM=xterm ?)




















You shall note however, if $TERM=sun-color (or some other value), then the some screen commands such as CLEAR SCREEN and SET CURSOR OFF won't work as expected if they'll work at all. Therefore, it's advisable to check for $TERM for determining in which runtime environment the program is and adjust screen behavior accordingly.
    
$ cat bitness.prg
PROCEDURE main

  #ifdef __ARCH32BIT__
  ? "32"
  #else
  ? "64"
  #endif

  RETURN


If using the 64-bit build you'll get:

$ $HB_INSTALL_PREFIX/bin/hbssr bitness.prg
64