Opened 12 years ago

Closed 12 years ago

#1 closed enhancement (fixed)

Watcom builds to work

Reported by: abwillis Owned by: bsmith
Priority: major Milestone:
Component: component1 Version:
Keywords: Cc:

Description

The following diff and files allow build to work with dwtest built with Watcom as well... the DLLs from VAC will not work with this dwtest nor will the dwtest from VAC work with the DLLs from Watcom. For that the exported functions will need to have a calling convention setup... probably _System would be best.

Attachments (2)

dw.lnk (12.2 KB) - added by abwillis 12 years ago.
dwcompat.lnk (766 bytes) - added by abwillis 12 years ago.

Download all attachments as: .zip

Change History (32)

comment:1 Changed 12 years ago by abwillis

Index: makefile.wpm
===================================================================
--- makefile.wpm	(revision 1409)
+++ makefile.wpm	(working copy)
@@ -5,20 +5,43 @@
 #===================================================================
 OS22_H = $(%WATCOM)\h\os2
 CFLAGS  = -i=os2 -i=$(OS22_H) -bt=OS2 -zq -d2 -bd
+TOOLKIT = e:\os2tk45
+TLKTLIB = $(TOOLKIT)\LIB

 .SUFFIXES:
 .SUFFIXES: .obj .c
 .c.obj: .AUTODEPEND
 	wcc386 $(CFLAGS) $*.c

-all:	dw.dll dwcompat.dll
+all:	dw.dll dwcompat.dll dwtest.exe

