Harbour for beginners

How to install the Harbour and compile on it your program. Features of the Harbour.

Alexander Kresin
2003 - 2016

Download manual: chm, version 1.02

In writing this article there were used materials from Harbour/readme.txt, Harbour/Changelog, Harbour/doc/xhb-diff.txt and other files from the Harbour/doc, from the Harbour developers list, the source files of the project.


1. Installation

1.1 Download Harbour

The most obvious and simple way to obtain Harbour - is go to the site of the project - https://harbour.github.io/. The button More downloads will lead you to the project page on Sourceforge, where are laid out the source and ready-to-run binary packages of different versions. If you need a binary file, then choose designed for your platform ( Windows, any of the UNIX/Linux, OS/2, etc. ). It may be that there is no such thing, or that for your platform lacks the latest version of it, it often happens because of there are a lot of different Unixes/Linuxes etc, but the number of active developers - those who are ready to compile, to test, and to put packages on different platforms is limited. So, if you do not find your package, don't worry - the path to the Harbour is not closed for you. Download the sources and build from them ready binary package. It is not difficult, much easier than it may seem at first. By the way, if there is no binary package of the latest version for a desired platform , it probably makes sense to download the version that is there. 2.0, and even 1.0 are quite good and, it is possible that it will fully satisfy your needs.

