using wxThread with different MinGW-W64 Compiler versions

Do you have a question about makefiles, a compiler or IDE you are using and need to know how to set it up for wxWidgets or why it doesn't compile but other IDE's do ? Post your questions here.
Post Reply
tigerbeard
Experienced Solver
Experienced Solver
Posts: 68
Joined: Sat Oct 07, 2006 1:56 pm

using wxThread with different MinGW-W64 Compiler versions

Post by tigerbeard » Sun Jan 10, 2021 2:54 pm

This is about the correct way of using "wxThread" with different MinGW-W64 compiler versions (or better different toolchains). I did not find something about this in the docs or the forum, but maybe used bad search terms.

I have an old program created with a very old MinGW version (before MinGW-W64) for WindowsXP . I guess MinGW was using the WIN32 thread model. Now I want to compile it with a current MinGW-W64 compiler. I would like to make both a WIN32 and a POSIX version. Or in other words, one version that uses behind the scenes of "wxThread" the POSIX thread model and another version that uses win32 thread model.
I am
* compiling on Win7x64 Host and for Win7x64 Targets and Win7x32 Targets
* using wxWidgets as static libs (no DLLs).

The backgound why I want to do this is because I want to find out if the application runtime behaviour differs in any way between the two approaches and if so if the difference is small enough to move to the POSIX model.


On the MinGW-W64 site I read (unfortuately can't remember where) that one 'could' use win32 threading with a POSIX compiler version, but that its not recommended because it could cause hard to trace run-time trouble. Since I am using CodeBlocks its easy to create two compiler configurations: one using MinGW-W64 "8.1.0 x86_64-posix-seh" and another one using "8.1.0 x86_64-win32-seh" and compile two versions. But how to handle wxWidgets?

So my questions is: What exactly do I have to do concerning wxWidgets to create a wxThread with WIN32 and POSIX? More specifically, what is required when compiling wxWidgets itself and what is required when compiling an application using wxWidgets?

My guesses are
* I need to compile 2 versions of wxWidgets libs. Do they need to differ in settings? Ist it OK to have both with "CXXFLAGS="-std=c++17"
* in both cases I need to add compiler switch "-pthread"
* for WIN32 I do not need to add anything (beside the code itself of couse)
* For POSIX I only need to add "libwinthread". But this is requried anyway whether using threads or not.
System config: Xubuntu16.04/Win7/XP/2K, wxWidgets 2.9.3, C::B, GCC, VC

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2781
Joined: Sun Jan 03, 2010 5:45 pm

Re: using wxThread with different MinGW-W64 Compiler versions

Post by PB » Sun Jan 10, 2021 5:55 pm

I am not saying I know a lot about threads or GCC but are you sure a different thread model affects wxThread at all?

AFAICS, on MSW, wxThread uses either MSCRT (e.g., _beginthreadex) or Windows API (e.g., CreateThread) functions, as can be seen in its source.

OTOH, AFAIK, std::thread does not work out of the box with Win32 threads.

tigerbeard
Experienced Solver
Experienced Solver
Posts: 68
Joined: Sat Oct 07, 2006 1:56 pm

Re: using wxThread with different MinGW-W64 Compiler versions

Post by tigerbeard » Sun Jan 10, 2021 6:59 pm

PB wrote:
Sun Jan 10, 2021 5:55 pm
I am not saying I know a lot about threads or GCC but are you sure a different thread model affects wxThread at all?
You are right, not I am not sure. Thats part of why I asked the question.
I was coming from the compiler selection: MinGW-W64 offers 2 compiler models and says better not use win32 threads with the POSIX version. Now I have code using wxThread and the choice is abstracted away from me. So somewhere should be a selection.

Currently I do not know what is influencing the selection. Is it my choice of compiler, is it my compilation of wxWidgets with "-std=c++11" or "-std=c++17" or is it only something I set at compile time?

And of course you are right, I am not sure if its relevant. But is the fact that wxWidgets 3.x is not exposing this selection in the API enough evidence that its not relevant?
I think unless I have some credible source or other evidence its the better strategy to expect it is relevant. Thats kind of why I wanted to compare the two versions to find out. Hopefully its not relevant enough that I would care :)

