pawn icon indicating copy to clipboard operation
pawn copied to clipboard

Some 64 bit defines appear to be set to default on 32 bit MSVC builds

Open pbartruff opened this issue 2 years ago • 1 comments

Summary

It seems a 64 bit define exists somewhere in the 32bit default build using msvc. I hard edited amxfile.c to use _stat vs __stat that was being defined and I had to add three #undef's to amx.h to ensure some 64bit checks were not getting called in amx.c.

I am not sure if these FIXES are the correct solution, thus no PR! However, I wanted to take the time and elaborate on the steps I took to resolve the issue. It's a pretty long writeup.

Error while building 32bit version

cmake -DCMAKE_INSTALL_PREFIX=..\..\..\libraries\amx -DCMAKE_BUILD_TYPE=Debug \
-DDYNCALL_INCLUDE_DIR=..\..\..\libraries\dyncall\include \
-DDYNLOAD_INCLUDE_DIR=..\..\..\libraries\dyncall\include \
-DDYNCALL_LIBRARIES=..\..\..\libraries\dyncall\lib\dyncall_s.lib \
-DDYNCALL_EXTRA_LIBRARY=..\..\..\libraries\dyncall\lib\dynload_s.lib ..

D:\Development\repos\pawn\working>cmake --build .
[ 29%] Built target pawncc
[ 33%] Built target stategraph
[ 37%] Built target pawndisasm
[ 41%] Built target amxTime
[ 46%] Built target amxArgs
[ 51%] Built target amxDGram
[ 53%] Building C object amx/CMakeFiles/amxFile.dir/amxfile.c.obj
amxfile.c
D:\Development\repos\pawn\amx\amxfile.c(717): error C2079: 'stbuf' uses undefined struct '__stat'
D:\Development\repos\pawn\amx\amxfile.c(718): warning C4133: 'function': incompatible types - from 'int *' to '_stat64i32 *'
D:\Development\repos\pawn\amx\amxfile.c(720): error C2224: left of '.st_mode' must have struct/union type
D:\Development\repos\pawn\amx\amxfile.c(893): error C2079: 'stbuf' uses undefined struct '__stat'
D:\Development\repos\pawn\amx\amxfile.c(894): warning C4133: 'function': incompatible types - from 'int *' to '_stat64i32 *'
D:\Development\repos\pawn\amx\amxfile.c(898): error C2224: left of '.st_size' must have struct/union type
D:\Development\repos\pawn\amx\amxfile.c(900): error C2224: left of '.st_mtime' must have struct/union type
D:\Development\repos\pawn\amx\amxfile.c(902): error C2224: left of '.st_mode' must have struct/union type
D:\Development\repos\pawn\amx\amxfile.c(904): error C2224: left of '.st_ino' must have struct/union type
NMAKE : fatal error U1077: 'C:\PROGRA~2\MICROS~2\2019\PROFES~1\VC\Tools\MSVC\1429~1.300\bin\Hostx86\x86\cl.exe' : return code '0x2'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30037\bin\HostX86\x86\nmake.exe"' : return code '0x2'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30037\bin\HostX86\x86\nmake.exe"' : return code '0x2'
Stop.

Okay looks like stbuf is the wrong type

 713     #if defined _WIN64
 714       struct __stat64 stbuf;
 715       _tstat64(fullname, &stbuf);
 716     #else
 717       struct t_stat stbuf;
 718       _tstat(fullname, &stbuf);
 719     #endif

stat, _stat, __stat

Given this project is cross platform, I am not surprised that amxfile.c has an exceptionally confusing set of defines between lines 30-129. The lines that seem to be of interest are between 110 and 116, specifically line 114:

 110   #elif defined __WIN32__
 111     #if defined __WATCOMC__
 112       #define t_stat    _stat
 113     #else
 114       #define t_stat    __stat
 115     #endif
 116   #else

Troubleshooting

Reading tchar.h and stat.h, it looks like 114 should be "_stat". So, if I explicitly edit this line and rebuild, it will build; however, there is a warning: D:\Development\repos\pawn\amx\amx.c(1936): warning C4293: '>>': shift count negative or too big, undefined behavior

This warning makes me something is still wonky with a 64 bit define somewhere!

1934         #if defined _I64_MAX || defined __x86_64__ || defined HAVE_I64
1935           /* for 64-bit version the high part of the pointer must be stored too */
1936           func->nameofs=(uint32_t)((intptr_t)funcptr >> 32);
1937         #endif

The default defines for me in cmake are the following, so I am not seeing any 64bit stuff CMAKE_C_FLAGS: /DWIN32 /D_WINDOWS /W3 CMAKE_CXX_FLAGS: /DWIN32 /D_WINDOWS /W3 /GR /EHsc

To get around all this I added the following undefs to amx.h #undef _I64_MAX #undef x86_64 #undef HAVE_I64

It builds completely, with a couple of warnings in ezxm.c for type conversions, but they do not seem to be related to bit-ness issues.

Again, not sure if this is the correct approach as my depth with the entire source is still relatively limited.

pbartruff avatar Oct 03 '21 23:10 pbartruff

the whole posix thing is a big mess on windows tbh (especially with unicode considerations), the proper solution would probably be just making a separate implementation of every primitive for windows and posix. Also should just drop non-unicode windows, dont think anyone cares about windows 98 in current year. Additionally, most windows apis still have the 260 MAX_PATH limit even though it can be disabled in windows now

namazso avatar Oct 21 '21 20:10 namazso