2

I am porting an application I wrote on linux to Windows. I am trying to cross-compile on linux for windows. Part of porting the application includes the usage of the winsock library. In order to cross-compile, I decided to use x86_64-w64-mingw32-g++.

I followed the instructions provided on cmakes official documentation on cross-compiling, where I specify a toolchain file tc-mingw.cmake.

test.cpp:

#include "winsock2.h"


int main()
{
  pollfd poll_fd;

  return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.20)
project(Multi3D)

set(CMAKE_CXX_FLAGS "-std=c++17 -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "-std=c++17 -Wall -O3")

find_library(WSOCK32_LIBRARY wsock32 HINTS /usr/x86_64-w64-mingw32/lib/)
find_library(WS2_32_LIBRARY ws2_32 HINTS /usr/x86_64-w64-mingw32/lib/)

if (NOT WSOCK32_LIBRARY OR NOT WS2_32_LIBRARY)
  message(FATAL_ERROR "Could not find winsock libraries")
else()
  message(STATUS "Windows libs found: ${WSOCK32_LIBRARY} ${WS2_32_LIBRARY}")
endif()

add_executable(testbinary test.cpp)

target_link_libraries(testbinary
                      ${WSOCK32_LIBRARY}
                      ${WS2_32_LIBRARY})

tc-mingw.cmake

set(CMAKE_SYSTEM_NAME Windows)

set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)

set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32/)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

Calling with

cmake -DCMAKE_TOOLCHAIN_FILE=../tc-mingw.cmake ..

Finds the libraries

-- Windows libs found: /usr/x86_64-w64-mingw32/lib/libwsock32.a /usr/x86_64-w64-mingw32/lib/libws2_32.a

but oddly results in the compilation error

> error: ‘pollfd’ was not declared in this scope
    6 |   pollfd poll_fd;

And so, winsock types seem to not be declared when compiling with my build setup. I can't figure out why! Any help would be greatly appreciated.

I checked under /usr/x86_64-w64-mingw32/include/, which should be where the includes are, and all the correct files are there, including winsock2.h.

aai922
  • 21
  • 2
  • 1
    Probably unrelated, but please take some time to read [What is the difference between #include and #include "filename"?](https://stackoverflow.com/questions/21593/what-is-the-difference-between-include-filename-and-include-filename). – Some programmer dude Sep 11 '22 at 12:25
  • 1
    Thanks for pointing that out. Researching this issue actually introduced me to this difference for the first time! I wasn't aware that there was one. It turns out that defining #define _WIN32_WINNT 0x0600 fixes my issue. It appears that the detected version of windows my mingw compiler uses is incompatible with many winsock2 types? – aai922 Sep 11 '22 at 12:27
  • Unless you found the solution here on Stack Overflow, you should write an answer about that (please read about [how to write good answers](https://stackoverflow.com/help/how-to-answer)). Otherwise, and if possible, please either close the question as a duplicate or delete it to avoid duplicates. :) – Some programmer dude Sep 11 '22 at 12:31
  • I will refrain from writing an answer as I do not wish to add a 'bad answer'. I don't understand _WIN32_WINNT, nor do I understand potential consequences that may or may not arise due to this manual definition. As such, I don't want to lead people to unwittingly include buggy code in their project! If someone with knowledge on _WIN32_WINNT could confirm that my comment above is an acceptable solution, that'd be great. – aai922 Sep 11 '22 at 12:36
  • These are the versions of windows from which the code can run. "0x0600" is for windows vista. Earlier versions do not have the appropriate dlls for the code in question. – CGi03 Sep 11 '22 at 13:40
  • Winsock doesn't define the `pollfd` type, because it doesn't have the `poll()` function to begin with. That is a POSIX function, not a Windows function. Winsock has a (buggy) `WSAPoll()` function, which uses a `WSAPOLLFD` type instead. – Remy Lebeau Sep 11 '22 at 18:42

1 Answers1

0

First of all winsock2.h is a system library, so it makes more sense to use angle brackets instead of double quotes.

So test.cpp will should look like this:

#include <winsock2.h>


int main()
{
  pollfd poll_fd;

  return 0;
}

If I build that with g++ -std=c++17 -Wall -O3 test.cpp -o test.exe -lws2_32 with a recent version if MinGW-w64 it succeeds (apart from warning: unused variable 'poll_fd' [-Wunused-variable], which makes sense).

Latest version is 12.2.0.

You can check the version you're using by running g++ --version.

If you're cross-building on Linux you should replace g++ in the commands above with x86_64-w64-mingw32-g++-win32

Brecht Sanders
  • 6,215
  • 1
  • 16
  • 40