I kind of hoped that I am not the first person to come across this issue. But maybe I am just not seeing the obvious. #-o
System config: Xubuntu16.04/Win7/XP/2K, wxWidgets 2.9.3, C::B, GCC, VC

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2781
Joined: Sun Jan 03, 2010 5:45 pm

Re: using wxThread with different MinGW-W64 Compiler versions

Post by PB » Sun Jan 10, 2021 7:24 pm

tigerbeard wrote:
Sun Jan 10, 2021 6:59 pm
Currently I do not know what is influencing the selection. Is it my choice of compiler
I believe thread and exception handling models may be related to how the compiler was built, when you run

Code: Select all

gcc -v
for mingw-w64 distributions i686-8.1.0-posix-sjlj-rt_v6-rev0 and i686-8.1.0-win32-sjlj-rt_v6-rev0 you get
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/Program\ Files\ (x86)/mingw-w64/i686-8.1.0-posix-sjlj-rt_v6-rev0/mingw32/bin/../libexec/gcc/i686-w64-mingw32/8.1.0/lto-wrapper.exe
Target: i686-w64-mingw32
Configured with: ../../../src/gcc-8.1.0/configure --host=i686-w64-mingw32 --build=i686-w64-mingw32 --target=i686-w64-mingw32 --prefix=/mingw32 --with-sysroot=/c/mingw810/i686-810-posix-sjlj-rt_v6-rev0/mingw32 --enable-shared --enable-static --enable-targets=all --enable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --enable-sjlj-exceptions --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch-32=i686 --with-arch-64=nocona --with-tune-32=generic --with-tune-64=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-mpfr=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-mpc=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-isl=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-pkgversion='i686-posix-sjlj-rev0, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/i686-810-posix-sjlj-rt_v6-rev0/mingw32/opt/include -I/c/mingw810/prerequisites/i686-zlib-static/include -I/c/mingw810/prerequisites/i686-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/i686-810-posix-sjlj-rt_v6-rev0/mingw32/opt/include -I/c/mingw810/prerequisites/i686-zlib-static/include -I/c/mingw810/prerequisites/i686-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw810/i686-810-posix-sjlj-rt_v6-rev0/mingw32/opt/include -I/c/mingw810/prerequisites/i686-zlib-static/include -I/c/mingw810/prerequisites/i686-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw810/i686-810-posix-sjlj-rt_v6-rev0/mingw32/opt/lib -L/c/mingw810/prerequisites/i686-zlib-static/lib -L/c/mingw810/prerequisites/i686-w64-mingw32-static/lib -Wl,--large-address-aware'
Thread model: posix
gcc version 8.1.0 (i686-posix-sjlj-rev0, Built by MinGW-W64 project)
vs
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/Program\ Files\ (x86)/mingw-w64/i686-8.1.0-win32-sjlj-rt_v6-rev0/mingw32/bin/../libexec/gcc/i686-w64-mingw32/8.1.0/lto-wrapper.exe
Target: i686-w64-mingw32
Configured with: ../../../src/gcc-8.1.0/configure --host=i686-w64-mingw32 --build=i686-w64-mingw32 --target=i686-w64-mingw32 --prefix=/mingw32 --with-sysroot=/c/mingw810/i686-810-win32-sjlj-rt_v6-rev0/mingw32 --enable-shared --enable-static --enable-targets=all --enable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=win32 --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --enable-sjlj-exceptions --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch-32=i686 --with-arch-64=nocona --with-tune-32=generic --with-tune-64=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-mpfr=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-mpc=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-isl=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-pkgversion='i686-win32-sjlj-rev0, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/i686-810-win32-sjlj-rt_v6-rev0/mingw32/opt/include -I/c/mingw810/prerequisites/i686-zlib-static/include -I/c/mingw810/prerequisites/i686-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/i686-810-win32-sjlj-rt_v6-rev0/mingw32/opt/include -I/c/mingw810/prerequisites/i686-zlib-static/include -I/c/mingw810/prerequisites/i686-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw810/i686-810-win32-sjlj-rt_v6-rev0/mingw32/opt/include -I/c/mingw810/prerequisites/i686-zlib-static/include -I/c/mingw810/prerequisites/i686-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw810/i686-810-win32-sjlj-rt_v6-rev0/mingw32/opt/lib -L/c/mingw810/prerequisites/i686-zlib-static/lib -L/c/mingw810/prerequisites/i686-w64-mingw32-static/lib -Wl,--large-address-aware'
Thread model: win32
gcc version 8.1.0 (i686-win32-sjlj-rev0, Built by MinGW-W64 project)
I think wxWidgets MinGW binaries using Win32 threads may be an oddity. For example, MSYS2 and Qt distributions both use Posix model. And as I wrote above, std:: thread and related do not work correctly out of the box with Win32 threading model. If we go by the order, Posix also seems to be the default for mingw-w64 distributions (which are now quite outdated, BTW).
tigerbeard wrote:
Sun Jan 10, 2021 6:59 pm
I think unless I have some credible source or other evidence
I would say the source code itself is the highest authority, wouldn't you? But if you do not trust your own eyes, try asking the developers in the wx-users mailing list. And you may get an answer along the lines: do not use wxThread anymore, use std::thread instead.

tigerbeard
Experienced Solver
Experienced Solver
Posts: 68
Joined: Sat Oct 07, 2006 1:56 pm

Re: using wxThread with different MinGW-W64 Compiler versions

Post by tigerbeard » Sun Jan 10, 2021 8:22 pm

appreciate your feedback
PB wrote:
Sun Jan 10, 2021 7:24 pm
I believe thread and exception handling models may be related to how the compiler was built, when you run

Code: Select all

gcc -v
targets=all --enable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-

targets=all --enable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=win32 --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-
Very good find, did not see that. However, doesn't this just say that the toolchains indeed use POSIX and WIN32. As the name suggested. Do you think one should use the same compiler switch for compiling the wxWidget libs, i.e. if that would determine which of those is used, wouldn't that be transparent to the wxWidgets library code?
I think wxWidgets MinGW binaries using Win32 threads may be an oddity. For example, MSYS2 and Qt distributions both use Posix model.
Its good that all use move to the posix mode. For new code this then creates at least no new diversions. I guess noting that on MinGW-W64's download page would dampen a bit the confusion people often report with the multiple MinGW-W64 versions.
And as I wrote above, std:: thread and related do not work correctly out of the box with Win32 threading model.
I understand that as: when using a POSIX compiler and default wxWidgets old Win32 code would behave differently from when it was conceived (not working maybe a rather extreme form of behaving differently). Hope I got you correct.
Sp yes. I think this is exactly the issue you have when dealing with code from the pre-MinGW-W64 area. Most sample code with threads on the web should have that issue. Since most IDE are bundled with posix as you say I wonder why not more people have those problems. So where you have only your POSIX compiler (and are not aware that there are other versions out there) what would you do?
I know that I can switch to a WIN32 compiler and it will work. But I would rather use a the posix compilers for both 32 and 64 bit codes and just have a single wxLib binary set and tweak build settings per project. Its bad enough to have different sets for wxWidget versions and different compiler versions. This would double when I add a dimension with thread model.
tigerbeard wrote:
Sun Jan 10, 2021 6:59 pm
I would say the source code itself is the highest authority, wouldn't you? But if you do not trust your own eyes, try asking the developers in the wx-users mailing list. And you may get an answer along the lines: do not use wxThread anymore, use std::thread instead.
Fair comment. I was hoping to get user experience/background/best practice with it. But true, if there is a compile switch or not in wxThread class or if there is a runtime switch or not should be not too hard to find out.
System config: Xubuntu16.04/Win7/XP/2K, wxWidgets 2.9.3, C::B, GCC, VC

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2781
Joined: Sun Jan 03, 2010 5:45 pm

