# MingW64 Cross-Compiling with Extra Libraries

**URL:** <https://discourse.cmake.org/t/mingw64-cross-compiling-with-extra-libraries/7343>\
**Category:** Code\
**Created:** [January 28, 2023, 1:16pm UTC](https://discourse.cmake.org/t/mingw64-cross-compiling-with-extra-libraries/7343 "2023-01-28T13:16:03Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Xaldew](https://discourse.cmake.org/user_avatar/discourse.cmake.org/xaldew/32/3068_2.png) [@Xaldew](https://discourse.cmake.org/u/Xaldew)\
**Post date:** [January 28, 2023, 1:16pm UTC](https://discourse.cmake.org/t/mingw64-cross-compiling-with-extra-libraries/7343/1 "2023-01-28T13:16:04Z")

</div>

This is a bit of weird thing that _might_ be a bug, or just me doing something  
wrong.

Given the MingW64 CMake toolchain file:

```
set(CMAKE_SYSTEM_NAME Windows)
set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)

# Cross compilers to use for C, C++ and Fortran.

# NOTE: Use -posix suffix to explicitly use the pthreads threading model. By
# default, the -win32 based threading model is used.
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc-posix)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++-posix)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)

# Extra compiler and library flags.
set(CMAKE_C_FLAGS_INIT "-D_WIN32_WINNT=0x600")
set(CMAKE_CXX_FLAGS_INIT "-D_WIN32_WINNT=0x600")
set(CMAKE_C_STANDARD_LIBRARIES "-lws2_32")
set(CMAKE_CXX_STANDARD_LIBRARIES "-lws2_32")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-lws2_32")
set(CMAKE_STATIC_LINKER_FLAGS_INIT "-lws2_32")
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-lws2_32")
set(CMAKE_MODULE_LINKER_FLAGS_INIT "-lws2_32")

# target environment on the build host system.
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX})
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_FIND_ROOT_PATH})
set(ENV{PKG_CONFIG_LIBDIR} "${CMAKE_FIND_ROOT_PATH}/usr/lib/pkgconfig:${CMAKE_FIND_ROOT_PATH}/usr/share/pkgconfig")

# Modify default behavior of FIND_XXX() commands.
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_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

```

And an example project as follows (CMakeLists.txt, main.cpp):

CMakeLists.txt:

```
project(CCL LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
add_executable(main main.cpp)

```

Main.cpp:

```
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>

int main(void)
{
    WSADATA wsaData;
    WSAStartup(0x0101, &wsaData);
    WSACleanup();
    return 0;
}

```

This project consistently fails to build (i.e., link) with the errors:

```
$ mkdir -p build && cd build && cmake -DCMAKE_TOOLCHAIN_FILE=../mingw64-toolchain.cmake .. && make VERBOSE=1
# ...
[50%] Building CXX object CMakeFiles/main.dir/main.cpp.obj
/usr/bin/x86_64-w64-mingw32-g++-posix -D_WIN32_WINNT=0x600 -std=gnu++17 -MD -MT CMakeFiles/main.dir/main.cpp.obj -MF CMakeFiles/main.dir/main.cpp.obj.d -o CMakeFiles/main.dir/main.cpp.obj -c /home/xaldew/Dokument/cmake-mingw64/main.cpp
[100%] Linking CXX executable main.exe
/usr/bin/cmake -E cmake_link_script CMakeFiles/main.dir/link.txt --verbose=1
/usr/bin/cmake -E rm -f CMakeFiles/main.dir/objects.a
/usr/bin/x86_64-w64-mingw32-ar qc CMakeFiles/main.dir/objects.a @CMakeFiles/main.dir/objects1.rsp
/usr/bin/x86_64-w64-mingw32-g++-posix -D_WIN32_WINNT=0x600 -lws2_32 -Wl,--whole-archive CMakeFiles/main.dir/objects.a -Wl,--no-whole-archive -o main.exe -Wl,--out-implib,libmain.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles/main.dir/linklibs.rsp
/usr/bin/x86_64-w64-mingw32-ld: CMakeFiles/main.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x24): undefined reference to `__imp_WSAStartup'
/usr/bin/x86_64-w64-mingw32-ld: CMakeFiles/main.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x2d): undefined reference to `__imp_WSACleanup'
collect2: error: ld returned 1 exit status

```

However, if I touch any of the CMake files (toolchain or CMakeLists.txt) after  
the project was attempted to be built, the thing will build without any issues:

```
$ touch ../CMakeLists.txt && make VERBOSE=1
/usr/bin/cmake -S/home/xaldew/Dokument/cmake-mingw64 -B/home/xaldew/Dokument/cmake-mingw64/build --check-build-system CMakeFiles/Makefile.cmake 0
# ...
[50%] Linking CXX executable main.exe
/usr/bin/cmake -E cmake_link_script CMakeFiles/main.dir/link.txt --verbose=1
/usr/bin/cmake -E rm -f CMakeFiles/main.dir/objects.a
/usr/bin/x86_64-w64-mingw32-ar qc CMakeFiles/main.dir/objects.a @CMakeFiles/main.dir/objects1.rsp
/usr/bin/x86_64-w64-mingw32-g++-posix -D_WIN32_WINNT=0x600 -lws2_32 -Wl,--whole-archive CMakeFiles/main.dir/objects.a -Wl,--no-whole-archive -o main.exe -Wl,--out-implib,libmain.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles/main.dir/linklibs.rsp
make[2]: Lämnar katalogen ”/home/xaldew/Dokument/cmake-mingw64/build”
[100%] Built target main
make[1]: Lämnar katalogen ”/home/xaldew/Dokument/cmake-mingw64/build”
/usr/bin/cmake -E cmake_progress_start /home/xaldew/Dokument/cmake-mingw64/build/CMakeFiles 0

```

Looking at the command lines, it looks like the socket library (`-lws2_32`) is  
added way too early and the symbols for it discarded before the actual object is  
processed. Am I missing some CMake library variable in my toolchain that causes  
this problem, or are one of the `LINKER` variables incorrectly being set too  
early on the command line for the first run?

---

<div class="post-metadata">

**Author:** ![Xaldew](https://discourse.cmake.org/user_avatar/discourse.cmake.org/xaldew/32/3068_2.png) [@Xaldew](https://discourse.cmake.org/u/Xaldew)\
**Post date:** [February 3, 2023, 2:53pm UTC](https://discourse.cmake.org/t/mingw64-cross-compiling-with-extra-libraries/7343/2 "2023-02-03T14:53:45Z")

</div>

One way to solve this is simply to add the library dependency to the target in  
the main `CMakeLists.txt`:

```
if (WIN32)
  find_library(WINSOCK2 ws2_32)
  target_link_libraries(main PUBLIC ${WINSOCK2})
endif()

```

I would have preferred not to do that and keep the platform specific  
dependencies in the toolchain but maybe that’s not possible?
