c-chess-cli: experimental windows support

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

c-chess-cli: experimental windows support

Post by lucasart »

Largely copy/pasted from gomoku-cli code written Haobin Duan (dhbloo).

I don't have a Windows machine to test it. But I'm interested if someone can give it a try.

Either from Linux, or (untested) from an msys2 shell on Windows:

Code: Select all

git clone https://github.com/lucasart/c-chess-cli.git
cd ./c-chess-cli
./make.py -c x86_64-w64-mingw32-gcc -o c-chess-cli.exe
I would advise to start from the simplest possible test, where c-chess-cli.exe and engine.exe are in the same directory (and no '/' parsing is involved):

Code: Select all

./c-chess-cli.exe -each cmd=engine.exe depth=2 -engine name=e1 -engine name=e2
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
mar
Posts: 2567
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: c-chess-cli: experimental windows support

Post by mar »

I can confirm it builds, got some warnings though (speaking of dependency hell - python3 required to build?! :shock: - what's wrong with a plain makefile?):
warnings seem to be mostly related to a format string, perhaps my mingw is old or maybe that's actually because it uses the old msvcrt.dll, which probably doesn't support %zu (either way the format string warnings seem like a total nonsense)

Code: Select all

In file included from src/engine.c:37:
src/engine.h:41:1: warning: padding struct size to alignment boundary [-Wpadded]
 } Engine;
 ^
In file included from src/game.h:18,
                 from src/game.c:17:
src/engine.h:41:1: warning: padding struct size to alignment boundary [-Wpadded]
 } Engine;
 ^
In file included from src/main.c:18:
src/engine.h:41:1: warning: padding struct size to alignment boundary [-Wpadded]
 } Engine;
 ^
src/main.c: In function 'thread_start':
src/main.c:118:36: warning: unknown conversion type character 'z' in format [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                    ^
src/main.c:118:43: warning: unknown conversion type character 'z' in format [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                           ^
src/main.c:118:48: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'size_t' {aka 'long long unsigned int'} [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                               ~^                   ~~~~~~~
                                               %I64d
src/main.c:118:54: warning: format '%s' expects argument of type 'char *', but argument 4 has type 'size_t' {aka 'long long unsigned int'} [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                                     ~^                      ~~~~~
                                                     %I64d
src/main.c:118:16: warning: too many arguments for format [-Wformat-extra-args]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.c:118:36: warning: unknown conversion type character 'z' in format [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                    ^
src/main.c:118:43: warning: unknown conversion type character 'z' in format [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                           ^
src/main.c:118:48: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'size_t' {aka 'long long unsigned int'} [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                               ~^                   ~~~~~~~
                                               %I64d
src/main.c:118:54: warning: format '%s' expects argument of type 'char *', but argument 4 has type 'size_t' {aka 'long long unsigned int'} [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                                     ~^                      ~~~~~
                                                     %I64d
src/main.c:118:16: warning: too many arguments for format [-Wformat-extra-args]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.c:139:37: warning: unknown conversion type character 'z' in format [-Wformat=]
         printf("[%d] Finished game %zu (%s vs %s): %s {%s}\n", w->id, idx + 1,
                                     ^
src/main.c:139:42: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'size_t' {aka 'long long unsigned int'} [-Wformat=]
         printf("[%d] Finished game %zu (%s vs %s): %s {%s}\n", w->id, idx + 1,
                                         ~^                            ~~~~~~~
                                         %I64d
src/main.c:139:16: warning: too many arguments for format [-Wformat-extra-args]
         printf("[%d] Finished game %zu (%s vs %s): %s {%s}\n", w->id, idx + 1,
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.c:139:37: warning: unknown conversion type character 'z' in format [-Wformat=]
         printf("[%d] Finished game %zu (%s vs %s): %s {%s}\n", w->id, idx + 1,
                                     ^
src/main.c:139:42: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'size_t' {aka 'long long unsigned int'} [-Wformat=]
         printf("[%d] Finished game %zu (%s vs %s): %s {%s}\n", w->id, idx + 1,
                                         ~^                            ~~~~~~~
                                         %I64d
src/main.c:139:16: warning: too many arguments for format [-Wformat-extra-args]
         printf("[%d] Finished game %zu (%s vs %s): %s {%s}\n", w->id, idx + 1,
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
the resulting binary is small, but seems to depend on libwinpthread-1.dll (who said dependency hell again?), which I'm pretty sure won't be available out-of-the box, probably comes with mingw, I don't know, but it runs for me
EDIT: to be fair, libwinpthread-1.dll is 57kb without additional dependencies, so still waay better than cutechess-cli's 6MB Qt5Core

anyway - the test works, got a single game but no pgn output, which probably requires an additional argument
so will probably wait for a stable release and switch from cutechess-cli, but I don't feel like replacing something that works well for me at the moment

thanks anyway
Last edited by mar on Tue Jun 22, 2021 8:12 am, edited 2 times in total.
Ferdy
Posts: 4840
Joined: Sun Aug 10, 2008 3:15 pm
Location: Philippines

Re: c-chess-cli: experimental windows support

Post by Ferdy »

It works. I installed python in msys2 first.

Then run the cli in power shell.

Code: Select all

PS F:\Tmp\c-chess-cli> ./c-chess-cli.exe -engine cmd=deuterium-106.exe name=e1 -engine cmd=Deuterium_v2019.2.37.73_64bit_pop.exe name=e2 -each depth=4 -games 8
[1] Started game 1 of 8 (e1 vs e2)
[1] Finished game 1 (e1 vs e2): 1-0 {checkmate}
Score of e1 vs e2: 1 - 0 - 0  [1.000] 1
[1] Started game 2 of 8 (e2 vs e1)
[1] Finished game 2 (e2 vs e1): 0-1 {checkmate}
Score of e1 vs e2: 2 - 0 - 0  [1.000] 2
[1] Started game 3 of 8 (e1 vs e2)
[1] Finished game 3 (e1 vs e2): 0-1 {checkmate}
Score of e1 vs e2: 2 - 1 - 0  [0.667] 3
[1] Started game 4 of 8 (e2 vs e1)
[1] Finished game 4 (e2 vs e1): 0-1 {checkmate}
Score of e1 vs e2: 3 - 1 - 0  [0.750] 4
[1] Started game 5 of 8 (e1 vs e2)
[1] Finished game 5 (e1 vs e2): 0-1 {checkmate}
Score of e1 vs e2: 3 - 2 - 0  [0.600] 5
[1] Started game 6 of 8 (e2 vs e1)
[1] Finished game 6 (e2 vs e1): 0-1 {checkmate}
Score of e1 vs e2: 4 - 2 - 0  [0.667] 6
[1] Started game 7 of 8 (e1 vs e2)
[1] Finished game 7 (e1 vs e2): 0-1 {checkmate}
Score of e1 vs e2: 4 - 3 - 0  [0.571] 7
[1] Started game 8 of 8 (e2 vs e1)
[1] Finished game 8 (e2 vs e1): 0-1 {checkmate}
Score of e1 vs e2: 5 - 3 - 0  [0.625] 8
Ferdy
Posts: 4840
Joined: Sun Aug 10, 2008 3:15 pm
Location: Philippines

Re: c-chess-cli: experimental windows support

Post by Ferdy »

Compiling:

Code: Select all

$ python make.py -c x86_64-w64-mingw32-gcc -o c-chess-cli.exe
% x86_64-w64-mingw32-gcc -I./src -std=gnu11 -mpopcnt -DNDEBUG -Os -ffast-math -flto -s -DVERSION=\"2021-06-22\" -Wfatal-errors -Wall -Wextra -Wstrict-prototypes -Wsign-conversion -Wshadow -Wpadded -Wmissing-prototypes src/bitboard.c src/gen.c src/position.c src/str.c src/util.c src/vec.c src/engine.c src/game.c src/jobs.c src/main.c src/openings.c src/options.c src/seqwriter.c src/sprt.c src/workers.c -o c-chess-cli.exe -lpthread -lm
In file included from src/engine.c:37:
src/engine.h:41:1: warning: padding struct size to alignment boundary [-Wpadded]
   41 | } Engine;
      | ^
In file included from src/game.h:18,
                 from src/game.c:17:
src/engine.h:41:1: warning: padding struct size to alignment boundary [-Wpadded]
   41 | } Engine;
      | ^
In file included from src/main.c:18:
src/engine.h:41:1: warning: padding struct size to alignment boundary [-Wpadded]
   41 | } Engine;
      | ^
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: c-chess-cli: experimental windows support

Post by lucasart »

mar wrote: Tue Jun 22, 2021 7:53 am I can confirm it builds, got some warnings though (speaking of dependency hell - python3 required to build?! :shock: - what's wrong with a plain makefile?):
warnings seem to be mostly related to a format string, perhaps my mingw is old or maybe that's actually because it uses the old msvcrt.dll, which probably doesn't support %zu (either way the format string warnings seem like a total nonsense)

Code: Select all

In file included from src/engine.c:37:
src/engine.h:41:1: warning: padding struct size to alignment boundary [-Wpadded]
 } Engine;
 ^
In file included from src/game.h:18,
                 from src/game.c:17:
src/engine.h:41:1: warning: padding struct size to alignment boundary [-Wpadded]
 } Engine;
 ^
In file included from src/main.c:18:
src/engine.h:41:1: warning: padding struct size to alignment boundary [-Wpadded]
 } Engine;
 ^
src/main.c: In function 'thread_start':
src/main.c:118:36: warning: unknown conversion type character 'z' in format [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                    ^
src/main.c:118:43: warning: unknown conversion type character 'z' in format [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                           ^
src/main.c:118:48: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'size_t' {aka 'long long unsigned int'} [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                               ~^                   ~~~~~~~
                                               %I64d
src/main.c:118:54: warning: format '%s' expects argument of type 'char *', but argument 4 has type 'size_t' {aka 'long long unsigned int'} [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                                     ~^                      ~~~~~
                                                     %I64d
src/main.c:118:16: warning: too many arguments for format [-Wformat-extra-args]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.c:118:36: warning: unknown conversion type character 'z' in format [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                    ^
src/main.c:118:43: warning: unknown conversion type character 'z' in format [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                           ^
src/main.c:118:48: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'size_t' {aka 'long long unsigned int'} [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                               ~^                   ~~~~~~~
                                               %I64d
src/main.c:118:54: warning: format '%s' expects argument of type 'char *', but argument 4 has type 'size_t' {aka 'long long unsigned int'} [-Wformat=]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                                                     ~^                      ~~~~~
                                                     %I64d
src/main.c:118:16: warning: too many arguments for format [-Wformat-extra-args]
         printf("[%d] Started game %zu of %zu (%s vs %s)\n", w->id, idx + 1, count,
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.c:139:37: warning: unknown conversion type character 'z' in format [-Wformat=]
         printf("[%d] Finished game %zu (%s vs %s): %s {%s}\n", w->id, idx + 1,
                                     ^
src/main.c:139:42: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'size_t' {aka 'long long unsigned int'} [-Wformat=]
         printf("[%d] Finished game %zu (%s vs %s): %s {%s}\n", w->id, idx + 1,
                                         ~^                            ~~~~~~~
                                         %I64d
src/main.c:139:16: warning: too many arguments for format [-Wformat-extra-args]
         printf("[%d] Finished game %zu (%s vs %s): %s {%s}\n", w->id, idx + 1,
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.c:139:37: warning: unknown conversion type character 'z' in format [-Wformat=]
         printf("[%d] Finished game %zu (%s vs %s): %s {%s}\n", w->id, idx + 1,
                                     ^
src/main.c:139:42: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'size_t' {aka 'long long unsigned int'} [-Wformat=]
         printf("[%d] Finished game %zu (%s vs %s): %s {%s}\n", w->id, idx + 1,
                                         ~^                            ~~~~~~~
                                         %I64d
src/main.c:139:16: warning: too many arguments for format [-Wformat-extra-args]
         printf("[%d] Finished game %zu (%s vs %s): %s {%s}\n", w->id, idx + 1,
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
the resulting binary is small, but seems to depend on libwinpthread-1.dll (who said dependency hell again?), which I'm pretty sure won't be available out-of-the box, probably comes with mingw, I don't know, but it runs for me
EDIT: to be fair, libwinpthread-1.dll is 57kb without additional dependencies, so still waay better than cutechess-cli's 6MB Qt5Core

anyway - the test works, got a single game but no pgn output, which probably requires an additional argument
so will probably wait for a stable release and switch from cutechess-cli, but I don't feel like replacing something that works well for me at the moment

thanks anyway
Thanks.
* struct padding warning is benign. will fix it.
* I much prefer python to make. so much easier and more flexible. either one is a dependency. but it's trivial to compile without the script, so not a real dependency (some use IDE for that).
* libwinpthread is indeed an avoidable dependency. I can just replace the pthread code by some OS specific wrapper, not hard to do, just tedious. will fix that eventually.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: c-chess-cli: experimental windows support

Post by lucasart »

lucasart wrote: Tue Jun 22, 2021 9:08 am * libwinpthread is indeed an avoidable dependency. I can just replace the pthread code by some OS specific wrapper, not hard to do, just tedious. will fix that eventually.
Can't I just statically link libpthread ? If I use -static, it will include glibc which is insanely bloated, so I don't want that. There must be a way to statically link a specific lib (ie. just the '-lpthread' part)...

Edit:This should work. Links libpthread statically (but not libc and libm). No python and git dependency either (make.py is just for practicality, not a real dependency):

Code: Select all

$ x86_64-w64-mingw32-gcc -I./src -std=gnu11 -mpopcnt -DNDEBUG -Os -ffast-math -flto -s -DVERSION=\"2021-06-22\" src/*.c -o ./c-chess-cli -static -lpthread -Wl,-Bdynamic -lm
PS: I wonder. Doesn't libc and libm also require static linking ? Would mingw produce an executable that dynamically links against the microsoft one (on Windows by default) ? Or would it link against its own GNU based one, which requires the user to install some DLLs ?
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
mar
Posts: 2567
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: c-chess-cli: experimental windows support

Post by mar »

lucasart wrote: Tue Jun 22, 2021 10:53 am
lucasart wrote: Tue Jun 22, 2021 9:08 am * libwinpthread is indeed an avoidable dependency. I can just replace the pthread code by some OS specific wrapper, not hard to do, just tedious. will fix that eventually.
Can't I just statically link libpthread ? If I use -static, it will include glibc which is insanely bloated, so I don't want that. There must be a way to statically link a specific lib (ie. just the '-lpthread' part)...

Edit:This should work. Links libpthread statically (but not libc and libm). No python and git dependency either (make.py is just for practicality, not a real dependency):

Code: Select all

$ x86_64-w64-mingw32-gcc -I./src -std=gnu11 -mpopcnt -DNDEBUG -Os -ffast-math -flto -s -DVERSION=\"2021-06-22\" src/*.c -o ./c-chess-cli -static -lpthread -Wl,-Bdynamic -lm
yes, you're right - actually using make.py ... --static links libwinpthread statically while still linking to dynamic msvcrt.dll for me - so I get a single binary that's now 81kb without any external dependencies, that's pretty cool and shows the power of compact code written in plain C

in contrast cutechess-cli is 920kb binary with a dependency on 2 external libs, totalling 6.6MB
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: c-chess-cli: experimental windows support

Post by lucasart »

mar wrote: Tue Jun 22, 2021 11:20 am
lucasart wrote: Tue Jun 22, 2021 10:53 am
lucasart wrote: Tue Jun 22, 2021 9:08 am * libwinpthread is indeed an avoidable dependency. I can just replace the pthread code by some OS specific wrapper, not hard to do, just tedious. will fix that eventually.
Can't I just statically link libpthread ? If I use -static, it will include glibc which is insanely bloated, so I don't want that. There must be a way to statically link a specific lib (ie. just the '-lpthread' part)...

Edit:This should work. Links libpthread statically (but not libc and libm). No python and git dependency either (make.py is just for practicality, not a real dependency):

Code: Select all

$ x86_64-w64-mingw32-gcc -I./src -std=gnu11 -mpopcnt -DNDEBUG -Os -ffast-math -flto -s -DVERSION=\"2021-06-22\" src/*.c -o ./c-chess-cli -static -lpthread -Wl,-Bdynamic -lm
yes, you're right - actually using make.py ... --static links libwinpthread statically while still linking to dynamic msvcrt.dll for me - so I get a single binary that's now 81kb without any external dependencies, that's pretty cool and shows the power of compact code written in plain C

in contrast cutechess-cli is 920kb binary with a dependency on 2 external libs, totalling 6.6MB
Awesome. I could grind a few kB by implementing the few 'pthread_' functions directly in win32 API, but I'd say it's not worth the trouble (just pollutes the code base for little gain).
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
mar
Posts: 2567
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: c-chess-cli: experimental windows support

Post by mar »

lucasart wrote: Tue Jun 22, 2021 11:25 am Awesome. I could grind a few kB by implementing the few 'pthread_' functions directly in win32 API, but I'd say it's not worth the trouble (just pollutes the code base for little gain).
I don't think it's worth the effort, a single 81kB binary is plenty good these days, like plenty :)
mar
Posts: 2567
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: c-chess-cli: experimental windows support

Post by mar »

ok, I'm running a first real test with c-chess-cli, seems to work so far!
had to change "re" to "rt" in openings.c (actually "r" would work probably - never heard of "e" though), somehow microsoft CRT doesn't like "re" and fails with an error
EDIT: actually had to replace all "re" with "r", "we" with "w" and "ae" with "a", now everything seems to work fine