跨编译项目在Linux上为Windows。

huangapple go评论83阅读模式
英文:

Crosscompilation project on Linux for Windows

问题

I would like to compile C++ http server on my archlinux using drogon framework for Windows.
我想在我的Arch Linux上使用Drogon框架为Windows编译C++ HTTP服务器。

I read about possible way on official cmake docs:
我在官方CMake文档上了解了可能的方法:

https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html

I have installed all required mingw64-*** utilities and faced problem that after specialized -DCMAKE_TOOLCHAIN_FILE cmake no more can find Drogon package with find_package() command.
我已安装了所有必需的mingw64-***工具,但遇到了问题,即在使用专门的-DCMAKE_TOOLCHAIN_FILE后,CMake不能再使用find_package()命令找到Drogon包。

here is my main CMakeList.txt
这是我的主要CMakeList.txt文件

cmake_minimum_required(VERSION 3.5)
project(lru_server CXX)

include(CheckIncludeFileCXX)

check_include_file_cxx(any HAS_ANY)
check_include_file_cxx(string_view HAS_STRING_VIEW)
check_include_file_cxx(coroutine HAS_COROUTINE)
if (NOT "${CMAKE_CXX_STANDARD}" STREQUAL "")
    # Do nothing
elseif (HAS_ANY AND HAS_STRING_VIEW AND HAS_COROUTINE)
    set(CMAKE_CXX_STANDARD 20)
elseif (HAS_ANY AND HAS_STRING_VIEW)
    set(CMAKE_CXX_STANDARD 17)
else ()
    set(CMAKE_CXX_STANDARD 14)
endif ()

set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

add_executable(${PROJECT_NAME} main.cpp)
target_include_directories(${PROJECT_NAME} PUBLIC
    lru_cache/
    endpoints/
)

target_sources( ${PROJECT_NAME} PUBLIC
    lru_cache/lru_cache.cpp
    endpoints/ApiController.cpp
)

find_package(Drogon CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE Drogon::Drogon)

if (CMAKE_CXX_STANDARD LESS 17)
    # With C++14, use boost to support any, string_view and filesystem
    message(STATUS "use c++14")
    find_package(Boost 1.61.0 REQUIRED)
    target_link_libraries(${PROJECT_NAME} PUBLIC Boost::boost)
elseif (CMAKE_CXX_STANDARD LESS 20)
    message(STATUS "use c++17")
else ()
    message(STATUS "use c++20")
endif ()

aux_source_directory(controllers CTL_SRC)
aux_source_directory(filters FILTER_SRC)
aux_source_directory(plugins PLUGIN_SRC)
aux_source_directory(models MODEL_SRC)

drogon_create_views(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/views
                    ${CMAKE_CURRENT_BINARY_DIR})

target_include_directories(${PROJECT_NAME}
                           PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
                                   ${CMAKE_CURRENT_SOURCE_DIR}/models)
target_sources(${PROJECT_NAME}
               PRIVATE
               ${SRC_DIR}
               ${CTL_SRC}
               ${FILTER_SRC}
               ${PLUGIN_SRC}
               ${MODEL_SRC})

also toolchain file:
还有工具链文件:

# the name of the target operating system
set(CMAKE_SYSTEM_NAME Windows)

# which compilers to use for C and C++
set(CMAKE_C_COMPILER   x86_64-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)

# where is the target environment located
set(CMAKE_FIND_ROOT_PATH 
    /usr/x86_64-w64-mingw32    
    /usr/x86_64-w64-mingw32/lib
    /usr/lib
    /usr/lib/cmake
    /usr/lib/cmake/Drogon)

# adjust the default behavior of the FIND_XXX() commands:
# search programs in the host environment
# set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

# search headers and libraries in the target environment
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

cmake -S /my_project_dir -B build-lru_server-MinGW64 -DCMAKE_TOOLCHAIN_FILE=/toolchain-mingw.cmake

without -DCMAKE_TOOLCHAIN_FILE all works (using clang++ compiller).

the cmake output error:
CMake输出错误:

[20:01:45] @archlinux bin$ cmake -S /var/repo/lru_cpp_rest_server/lru_server -B /var/repo_build/lru_cpp_rest_server/build-lru_server-MinGW64 -DCMAKE_TOOLCHAIN_FILE=/var/repo/lru_cpp_rest_server/lru_server/TC-mingw.cmake
CMake Warning (dev) at CMakeLists.txt:29 (target_sources):
  Policy CMP0076 is not set: target_sources() command converts relative paths
  to absolute.  Run "cmake --help-policy CMP0076" for policy details.  Use
  the cmake_policy command to set the policy and suppress this warning.

  An interface source of target "lru_server" has a relative path.
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Error at CMakeLists.txt:42 (find_package):
  Could not find a package configuration file provided by "Drogon" with any
  of the following names:

    DrogonConfig.cmake
    drogon-config.cmake

  Add the installation prefix of "Drogon" to CMAKE_PREFIX_PATH or set
  "Drogon_DIR" to a directory containing one of the above files.  If "Drogon"
  provides a separate development package or SDK, be sure it has been
  installed.

Why when i using toolchain drogon and other installed on system files not foundable?

为什么使用Drogon工具链和其他已安装在系统上的文件找不到?

英文:

I would like to compile C++ http server on my archlinux using drogon framework for Windows.
I read about possible way on official cmake docs:
https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html

I have installed all required mingw64-*** utilities and faced problem that after specialized -DCMAKE_TOOLCHAIN_FILE cmake no more can find Drogon package with find_package() command.

here is my main CMakeList.txt

cmake_minimum_required(VERSION 3.5)
project(lru_server CXX)

include(CheckIncludeFileCXX)

check_include_file_cxx(any HAS_ANY)
check_include_file_cxx(string_view HAS_STRING_VIEW)
check_include_file_cxx(coroutine HAS_COROUTINE)
if (NOT "${CMAKE_CXX_STANDARD}" STREQUAL "")
    # Do nothing
elseif (HAS_ANY AND HAS_STRING_VIEW AND HAS_COROUTINE)
    set(CMAKE_CXX_STANDARD 20)
elseif (HAS_ANY AND HAS_STRING_VIEW)
    set(CMAKE_CXX_STANDARD 17)
else ()
    set(CMAKE_CXX_STANDARD 14)
endif ()

set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

add_executable(${PROJECT_NAME} main.cpp)
target_include_directories(${PROJECT_NAME} PUBLIC
    lru_cache/
    endpoints/
)

target_sources( ${PROJECT_NAME} PUBLIC
    lru_cache/lru_cache.cpp
    endpoints/ApiController.cpp
)


find_package(Drogon CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE Drogon::Drogon)


if (CMAKE_CXX_STANDARD LESS 17)
    # With C++14, use boost to support any, string_view and filesystem
    message(STATUS "use c++14")
    find_package(Boost 1.61.0 REQUIRED)
    target_link_libraries(${PROJECT_NAME} PUBLIC Boost::boost)
elseif (CMAKE_CXX_STANDARD LESS 20)
    message(STATUS "use c++17")
else ()
    message(STATUS "use c++20")
endif ()

aux_source_directory(controllers CTL_SRC)
aux_source_directory(filters FILTER_SRC)
aux_source_directory(plugins PLUGIN_SRC)
aux_source_directory(models MODEL_SRC)

drogon_create_views(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/views
                    ${CMAKE_CURRENT_BINARY_DIR})

target_include_directories(${PROJECT_NAME}
                           PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
                                   ${CMAKE_CURRENT_SOURCE_DIR}/models)
target_sources(${PROJECT_NAME}
               PRIVATE
               ${SRC_DIR}
               ${CTL_SRC}
               ${FILTER_SRC}
               ${PLUGIN_SRC}
               ${MODEL_SRC})

also toolchain file:

# the name of the target operating system
set(CMAKE_SYSTEM_NAME Windows)

# which compilers to use for C and C++
set(CMAKE_C_COMPILER   x86_64-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)

# where is the target environment located
set(CMAKE_FIND_ROOT_PATH 
    /usr/x86_64-w64-mingw32    
    /usr/x86_64-w64-mingw32/lib
    /usr/lib
    /usr/lib/cmake
    /usr/lib/cmake/Drogon)