Re: using wxThread with different MinGW-W64 Compiler versions

Post by PB » Sun Jan 10, 2021 10:31 pm

I am not sure I understand you.

IMO,
1. wxThread is MinGW thread-model agnostic and uses directly either MSCRT functions (when available) or Windows API ones.
2. A library and an application using it should be always built with the same compiler toolchain and the same settings.

I assume you also found this
https://stackoverflow.com/a/30390278/7267315

tigerbeard
Experienced Solver
Experienced Solver
Posts: 68
Joined: Sat Oct 07, 2006 1:56 pm

Re: using wxThread with different MinGW-W64 Compiler versions

Post by tigerbeard » Mon Jan 11, 2021 12:40 am

PB wrote:
Sun Jan 10, 2021 10:31 pm
I assume you also found this
https://stackoverflow.com/a/30390278/7267315
Indeed i did. Maybe I do not see the obvious.

Isn't that what that posts said (just resorted the text)

Code: Select all

    posix:  enable C++11/C11 multithreading features. 
        means native std:thread
    win32: No C++11 multithreading features. 
        means: libstdc++'s C++11 <thread>,.. does not have a complete 
                     implementation in GCC Win32 threading model.
                    But:  MinGW-w64 GCC can link winpthreads (implementation 
                     on top of Win32) ->  it enables all the fancy features
If I did not get the text wrong, it tells me I could use std::thread in both. The first needs winpthreads anyway, to the second I can link it manually, but only then.

PB wrote:
Sun Jan 10, 2021 10:31 pm
1. wxThread is MinGW thread-model agnostic and uses directly either MSCRT functions (when available) or Windows API ones.
2. A library and an application using it should be always built with the same compiler toolchain and the same settings.
Supposed I use the win32 version and link to winpthreads I could use std:threads in my own code, but wxThread will not use it because the when the lib was compiled with the MinGW gcc-win32 it did not include the posix code, because it was not available. Maybe I am thinking too complicated..
System config: Xubuntu16.04/Win7/XP/2K, wxWidgets 2.9.3, C::B, GCC, VC

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2781
Joined: Sun Jan 03, 2010 5:45 pm

Re: using wxThread with different MinGW-W64 Compiler versions

Post by PB » Mon Jan 11, 2021 6:36 am

tigerbeard wrote:
Mon Jan 11, 2021 12:40 am
Indeed i did. Maybe I do not see the obvious.

Isn't that what that posts said (just resorted the text)

Code: Select all

    posix:  enable C++11/C11 multithreading features. 
        means native std:thread
    win32: No C++11 multithreading features. 
        means: libstdc++'s C++11 <thread>,.. does not have a complete 
                     implementation in GCC Win32 threading model.
                    But:  MinGW-w64 GCC can link winpthreads (implementation 
                     on top of Win32) ->  it enables all the fancy features
If I did not get the text wrong, it tells me I could use std::thread in both. The first needs winpthreads anyway, to the second I can link it manually, but only then.
The text you quoted says "Win32: No C++11 multithreading features." How do you interpret that as "could use std::thread"? But may be I am missing something.
tigerbeard wrote:
Mon Jan 11, 2021 12:40 am
Supposed I use the win32 version and link to winpthreads I could use std:threads in my own code, but wxThread will not use it because the when the lib was compiled with the MinGW gcc-win32 it did not include the posix code, because it was not available. Maybe I am thinking too complicated..
As I wrote twice already, I believe that wxThread on MSW never uses std::thread nor winipthreads, regardless of the GCC thread model. Did you find something that contradicts that?

I think you are over complicating this. Just build the library and the application with posix threads and use wxThread and std::thread.

Post Reply