英文:
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
- 将标头和库重命名为小写,因为我们的设置区分大小写,与本机 Windows 不同:
-
构建 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
已报告的问题:
- https://github.com/an-tao/trantor/issues/267
- https://github.com/an-tao/trantor/issues/268
- https://github.com/drogonframework/drogon/issues/1655
- https://github.com/drogonframework/drogon/issues/1656
英文:
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 "$(wget -O - https://apt.llvm.org/llvm.sh)"
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 's/(Windows.h|WinSock2.h|Rpc.h|Rpcrt4|Crypt32|Secur32)/\L/g' {} +
- Add missing headers:
(echo -e '#include <dirent.h>\n#include <sys/stat.h>'; cat drogon/trantor/trantor/utils/AsyncFileLogger.cc) | sponge drogon/trantor/trantor/utils/AsyncFileLogger.cc
- Rename headers and libraries to lowercase, since our setup is case-sensitive, unlike native Windows:
-
Build 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
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:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论