基于MinGW编译依赖Protobuf/Asio的C++项目为Windows可执行文件的问题
问题描述
我有一个基于Protobuf和Asio的C项目,在Linux环境下用g可正常编译。但配置CMake Presets使用MinGW交叉编译生成Windows可执行文件时,CMake生成步骤失败,提示找不到ZLIB::ZLIB目标;同时存在absl相关警告,不过Linux下g++编译时无此问题。以下是相关文件和日志,求指导如何用MinGW完成编译。
CMakePresets.json
{ "version": 8, "configurePresets": [ { "name": "debug", "displayName": "Debug", "description": "Using compiler: CXX = /usr/bin/g++", "binaryDir": "${sourceDir}/out/build/${presetName}", "cacheVariables": { "CMAKE_CXX_COMPILER": "/usr/bin/g++", "CMAKE_BUILD_TYPE": "Debug" } }, { "name": "windows-debug", "displayName": "Windows Debug", "description": "Using compiler: CXX = /usr/bin/x86_64-w64-mingw32-g++", "binaryDir": "${sourceDir}/out/build/${presetName}", "cacheVariables": { "CMAKE_SYSTEM_NAME": "Windows", "CMAKE_CXX_COMPILER": "/usr/bin/x86_64-w64-mingw32-g++", "CMAKE_BUILD_TYPE": "Debug" } } ], "buildPresets": [ { "name": "debug", "configurePreset": "debug" }, { "name": "windows-debug", "configurePreset": "windows-debug" } ] }
MinGW编译时CMake错误日志
[main] Configuring project: dark-proxy [proc] Executing command: /usr/bin/cmake -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_CXX_COMPILER=/usr/bin/x86_64-w64-mingw32-g++ -DCMAKE_BUILD_TYPE=Debug -S/home/burger/Desktop/dark-proxy -B/home/burger/Desktop/dark-proxy/out/build/windows-debug [cmake] -- Could NOT find ZLIB (missing: ZLIB_LIBRARY) (found version "1.3") [cmake] CMake Warning at /usr/local/lib/cmake/protobuf/protobuf-config.cmake:9 (find_package): [cmake] Found package configuration file: [cmake] [cmake] /usr/local/lib/cmake/absl/abslConfig.cmake [cmake] [cmake] but it set absl_FOUND to FALSE so package "absl" is considered to be NOT [cmake] FOUND. Reason given by package: [cmake] [cmake] The following imported targets are referenced, but are missing: [cmake] protobuf::gmock [cmake] [cmake] Call Stack (most recent call first): [cmake] protos/CMakeLists.txt:1 (find_package) [cmake] [cmake] [cmake] -- Found Protobuf package with version : 29.0.0 [cmake] -- Configuring done (0.0s) [cmake] CMake Error at /usr/local/lib/cmake/protobuf/protobuf-targets.cmake:70 (set_target_properties): [cmake] The link interface of target "protobuf::libprotobuf" contains: [cmake] [cmake] ZLIB::ZLIB [cmake] [cmake] but the target was not found. Possible reasons include: [cmake] [cmake] * There is a typo in the target name. [cmake] * A find_package call is missing for an IMPORTED target. [cmake] * An ALIAS target is missing. [cmake] [cmake] Call Stack (most recent call first): [cmake] /usr/local/lib/cmake/protobuf/protobuf-config.cmake:16 (include) [cmake] protos/CMakeLists.txt:1 (find_package) [cmake] [cmake] [cmake] -- Generating done (0.0s) [cmake] CMake Generate step failed. Build files cannot be regenerated correctly. [proc] The command: /usr/bin/cmake -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_CXX_COMPILER=/usr/bin/x86_64-w64-mingw32-g++ -DCMAKE_BUILD_TYPE=Debug -S/home/burger/Desktop/dark-proxy -B/home/burger/Desktop/dark-proxy/out/build/windows-debug exited with code: 1
Linux下g++编译的CMake日志
[main] Configuring project: dark-proxy [proc] Executing command: /usr/bin/cmake -DCMAKE_CXX_COMPILER=/usr/bin/g++ -DCMAKE_BUILD_TYPE=Debug -S/home/burger/Desktop/dark-proxy -B/home/burger/Desktop/dark-proxy/out/build/debug [cmake] CMake Warning at /usr/local/lib/cmake/protobuf/protobuf-config.cmake:9 (find_package): [cmake] Found package configuration file: [cmake] [cmake] /usr/local/lib/cmake/absl/abslConfig.cmake [cmake] [cmake] but it set absl_FOUND to FALSE so package "absl" is considered to be NOT [cmake] FOUND. Reason given by package: [cmake] [cmake] The following imported targets are referenced, but are missing: [cmake] protobuf::gmock [cmake] [cmake] Call Stack (most recent call first): [cmake] protos/CMakeLists.txt:1 (find_package) [cmake] [cmake] [cmake] -- Found Protobuf package with version : 29.0.0 [cmake] -- Configuring done (0.0s) [cmake] -- Generating done (0.0s) [cmake] -- Build files have been written to: /home/burger/Desktop/dark-proxy/out/build/debug
项目CMakeLists.txt文件
根目录CMakeLists.txt
cmake_minimum_required(VERSION 3.8) project(dark_proxy CXX) add_subdirectory(protos) add_subdirectory(dark_networking) add_executable(dark_proxy source.cpp) target_link_libraries(dark_proxy PRIVATE dark_networking)
protos/CMakeLists.txt
find_package(Protobuf REQUIRED CONFIG) if (${Protobuf_FOUND}) message(STATUS "Found Protobuf package with version : ${Protobuf_VERSION}") endif() set(PROTO_FILES // ... ) add_library(protos ${PROTO_FILES}) target_include_directories(protos INTERFACE ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(protos PUBLIC protobuf::libprotobuf ) protobuf_generate(TARGET protos LANGUAGE cpp)
dark_networking/CMakeLists.txt
project(dark_networking) file(GLOB SRC "src/*.cpp" "src/*.h") file(GLOB PROJECT_FILES FILES ${SRC}) add_library(dark_networking ${PROJECT_FILES}) target_include_directories(dark_networking PUBLIC "include" PRIVATE "src" ) target_link_libraries(dark_networking PUBLIC "$<LINK_LIBRARY:WHOLE_ARCHIVE,protos>")
解决方案
1. 修复ZLIB找不到的问题
交叉编译Windows目标时,CMake默认查找Linux系统的ZLIB库,而非MinGW的Windows版本,导致找不到ZLIB::ZLIB目标。可按以下步骤处理:
- 安装MinGW版本的ZLIB库:
sudo apt-get install x86_64-w64-mingw32-zlib1g-dev - 方式一:修改
windows-debug预设,指定ZLIB路径:"cacheVariables": { "CMAKE_SYSTEM_NAME": "Windows", "CMAKE_CXX_COMPILER": "/usr/bin/x86_64-w64-mingw32-g++", "CMAKE_BUILD_TYPE": "Debug", "ZLIB_LIBRARY": "/usr/x86_64-w64-mingw32/lib/libz.a", "ZLIB_INCLUDE_DIR": "/usr/x86_64-w64-mingw32/include" } - 方式二:在
protos/CMakeLists.txt中先查找ZLIB再处理Protobuf:find_package(ZLIB REQUIRED) find_package(Protobuf REQUIRED CONFIG)
2. 消除absl相关警告
警告源于系统中absl配置文件依赖protobuf::gmock,但交叉编译环境无对应Windows版本的gmock。可选择:
- 若项目未使用absl,在查找Protobuf时禁用absl依赖:
set(Protobuf_ABSL_PROVIDER none) find_package(Protobuf REQUIRED CONFIG) - 若需使用absl,需交叉编译Windows版本的absl,并确保CMake能找到其配置文件。
3. 优化交叉编译配置
建议使用完整的MinGW工具链文件,避免手动指定单个库路径:
- 创建
toolchain-mingw.cmake文件:set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_C_COMPILER /usr/bin/x86_64-w64-mingw32-gcc) set(CMAKE_CXX_COMPILER /usr/bin/x86_64-w64-mingw32-g++) set(CMAKE_RC_COMPILER /usr/bin/x86_64-w64-mingw32-windres) set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) 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) - 修改
CMakePresets.json的windows-debug预设:
此配置会让CMake自动在MinGW根路径下查找所有依赖库,无需手动指定路径。"cacheVariables": { "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/toolchain-mingw.cmake", "CMAKE_BUILD_TYPE": "Debug" }
内容的提问来源于stack exchange,提问作者Nicolas Cinq-Mars
相关产品推荐
相关产品推荐