# adjust the default behavior of the FIND_XXX() commands:
# search programs in the host environment
# set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

# search headers and libraries in the target environment
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

cmake -S /my_project_dir -B build-lru_server-MinGW64 -DCMAKE_TOOLCHAIN_FILE=/toolchain-mingw.cmake

without -DCMAKE_TOOLCHAIN_FILE all works (using clang++ compiller).

the cmake output error:

[20:01:45] @archlinux bin$ cmake -S /var/repo/lru_cpp_rest_server/lru_server -B /var/repo_build/lru_cpp_rest_server/build-lru_server-MinGW64 -DCMAKE_TOOLCHAIN_FILE=/var/repo/lru_cpp_rest_server/lru_server/TC-mingw.cmake
CMake Warning (dev) at CMakeLists.txt:29 (target_sources):
  Policy CMP0076 is not set: target_sources() command converts relative paths
  to absolute.  Run "cmake --help-policy CMP0076" for policy details.  Use
  the cmake_policy command to set the policy and suppress this warning.

  An interface source of target "lru_server" has a relative path.
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Error at CMakeLists.txt:42 (find_package):
  Could not find a package configuration file provided by "Drogon" with any
  of the following names:

    DrogonConfig.cmake
    drogon-config.cmake

  Add the installation prefix of "Drogon" to CMAKE_PREFIX_PATH or set
  "Drogon_DIR" to a directory containing one of the above files.  If "Drogon"
  provides a separate development package or SDK, be sure it has been
  installed.

Why when i using toolchain drogon and other installed on system files not foundable?

UPD:
after advices from @Tsyvarev

[22:19:01] alxndrklbk@archlinux bin$ cmake -S /var/repo/lru_cpp_rest_server/lru_server/ -B build-lru_server-MinGW-Debug -DCMAKE_TOOLCHAIN_FILE=/var/repo/lru_cpp_rest_server/lru_server/TC-mingw.cmake
-- The CXX compiler identification is GNU 12.2.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/x86_64-w64-mingw32-gcc - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for C++ include any
-- Looking for C++ include any - found
-- Looking for C++ include string_view
-- Looking for C++ include string_view - found
-- Looking for C++ include coroutine
-- Looking for C++ include coroutine - not found
CMake Warning (dev) at CMakeLists.txt:29 (target_sources):
  Policy CMP0076 is not set: target_sources() command converts relative paths
  to absolute.  Run "cmake --help-policy CMP0076" for policy details.  Use
  the cmake_policy command to set the policy and suppress this warning.

  An interface source of target "lru_server" has a relative path.
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Found Jsoncpp: /usr/x86_64-w64-mingw32/include  
CMake Error at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
  Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the
  system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY
  OPENSSL_INCLUDE_DIR)
Call Stack (most recent call 

答案1

得分: 1

我已成功使用 quasi-msys2(我是其作者)对您的项目进行了交叉编译。

它会处理工具链文件,所以您不需要自己编写。

  • 首先,安装 quasi-msys2 的先决条件(这是针对 Ubuntu 22.04 的,根据 Arch 进行调整):

    sudo apt install make wget tar zstd gpg wine
    # 安装 Clang 和 LLD
    bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
    

    请注意,这里使用 Clang 代替 GCC。

  • 然后安装 quasi-msys2,以及其中的必要软件包:

    git clone https://github.com/HolyBlackCat/quasi-msys2
    cd quasi-msys2 
    make install _gcc _jsoncpp _zlib _openssl
    env/shell.sh
    cd ..
    

    在这里,我们安装 MSYS2 GCC 以获取它提供的库。由于 Drogon 不在 MSYS2 软件包中,我们必须自己构建它并安装其依赖项:jsoncpp、zlib、openssl。

  • 克隆 Drogon:

    git clone https://github.com/drogonframework/drogon
    cd drogon
    git submodule update --init --recursive
    cd ..
    
  • 修复其中的问题:

    • 将标头和库重命名为小写,因为我们的设置区分大小写,与本机 Windows 不同:
      find drogon -type f -exec sed -i -E 's/(Windows.h|WinSock2.h|Rpc.h|Rpcrt4|Crypt32|Secur32)/\L/g' {} +
      
    • 添加缺少的标头:
      (echo -e '#include <dirent.h>\n#include <sys/stat.h>'; cat drogon/trantor/trantor/utils/AsyncFileLogger.cc) | sponge drogon/trantor/trantor/utils/AsyncFileLogger.cc
      
  • 构建 Drogon:

    CXXFLAGS='-Wno-defaulted-function-deleted -Wno-unqualified-std-cast-call -Wno-inconsistent-missing-override' cmake -S drogon -B drogon-build
    cmake --build drogon-build -j`nproc`
    cmake --install drogon-build
    

    在这里,我们消除了一些 Clang 警告。

    我们还将生成的库安装到 quasi-msys2 安装中。通常情况下,我会建议避免这样做,因为这会将您的文件与 msys2 软件包的文件混合在一起。

    但这会让事情变得更容易。如果您搞砸了什么,您可以快速使用 make reinstall-all 将 quasi-msys2 重置为干净的状态。

  • 最后,克隆并构建您的项目:

    git clone https://github.com/AlxndrKlbk/lru_cpp_rest_server
    cmake -S lru_cpp_rest_server/lru_server/ -B lru_server-build
    cmake --build lru_server-build -j`nproc`
    
  • 然后运行它(这将使用 Wine):

    lru_server-build/lru_server.exe 
    

已报告的问题:

英文:

I've successfully cross-compiled your project with quasi-msys2 (which I'm the author of).

It takes care of the toolchain file, so you don't need to write one yourself.

  • First, install quasi-msys2 prerequisites (this is for Ubuntu 22.04, adjust for Arch):

    sudo apt install make wget tar zstd gpg wine
    # Install Clang and LLD
    bash -c &quot;$(wget -O - https://apt.llvm.org/llvm.sh)&quot;
    

    Note Clang, I'm going to be using it instead of GCC for this.

  • Then install quasi-msys2, and the necessary packages from it:

    git clone https://github.com/HolyBlackCat/quasi-msys2
    cd quasi-msys2 
    make install _gcc _jsoncpp _zlib _openssl
    env/shell.sh
    cd ..
    

    Here we install MSYS2 GCC for the libraries it provides. Also, since Drogon is not in MSYS2 packages, we have to build it ourselves, and need to install its dependencies: jsoncpp, zlib, openssl.

  • Clone Drogon:

    git clone https://github.com/drogonframework/drogon
    cd drogon
    git submodule update --init --recursive
    cd ..
    
  • Patch out their bugs:

    • Rename headers and libraries to lowercase, since our setup is case-sensitive, unlike native Windows:
      find drogon -type f -exec sed -i -E &#39;s/(Windows.h|WinSock2.h|Rpc.h|Rpcrt4|Crypt32|Secur32)/\L/g&#39; {} +
      
    • Add missing headers:
      (echo -e &#39;#include &lt;dirent.h&gt;\n#include &lt;sys/stat.h&gt;&#39;; cat drogon/trantor/trantor/utils/AsyncFileLogger.cc) | sponge drogon/trantor/trantor/utils/AsyncFileLogger.cc
      
  • Build Drogon:

    CXXFLAGS=&#39;-Wno-defaulted-function-deleted -Wno-unqualified-std-cast-call -Wno-inconsistent-missing-override&#39; cmake -S drogon -B drogon-build
    cmake --build drogon-build -j`nproc`
    cmake --install drogon-build
    

    Here we silence a few Clang warnings here.

    We also install the resulting library into our quasi-msys2 installation. Normally I would advise against this, since this mixes your files with those from msys2 packages.

    But it makes things easier. And you can quickly reset quasi-msys2 to a clean state using make reinstall-all, if you mess something up.

  • Lastly, clone and build your project:

    git clone https://github.com/AlxndrKlbk/lru_cpp_rest_server
    cmake -S lru_cpp_rest_server/lru_server/ -B lru_server-build
    cmake --build lru_server-build -j`nproc`
    
  • And run it (this uses Wine):

    lru_server-build/lru_server.exe 
    

Reported issues:

huangapple
  • 本文由 发表于 2023年6月29日 23:27:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76582506.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定