An issue and question about HBMK2 settings

Issues and Discussions related to Harbour

Moderator: Rathinagiri

Post Reply
Posts: 32
Joined: Wed Dec 29, 2010 5:12 pm
Location: Tennessee / USA

An issue and question about HBMK2 settings

Post by DenCo »

Hello All,,,

I hope this is entertaining. Here is a hbp I'm having a simple problem with.

I have read and studied all the hbmk2 information that I can find.

I have used hbmk2 a lot and have had good (lucky) results. I have compiled a lot of applications and re-written library files with it.

Below is a hbp. The "Topprog.prg" calls about 90 routines, one of them is
"userstat" (it's a .prg file and is a simple screen routine in the corner of the
menu that shows the user some basic info)

One of the other programs in the hbp list "tools1" also calls this same
"userstat" routine in one of it's functions. In both cases, it is called with a
simple "do userstat"

With my current settings, I get an exit status because of this, and my compile
stops. Of course I can fix it,, but I'm trying to learn something.

Here is the .hbp


-es0 (These settings were just experimenting around, both on and off)


topprog.prg (calls do userstat)

tools1.prg (also calls: do userstat)



ps32.hbc (pagescript,, it's ok)

Harbour(3.0) finds this double call to "userstat" and complains about it

multiple definition of `HB_FUN_USERSTAT'

0): first defined here

collect2: ld returned 1 exit status
hbmk2: Error: Running linker. 1

So, is there a basic setting or method to avoid this that I need to learn about ?

I have tried the /m switch after each of the tool* programs, but in that case I
get some undefined references to some other functions that are in "topprog". In other words, the errors are worse !

This is a big old application that has been in service for decades.

Here is the .bat file used to compile in Clipper,, all ok for years.

clipper tools1 /m
clipper tools2 /m
clipper tools3 /m

rtlink FI topprog,tools1,tools2,tools3 VERBOSE lib grump52,clipper,extend,esc30_52

Thanks, and good day to all

User avatar
Posts: 4543
Joined: Wed Jul 30, 2008 9:17 pm
DBs Used: DBF
Location: iskenderun / Turkiye
Has thanked: 411 times
Been thanked: 120 times

Post by esgici »

Hi Bill

Congrats, good advancing ...

My humble suggestions on compile stage are :

- KISS : keep simple and short everything as soon as possible ( in windows environment everything is already complex ;) )
- forgot all you know about compiling, linking
- hold off advanced concepts ( such as build first a .lib and then use it while linking )
- remove throw away obsolete compiler switches such as /m /n ...
- /m : separate compiling each .prg file; default of hmbk2 is "all in together" concept
- /n ( Suppresses the automatic definition of a procedure with the same name as the program file (.prg).):
this automatic definition too isn't a good way; give name to all your modules ( procedure / function ) by your hand
and don't give a name to your .prg file same name of a module.
- Enclose all modules in block / structure with PROCEDURE / FUNCTION ... RETURN statements; don't left any statement / line out of module.
- If any, remove SET PROCEDURE TO ... and #include .... ( .prg file ) statements from your source files.

For compiling and and linking process together your project ( say name is myProject) all you need is

- a myProject).hbp file include your .prg files
- a command ( in command prompt or within a .bat file ):

<pathOf_hbmk2.exe>\hmbk2 myProject)

Regarding your sample:

topProject.hbp :


( in addition other extra ( .hbc, .a ) files.

Exactly same as Clipper, a module can be called from and can be defined in anywhere (in any file and into any module) of project; but can't be defined more than one place. So USERSTAT' module may be defined more than one time anywhere of your module files. You need use search USERSTAT string in your .prg files.

Happy HMG'ing :D

User avatar
Posts: 425
Joined: Fri Aug 01, 2008 6:03 pm
Location: uruguay
Has thanked: 96 times
Been thanked: 87 times

Post by apais »

One of the other programs in the hbp list "tools1" also calls this same
"userstat" routine in one of it's functions. In both cases, it is called with a
simple "do userstat"
do userstat is obsolete
simply call it with: userstat()

Angel Pais
Web Apps consultant/architect/developper.
HW_apache (webserver modules) co-developer.
HbTron (Html GUI for harbour desktop hybrid apps) co-developer.

Posts: 32
Joined: Wed Dec 29, 2010 5:12 pm
Location: Tennessee / USA

Post by DenCo »

Hi Esgici,,,

Yes,, I have used the "kiss" method always.

Here is what's going on..... I actually do know how to do this correctly, but an unusual situation has occurred.

As you might remember my last posts a couple of weeks ago,, I have had an unusual situation happen.

I have a factory (customer) that has moved to win7 enterprise(64) about 6 months ahead of schedule.

So,, what I have been doing is Forcing these programs they have used for years into HB to keep them going. It has worked. In this case, I had to do it FAST !

I have a couple more to force into production, and my last post was about one of those.

I do intend to go back and clean them up, and convert over just as you described...

However, I have learned a lot making the "old way" work...

I did create libs ".a" files not because I thought it was fun,, it was because I had to have them...

I pulled some of the old grumpfish library programs I use and re-made them,, and I built PS32 because I needed to replace the old ESCAPE printer library.

Also,, PS32 (newest version, 3.03 needs more work than Victor's current "Diff" file.)

I wanted to tell you this,, because in all of the posts I'm making here on this forum,, I'm doing what I'm doing this way because I have to right now !

When I get done with this "emergency",,, I will be progressing with topics that are a lot more fun.

Thank You

Posts: 32
Joined: Wed Dec 29, 2010 5:12 pm
Location: Tennessee / USA

Post by DenCo »

Hi Angel,,,,

I wanted to tell you that your suggestion works.

In this case, the "userstat" routine is compiled in the main program with the "do",, but it is not called again from the tools* area,,, only referenced with the () ...

It compiles and operates correctly. Please notice my reply to Esgici,, I'm only doing this the way I am right now because I have to for time reasons.

Thank you,,,

Post Reply