aai922
aai922

Reputation: 31

Why are winsock types undeclared when compiling C++ with winsock, cmake and mingw?

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.

Upvotes: 3

Views: 338

Answers (1)

Brecht Sanders
Brecht Sanders

Reputation: 7287

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

Upvotes: 1

Related Questions