从Linux交叉编译至32位Windows时CMake无法识别libcurl文件
交叉编译Windows 32位程序时libcurl链接错误解决
环境与项目信息
- 系统:Debian 11
- 项目目录结构:
C_UPDATER/ Main/ ...(.cpp文件) App/ ...(.cpp文件) Loader.cpp
- 代码中使用
#include <curl/curl.h>,已找到对应文件:- 静态库路径:
➜ ~ sudo find / -name libcurl.a /usr/i686-w64-mingw32/lib/libcurl.a /usr/lib/x86_64-linux-gnu/libcurl.a - 头文件路径:
➜ ~ sudo find / -name curl.h /usr/i686-w64-mingw32/include/curl/curl.h /usr/include/x86_64-linux-gnu/curl/curl.h
- 静态库路径:
问题描述
使用CMake交叉编译至Windows 32位,当前CMakeLists.txt配置如下:
cmake_minimum_required(VERSION 3.13) project(updater) set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_COMPILER /usr/bin/i686-w64-mingw32-g++-posix) set(CMAKE_C_COMPILER /usr/bin/i686-w64-mingw32-gcc-posix) SET(CMAKE_INSTALL_PREFIX "/usr/i686-w64-mingw32" CACHE PATH "Cmake install prefix") set(CMAKE_FIND_ROOT_PATH ${CMAKE_INSTALL_PREFIX}) set(CMAKE_SYSTEM_PREFIX_PATH /) # 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 NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER) find_package(Threads REQUIRED) find_package(CURL REQUIRED) # Include libcurl header files include_directories(/usr/i686-w64-mingw32/include) add_library(AppModules Main/Main.cpp) # Link against libcurl library target_link_libraries(AppModules CURL::libcurl) # Set compiler options set(CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic -static -static-libstdc++ -lpthread -lstdc++ -lcurl") set(CMAKE_EXE_LINKER_FLAGS "-DCURL_STATICLIB -static -static-libstdc++ -lpthread -lcurl") # Add executable target add_executable(updater Loader.cpp) # Link against AppModules library target_link_libraries(updater AppModules)
编译时出现错误:
➜ C_Updater make [ 50%] Built target AppModules [ 75%] Linking CXX executable updater /usr/lib/x86_64-linux-gnu/libcurl.so: file not recognized: file format not recognized collect2: error: ld returned 1 exit status make[2]: *** [CMakeFiles/updater.dir/build.make:105: updater] Error 1 make[1]: *** [CMakeFiles/Makefile2:97: CMakeFiles/updater.dir/all] Error 2 make: *** [Makefile:103: all] Error 2
推测问题在于find_package找到的是主机平台的libcurl.so而非目标Windows 32位的libcurl.a,尝试调整CMAKE_FIND_ROOT_PATH等参数、直接链接静态库均未解决。
解决方案
核心问题修正
当前CMake配置中,CMAKE_FIND_ROOT_PATH_MODE_LIBRARY和INCLUDE被设置为NEVER,这会导致CMake跳过目标环境的路径,直接在主机系统里找库,所以才会拿到x86_64的libcurl.so。
修改后的CMakeLists.txt
cmake_minimum_required(VERSION 3.13) project(updater) set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_CXX_STANDARD 17) # 指定交叉编译器 set(CMAKE_CXX_COMPILER /usr/bin/i686-w64-mingw32-g++-posix) set(CMAKE_C_COMPILER /usr/bin/i686-w64-mingw32-gcc-posix) # 配置目标环境根路径 set(CMAKE_INSTALL_PREFIX "/usr/i686-w64-mingw32" CACHE PATH "CMake install prefix") set(CMAKE_FIND_ROOT_PATH ${CMAKE_INSTALL_PREFIX}) # 调整查找规则:程序找主机,库和头文件找目标环境 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) # 启用静态库查找 set(CURL_USE_STATIC_LIBS ON) find_package(CURL REQUIRED) # 使用target_include_directories替代全局include,更规范 add_library(AppModules Main/Main.cpp) target_include_directories(AppModules PRIVATE ${CURL_INCLUDE_DIRS}) target_link_libraries(AppModules PRIVATE CURL::libcurl Threads::Threads) # 编译和链接选项:避免重复设置库,依赖由CMake自动处理 set(CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic -static -static-libstdc++") set(CMAKE_EXE_LINKER_FLAGS "-static -static-libstdc++") add_executable(updater Loader.cpp) target_link_libraries(updater PRIVATE AppModules)
关键修改点说明
- 修正查找规则:将
CMAKE_FIND_ROOT_PATH_MODE_LIBRARY和INCLUDE改为ONLY,强制CMake只在CMAKE_FIND_ROOT_PATH指定的目标环境路径(/usr/i686-w64-mingw32)里找库和头文件。 - 启用CURL静态库:添加
set(CURL_USE_STATIC_LIBS ON),让find_package优先查找静态库libcurl.a。 - 规范依赖管理:用
target_include_directories和target_link_libraries的PRIVATE属性替代全局include_directories,避免污染其他目标;依赖库由CMake自动传递,不需要手动在CXX_FLAGS里加-lcurl、-lpthread。 - 清理冗余选项:去掉
CMAKE_CXX_FLAGS和CMAKE_EXE_LINKER_FLAGS里重复的库链接参数,避免冲突。
编译步骤
- 清理之前的构建文件:
cd C_UPDATER rm -rf build && mkdir build && cd build
- 重新运行CMake:
cmake ..
- 编译:
make
内容的提问来源于stack exchange,提问作者PROGRAMMER1
相关产品推荐
相关产品推荐