From the project site you can download an archive of fresh source code ( it's called Source snapshot ) and the so-called nightly binary - it is ready for use distribution, compiled from the GIT repository the night before.

If you want you can get the source code directly from the repository using the GIT-client ( In March 2013 Harbour moved from SVN to GIT on https://github.com/harbour/. Personally I do not see much sense in it, unless you decide to join the developers or the code laid out five minutes ago is very important for you... If so, then read the next section about GIT.

1.2 What is GIT

Git ( see. article in Wikipedia ) - is a modern version control system, the successor to CVS and a rival of SVN. So, Git is a program with server and client parts, which allows developers who have installed the client part, work together with the sources of the project, which are located on the server ( in the Internet or local network ), and solves the conflicts arising by the simultaneous variation of one file by different people. The Git provides the versions control - i.e., all versions of each file are stored, may be recovered, restored; you can check what changes and by whom have been made.
This is a very convenient thing and I also recommend it ( or its predecessor CVS) for the internal use within the organization.

Since March 2013 Harbour is situated at Github.com - one of the largest portals for Open Source projects. By installing Git client, you can get access to the Harbour sources - the most recent version that developers have. For the first time, you will need to download a complete set, for subsequent renewals only the changes will be transmitted.

Git client can be downloaded from the the site of this product. If you have Linux, may be the SVN client is included in your distribution. If you have Windows, you should create a directory, for example, GIT, and execute in this directory the following command, which will create a directory core/ there, and in it - the local Harbour repository :

  git.exe clone http://github.com/harbour/core.git
    

And then update from time to time your local repository, performing in core/ the command git pull:

  cd core
      git.exe pull
    

In addition to the command git.exe distribution Git contains a graphical tool, which, among other things, provides a convenient means to view the history of changes, compare versions, etc.

1.3 Choose C compiler

There is one important question that you need to answer for yourself right before downloading Harbour distribution - this is the question of the C compiler.
The fact is that the Harbour compiler does not create the object files ( obj, o ), the result of his work is a *.c file, which should be then compiled with the C compiler, in order to get the executable file. But don't be scared ! You do not need to know C for this, the installation of the C compiler is enough. And using it by compilation and linking your files is not any harder than using Rtlink or Blinker.
If you work in Linux, or in any of the Unixes, MAC OS, OS/2, then you already have the C compiler - this is the standard GNU C. If your platform is Windows, then you have to choose. Many of those who work with Harbour, use the free Borland C ++ 5.5.1, it can be downloaded from the this page. Another popular C ++ compiler is Mingw http://www.mingw.org. If you already have C++ Builder or Visual C++, you can use them. The binary distribution of Harbour for Windows, provided in the form of installation exe file, includes Mingw C ++ compiler.

Take into considaration in case you will install Borland C ++ 5.5.1 and won't read their readme.txt: you must manually create the bcc55\bin 2 file:
BCC32.CFG:

  -I"c:\Borland\Bcc55\include"
-L"c:\Borland\Bcc55\lib"
and ILINK32.CFG:
  -L"c:\Borland\Bcc55\lib;c:\Borland\Bcc55\lib\PSDK"
    

By the way, starting the execution of a little program you can do without C.

1.4 Install the Harbour binaries

Binary packages are laid out in the specific to a corresponding platform formats. For Windows it is an EXE - start it and follow the instructions of the installer; for Ubuntu it is a deb file - Ubuntu users know what to do with it; etc.

1.5 Install the Harbour from source

To build a harbour compiler and the libraries, we need to have theC compiler, we have already discussed it previously.

In the root of your distribution there is a file README.txt ( up to 14.11.2012 it was called INSTALL ), it includes detailed instructions about building Harbour from the source code. Below I will tell about it very briefly, for the majority of cases this will be enough.

If you have Windows, specify the path to the bin/ directory of your C compiler and run win-make.exe - this file is in your Harbour distribution. I usually make bat-file with these lines and execute it.

So, if you have Borland C 5.5, it will look something like this:

  set path=c:\borland\bcc55\bin
      win-make.exe
    

For mingw it can be like this:

  set path=c:\mingw\bin
      win-make.exe
    

For Open Watcom:

  set watcom=C:\watcom
      set path=%WATCOM%\BINNT;%WATCOM%\BINW;%PATH%
      set edpath=%WATCOM%\EDDAT
      set include=%WATCOM%\H;%WATCOM%\H\NT
      win-make.exe
    

If you have a Linux/UNIX, you just run the command make.

If you need examples for other platforms and compilers, see the README.txt ( up to 14.11.2012 it was called INSTALL ), section 8.EXAMPLES, there are lots of them.

For the beginning it'll be enough, but then you may need to install additional environment variables to control the process. The full list of them see in the README.txt and here I will cite only a few examples, in order to be clear.

Some Harbour modules ( basically they are extra - those in the contribs ) depend on the so-called 3rd party components, i.e., on the already set in your system third-party programs. For example, to build the library hbmysql from the Harbour/contrib header files ( .h ) from the MySql client are required that you already have installed. Therefore, if you want this library to be created during building the Harbour and to make it work with the installed MySQL client, you should specify the path to the header files of this client:

  set HB_WITH_MYSQL=C:\mysql\include
    
Similar to this:
  set HB_WITH_ADS=C:\ads\acesdk
      set HB_WITH_ALLEGRO=C:\allegro\include
      set HB_WITH_BLAT=C:\blat\full\source
      set HB_WITH_CAIRO=C:\cairo\include\cairo
      set HB_WITH_CURL=C:\curl\include
      set HB_WITH_GS=C:\ghostscript-9.01\psi
      set HB_WITH_GS_BIN=C:\ghostscript-9.01\bin (on Windows)
      set HB_WITH_FIREBIRD=C:\InterBase\include
      set HB_WITH_FREEIMAGE=C:\FreeImage\Dist
      set HB_WITH_GD=C:\gd\include
      set HB_WITH_OCILIB=C:\ocilib\include
      set HB_WITH_OPENSSL=C:\openssl\inc32 OR C:\openssl\include
      set HB_WITH_PGSQL=C:\pgsql\include
    

On Unix/Linux systems, this is usually not required, since all of these 3rd party components are located in the strictly certain locations, and the Make program will find them. To, prohibit the compiling of these modules, you need on the contrary to assign to the appropriate variable value no

For some of these modules al necessary files ( as well as headers ) are already included in Harbour. In this case you may specify the path to the installed component or to set to a variable a value local - in order to use the Harbour files and headers, or, on the contrary, nolocal - to prohibit the usage of the predefined in the Harbor files:

  set HB_WITH_BZIP2=C:\bzip2
      set HB_WITH_EXPAT=C:\expat\lib
      set HB_WITH_JPEG=C:\jpeglib
      set HB_WITH_LIBHARU=C:\libharu\include
      set HB_WITH_LZF=C:\liblzf
      set HB_WITH_MINILZO=C:\minilzo\
      set HB_WITH_MINIZIP=C:\zlib\contrib\minizip
      set HB_WITH_MXML=C:\minixml
      set HB_WITH_PCRE=C:\pcre
      set HB_WITH_PNG=C:\libpng
      set HB_WITH_SQLITE3=C:\sqlite3
      set HB_WITH_TIFF=C:\libtiff
      set HB_WITH_TINYMT=C:\tinymt\tinymt
      set HB_WITH_XDIFF=C:\libxdiff-0.23\xdiff
      set HB_WITH_ZLIB=C:\zlib
    

Well and, at last, one more variable, it points to the directory where you should install the Harbour binaries:

  set HB_INSTALL_PREFIX
    

1.6 xHarbour

xHarbour is another Harbour, branch fork from Harbour. In the early 2000s one of the developers (Ron Pinkas) left the project and founded his own because of disagreements with other members of the team. Later he was joined by another group of people. Letter x in the title of the new project was supposed to mean extended - advanced. The code has been entirely inherited from the Harbour, but Pinkas made the changes/additions, many of which had been previously rejected by the main developers of the Harbour. In the course of the further development the xHarbour borrowed a lot from the Harbour and Harbour borrowed something from xHarbour, so that both projects are closely related and in most cases, if you do not use some language extensions, programs are successfully compiled with each of them. xHarbour exists in two forms - open and commercial. Where they differ I don't know, try to figure out on your own if you want to. About the differences between the Harbour and xHarbour you can read in xhb-diff.txt, this file is in any Harbour distributive in the Doc directory. I am a member of the Harbour from the very beginning and use exclusively it, which I also can recommend to you. The more so, for today ( November 2012 ) Harbour is safer, faster and has more possibilities. All described here refers to the Harbour. Much from this( but not all, Hbmk, for example is not included in the xHarbour ) can be applied to the xHarbour as well.

2. Compilation and linking of programs

2.1 Overview

There are three ways to create your program in the Harbour: with the help of the traditional make-system, which is a part of any C compiler, using the command files ( bat for Windows and shell scripts for Unix/Linux ) or using the special Harbour utility hbmk2. Here we will look at the last two ways.

Hbmk2 is a convenient and powerful tool. Its main advantage is that it allows you to build both - a simple program and the large projects, without going into the details of the work of the compiler and linker. Hbmk2 itself finds your C compiler and makes the necessary actions. What could be easier than run from the command line utility with a list of source files of a project ? For more complex cases - if you need to install any special compiler options, attach additional libraries or use dynamic libraries, you need to know special parameters of hbmk2, or to create the configuration files of the project, but all the same it will be easier than to use other methods.

I, however, prefer the traditional way to build programs - with the help of batch files, because it gives a full control over the process, so I can clearly see what I'm going to do. The general sequence of the actions is simple:

1. Compile *.prg to *.c with the help of harbour.exe.
Compiler options are backward compatible with Clipper's. The full list of them can be obtained by running harbour.exe without parameters. In one line several prg files can be mentioned.
2. Compile *.c to the object files with your C compiler.
3. Link object files with the linker, which comes with a C compiler.
While linking you should specify the list of the Harbour libraries that are needed for your application.
All C compilers, which are used with Harbour, allow you to combine steps 2 and 3, do as you like.

2.2 Windows, the bat file

Below is bat file, which I usually use to compile one prg (Borland C, gtwin):

  @set HB_INSTALL=d:\harbour

      %HB_INSTALL%\bin\harbour %1.prg -n -i%HB_INSTALL%\include
      bcc32 -O2 -d -I%HB_INSTALL%\include -L%HB_INSTALL%\lib %1.c hbdebug.lib hbvm.lib
       hbrtl.lib gtwin.lib hbcpage.lib hblang.lib hbrdd.lib hbmacro.lib hbpp.lib
       rddntx.lib rddcdx.lib rddfpt.lib hbsix.lib hbcommon.lib hbct.lib
    

If you want to use the gtwvt display driver, the last line would look like this:

  bcc32 -O2 -tW -I%HB_INSTALL%\include -L%HB_INSTALL%\lib %1.c hbdebug.lib hbvm.lib
     hbrtl.lib gtwvt.lib hbcpage.lib hblang.lib hbrdd.lib hbmacro.lib hbpp.lib rddntx.lib
     rddcdx.lib rddfpt.lib hbsix.lib hbcommon.lib hbct.lib
    

Note the Harbour option -i . It indicates the path to the header file ( *.h, *.ch ), in this case to the Harbour standard header files , which are usually located in harbour\include. If your program has no header files, you can omit this option. If you are using header files located somewhere else (own, or from any additional libraries), you need to add the path to them in this option -i, multiple paths can be separated by semicolons, for example:

  %HB_INSTALL%\bin\harbour %1.prg -n -i%HB_INSTALL%\include;c:\hwgui\install
    

The same applies to the C compiler option -L . It indicates the path to the libraries, which should be connected to your application. These, of course, the standard Harbour libraries, which are usually located in a folder harbour\lib, but they can also be in a folder for a specific C compiler, for example, harbour\lib\win\bcc. If you use additional libraries, located somewhere else, you must add the path to them in the -L option - as it was shown above for -i.

For Mingw C replace the call command of the C compiler with:

  gcc -Wall -mno -cygwin -c -I%HB_INSTALL%\include %1.c
      gcc -Wall -mwindows -o%1%.exe %1.o -L%HB_INSTALL%/lib/win/mingw -Wl,--start-group \
          -lhbvm -lhbrtl -lgtwvt -lhblang -lhbrdd -lhbmacro -lhbpp -lrddntx -lrddcdx \
          -lrddfpt -lhbsix -lhbcommon -lhbcpage -lhbct -luser32 -lgdi32 -lwinspool \
          -lcomctl32 -luuid -lkernel32 -lws2_32 -Wl,--end-group
    

If you need to build the program from several files, you can use something like this (Borland C, gtwin):

  @set HB_INSTALL=d:\harbour

      %HB_INSTALL%\harbour file1.prg -n -i%HB_INSTALL%\include
      %HB_INSTALL%\harbour file2.prg -n -i%HB_INSTALL%\include
      ...
      bcc32 -O2 -d -I%HB_INSTALL%\include -L%HB_INSTALL%\lib file1.c file2.c ... 
       hbdebug.lib hbvm.lib hbrtl.lib gtwin.lib hbcpage.lib hblang.lib hbrdd.lib
       hbmacro.lib hbpp.lib rddntx.lib rddcdx.lib rddfpt.lib hbsix.lib hbcommon.lib
       hbct.lib
    

2.3 Linux, sh script

The sequence, of course, remains the same, only the syntax is a bit different (for the console application with gttrm):

  #!/bin/sh
      HB_INS="/apps/harbour"
      $HB_INS/bin/harbour $1.prg -n -q0 -es2 -gc0 -I$HB_INS/include -I../include
      gcc -I. -I$HB_INS/include -Wall -c $1.c -o$1.o
      gcc -Wall -o$1 $1.o -L $HB_INS/lib \
            -Wl,--start-group -lhbvm -lhbrtl -lhblang -lhbrdd \
            -lhbmacro -lhbpp -lhbcommon -lrddntx -lrddcdx -lrddfpt -lhbsix \
            -lhbct -lgttrm -lhbcpage -Wl,--end-group -lm -lgpm
    

2.4 Hbmk2

With the help of Hbmk2 things are a bit easier. In order to compile the program of one prg file (for example, hello.prg), just type:

  hbmk2 hello.prg
    

Of the two prg:

  hbmk2 mymain.prg second.prg
    

Build the application, using a special configuration file of the project:

  hbmk2 myapp.hbp
    

Build the application using the library:

  hbmk2 myapp.prg -lmylib -L
    

Build the application, of all the prg and c files located in the directory src:

  hbmk2 -omyapp src/*.prg src/*.c
    

Hbmk2 itself determines which C compiler you have installed, it's looking for a way to it in the environment variable PATH. If you have more than one installed C compiler and want to specify which one hbmk2 should use, write the parameter -comp=<name>, where <name> is a conventional designation of the compiler, for example:

- for Windows: mingw and msvc, bcc, watcom, icc, pocc, xcc, mingw64, msvc64, msvcia64, iccia64, pocc64;
for Linux: gcc, clang, icc, watcom, sunpro, open64, pcc.

A very useful option -trace displays all calls of compiler and linker with all of the options that were required to build the project - so you can easier understand the problem, if something went wrong. As to my opinion, I think it is useful to know, how your application was built.

2.5 How to use dynamic libraries ( dll, so )

As a result of the build process, described in the previous subsections, you get the executable module, which includes your source texts, compiled to p-code, the Harbour virtual machine, which executes this p-code, RTL - Run-Time Library - Harbour functions library and possibly other libraries, which you have included in the project. So this executable has quite a large size. It can be significantly reduced, if you use the shared library. Harbour binary distributions include in addition to static library ( .lib, .a ) a dynamic one ( .dll, .so ), which includes all the functions of the main Harbour libraries. Its name may include the version number of the Harbour and the name of the C compiler; so, for example, for the Harbour 2.1, built with the Borland C, it is harbour-21-bcc.dll. Of course, such an executable module can be used only in conjunction with the dynamic library.

So, our bat file for the compilation of a prg with the Borland C acquires the following form:

  @set HB_INSTALL=d:\harbour

      %HB_INSTALL%\harbour %1.prg -n -i%HB_INSTALL%\include
      bcc32 -O2 -d -I%HB_INSTALL% -L%HB_INSTALL%\lib %1.c hbmainstd.lib harbour-21-bcc.lib
    
The difference is that instead of a long list of libraries we use now only two - hbmainstd.lib and harbour-21-bcc.lib. The last one is a so-called import library - the library which is a pointer to the functions of the corresponding DLLs. Such a library is required for static linking with the dll by some C compilers, incl. Borland C ++ and MSVC. Mingw and the GNU C, by the way, do not require this. The name of this library can be different, if you have another version of the Harbour - harbour-32-bcc.lib, for example. I will not explain here why you need the hbmainstd.lib - it is still the Harbour for beginners :), I will say only that, for some GT, for example gtwvt, you need to use hbmainwin.lib instead of it.

For Mingw C compiler replace the last line with:

       gcc -Wall -mno-cygwin -c -I%HB_INSTALL%\include %1.c
       gcc -Wall -mwindows -o%1%.exe %1.o %HB_INSTALL%/lib/win/mingw/harbour-21.dll \
          -L%HB_INSTALL%/lib/win/mingw -Wl,--start-group -lhbmainstd -luser32 -lgdi32 \
          -lwinspool -lcomctl32 -luuid -lkernel32 -lws2_32 -Wl,--end-group
    

For Unix/Linux and GNU C it will look like this:

       #!/bin/sh
       HB_INS="/apps/harbour"
       $HB_INS/bin/harbour $1.prg -n -q0 -es2 -gc0 -I$HB_INS/include -I../include
       gcc -I. -I$HB_INS/include -Wall -c $1.c -o$1.o
       gcc -Wall -o$1 $1.o $HB_INS/lib/libharbour-2.1.0.so -lm -lgpm
    
i.e. the whole list of libraries, we replaced with the libharbour-2.1.0.so (for other versions of the Harbour this name, of course, will be different) - the dynamic library, import library is not needed here.

With the hbmk2 all is much easier regardless of the platform and the compiler:

  hbmk2 hello.prg -shared
    

Now lets turn to another variant of the usage of dynamic libraries, the so - called p-code dll. You can compile and build some of your prg in a dynamic library ( dll or so ) and then use it with their applications; such dynamic library we call p-code dll.

So, we have a file mylib.prg with the function M1(), which we want to build in the form of p-code dll in order to subsequently use it with the main application myapp.prg:

// mylib.prg
    FUNCTION M1
       ? "It is the function of the dynamic library " + Procname()
       Inkey(0)
       RETURN Nil
    

Our main application myapp can be compiled with static libraries or from the Harbour dll ( so ), as described in the beginning of this section. Here we look at the second option, when myapp is built with the Harbour dll, because the first requires rebuilding of Harbour with the key set HB_USER_CFLAGS=-DHB_DYNLIB. We have 2 ways to build myapp with mylib - with the static linking and dynamic linking. The static linking of a shared library - it sounds a bit strange :), but let me explain what is meant. Static linking assumes that at the very stage of linking all links to external functions are allowed. As mentioned above, some compilers, in particular, Borland C, MSVC, require the preliminary creation of the import library - the static library with links to functions in the corresponding dynamic library; it is this import library which will be then linked to the main application in order to ensure the static linking. While static linking the presence of the "tied" dynamic link library is necessary for the very start of the program, regardless of whether you are going to use its functions in the current session or not; without this library the application displays a warning message and does not start. While dynamic linking the links to external functions are allowed at the run time, before using these functions you should only load dynamic library with the help of the function hb_LibLoad()and not forget to unload it with the help of hb_LibFree(). In this case, the presence of dynamic libraries will be needed not at the time when you start the program, but in that moment, when you execute a hb_LibLoad()if it ever will be. With this approach you can save time of loading the program and its occupied memory - loading dynamic modules only when needed.

When considering ways of building let's use Hbmk2 for simplicity. So, now about static linking. Build the first dynamic library. For Borland C ++ and MSVC we need, as you remember, to create import library, so write in the command line:

  hbmk2 mylib.prg -shared -hbdynvm -nohblib -implib
    
The result of this command will be the appearance of mylib.dll and mylib.lib, where the last one is import library; the option "-implib" just indicates for hbmk2 to create this library. For other compiler ( Mingw, GNU C ) write:
  hbmk2 mylib.prg -shared -hbdynvm -nohblib -olibmylib
    
i.e. the same, but without the "-implib", resulting in the output libmylib.dll ( or libmylib.so for Linux GNU C ).

Now we have to build the application itself myapp, statically linking it with mylib.

// myapp.prg
    FUNCTION Main
       hb_cdpSelect( "RU866" )
       M1()
       RETURN Nil
    
Do this as follows ( for Borland C ++ and MSVC ):
 hbmk2 myapp.prg -shared -lmylib.lib
    
or ( for Mingw, GNU C ):
  hbmk2 myapp.prg -shared -L. -lmylib
    

Now the dynamic binding. The dynamic library should be built in the same way as for the static binding, only there is no need to use the "-implib", because we don't need import library. But myapp.prg has to be changed, because we have to download the dynamic library with the help of hb_LibLoad():

// myapp.prg
    DYNAMIC M1
    FUNCTION Main
       Local hLib

       hb_cdpSelect( "RU866" )
       hLib := hb_LibLoad( "mylib.dll" )
       IF !Empty( hLib )
          M1()
       ENDIF
       hb_LibFree( hLib )
       RETURN Nil
    
Note the line DYNAMIC M1. Since we will not be linking any library to our myapp.prg, and we will load it dynamically, so in order for the linker not to curse on the unresolved references, we have to declare all functions of the dynamic library, which we are going to use as DYNAMIC. We build our application (note, no mentioning of mylib, because it is tied not statically during linking, but dynamically at runtime) :
  hbmk2 myapp.prg -shared
    

2.6 How to do without C compiler

Yes, you can compile your program and run it on execution and all this without the C compiler ! Harbour.exe can create special p-code file from your prg ( like a Fox. fxp ), small in size, which can be fulfilled with the help of the utility Hbrun.exe, it is in the distribution kit.

Now, compile the program with the /gh ( rest of the keys - /n /w, ... as usual, if necessary ) :
  harbour.exe my.prg /gh
    
If the compilation is completed without errors, you get a file my.hrb and execute it:
  hbrun.exe my.hrb [ parameters ]
    
where parameters are the parameters with which you start your program.
There is, however, one unfortunate limitation: you can compile the program only from one prg.

By the way, this can also be done with the help of hbmk2:

  hbmk2 -gh my.prg
      hbmk2 my.hrb [ parameters ]
    

And, finally, the easiest option is simply to start the execution of your prg using the same hbrun:

  hbrun.exe my.prg [ parameters ]
    

Note that this hrb file can be run for execution from your program, you can even call and separate functions from hrb ( for more on this see below, in section 3.6 Working with hrb - files ). And, generally speaking, the hrb file is very similar in its usage with p-code dll, considered in the previous subsection.



Comments:       ()       prev.    next.       Add comment
The length of a comment - no more than 4000 characters.
Your name:

Email address:
(not be shown publicly)
 
Input text from an image: