Theldus / wsServer

wsServer - a tiny WebSocket server library written in C
https://theldus.github.io/wsServer
GNU General Public License v3.0
422 stars 80 forks source link

(C question) Pd external and macOS #37

Closed Lucarda closed 2 years ago

Lucarda commented 2 years ago

Hi,

Thanks for this project. :)

I'm building a Pure-Data external that holds wsServer. So far it works fine on Linux and Windows but I'm having a strange issue on macOS: as soon as a client connects I get a segfault.

I'm scratching my head. I came around this issue https://github.com/Lucarda/pd-websocketserver/issues/1 some time ago. I'm now updating the wsServer sources but get the same debugger (lldb) message: pointing to base64_encode.

I'm working on this branch: https://github.com/Lucarda/pd-websocketserver/tree/v0.0.2

I'm on kindergarten/primary on C.

Could it be some compiler flag? These are defined https://github.com/Lucarda/pd-websocketserver/blob/v0.0.2/pd-lib-builder/Makefile.pdlibbuilder#L506-L536

The main makefile is: https://github.com/Lucarda/pd-websocketserver/blob/v0.0.2/Makefile

Any clues?


I'm compiling and testing with:

msys2/MinGW on Windows10 gcc on Debian10 clang on (QEMU virtual machine / Catalina macOS) NOTE: the wsServer/example/send_receive.c works fine.

ws

Theldus commented 2 years ago

Hi @Lucarda, Thanks for giving a chance to wsServer. I'm glad that my lib is being used in other projects =).

Regarding your issue... the base64_encode routine is quite generic and doesn't depend on specific features (other than malloc, free...) of any operating system, so it's curious that this only occurs on macOS.

Since the issue doesn't occur in send_receive.c, I'm limited on what I can suggest to you, but what I can think of:

Also, are you able to replicate a minimal example where this issue occurs? This helps to eliminate as many variables as possible and focus directly on the problem.

How do I reproduce this issue? I would like to investigate more closely.

Lucarda commented 2 years ago

Build the project with debug symbols enabled (-g) and without optimizations (-O0) and let me know the stack trace, so we'll be able to know which line inside base64_encode the segfault occurs.

I'll do this.

Valgrind usually gives better error messages than GDB/LLDB. Try to run your project with Valgrind (something like, valgrind --leak-check=full ./your_executable) and put the output here if possible.

I'll try to find out how to Valgrind on macOS.

How do I reproduce this issue? I would like to investigate more closely.

:)

It shouldn't be hard to build and test if you want.

Here's how-to:


All this guides assumes x86_64 arch only


Building on Linux/Debian

Build Pd

download Pd sources from http://msp.ucsd.edu/software.html get the current "stable version".

install dependencies:

sudo apt-get install libasound2-dev tcl tk

cd to src dir in your Pd folder and do:

make -f makefile.gnu

when finished (2min approx.) start Pd with:

cd ../bin
./pd

On first run you will be asked to create a folder on your documents folder. Select yes.

You can quit Pd.

Build pd-websocketserver

Download v0.0.2 branch from https://github.com/Lucarda/pd-websocketserver/tree/v0.0.2

cd to your extracted folder and do:

make PDDIR=<full/path/to/your/Pd-folder(no-white-spaces-please)>

Now you can start Pd and open the file websocketserver-help.pd on the pd-websocketserver folder.

\:)


Building on macOS

mac is not my territory but this is how I build this and other working projects.

from http://msp.ucsd.edu/software.html get the current "stable version" app built for mac.

Move Pd to the applications folder. (don't skip this)

start Pd. (on first time you cant until you give it permissions on preferences/security)

quit Pd

Build pd-websocketserver

open the terminal and install xcode with:

xcode-select --install

Download v0.0.2 branch from https://github.com/Lucarda/pd-websocketserver/tree/v0.0.2

Open a terminal on pd-websocketserver folder

and just do

make

you can do

make alldebug

this builds all with -g option turned on for debug symbols

Now you can start Pd and open the file websocketserver-help.pd on the pd-websocketserver folder.

Here you will get the crash when you connect from the bowser.

\:(


Building on Windows

from http://msp.ucsd.edu/software.html get the current "stable version" installer for Windows.

Run the installer with all defaults paths and options.

Start Pd

Quit Pd

Build pd-websocketserver With Msys2

Download the 64-bit installer from:

https://www.msys2.org/

Follow installation instructions on: https://www.msys2.org/wiki/MSYS2-installation/

Start "msys2-msys" shell and add with pacman these packages

pacman -S make pkg-config autoconf automake libtool

and the 64bit compiler

pacman -S mingw64/mingw-w64-x86_64-gcc 

Optionally this is needed

pacman -S mingw64/mingw-w64-x86_64-ntldd-git

close the msys2-msys shell.

Download v0.0.2 branch from https://github.com/Lucarda/pd-websocketserver/tree/v0.0.2

open the "MSYS2 MINGW 64-bit" shell and cd to the pd-websocketserver folder

(note that MSYS it uses unix-like paths (path/to/folder) and not Windows (path\to\folder))

do

make

Now you can start Pd and open the file websocketserver-help.pd on the pd-websocketserver folder.

\:)

Lucarda commented 2 years ago

To get this debugger info I changed : https://github.com/Lucarda/pd-websocketserver/blob/v0.0.2/pd-lib-builder/Makefile.pdlibbuilder#L631

to:

## optimization.flags = -O3 -ffast-math -funroll-loops -fomit-frame-pointer
optimization.flags = 

and build with:

make alldebug

then I got:

Last login: Thu Nov 11 19:37:18 on ttys000
lucarda@lucardas-iMac ~ % cd /Applications/Pd-0.51-4.app/Contents/Resources/bin  
lucarda@lucardas-iMac bin % lldb
(lldb) target create ./pd
Current executable set to '/Applications/Pd-0.51-4.app/Contents/Resources/bin/pd' (x86_64).
(lldb) run
Process 702 launched: '/Applications/Pd-0.51-4.app/Contents/Resources/bin/pd' (x86_64)
2021-11-11 19:47:47.157845-0300 pd[702:8711] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x100410fa0> F8BB1C28-BAE8-11D6-9C31-00039315CD46
Unable to create basic Accelerated OpenGL renderer.
Unable to create basic Accelerated OpenGL renderer.
Core Image is now using the software OpenGL renderer. This will be slow.
2021-11-11 19:47:51.960686-0300 Pd[707:8851] [si_destination_compare] send failed: Invalid argument
2021-11-11 19:47:51.960834-0300 Pd[707:8851] [si_destination_compare] send failed: Undefined error: 0
2021-11-11 19:47:51.960880-0300 Pd[707:8851] [si_destination_compare] send failed: Invalid argument
Process 702 stopped
* thread #6, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x00007fff559635f3 Heimdal`base64_encode + 467
Heimdal`base64_encode:
->  0x7fff559635f3 <+467>: movq   %rax, (%rcx)
    0x7fff559635f6 <+470>: movq   -0x28(%rbp), %rdi
    0x7fff559635fa <+474>: callq  0x7fff559a171e            ; symbol stub for: strlen
    0x7fff559635ff <+479>: movl   %eax, -0x4(%rbp)
Target 0: (pd) stopped.
(lldb) bt
* thread #6, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x00007fff559635f3 Heimdal`base64_encode + 467
    frame #1: 0x0000000100702e04 websocketserver.pd_darwin`get_handshake_accept(wsKey="CqsgqSTypZphn2v3ecggpQ==", dest=0x000070000062a630) at handshake.c:68:10
    frame #2: 0x0000000100702f68 websocketserver.pd_darwin`get_handshake_response(hsrequest="GET / HTTP/1.1", hsresponse=0x000070000062a688) at handshake.c:110:8
    frame #3: 0x000000010070521a websocketserver.pd_darwin`do_handshake(wfd=0x000070000062a6f8, p_index=0, x=0x000000010101d000) at ws.c:684:6
    frame #4: 0x0000000100704e4f websocketserver.pd_darwin`ws_establishconnection(x=0x000000010101d000) at ws.c:1298:6
    frame #5: 0x00007fff6d16a109 libsystem_pthread.dylib`_pthread_start + 148
    frame #6: 0x00007fff6d165b8b libsystem_pthread.dylib`thread_start + 15
(lldb) bt
* thread #6, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x00007fff559635f3 Heimdal`base64_encode + 467
    frame #1: 0x0000000100702e04 websocketserver.pd_darwin`get_handshake_accept(wsKey="CqsgqSTypZphn2v3ecggpQ==", dest=0x000070000062a630) at handshake.c:68:10
    frame #2: 0x0000000100702f68 websocketserver.pd_darwin`get_handshake_response(hsrequest="GET / HTTP/1.1", hsresponse=0x000070000062a688) at handshake.c:110:8
    frame #3: 0x000000010070521a websocketserver.pd_darwin`do_handshake(wfd=0x000070000062a6f8, p_index=0, x=0x000000010101d000) at ws.c:684:6
    frame #4: 0x0000000100704e4f websocketserver.pd_darwin`ws_establishconnection(x=0x000000010101d000) at ws.c:1298:6
    frame #5: 0x00007fff6d16a109 libsystem_pthread.dylib`_pthread_start + 148
    frame #6: 0x00007fff6d165b8b libsystem_pthread.dylib`thread_start + 15
(lldb) 
Theldus commented 2 years ago

Hi @Lucarda,

Thank you for the very detailed step-by-step description of how to reproduce the issue. After some time, I was able to set up a virtual machine with macOS 10.12 and reproduce it here.

Everything indicates that there is a problem with the base64_encode routine, but what I could see is that it is not even invoked: the segfault is in the attempt to invoke the function, not within its execution, which leads me to believe that it is a build problem or a Pure-Data incompatibility/limitation, I don't know.

But one interesting thing I could observe is that if you change the function name 'base64_encode' to something else, the code works fine. You can apply the following patch to pd-websocketserver (branch v0.0.2) and test:

cd pd-websocketserver
wget https://git.io/JXdrG -O rename.diff
git apply rename.diff
make 

the example will work as expected, even in the normal build, with optimizations.

I don't know how pd-websocketserver works, nor does Pure-Data, but I believe the base64_encode of wsServer conflicts with some other internal name of Pure-Data or even some dynamically loaded library (be it variable, function, and etc) which means that this routine is not executed in any way.

I believe the fix is just that, renaming the routine (which I can push a fix in the master), but let me know what you think about it and if my proposed fix works as expected in your environment.


Edit: A closer look at your stacktrace reveals that the addresses of the wsServer routines is 0x100... while base64_encode is 0x7fff.... implying that they are not in the same portion of memory:

frame #0: 0x00007fff559635f3 Heimdal`base64_encode + 467
frame #1: 0x0000000100702e04 websocketserver.pd_darwin`get_handshake_accept
frame #2: 0x0000000100702f68 websocketserver.pd_darwin`get_handshake_response
frame #3: 0x000000010070521a websocketserver.pd_darwin`do_handshake
frame #4: 0x0000000100704e4f websocketserver.pd_darwin`ws_establishconnection

Also, base64_encode appears prefixed with the name 'Heimdal', which probably indicates where the 'collision' came from.

In fact, a closer look reveals that Heimdal used these names in the past, but it was renamed to rk_base64_[en|de]code due to conflict with other project.

Lucarda commented 2 years ago

@Theldus very interesting!

Now I'm scratching my head with my two hands :)

Not having applied the diff yet (or doing any test) the only thing that comes to my head is that there must be base64_encode function only and only on the macOS tcl/tk shipped inside the Pd app ?

?

Will apply the patch and do tests

:)

Lucarda commented 2 years ago

I believe the fix is just that, renaming the routine (which I can push a fix in the master), but let me know what you think about it and if my proposed fix works as expected in your environment.

@Theldus the patch worked nicely here.

Total thanks. :)

About you pushing a fix to master should probably be sane. This was an edge case but it could happen on another similar situation. Who knows :).

I can perfectly live now that I know how to fix it and the files in my project already have lots of manual surgery anyway.

I'm totally happy.

:)

Theldus commented 2 years ago

Hi,

there must be base64_encode function only and only on the macOS tcl/tk shipped inside the Pd app ?

I don't know if Heimdal would be a tcl/tk dependency. I didn't figure out where it's loaded from. I just know it is.

About you pushing a fix to master should probably be sane. This was an edge case but it could happen on another similar situation. Who knows :).

Yeah, I will think of some prefix or a better way to organize the names of the routines, although this is a kind of situation that can always happen.

I can perfectly live now that I know how to fix it and the files in my project already have lots of manual surgery anyway. I'm totally happy.

Yes, I had a look at your project =)... If you do not mind, what is your project about? I'm not familiar with Pure-Data, so it's something new to me.

Anyway, I'm glad to help.

Lucarda commented 2 years ago

I don't know if Heimdal would be a tcl/tk dependency. I didn't figure out where it's loaded from. I just know it is.

