Compiling Notes
These are some set of light notes I took while trying to compile some old PM samples on 2023. My goal was to see how some PM samples can be compiled with open source tools like gcc, wrc, wl and make.
Environment
RPM Packages
I always confuse the RPM packages that I use to compile things with GCC. I want to use as much as open source tools available. Here it is what I install:
- yum install git gcc make libc-devel binutils
- watcom-wrc
- watcom-wlink-hll
Checking the Environments
Execute %INCLUDE% and see if something shows up.
PM Code Errors/Warnings with GCC
CHAR * {aka char *}
- Warning
gcc -Wall -Zomf -c -O2 bitcat2.c -o bitcat2.obj bitcat2.c: In function 'main': bitcat2.c:36:29: warning: pointer targets in passing argument 2 of 'WinRegisterClass' differ in signedness [-Wpointer-sign] 36 | WinRegisterClass(hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0); | | | | CHAR * {aka char *} In file included from W:/usr/include/os2.h:39, from bitcat2.c:4: W:/usr/include/os2emx.h:6138:47: note: expected 'PCSZ' {aka 'const unsigned char *'} but argument is of type 'CHAR *' {aka 'char *'}
- Fix
I replaced
static CHAR szClientClass[] = "BitCat2";
for
unsigned char szClientClass[] = "BitCat2";
and warnings were removed.
'WinCreateStdWindow' makes integer from pointer without a cast [-Wint-conversion]
vectfont.c:33:38: warning: passing argument 7 of 'WinCreateStdWindow' makes integer from pointer without a cast [-Wint-conversion] 33 | NULL, ID_RESOURCE, &hwndClient) ; | ^~~~ | | | void *
- Fix
I replaced the NULL by 0
weakld: error: Unresolved symbol (UNDEF) '_max' '_min'
- Error
weakld: error: Unresolved symbol (UNDEF) '_max'. weakld: info: The symbol is referenced by: C:\dev\DEV-SAMPLES-PM-VectFont\vf00.obj C:\dev\DEV-SAMPLES-PM-VectFont\vf14.obj weakld: error: Unresolved symbol (UNDEF) '_min'. weakld: info: The symbol is referenced by: C:\dev\DEV-SAMPLES-PM-VectFont\vf00.obj C:\dev\DEV-SAMPLES-PM-VectFont\vf05.obj C:\dev\DEV-SAMPLES-PM-VectFont\vf14.obj Ignoring unresolved externals reported from weak prelinker. Warning! W1058: file ldgVmPcu.: line(35): protmode option not valid for an OS/2 EMX executable Error! E2028: _max is an undefined reference Error! E2028: _min is an undefined reference file C:\dev\DEV-SAMPLES-PM-VectFont\vf00.obj(vf00.obj): undefined symbol _max file C:\dev\DEV-SAMPLES-PM-VectFont\vf00.obj(vf00.obj): undefined symbol _min
- Fix
Include to the .H file the following missing:
#ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif
weakld: error: Unresolved symbol (UNDEF)
- Error
weakld: error: Unresolved symbol (UNDEF)
- Fix
Removed this from .def
EXPORTS OBJECTWINPROC CLIENTWINPROC
weakld: error: Unresolved symbol (UNDEF) '_CSPCSTA4'.
- Error
weakld: error: Unresolved symbol (UNDEF) '_CSPCSTA4'. file C:\dev\5TRYING\UTIL-FILE-NewFileManager\nfm.obj(nfm.c): undefined symbol _CSPCSTA4
- Fix
Need a leading underscore in the export in cspcsta4.def,
EXPORTS _CSPCSTA4 @1
'WinSendMsg' makes pointer from integer without a cast
- Warning
vectfont.c:36:18: warning: passing argument 3 of 'WinSendMsg' makes pointer from integer without a cast [-Wint-conversion] 36 | WinQuerySysPointer (HWND_DESKTOP, SPTR_APPICON, FALSE), | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | HPOINTER {aka long unsigned int} In file included from C:/usr/include/os2.h:39, from vectfont.c:7: C:/usr/include/os2emx.h:5819:59: note: expected 'MPARAM' {aka 'void *'} but argument is of type 'HPOINTER' {aka 'long unsigned int'} 5819 | MRESULT APIENTRY WinSendMsg (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2); | ~~~~~~~^~~
- Fix
Changed:
WinSendMsg (hwndFrame, WM_SETICON, WinQuerySysPointer (HWND_DESKTOP, SPTR_APPICON, FALSE), NULL) ;
To:
WinSendMsg (hwndFrame, WM_SETICON, (MPARAM) WinQuerySysPointer (HWND_DESKTOP, SPTR_APPICON, (BOOL) FALSE), NULL) ;
warning: pointer targets in passing argument 4 of 'GpiCharStringAt' differ in signedness
- Warning
vf01.c: In function 'Display_24Point': vf01.c:44:38: warning: pointer targets in passing argument 4 of 'GpiCharStringAt' differ in signedness [-Wpointer-sign] 44 | szFacename[iFont]) ; | ~~~~~~~~~~^~~~~~~ | | | CHAR * {aka char *} In file included from C:/usr/include/os2.h:39, from vf01.c:6: C:/usr/include/os2emx.h:9050:11: note: expected 'PCCH' {aka 'const unsigned char *'} but argument is of type 'CHAR *' {aka 'char *'} 9050 | PCCH pchString); | ~~~~~^~~~~~~~~
- Fix
Changed
GpiCharStringAt (hps, &ptl, (LONG) strlen (szFacename[iFont]), szFacename[iFont]) ;
to
GpiCharStringAt (hps, &ptl, (LONG) strlen (szFacename[iFont]), (PCCH) szFacename[iFont]) ;
warning: pointer targets in passing argument 3 of 'GpiCharString' differ in signedness [-Wpointer-sign]
- Warning
vf01.c:46:36: warning: pointer targets in passing argument 3 of 'GpiCharString' differ in signedness [-Wpointer-sign] 46 | GpiCharString (hps, 10L, " - abcdefg") ; | ^~~~~~~~~~~~ | | | char * In file included from C:/usr/include/os2.h:39, from vf01.c:6: C:/usr/include/os2emx.h:9048:57: note: expected 'PCCH' {aka 'const unsigned char *'} but argument is of type 'char *' 9048 | LONG APIENTRY GpiCharString (HPS hps, LONG lCount, PCCH pchString); | ~~~~~^~~~~~~~~
- Fix
Changed
GpiCharString (hps, 10L, " - abcdefg") ;
to
GpiCharString (hps, 10L, (PCCH) " - abcdefg") ;
warning: missing braces around initializer
- Warning
vectfont.c:55:34: warning: missing braces around initializer [-Wmissing-braces] 55 | vectfont [] = { | ^
- Fix
Changed
vectfont [] = { IDM_NOTHING, NULL, IDM_24POINT, Display_24Point, IDM_MIRROR, Display_Mirror, IDM_STRETCH, Display_Stretch, IDM_CHARANGLE, Display_CharAngle, IDM_ROTATE, Display_Rotate, IDM_CHARSHEAR, Display_CharShear, IDM_SHADOW, Display_Shadow, IDM_HOLLOW, Display_Hollow, IDM_DROPSHADOW, Display_DropShadow, IDM_BLOCK, Display_Block, IDM_NEON, Display_Neon, IDM_FADE, Display_Fade, IDM_SPOKES, Display_Spokes, IDM_WAVY, Display_Wavy, IDM_MODSPOKES, Display_ModSpokes } ;
To
vectfont [] = { {IDM_NOTHING, NULL}, {IDM_24POINT, Display_24Point}, {IDM_MIRROR, Display_Mirror}, {IDM_STRETCH, Display_Stretch}, {IDM_CHARANGLE, Display_CharAngle}, {IDM_ROTATE, Display_Rotate}, {IDM_CHARSHEAR, Display_CharShear}, {IDM_SHADOW, Display_Shadow}, {IDM_HOLLOW, Display_Hollow}, {IDM_DROPSHADOW, Display_DropShadow}, {IDM_BLOCK, Display_Block}, {IDM_NEON, Display_Neon}, {IDM_FADE, Display_Fade}, {IDM_SPOKES, Display_Spokes}, {IDM_WAVY, Display_Wavy}, {IDM_MODSPOKES, Display_ModSpokes} } ;
expected '=', ',', ';', 'asm' or '__attribute__' before
- Error
APP.h:26:20: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'KidWndProc' 26 | MRESULT FAR PASCAL KidWndProc ( HWND, USHORT, MPARAM, MPARAM );
- Fix
Changed
MRESULT FAR PASCAL KidWndProc ( HWND, USHORT, MPARAM, MPARAM );
to
MRESULT EXPENTRY KidWndProc ( HWND, USHORT, MPARAM, MPARAM );
MIN / MAX Missing
- Warning
atccnr.c: In function 'CnrSubclassWndProc': atccnr.c:768:33: warning: implicit declaration of function 'min'; did you mean ' main'? [-Wimplicit-function-declaration] 768 | arcp.lP = arcp.lQ = min (rclCnr.xRight, rclCnr.yTop) / 9; | ^~~ | main make: *** No rule to make target `-o', needed by `atccnr.exe'. Stop.
- Fix
Include to the .H file the following missing:
#ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif
Seems like an old .H file that came with OS/2 used to have that declared and now is missing.
line(20): protmode
- Warning
Warning! W1058: file ldSBPZPt.: line(20): protmode option not valid for an OS/2 EMX executable
- Fix
Check the protmode on the .def file. In this case it was empty so I removed it. It was not needed.
returning 'int' from a function with return type 'MRESULT'
- Warning
randrect.c:90:28: warning: returning 'int' from a function with return type 'MRESULT' {aka 'void *'} makes pointer from integer without a cast [-Wint-conversion] 90 | return 1 ; | ^
- Fix
Changed
return 1 ;
for
return (MRESULT) TRUE
- Fix2
Change for:
return ((MRESULT)TRUE) ;
warning: comparison between pointer and integer
- Warning
randrect.c:47:20: warning: comparison between pointer and integer 47 | if (hwndFrame != NULL)
- Fix
Changed
if (hwndFrame != NULL)
to
if (hwndFrame != '\0')
UNDEF
- Warning
gcc -Zomf atccnr.obj atccnr.res atccnr.def -o atccnr.exe weakld: error: Unresolved symbol (UNDEF) 'ClientWndProc'. weakld: info: The symbol is referenced by: C:/dev/DEV-SAMPLES-PM-Air_Traffic_Control_Container/atccnr.DEF Error! E2028: ClientWndProc is an undefined reference Error! E2044: exported symbol ClientWndProc not found make: *** [atccnr.exe] Error 1
- Fix
Removed the EXPORTS from "atccnr.DEF".
warning: format '%ld' expects argument of type 'long int'
- Warning
atccnr.c:485:30: warning: format '%ld' expects argument of type 'long int', but argument 4 has type 'int' [-Wformat=] 485 | sprintf (szBuf, "%s%ld", apszCallSignPrefixes [rand() % cPrefixes], | ~~^ | | | long int | %d 486 | rand() % 1000); | ~~~~~~~~~~~~~ | | | int
- Fix
Changed
sprintf (szBuf, "%s%ld", apszCallSignPrefixes [rand() % cPrefixes], rand() % 1000);
to
sprintf (szBuf, "%s%d", apszCallSignPrefixes [rand() % cPrefixes], rand() % 1000);
warning: pointer targets in initialization of 'unsigned char *'
- Warning
atccnr.c: In function 'InsertContainerRecords': atccnr.c:437:50: warning: pointer targets in initialization of 'unsigned char *' from 'char *' differ in signedness [-Wpointer-sign] 437 | static const PSZ apszCallSignPrefixes [] = { "AA", "DA", "UA", "TW" }; | ^~~~ atccnr.c:437:50: note: (near initialization for 'apszCallSignPrefixes[0]') atccnr.c:437:56: warning: pointer targets in initialization of 'unsigned char *' from 'char *' differ in signedness [-Wpointer-sign] 437 | static const PSZ apszCallSignPrefixes [] = { "AA", "DA", "UA", "TW" }; | ^~~~ atccnr.c:437:56: note: (near initialization for 'apszCallSignPrefixes[1]') atccnr.c:437:62: warning: pointer targets in initialization of 'unsigned char *' from 'char *' differ in signedness [-Wpointer-sign] 437 | static const PSZ apszCallSignPrefixes [] = { "AA", "DA", "UA", "TW" }; | ^~~~ atccnr.c:437:62: note: (near initialization for 'apszCallSignPrefixes[2]') atccnr.c:437:68: warning: pointer targets in initialization of 'unsigned char *' from 'char *' differ in signedness [-Wpointer-sign] 437 | static const PSZ apszCallSignPrefixes [] = { "AA", "DA", "UA", "TW" }; | ^~~~ atccnr.c:437:68: note: (near initialization for 'apszCallSignPrefixes[3]')
- Fix
All these signed/unsigned character warnings can be resolved by adding "-DOS2EMX_PLAIN_CHAR" to the compiler flags. See 'os2emx.h' for details.
gcc -Wall -Zomf -DOS2EMX_PLAIN_CHAR -c -O2 atccnr.c -o atccnr.obj
cdecl - error: expected '=', ',', ';', 'asm' or '__attribute__' before 'main'
- Error
browse.h:12:11: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'main' 12 | int cdecl main(int, char *[]); | ^~~~
- Fix
Changed
int cdecl main(int, char *[]);
to
int _cdecl main(int, char *[]);
VOID Main issue
- Error
Issue on main
- Fix
Changed
VOID main( VOID )
to
int main( VOID )
warning: return type of 'main' is not 'int' [-Wmain]
- Error
pmstars.c:7:6: warning: return type of 'main' is not 'int' [-Wmain]
7 | void main(int argc, char *argv[]) { | ^Martini (talk)
pmstars.c: In function 'ClientWndProc':
- Fix
Changed
void main(int argc, char *argv[]) {
to
int main(int argc, char *argv[]) { return 0;
warning: implicit declaration of function 'rand' [-Wimplicit-function-declaration]
- Error
game.c:48:17: warning: implicit declaration of function 'rand' [-Wimplicit-function-declaration] 48 | pgs->playx = rand()%35; | ^~~~
- Fix
It may be that you are forgetting some .h where the function is declared.
Included on game.c
#include <stdlib.h>
VOID _CDECL FAR runThread(PCALCPARM);
- Error
VOID _CDECL FAR runThread(PCALCPARM);
- Fix
Changed
VOID _CDECL FAR runThread(PCALCPARM);
to
VOID FAR runThread(PCALCPARM);
dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
- Error
pmcolour.c: In function 'DlgProc': pmcolour.c:116:23: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] 116 | *cwdata->rgb = *((RGB *) &mp1); | ~^~~~~~~~~~~~~
- Fix
Changed Added -O1 on the compile process to remove warning.
gcc -Wall -Zomf -c -O1 pmcolour.c -o pmcolour.obj
warning: missing braces around initializer [-Wmissing-braces]
- Error
clipbrd.c:160:25: warning: missing braces around initializer [-Wmissing-braces] 160 | DRIVDATA drvdata[] = {44L, 0L, "DISPLAY", 0L}; | ^ | { { }}
- Fix
Changed
DRIVDATA drvdata[] = {44, 0L, "DISPLAY", 0L};
for
DRIVDATA drvdata[] = {{44, 0, "DISPLAY", {0}}};
warning: suggest parentheses around assignment used as truth value [-Wparentheses]
- Error
show.c:107:9: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 107 | if ( rc = DirectScreenDisplay ( pbImageBottom, | ^~
- Fix
Changed
if ( rc = DirectScreenDisplay ( pbImageBottom, pbBMP + 14 + pbmfHeader->bmp2.cbFix, pbmfHeader->bmp2.cx, pbmfHeader->bmp2.cy ) )
for
if ( ( rc = DirectScreenDisplay ( pbImageBottom, pbBMP + 14 + pbmfHeader->bmp2.cbFix, pbmfHeader->bmp2.cx, pbmfHeader->bmp2.cy ) ))
Linkers
Change to WLINK
You need to add:
set EMXOMFLD_TYPE=WLINK set EMXOMFLD_LINKER=wl.exe
Remember that the Wacom Linker is "wl.exe" and is on the "watcom-wlink-hll" RPM package.
Resource Compiler
Change to WRC
You need to add:
SET EMXOMFLD_RC_TYPE=WRC SET EMXOMFLD_RC=wrc.exe
Remember that the Wacom Resource Compiler is "wrc.exe" and it is on the "watcom-wrc" RPM Package
Resource Compiler
- Error 1
Reading binary resource file walker.res (0) RC: error - Only integer TYPE allowed (). RC: 1 error detected make: *** [walker.exe] Error 1
- It is possible of an error on the SET INCLUDE directory. Type %INCLUDE% and check if it is pointing to the directory that contains OS2.H
- Error 2
[E:\PROJECTS\SAMPLEPACK\PMWALKER]make 2>&1 | tee make.out wrc -r walker.rc Open Watcom Windows and OS/2 Resource Compiler Version 2.0beta1 LA Portions Copyright (c) 1993-2002 Sybase, Inc. All Rights Reserved. Source code is available under the Sybase Open Watcom Public License. See http://www.openwatcom.org/ for details. walker.rc(2): Error! E062: Unable to open 'os2.h' make: *** [walker.res] Error 9
- It is possible of an error on the SET INCLUDE directory. Type %INCLUDE% and check if it is pointing to the directory that contains OS2.H
Make Samples
Generate DLL
- https://github.com/OS2World/DEV-SAMPLES-C-PM-edctl1/blob/master/makefile
- https://github.com/OS2World/UTIL-FILE-NewFileManager/blob/master/makefile
Generate / Link LIB
- https://github.com/OS2World/DEV-SAMPLES-C-PM-edctl1/blob/master/makefile
- https://github.com/OS2World/UTIL-FILE-NewFileManager/blob/master/makefile
Generate HLP
- https://github.com/OS2World/DEV-SAMPLES-C-PM-AirTrafficControlContainer/blob/master/makefile
- https://github.com/OS2World/DEV-SAMPLES-C-PM-framctl/blob/master/framctl1/makefile
- https://github.com/OS2World/DEV-SAMPLES-C-PM-Template/blob/main/makefile
Link MMPM - DIVE
Using DIFF
Yes, to catch the changes, something like cp makefile makefile.orig (could be makefile.bak or whatever), then after making changes,
diff -u makefile.orig makefile > makefile.patch
Can also do whole directories, cp newfilemanager/ newfilemanager.orig or such, then from above the directory,
diff -ru newfilemanager/ newfilemanager.orig/ > newfilemanager.diff
Which made a huge patch here. Make clean did not clean everything is the big problem, in both directories. There's other options such as -w to ignore white space, which IIRC includes line endings
diff --help | less to see all the options
There's also git diff, svn diff and such to create similar patches that can be applied much the same way tasking care with the -p parameter. Patch will let you know if it can't find the files to patch or ask about a reversed patch if already applied. Reversed patching undoes a patch, see the help.
ExeHDR
To remove the console on a previously compiled exe you can run
exehdr /PMTYPE:PM rocksndiamonds.exe
exehdr is provided with the IBM OS/2 Toolkit.