Search code examples
c++mingwcross-compilingmingw-w64

Setting up stdlib path while compiling with mingw on linux


I am trying to build my c++ CMake project on linux with mingw. CMakeLists.txt consists of (for understanding):

  • Setting up project info:
project(<project name> LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
  • Setting up TRY_COMPILE target type:
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
  • Setting up boost:
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)

find_package(Boost COMPONENTS system program_options REQUIRED)
  • Including subdirectories in which there is nothing about mingw:
add_subdirectory(<some_subdirectory>)
...

At the time of build process I see the following compilation command in the log:

/usr/bin/x86_64-w64-mingw32-g++  -I/usr/include -I<user include 1> -I<user include 2> -O3 -DNDEBUG -std=gnu++20 -MD -MT CMakeFiles/common.dir/<source>.cpp.o -MF <source>.cpp.o.d -o <source>.cpp.o -c <project path>/<source>.cpp

After that goes a compiler error message with the following beginning:

[build] In file included from /usr/x86_64-w64-mingw32/include/c++/12.2.0/cstdint:41,
[build]                  from /usr/x86_64-w64-mingw32/include/c++/12.2.0/bits/char_traits.h:731,
[build]                  from /usr/x86_64-w64-mingw32/include/c++/12.2.0/ios:40,
[build]                  from /usr/x86_64-w64-mingw32/include/c++/12.2.0/ostream:38,
[build]                  from <project path>/<source>.hpp:5,
[build]                  from <project path>/<source>.cpp:1:
[build] /usr/include/stdint.h:90:33: error: conflicting declaration «typedef long unsigned int uintptr_t»
[build]    90 | typedef unsigned long int       uintptr_t;
[build]       |                                 ^~~~~~~~~
...

According to the internet this error message is connected with the different mingw standard library implementation. I guess in a compile command there should somehow be -I/usr/x86_64-w64-mingw32/include on a place of -I/usr/include in a compilation command. If I am right there, the question is "How to change standard include directory for mingw build spicifically?". If I am not right there, then how to solve the problem with project building?

PS: The project builds using both clang++ and g++.


Solution

  • I found two ways of solving the problem without additional tools.

    Installing special boost package for MinGW

    First of all, to cross-compile project with boost it is good to have special package of boost. For me it was mingw-w64-boost:

    > yay mingw-w64-boost
    

    Then I had to set BOOST_ROOT to /usr/x86_64-w64-mingw32/include/ before find_package(...) or set BOOST_INCLUDEDIR manually (again, to /usr/x86_64-w64-mingw32/include/).

    Including boost from sources

    It is also possible to add boost modules directly from github:

    function(add_boost_package PackageName package_repo_addr tag)
        message(STATUS "FetchContent: ${PackageName}, ${package_repo_addr}, ${tag}")
    
        FetchContent_Declare(
            ${PackageName}
            GIT_REPOSITORY https://github.com/boostorg/${package_repo_addr}.git
            GIT_TAG ${tag}
        )
    
        FetchContent_MakeAvailable(${PackageName})
    endfunction()
    
    SET(BOOST_FETCHCONTENT_TAG boost-1.81.0)
    
    add_boost_package(Boost.Core core ${BOOST_FETCHCONTENT_TAG})
    add_boost_package(Boost.Config config ${BOOST_FETCHCONTENT_TAG})
    add_boost_package(Boost.Assert assert ${BOOST_FETCHCONTENT_TAG})
    ...