You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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工具链文件,避免手动指定单个库路径:

  1. 创建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)
    
  2. 修改CMakePresets.json的windows-debug预设:
    "cacheVariables": {
        "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/toolchain-mingw.cmake",
        "CMAKE_BUILD_TYPE": "Debug"
    }
    
    此配置会让CMake自动在MinGW根路径下查找所有依赖库,无需手动指定路径。

内容的提问来源于stack exchange,提问作者Nicolas Cinq-Mars

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 06:07:02