ThePhD / infoware

C++ Library for pulling system and hardware information, without hitting the command line.
Creative Commons Zero v1.0 Universal
410 stars 84 forks source link

Cannot build with MinGW on Linux for Windows #71

Closed nthirtyone closed 6 months ago

nthirtyone commented 6 months ago

When cross-compiling on Linux for Windows using MinGW build fails due to:

  1. "no known conversion (...) to MONITORENUMPROC" in _src/system/displays/displayswindows.cpp:26:57:
[  3%] Built target infoware_pci_generator
[  5%] Built target infoware_generate_pcis
[  7%] Building CXX object CMakeFiles/infoware.dir/src/system/displays/displays_windows.cpp.obj
/home/aki/src/infoware/src/system/displays/displays_windows.cpp: In function ‘std::vector<iware::system::display_t> iware::system::displays()’:
/home/aki/src/infoware/src/system/displays/displays_windows.cpp:26:57: error: invalid user-defined conversion from ‘iware::system::displays()::<lambda(auto:1, auto:2, auto:3, auto:4)>’ to ‘MONITORENUMPROC’ {aka ‘int (__attribute__((stdcall)) *)(HMONITOR__*, HDC__*, tagRECT*, long int)’} [-fpermissive]
   26 |         EnumDisplayMonitors(bundle.desktop_dc, nullptr, [](auto, auto hdc, auto rect, auto userdata) CALLBACK -> BOOL {
      |                                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   27 |         auto& bundle = *reinterpret_cast<struct bundle*>(userdata);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   28 | 
      |                                                          
   29 |         const unsigned int desktop_dpi = GetDeviceCaps(bundle.desktop_dc, LOGPIXELSX);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   30 |         // https://blogs.msdn.microsoft.com/oldnewthing/20101013-00/?p=12543
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   31 |         const unsigned int desktop_bpp    = GetDeviceCaps(bundle.desktop_dc, BITSPIXEL) * GetDeviceCaps(bundle.desktop_dc, PLANES);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   32 |         const double desktop_refresh_rate = GetDeviceCaps(bundle.desktop_dc, VREFRESH);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   33 | 
      |                                                          
   34 | 
      |                                                          
   35 |         // Sometimes returns 0 – fall back to the desktop's globals if so.
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   36 |         const unsigned int monitor_dpi    = GetDeviceCaps(hdc, LOGPIXELSX);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   37 |         const unsigned int monitor_bpp    = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   38 |         const double monitor_refresh_rate = GetDeviceCaps(hdc, VREFRESH);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   39 | 
      |                                                          
   40 |         const unsigned int width  = std::abs(rect->right - rect->left);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   41 |         const unsigned int height = std::abs(rect->bottom - rect->top);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   42 | 
      |                                                          
   43 |         // See http://stackoverflow.com/a/12654433/2851815 and up for DPI. In short: can't be done too too well, go with best solution.
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   44 |         bundle.ret.push_back({width, height, monitor_dpi ? monitor_dpi : desktop_dpi, monitor_bpp ? monitor_bpp : desktop_bpp,
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   45 |                               monitor_refresh_rate ? monitor_refresh_rate : desktop_refresh_rate});
      |                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   46 | 
      |                                                          
   47 |         return TRUE;
      |         ~~~~~~~~~~~~                                     
   48 |         }, reinterpret_cast<LPARAM>(&bundle));
      |         ~                                                
/home/aki/src/infoware/src/system/displays/displays_windows.cpp:26:57: note: candidate is: ‘iware::system::displays()::<lambda(auto:1, auto:2, auto:3, auto:4)>::operator BOOL (*)(auto:1, auto:2, auto:3, auto:4)() const [with auto:1 = HMONITOR__*; auto:2 = HDC__*; auto:3 = tagRECT*; auto:4 = long int; BOOL = int]’ (near match)
   26 |         EnumDisplayMonitors(bundle.desktop_dc, nullptr, [](auto, auto hdc, auto rect, auto userdata) CALLBACK -> BOOL {
      |                                                         ^
/home/aki/src/infoware/src/system/displays/displays_windows.cpp:26:57: note:   no known conversion from ‘BOOL (*)(HMONITOR__*, HDC__*, tagRECT*, long int)’ {aka ‘int (*)(HMONITOR__*, HDC__*, tagRECT*, long int)’} to ‘MONITORENUMPROC’ {aka ‘int (__attribute__((stdcall)) *)(HMONITOR__*, HDC__*, tagRECT*, long int)’}
In file included from /usr/i686-w64-mingw32/include/windows.h:72,
                 from /home/aki/src/infoware/src/system/displays/displays_windows.cpp:14:
/usr/i686-w64-mingw32/include/winuser.h:5866:90: note:   initializing argument 3 of ‘WINBOOL EnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM)’
 5866 |   WINUSERAPI WINBOOL WINAPI EnumDisplayMonitors(HDC hdc,LPCRECT lprcClip,MONITORENUMPROC lpfnEnum,LPARAM dwData);
      |                                                                          ~~~~~~~~~~~~~~~~^~~~~~~~
make[2]: *** [CMakeFiles/infoware.dir/build.make:617: CMakeFiles/infoware.dir/src/system/displays/displays_windows.cpp.obj] Error 1
make[1]: *** [CMakeFiles/Makefile2:94: CMakeFiles/infoware.dir/all] Error 2
make: *** [Makefile:146: all] Error 2
  1. Potential problems due to not being able to launch pci_generator in a correct emulation environment.
  2. Lowercase vs. Uppercase library names

Example toolchain file:

set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)

set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64)

set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
set(CMAKE_MC_COMPILER ${TOOLCHAIN_PREFIX}-windmc)

Example options:

-DCMAKE_TOOLCHAIN_FILE=../tools/x86_64-w64-mingw32.cmake
-DINFOWARE_EXAMPLES=ON
-DINFOWARE_TESTS=ON
-DINFOWARE_USE_D3D=ON