magiblot / tvision

A modern port of Turbo Vision 2.0, the classical framework for text-based user interfaces. Now cross-platform and with Unicode support.
Other
1.99k stars 150 forks source link

Error building for Win MinGW C++ #104

Closed IngvarRiga closed 10 months ago

IngvarRiga commented 1 year ago

Greetings! An error occurs when building a MinGW C++ project for Windows:

-- The C compiler identification is GNU 10.3.0
-- The CXX compiler identification is GNU 10.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/GCC/bin/gcc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/GCC/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test SUPPORTS_COUNTER_MACRO
-- Performing Test SUPPORTS_COUNTER_MACRO - Success
-- Install path: C:/Program Files (x86)/tvision
-- Build Examples: ON
-- Configuring done (2.6s)
-- Generating done (0.1s)
-- Build files have been written to: E:/tv/tets/build
[  1%] Building CXX object source/CMakeFiles/tvision.dir/cmake_pch.hxx.gch
...
[ 86%] Building CXX object source/CMakeFiles/tvision.dir/tvision/ttimerqu.cpp.obj
E:\tv\tets\source\tvision\ttimerqu.cpp: In function 'TTimePoint systemTimeMs()':
E:\tv\tets\source\tvision\ttimerqu.cpp:16:12: error: 'GetTickCount64' was not declared in this scope; did you mean 'GetTickCount'?                                                                                                                 
16 |     return GetTickCount64();
   |                ^~~~~~~~~~~~~~                                                                                             
   |            GetTickCount                                                                                         
   source\CMakeFiles\tvision.dir\build.make:3425: recipe for target 'source/CMakeFiles/tvision.dir/tvision/ttimerqu.cpp.obj' failed
   mingw32-make.exe[2]: *** [source/CMakeFiles/tvision.dir/tvision/ttimerqu.cpp.obj] Error 1 
   CMakeFiles\Makefile2:279: recipe for target 'source/CMakeFiles/tvision.dir/all' failed 
   mingw32-make.exe[1]: *** [source/CMakeFiles/tvision.dir/all] Error 2                                            
   Makefile:134: recipe for target 'all' failed 
   mingw32-make.exe: *** [all] Error 2

This has never happened before. The matter is complicated by the fact that it does not make sense to constantly update this compiler, since it is used to build Qt projects and is part of the free version.

In general, it is not entirely clear why the error occurs, since I found the function declaration itself in the headers.

the assembly is carried out by the following command file (cmake 3.26.1):

echo off
cmake.exe -B build "-GMinGW Makefiles" -DCMAKE_BUILD_TYPE=Release 
cmake --build build --config Release
echo on

Do you have any ideas?

paule32 commented 1 year ago

Hello,

first of all, make sure, you have new version stuff of MinGW - either, if you use Qt or not. Qt for Windows is compiled with the msys64 Toolchain (it is a suite of clang32/64, gcc/g++/(CLI)32/64 compilers). Then navigate to the source tree root directory. Do:

mkdir build && cd mkdir

cmake ..

Then it cmake should be write "Makefile" or "ninja.build". On first, use "# make", on last, use "# ninja" to compile the sources. If the Error still appear, try to edit E:\tv\tets\source\tvision\ttimerqu.cpp. Go to the top of the file. look, if you can find a line like # include If not, include this file with the Command above.

make or

ninja

again. If the Error still exists, try to # include If the Error still exists, modify the CMakefile.txt from the root source folder a little bit.. Add the compiler settings: "-l kernel32" (don't be confused with kernel32 on a 64 bit System - the Windows win32api will already be used in modern 64 Bit Windows Systems. Internally win32api should be named win64api - but you know Microsoft ...

More Information, you can find on MSDN

magiblot commented 1 year ago

Hi @IngvarRiga!

Could you please try adding the following line at the very beginning of ttimerqu.cpp?

#define _WIN32_WINNT 0x0600

Then build again and see if it works.

Cheers.

IngvarRiga commented 1 year ago

Hi!

Could you please try adding the following line at the very beginning of ttimerqu.cpp?

#define _WIN32_WINNT 0x0600

Result:

-- The C compiler identification is GNU 10.3.0 ... [ 86%] Building CXX object source/CMakeFiles/tvision.dir/tvision/ttimerqu.cpp.obj E:\tv\tets\source\tvision\ttimerqu.cpp:1: warning: "_WIN32_WINNT" redefined 1 #define _WIN32_WINNT 0x0600
In file included from C:/GCC/x86_64-w64-mingw32/include/corecrt.h:10, from C:/GCC/x86_64-w64-mingw32/include/crtdefs.h:10, from C:/GCC/x86_64-w64-mingw32/include/limits.h:6, from C:/GCC/lib/gcc/x86_64-w64-mingw32/10.3.0/include-fixed/limits.h:195, from C:/GCC/lib/gcc/x86_64-w64-mingw32/10.3.0/include-fixed/syslimits.h:7, from C:/GCC/lib/gcc/x86_64-w64-mingw32/10.3.0/include-fixed/limits.h:34 from E:/tv/tets/include/tvision/config.h:21, from E:/tv/tets/include/tvision/tv.h:664, from E:/tv/tets/include/pch.h:3, from E:/tv/tets/build/source/CMakeFiles/tvision.dir/cmake_pch.hxx:5, from : C:/GCC/x86_64-w64-mingw32/include/_mingw.h:233: note: this is the location of the previous definition 233 #define _WIN32_WINNT 0x502
  E:\tv\tets\source\tvision\ttimerqu.cpp: In function 'TTimePoint systemTimeMs()':                                        E:\tv\tets\source\tvision\ttimerqu.cpp:17:12: error: 'GetTickCount64' was not declared in this scope; did you mean 'GetTickCount'?

17 | return GetTickCount64(); | ^~~~~~ | GetTickCount source\CMakeFiles\tvision.dir\build.make:3425: recipe for target 'source/CMakeFiles/tvision.dir/tvision/ttimerqu.cpp.obj' failed mingw32-make.exe[2]: [source/CMakeFiles/tvision.dir/tvision/ttimerqu.cpp.obj] Error 1 CMakeFiles\Makefile2:279: recipe for target 'source/CMakeFiles/tvision.dir/all' failed mingw32-make.exe[1]: [source/CMakeFiles/tvision.dir/all] Error 2 Makefile:134: recipe for target 'all' failed mingw32-make.exe: *** [all] Error 2

Yes, I read the difference between these functions and just correcting on GetTickCount - everything came together fine. And their limitations are not critical for me.

IngvarRiga commented 1 year ago

Phew! After 100500 attempts, I found a valid GCC 13.1 build for Windows that builds the project normally. Probably in readme.md it is worth specifying under which version of the compiler the assembly should be performed. I tested MS Visual C for 2019 / 2022 (just for information)

magiblot commented 1 year ago

It is not clear to me which versions work and which don't. In the case of MinGW, I suspect it depends on where you got the compiler from. I had never run accross this issue even though this project is regularly built using MinGW in the GitHub Actions workflows.

Do you remember where you downloaded the compiler which doesn't work?

IngvarRiga commented 1 year ago

Greetings! Basically, as you can see from the first error messages, the compiler version was 10.3. It was a tdm gcc build, hence (https://jmeubank .github.io/tdm-gcc/). I just used it for a very long time and successfully. The Qt distribution has its own compiler, I won't say the version now, but in my opinion it's generally as old as mammoth shit. :) Anyway, now I have updated the compiler (link below) to 13.1 and the problem has disappeared by itself. I downloaded the latest version from here (https://winlibs.com /) version 13.1 (MCF/Latest). Well, there are many options for every taste and color. In general, it seems to me that it is worth paying more attention to the versions, I found here (https://web.archive.org/web/20160308010351/https://beefchunk.com/documentation/lang/c/pre-defined-c/precomp.html). To be honest, I don't understand at all why maintain backward compatibility with DOS, since I can't imagine a situation where such a need arises (well, maybe only after nuclear armageddon), but this is your decision and your library, so it's not for me to talk about it.

Yes. Another big question. In one of the options of the dialog editor, I saw how when installing/removing the checkbox, the availability of using another component of the /radiobutton/ button changed, etc. Including the backlight in gray. An attempt to implement such a completely standard action for today did not work out. Can you give an example of how to do this? Or to say that it is simply impossible on the STANDARD library and it is necessary to redefine the components. In my latest version of the dialog editor (I have now returned to this program) I have implemented TInputLong/TInputDouble. I suggest you take a look (if desired), maybe it's worth expanding the standard library?

IngvarRiga commented 1 year ago

Hi! May be fix it?

TButton in dialogs.h

str=277 >> ushort aFlags ) noexcept; ~TButton();

...

ushort command;

str=294 >> uchar flags;

ushort = 2 bytes / uchar = 1 bytes. Warning in empty space... :(

magiblot commented 11 months ago

Hi! Sorry for not aswering in a long time.

Greetings! Basically, as you can see from the first error messages, the compiler version was 10.3. It was a tdm gcc build, hence (https://jmeubank .github.io/tdm-gcc/). I just used it for a very long time and successfully. The Qt distribution has its own compiler, I won't say the version now, but in my opinion it's generally as old as mammoth shit. :) Anyway, now I have updated the compiler (link below) to 13.1 and the problem has disappeared by itself. I downloaded the latest version from here (https://winlibs.com /) version 13.1 (MCF/Latest). Well, there are many options for every taste and color. In general, it seems to me that it is worth paying more attention to the versions, I found here (https://web.archive.org/web/20160308010351/https://beefchunk.com/documentation/lang/c/pre-defined-c/precomp.html). To be honest, I don't understand at all why maintain backward compatibility with DOS, since I can't imagine a situation where such a need arises (well, maybe only after nuclear armageddon), but this is your decision and your library, so it's not for me to talk about it.

I haven't tried to reproduce the build issue yet, but I will try. This problem, though, has nothing to do with DOS backwards compatibility. It's just that we are using a Win32 API funciton (GetTickCount64) which these compilers do not provide even though it would be expected that they do so.

Yes. Another big question. In one of the options of the dialog editor, I saw how when installing/removing the checkbox, the availability of using another component of the /radiobutton/ button changed, etc. Including the backlight in gray. An attempt to implement such a completely standard action for today did not work out. Can you give an example of how to do this? Or to say that it is simply impossible on the STANDARD library and it is necessary to redefine the components.

I did not understand what you are trying to achieve. If you still need this, could you please explain it in more detail (e.g. with pictures)?

Hi! May be fix it?

TButton in dialogs.h

No, this is not a bug. The valid values for the aFlags parameter of TButton are:

const int
    bfNormal    = 0x00,
    bfDefault   = 0x01,
    bfLeftJust  = 0x02,
    bfBroadcast = 0x04,
    bfGrabFocus = 0x08,

All of which fit in a single byte. Therefore, an uchar is enough to store this value.

Cheers.

IngvarRiga commented 11 months ago

Greetings! Similarly, I don't approach the project for a long time, so I come back sometimes. The incomprehensible question is as follows. In modern frameworks there is such a concept of unavailability of components. That is, under certain conditions, the component is displayed on the form in gray. For example, if I select one of the checkboxes, then some buttons or input lines become unavailable for input, although they are not removed from the window. Is that clear?

In addition, if I make an input, sometimes some components have to change their value, which is usually provided by OnChangeValue or similar functions.

I don't see how to implement either the first or the second option, although in the editor of the Vision dialog from another author (old, for DOS, and I didn't find the source codes) I have seen such a reaction. Maybe I don't understand something in the library? Or maybe there is no such functionality (>>> worth adding)?

Can you comment or explain?

Thank you.

magiblot commented 11 months ago

Okay, I understand:

Disabling components of a dialog can be done by calling setState(sfDisabled, true) on them. In the particular case of TCluster and its subclasses, specific entries can be disabled through the setButtonState method.

The question then is: how do I make it so that these components get enabled/disabled right when I want it? An idiomatic solution would possibly be to define a custom command (e.g. cmValueChanged) and have your components message it to the owner view (the dialog) when their state changes (e.g. when checkbox is marked).

Most components (except TButton) don't do this by default, so you will have to create your own subclasses in order to implement this message. Then, in the dialog class (which is the recipient of this message), you can handle this command by checking the state of all the components and deciding which ones should be enabled or disabled.