c++ Linux for Windows上的交叉编译项目

vfhzx4xs  于 2023-07-01  发布在  Linux
关注(0)|答案(1)|浏览(183)

我想在我的archlinux上使用drogon framework for Windows编译C++ http服务器。我在官方的cmake文档中读到了可能的方法:
https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html
我已经安装了所有需要的mingw 64-* 实用程序,并面临的问题,在专门的-DCMAKE_TOOLCHAIN_FILE cmake没有更多的可以找到Drogon包与find_package()命令。
这是我的主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})

工具链文件:

# 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
不带-DCMAKE_TOOLCHAIN_FILE的情况下都可以工作(使用clang++ compiller)。
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.

为什么当我使用工具链drogon和其他安装在系统上的文件找不到?
UPD:在@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
ngynwnxp

ngynwnxp1#

我已经成功地用quasi-msys2(我是作者)交叉编译了你的项目。
它负责工具链文件,所以你不需要自己写一个。

  • 首先,安装quasi-msys 2先决条件(这是针对Ubuntu 22.04,针对Arch进行调整):
sudo apt install make wget tar zstd gpg wine
# Install Clang and LLD
bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"

注意Clang,我将使用它而不是GCC。

  • 然后安装quasi-msys 2,并从中安装必要的软件包:
git clone https://github.com/HolyBlackCat/quasi-msys2
cd quasi-msys2 
make install _gcc _jsoncpp _zlib _openssl
env/shell.sh
cd ..

这里我们为它提供的库安装MSYS 2 GCC。此外,由于Drogon不在MSYS 2包中,我们必须自己构建它,并需要安装它的依赖项:jsoncpp,zlib,openssl.

  • 克隆卓耿:
git clone https://github.com/drogonframework/drogon
cd drogon
git submodule update --init --recursive
cd ..
  • 修补他们的bug:
  • 将头文件和库文件重命名为小写,因为我们的设置是区分大小写的,这与原生Windows不同:
find drogon -type f -exec sed -i -E 's/(Windows.h|WinSock2.h|Rpc.h|Rpcrt4|Crypt32|Secur32)/\L\1/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

在这里,我们沉默了一些叮当声警告。
我们还将生成的库安装到准msys 2安装中。通常我会建议不要这样做,因为这会将您的文件与来自msys 2包的文件混合在一起。
但这会让事情变得简单。如果您搞砸了什么,您可以使用make reinstall-all将quasi-msys 2快速重置为干净的状态。

  • 最后,克隆并构建您的项目:
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

报告的问题:

相关问题