Sure. But not on Linux, not on Windows, and not on macOS running wsServer/example/send_receive.c. I'm too lazy to revert the files and start ./pd -nogui "load a patch that auto-starts [websocketserver] on port 8080". This will run Pd headless without the wish.app (tcl/tk): Pd's GUI. 99% of chances that Heimdal base64_encode will not be present. :)

If you do not mind, what is your project about?

Being able to use any browser (cellphone, tablet, Pc) to send or receive to a Pd patch.

TL;DR:

I'm not familiar with Pure-Data, so it's something new to me.

http://puredata.info/ briefly explains it the main page. It's a total paradise for "Computer Music". Being a "visual programming environment" might not be what you are used to as a programmer. But as you are a programmer your learning curve should be really fast in contrast to musicians/artists. You can also prototype "very fast" and "not coding" many things related or not to art. Watching your repositories I see you have many games. You could do really complex (also simple) audio things in a couple of minutes. You can also integrate the "sound engine" to the game with things like https://github.com/libpd/libpd.

You could give Pd a try. Preferably not on a VM :)

You could start reading and doing http://www.pd-tutorial.com/english/ch02.html Also you can follow Pd's examples by going to menu help/browser/Pure Data/2.control.examples

Pd comes with many [objects] this are called internals(menu help/List of objects) . Then there are many people that do externals [objects] like [websocketserver]. These are ready for the Pd users via menu "help/find externals". some are single objects others are a group of many objects.

You can also read the Pd manual. Menu "help/HTML manual" for how Pd loads externals and more.

And this might scare you : https://github.com/chr15m/pd-ws

A websocketserver done completely with internal [objects] (no threading, only one connection possible, no broadcast)

this is the base64encode part :

ws

Theldus commented 2 years ago

This will run Pd headless without the wish.app (tcl/tk): Pd's GUI. 99% of chances that Heimdal base64_encode will not be present. :)

It's actually still loaded, you can see it easily with:

export DYLD_PRINT_LIBRARIES=1
export DYLD_PRINT_LIBRARIES_POST_LAUNCH=1
export DYLD_PRINT_RPATHS=1
cd /Applications/Pd-0.51-4.app/Contents/Resources/bin
./pd -nogui

you will see at some point:

...
dyld loaded: /System/Library/PrivateFrameworks/Heimdal.framework/Versions/A/Heimdal
dyld loaded: /usr/lib/libheimdal-asn1.dylib
...

(One of the simplest and practical I can think of): I'm on stage with my guitar and press a pedal (connected to the Pd patch via MIDI or whatever) that tells the patch (on my laptop with a good sound card) to start playing a recording of the drum and bass of the song. Since time is now fixed (I follow the song) the Pd patch that I made throws me the lyrics on the screen of my cellphone (connected via websocket to the Pd patch). Since the screen is too small I had already set time points and the patch updates the browser accordingly. (yeah, I totally forgot the lyrics) (uh, I totally forgot about live performances. I'm more happy learning programing. really. :)

Really interesting, looks like a pretty valid use case =).

http://puredata.info/ briefly explains it the main page. It's a total paradise for "Computer Music". Being a "visual programming environment" might not be what you are used to as a programmer. But as you are a programmer your learning curve should be really fast in contrast to musicians/artists. You can also prototype "very fast" and "not coding" many things related or not to art. Watching your repositories I see you have many games. You could do really complex (also simple) audio things in a couple of minutes. You can also integrate the "sound engine" to the game with things like https://github.com/libpd/libpd.

You could give Pd a try. Preferably not on a VM :)

You could start reading and doing http://www.pd-tutorial.com/english/ch02.html Also you can follow Pd's examples by going to menu help/browser/Pure Data/2.control.examples

Pd comes with many [objects] this are called internals(menu help/List of objects) . Then there are many people that do externals [objects] like [websocketserver]. These are ready for the Pd users via menu "help/find externals". some are single objects others are a group of many objects.

You can also read the Pd manual. Menu "help/HTML manual" for how Pd loads externals and more.

Thanks for the insights, it really sounds pretty interesting, whether it's for audio production or even other stuff, as it's extensible.