-dwcompat.dll: compat.obj
-	wlink name dwcompat.dll system os2v2_pm d a library so32dll,tcp32dll option symf f $[@
+dwcompat.dll: dirent.obj compat.obj
+	wlink @os2\dwcompat.lnk name dwcompat.dll system os2v2_dll d a library $(TLKTLIB)\so32dll,$(TLKTLIB)\tcp32dll option implib=dwcompat option symf f $[@ f compat
+	copy dwcompat.lib lib

+dirent.obj:
+	wcc386 $(CFLAGS) os2\dirent.c
+
 dw.dll: dw.obj
-	wlink name dw.dll system os2v2_pm d a option symf f $[@
+	wlink @os2\dw.lnk name dw.dll system os2v2_dll d a library $(TLKTLIB)\so32dll,$(TLKTLIB)\tcp32dll option implib=dw option symf f $[@
+	copy dw.lib lib

 dw.obj: os2\dw.c
 	wcc386 $(CFLAGS) os2\dw.c

+dwtest.exe: dwtest.obj
+	wlink name dwtest.exe system os2v2_pm d a library lib\dw.lib,lib\dwcompat.lib option symf f $[@
+
+dwtest.obj:
+	wcc386 /DOS2 -i=os2 -i=$(OS22_H) -bt=OS2 -zq -d2 dwtest.c
+
+clean:
+	@if exist *.obj del *.obj
+	@if exist *.sym del *.sym
+	@if exist *.lib del *.lib
+	@if exist *.dll del *.dll
+	@if exist *.exe del *.exe
+	@if exist lib\*.lib del lib\*.lib
+
+
+
Index: platform/dirent.h
===================================================================
--- platform/dirent.h	(revision 1409)
+++ platform/dirent.h	(working copy)
@@ -25,7 +25,12 @@
 # define A_DIR     0x10
 # define A_ARCHIVE 0x20
 #endif
-
+#ifdef __WATCOMC__
+#undef DIR
+#undef direct
+#undef dirent
+#define DIR DIRW
+#endif
 struct dirent {
     int            d_ino;                 /* Dummy */
     int            d_reclen;		  /* Dummy, same as d_namlen */
Index: os2/dirent.c
===================================================================
--- os2/dirent.c	(revision 1409)
+++ os2/dirent.c	(working copy)
@@ -8,6 +8,12 @@
 #include "compat.h"
 #include <errno.h>

+#ifdef __WATCOMC__
+#include "platform\dirent.h"
+typedef struct _dirdescr DIRW;
+#define DIR DIRW
+#endif
+
 # define FFBUF	FILEFINDBUF3
 # define Word	ULONG
   /*
Last edited 12 years ago by abwillis (previous) (diff)

Changed 12 years ago by abwillis

Attachment: dw.lnk added

Changed 12 years ago by abwillis

Attachment: dwcompat.lnk added

comment:2 Changed 12 years ago by abwillis

Dwtest did launch but crashed after changing a tab or two... I do not claim this is the best way to do this, nor even necessarily the right way but it was what I was able to get working. After adding the Calling Conventions the lnk files will have to be updated.

comment:3 Changed 12 years ago by bsmith

Thanks I'll try to get this patch worked in with _System calling conventions... there is a #define for API that will specify the calling convention... I'll define this to _System for watcom and see if it works. I haven't really used Watcom much so will have to figure it out.

comment:4 Changed 12 years ago by bsmith

Thanks... I was able to get it all to build with your patches... and after debugging it it seems that the parameters are getting passed improperly which suggests calling convention issues to me.... which is why it is crashing. Hopefully I'll be able to figure out how to specify _System with Watcom shortly and have these changes committed to the repository.

comment:5 Changed 12 years ago by bsmith

Ok so... I have made modifications to get everything building and functioning with the _System calling convention... the only trouble is the changes make the code no longer compile with VisualAge?. The problem is with the definition of the function pointers...

Function pointer definition that works with VisualAge?:

void (* _System somefunc)(void)

Function pointer definition that works with Watcom:

void (_System * somefunc)(void)

Both of these work with gcc 4.4.

Not sure what the best way to handle this would be.

comment:6 Changed 12 years ago by bsmith

Ok so... one last followup. The code only has issues in VisualAge? 3.0... 3.6 seems to work ok.... so thinking I may require VisualAge? 3.6 from now on.... could let me use the safer vsnprintf functions as well.

comment:7 Changed 12 years ago by abwillis

I've mostly had to deal with calling convention issues with GCC but always used the second with it so had not realized that VAC did it differently. I don't recall if VAC uses Optlink or _System by default. If it uses _System by default then it may be possible to use the second for gcc and Watcom and not specify it for VAC to that all three would be compatible. Also wrote the above while you were posting the last comment and most of my work with VAC was with 365 so may also be why I had not seen it before (or at least forgotten it as I do have a vague recollection of something several years ago along those lines).

comment:8 Changed 12 years ago by abwillis

A statement by Mike Kaply in a Mozilla bug says that VAC uses Optlink by default.

comment:9 Changed 12 years ago by abwillis

GCC should also have _System defined as it uses cdecl by default (emx uses _System by default but the newer GCCs do not).

comment:10 Changed 12 years ago by bsmith

Well the issue wasn't the lack of _System ... on OS/2 all exported functions and all function pointers passed in need to be using the _System calling convention. So when a function pointer gets passed to my APIs I create a function pointer defined as _System ... and the VisualAge? 3.0 and Watcom accepted the _System declaration in those constructs on different sides of the "*" ... it appears that the Watcom way is the correct way and it seems that it was corrected in 3.6. GCC accepted _System on both sides of the * so it would always work for GCC.

There does seem to be another issue I am running into and it is a bit hard to debug... it seems that when I was testing it was using the VAC compiled version of the DLLs and working... however when using the Watcom versions it is dying when trying to call WinSubclassWindow?().

comment:11 Changed 12 years ago by abwillis

I find a consistent crash (didn't maybe once) when I click on "A button from data" on the buttons tab, I don't know if it is using the WinSubclassWindow?() or if it is a different issue. I get an occasional crash when I forget to turn off the beep and change tabs and then switch back to the "buttons and entry" tab to turn it off. I have successfully tested a VAC built exe with the Watcom DLLs and vice versa. In any build scenario the Watcom built DLLs are the only ones that crash as the above. If it is easier to deal with, the LNK files do not have to have the second =internal name entries if they are the same as the export name... I had to add them initially for the appended _ (i.e. export makedir.20=makedir can be just export makedir.20 if it is easier to maintain). The GCC comment above was from my seeing this:

# if (defined(IBMC)
defined(WATCOMC) defined(_System)) && !defined(API)

which I had taken to mean that GCC would not then have API defined as _System.

comment:12 Changed 12 years ago by bsmith

Oh ... hmm I figured gcc was getting picked up with the defined(_System) but I didn't actually test. I know it is using the _System calling convention with gcc ... not sure if that is because it defaults to it or if it is picking up API _System from the defined(_System) check.

comment:13 Changed 12 years ago by abwillis

I just built with GCC (the other day I had some odd problem trying to build but worked now) and a Watcom built dwtest worked with the GCC built DLLs so must be using _System as from the defined(_System) - it defaults to cdecl, that much I am familiar with. Built with GCC 4.5.2.

comment:14 Changed 12 years ago by abwillis

I got to thinking, if you want to keep VA 3.0 then API2 could be defined for VAC 3.0 behind the star such that only API or API2 is defined. void API * API2 somefunc(void) I don't know that VAC 3.0 is that big of a deal or not.

comment:15 Changed 12 years ago by bsmith

Well I have been wanting to move away from VAC for a while now... I'd prefer to use gcc for everything personally... however new versions of gcc bring the libc06x.dll depencency which I am trying to avoid, and VAC allows me to statically link libc. Building with watcom would work if I can figure out what is causing the instability, although I'd probably still use VAC and gcc during development since I prefer their development tools.

comment:16 Changed 12 years ago by bsmith

I discovered a problem with _System location for the PMPrintf call.. it seemed to be causing the instability here... do you have PMPrintf installed? If so get the latest revision and let me know if it resolves the instability.

comment:17 Changed 12 years ago by abwillis

I don't recall having installed it... I may have at some point though so will get the newer version. The _System issue fixed the crash I had with the button but I find if I do not turn off the beep then I can't move around to much to other tabs before it will crash. If I turn off the beep then it doesn't crash. Looks like if I don't turn off the beep then it will crash shortly after the first beep.

comment:18 Changed 12 years ago by abwillis

I do have pmprintf on the system, it is the latest I can find of March 09. Because of where it is at it shouldn't be being seen by the system as I don't have the path in any library path.

comment:19 Changed 12 years ago by bsmith

I see the crash you are talking about.... I can't really explain it though... I have a small _beepthread() function to make the beep sound without blocking execution... the second time it gets called the application dies. The calling convention does not appear to be an issue there. Execution does not even appear to make it into the passed function the second time when it crashes. Which indicates to me it is crashing in the CRT... but why? and why does it only happen the second time? I am a bit perplexed... (I instinctively click that button to stop the beeping because it drives me crazy) ;)

comment:20 Changed 12 years ago by abwillis

I found that I should have added -bm to the CFLAGS (and the dwtest compiler options) to use the multi-threaded libraries but that did not stop the crash. I thought it might have been a stack issue but increasing the stack size has not yet yielded any helpful results. I did while trying to find some ideas as to what would cause it come across this bit about the calling convention issue:

  • Check that the calling convention definition for function

pointers is correct for the used compiler. IBM for instance uses some strange non-common definition for functions which caused me quite some headaches to find it:

#if defined(IBMC)
defined(IBMCPP)

#define SQL_API_FUNC ( * _System ) #else #define SQL_API_FUNC ( _System * ) #endif

comment:21 Changed 12 years ago by abwillis

The following diff fixes the crash:

Index: makefile.wpm
===================================================================
--- makefile.wpm	(revision 1411)
+++ makefile.wpm	(working copy)
@@ -4,8 +4,8 @@
 #
 #===================================================================
 OS22_H = $(%WATCOM)\h\os2
-CFLAGS  = -i=os2 -i=$(OS22_H) -bt=OS2 -zq -d2 -bd
-TKPATH=C:\Toolkit
+CFLAGS  = -i=os2 -i=$(OS22_H) -bm -bt=OS2 -zq -d2 -bd
+TKPATH=e:\os2tk45
 TLKTLIB = $(TKPATH)\LIB
 
 .SUFFIXES:
@@ -16,28 +16,29 @@
 all:	dw.dll dwcompat.dll dwtest.exe
 
 dwcompat.dll: dirent.obj compat.obj
-	wlink @os2\dwcompat.lnk name dwcompat.dll system os2v2_dll d a library $(TLKTLIB)\so32dll,$(TLKTLIB)\tcp32dll option implib=dwcompat option symf f $[@ f compat
+	wlink @os2\dwcompat.lnk name dwcompat.dll system os2v2_dll d a library $(TLKTLIB)\so32dll,$(TLKTLIB)\tcp32dll option implib=dwcompat option map option symf f $[@ f compat
 	copy dwcompat.lib lib
 
 dirent.obj:
 	wcc386 $(CFLAGS) os2\dirent.c
 
 dw.dll: dw.obj
-	wlink @os2\dw.lnk name dw.dll system os2v2_dll d a option implib=dw option symf f $[@
+	wlink @os2\dw.lnk name dw.dll system os2v2_dll d a option implib=dw option map option symf f $[@
 	copy dw.lib lib
 
 dw.obj: os2\dw.c
 	wcc386 $(CFLAGS) os2\dw.c
 
 dwtest.exe: dwtest.obj
-	wlink name dwtest.exe system os2v2_pm d a library lib\dw.lib option symf f $[@
+	wlink name dwtest.exe system os2v2_pm d a library lib\dw.lib option symf option map f $[@
 
 dwtest.obj:
-	wcc386 /DOS2 -i=os2 -i=$(OS22_H) -bt=OS2 -zq -d2 dwtest.c
+	wcc386 /DOS2 -i=os2 -i=$(OS22_H) -bm -bt=OS2 -zq -d2 dwtest.c
 
 clean:
 	@if exist *.obj del *.obj
 	@if exist *.sym del *.sym
+	@if exist *.map del *.map
 	@if exist *.lib del *.lib
 	@if exist *.dll del *.dll
 	@if exist *.exe del *.exe
Index: os2/dw.c
===================================================================
--- os2/dw.c	(revision 1411)
+++ os2/dw.c	(working copy)
@@ -9734,7 +9734,7 @@
       info[0] = freq;
       info[1] = dur;
 
-      _beginthread(_beepthread, NULL, 100, (void *)info);
+      _beginthread(_beepthread, NULL, 8192, (void *)info);
    }
 }
 

It is possible this one should be increased as well but I don't know what hits it to test that: void API dw_percent_set_pos(HWND handle, unsigned int position) {

/* OS/2 doesn't really support indeterminate... */ if(position == DW_PERCENT_INDETERMINATE) {

if(!dw_window_get_data(handle, "_dw_ind")) {

/* So we fake it with a thread */ dw_window_set_data(handle, "_dw_ind", (void *)1); _beginthread(_percentthread, NULL, 100, (void *)handle);

}

This is from the toolkit reference: stack_size The size of the stack, in bytes, that is to be allocated for the new thread. The stack size should be a nonzero multiple of 4K and a minimum of 8K. Memory is used when needed, one page at a time.

http://www.warpspeed.com.au/cgi-bin/inf2html.cmd?..\html\book\Toolkt40\XPG4REF.INF+69

comment:22 Changed 12 years ago by bsmith

I added -sg which is an option to automatically grow the stack and it seems to fix the crashes in _beginthread() ... got the idea from reading this thread:

http://lists.harbour-project.org/pipermail/harbour/2008-November/013467.html

I came up with a slightly different fix...

comment:23 Changed 12 years ago by abwillis

The -sg didn't fix it here, though I only had tried it on the executable and not the DLLs as I had read that -sg did not work for beginlibthread so stopped pursuing that angle. Should still probably add the -bm and map file additions to the makefile.

Was about to post but it collided with yours: Is that second code snippet hit when the "A button from data" is pressed? As it seems to be running a percentage bar at the bottom I thought it might. I just had it crash again and so if it is also calling a _beginthread that could explain why I sometimes get crashes there. Increased it and have been able to use it several times but as it was more intermittent it is harder to tell for sure that increasing it actually did resolve it.

comment:24 Changed 12 years ago by abwillis

With -sg on the DLLs it does indeed help... I had seen the harbour list but had not put the -sg in the right place.

comment:25 Changed 12 years ago by bsmith

Added your makefile changes and added a API_FUNC that is defined differently for VAC so it should probably build with VAC30 again now... although I've switched my build system to 3.6 for now.

comment:26 Changed 12 years ago by abwillis

Just to confirm compatibility... I copied the Watcom built DLLs over for HandyFtp? to use and they are working there at least enough for basics, didn't thoroughly test it.

comment:27 Changed 12 years ago by bsmith

Yeah I tested like that and with a couple other of my apps... including the interface builder application I am working on ... no problems since I added -sg to the compile flags.

comment:28 Changed 12 years ago by bsmith

Owner: changed from somebody to bsmith
Status: newaccepted

comment:29 Changed 12 years ago by bsmith

Will leave the ticket open for a few days in case any new issues pop up and then close it as fixed. :)

comment:30 Changed 12 years ago by bsmith

Resolution: fixed
Status: acceptedclosed
Note: See TracTickets for help on using tickets.