In fact, I've played with 'flowgraph programming' a bit in the past, I even developed a simple image editing tool a few years ago. So the concept isn't exactly new to me, but I wasn't aware of Pure-Data and how the websocket fit into all of that.

But I'll definitely take a closer look later, whether it's Pure-Data, libpd and also your project, it looks very promising.

And this might scare you : https://github.com/chr15m/pd-ws

A websocketserver done completely with internal [objects] (no threading, only one connection possible, no broadcast)

this is the base64encode part :

My god, it takes a lot of courage to write a websocket server completely like this, I believe there are several limitations, but something like that is still very impressive.

Lucarda commented 2 years ago

It's actually still loaded, you can see it easily with: [...]

Aha, I now see. My horrible 1%. I Always knew I was talking to an expert. :)

My god, it takes a lot of courage to write a websocket server completely like this ...

Yep. It's a very complex patch but it works :)

I use it on my Pd Albums ("aleatory" / "Computer music" albums).

I just ship the Pd executable (which is very lightweight) with a script that starts Pd with -nogui and lunch a browser to interface the patch.

If you wish:

Download (112MB .zip) https://lucarda.com.ar/discos/Pd/lucarda2011-%5bPd%5d.zip

extract and run the appropriate script for your OS.

There are more @ https://lucarda.com.ar/discos/Pd/


I think I'm going off-topic on this issue.

Very glad knowing you. :)

Theldus commented 2 years ago

Aha, I now see. My horrible 1%. I Always knew I was talking to an expert. :)

You were right from the beginning... I made a tool in Python that recursively invokes otool -L and lists all dependencies in a tree-like form, and got the following output:

/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices
  -> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices
    -> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Metadata
      -> /System/Library/PrivateFrameworks/TCC.framework/Versions/A/TCC
        -> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices
          -> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/PrintCore.framework/Versions/A/PrintCore
            -> /usr/lib/libcups.2.dylib
              -> /System/Library/Frameworks/Kerberos.framework/Versions/A/Kerberos
                -> /System/Library/PrivateFrameworks/Heimdal.framework/Versions/A/Heimdal

the output above lists all dependencies until loading Heimdal, and as you can see, they all initially depend on CoreServices.

Quoting from Wikipedia:

Core Services are a set of macOS and iOS application programming interfaces that architecturally are underneath Carbon, Cocoa and Cocoa Touch. In addition to Core Foundation, it also encompasses other APIs including Grand Central Dispatch, Blocks, CFNetwork, CarbonCore, OSServices, and WebServicesCore.

So yes, CoreServices belongs to the GUI, so it makes sense to associate with tcl/tk.

The whole point is that these libraries are loaded even with -nogui enabled. I believe that to avoid this, Pure-Data should be compiled completely without GUI support, which I don't know if it's possible.

I use it on my Pd Albums ("aleatory" / "Computer music" albums).

I just ship the Pd executable (which is very lightweight) with a script that starts Pd with -nogui and lunch a browser to interface the patch.

Looks interesting, I'll take a look later =).

Very glad knowing you. :)

I say the same xD.

Well, I believe I will close this issue, unless there is any other question regarding it. Feel free to create any issues (or reopen this one) if you feel the need.

I am always open to issues, criticisms, suggestions, PR, etc.

Lucarda commented 2 years ago

@Theldus thanks a lot!

:)

Lucarda commented 2 years ago

May be "Core Services" comes from a dependency of one of Pd's mac audio back-ends: (port audio):

# need Carbon framework for PA on Mac
if MACOSX
LIBS += -framework Carbon -framework CoreFoundation
endif

https://github.com/pure-data/pure-data/blob/master/src/Makefile.am#L269

Theldus commented 2 years ago

May be "Core Services" comes from a dependency of one of Pd's mac audio back-ends: (port audio):

# need Carbon framework for PA on Mac
if MACOSX
LIBS += -framework Carbon -framework CoreFoundation
endif

https://github.com/pure-data/pure-data/blob/master/src/Makefile.am#L269

Makes sense, then it seems difficult to remove this dependency.

Just out of curiosity, I decided to publish the script (from recursive otool) to my Gist and also added image support to it, in case you want to see all PD dependencies, if it looks like this.

Lucarda commented 2 years ago

@Theldus

Amazing!

On Windows theres a nice program to find out this stuff : https://www.dependencywalker.com/

Here's websocketserver.dll:

wsserver2

q q q

Here (i already knew this of course) you can tell that "LIBWINPTHREAD-1.DLL" (the file is somewhere in the msys2/MINGW(arch) folders) must be shipped in the same folder as "WEBSOCKETSERVER.DLL"

Theldus commented 2 years ago

On Windows theres a nice program to find out this stuff : https://www.dependencywalker.com/

True, I'm a Linux user 99% of the time, so I forget about these other tools, and end up reinventing others...

Here (i already knew this of course) you can tell that "LIBWINPTHREAD-1.DLL" (the file is somewhere in the msys2/MINGW(arch) folders) must be shipped in the same folder as "WEBSOCKETSERVER.DLL"

This is something that bothers me, I know the libwinpthread dependency, but it bothers me that wsServer requires a single non-native Windows dependency.

It's something I plan to work on in the future, maybe putting together with wsServer some pthread/windows wrapper or even writing my own, although I have 0 experience with the Windows API.

Lucarda commented 2 years ago

It's something I plan to work on in the future, maybe putting together with wsServer some pthread/windows wrapper or even writing my own, although I have 0 experience with the Windows API.

ifeq (MINGW,$(findstring MINGW,$(uname)))
    foo = ${MINGW_PREFIX}/bin/libwinpthread-1.dll   
endif

this gets the correct arch dll. (its also possible to do this that also works for cross-compiling).

Lucarda commented 2 years ago

ADDED:

-static -lpthread i don't do this in the Pd external because:

I ship the file because MinGW will change to pthread-2 or whatever in some future. Since I'm not aware of that I ship the dll i use at compile time. (the external will work even with a Pd compiled with Msys3 or MSVC).

Lucarda commented 2 years ago

ADDED:

but it bothers me that wsServer requires a single non-native Windows dependency.

Is true but consider the fact that if you take the effort of handling natively in your code the Windows threading (with all the hassle in the .c files) then you are going to start depending on the correct Cruntime.%.dll from Windows. Distributing wsServer will have to ship the runtime from the MS-Compiler.

Is true anyway that someone wanting to use wsServer in his/her native Windows project will not need to include the https://sourceware.org/pthreads-win32/ sources (I think this is what MINGW uses).

Lucarda commented 2 years ago

ADD:

If you are wondering why MINGW compiled stuff does not ship C-runtime and work on all Windows versions?

MinGW (ab)uses the fact that Microsoft froze (long time ago) msvcrt.dll and guaranteed it will work on all future versions of Windows.

Microsoft has now a new Universal-CRT that needs to be shipped to older Windows versions. MinGW has now an especial use of that:

wsserver3

I had not did any test with it and don't know how to deal with it but will soon try

Theldus commented 2 years ago

MinGW is perfectly acceptable for wsServer. You can also perfectly live with LDLIBS=-ws2_32 -static -lpthread. This statically links the pthread.dll and you don't need the extra file.

Yes, actually I had forgotten that I already do this in my CMakeLists.txt, here:

if(WIN32)
    target_link_libraries(ws pthread ws2_32 -static)
else()
    target_link_libraries(ws pthread)
endif(WIN32)

so no major concerns, once built, the binary is rather portable across multiple versions of Windows, and without external libraries. As for supporting makefiles for Windows builds, I prefer to keep CMake as there will always be one thing or another to 'tweak'. Besides, CMake is very simple to maintain, that's what makes wsServer also able to build on FreeBSD for example, since its make (non-GNU) doesn't support most of the features I use on mine.

-static -lpthread i don't do this in the Pd external because [...]

Makes sense. In your case, as it is a dynamic library build, there would certainly be collisions. The traditional build of wsServer is a static library, which I believe prevents these collisions as only the routines used are compiled into the binary.

Is true anyway that someone wanting to use wsServer in his/her native Windows project will not need to include the https://sourceware.org/pthreads-win32/ sources (I think this is what MINGW uses).

This was what I intended to do in the beginning, until I found out that MinGW was already bundled with this library.

MinGW (ab)uses the fact that Microsoft froze (long time ago) msvcrt.dll and guaranteed it will work on all future versions of Windows.

I'm glad they opted for that, as someone who values portability a lot, having this guarantee saves me a lot of headaches.