CMake构建OpenSSL依赖项目时无法找到头文件目录求助
解决CMake重构项目中OpenSSL头文件找不到的问题
在使用CMake重构项目时,配置了自动查找/下载OpenSSL的逻辑,但编译时提示找不到openssl/evp.h等头文件,生成构建文件无报错,但编译失败。
问题根源分析
- OpenSSL外部项目构建方式错误:OpenSSL 1.1.1u默认不使用CMake构建,直接通过
CMAKE_ARGS传递参数会导致构建流程失效,最终没有生成预期的头文件和库文件。 - 静态库设置时机错误:
OPENSSL_USE_STATIC_LIBS必须在find_package(OpenSSL)之前设置,否则CMake的FindOpenSSL模块不会识别该选项。 - 路径配置冗余且易出错:手动拼接
OPENSSL_ROOT_DIR来设置头文件和库路径,不如直接利用find_package返回的标准变量可靠,且容易因平台差异(如Windows下lib目录为lib64或lib)导致路径错误。
修复后的CMake配置
1. 修改thirdparty/OpenSSL/CMakeLists.txt
# 检查系统是否已安装OpenSSL find_package(OpenSSL QUIET) if(OPENSSL_FOUND) message(STATUS "找到预安装的OpenSSL库:${OPENSSL_LIBRARIES}") add_library(OpenSSL_external INTERFACE) # 传递已找到的OpenSSL根目录 set(OPENSSL_ROOT_DIR ${OPENSSL_ROOT_DIR} CACHE INTERNAL "OpenSSL安装目录") else() message(STATUS "未找到预安装的OpenSSL库,将自动下载并安装到${STAGED_INSTALL_PREFIX}") include(ExternalProject) # 针对不同平台设置OpenSSL的Configure参数 if(WIN32) set(OPENSSL_CONFIGURE_COMMAND perl Configure VC-WIN64A no-shared --prefix=${STAGED_INSTALL_PREFIX}) set(OPENSSL_BUILD_COMMAND nmake) set(OPENSSL_INSTALL_COMMAND nmake install) elseif(APPLE) set(OPENSSL_CONFIGURE_COMMAND ./Configure darwin64-x86_64-cc no-shared --prefix=${STAGED_INSTALL_PREFIX}) set(OPENSSL_BUILD_COMMAND make) set(OPENSSL_INSTALL_COMMAND make install) else() set(OPENSSL_CONFIGURE_COMMAND ./Configure linux-x86_64 no-shared --prefix=${STAGED_INSTALL_PREFIX}) set(OPENSSL_BUILD_COMMAND make) set(OPENSSL_INSTALL_COMMAND make install) endif() ExternalProject_Add(OpenSSL_external GIT_REPOSITORY https://github.com/openssl/openssl.git GIT_TAG OpenSSL_1_1_1u UPDATE_COMMAND "" CONFIGURE_COMMAND ${OPENSSL_CONFIGURE_COMMAND} BUILD_COMMAND ${OPENSSL_BUILD_COMMAND} INSTALL_COMMAND ${OPENSSL_INSTALL_COMMAND} TEST_AFTER_INSTALL 0 DOWNLOAD_NO_PROGRESS 1 LOG_CONFIGURE 1 LOG_BUILD 1 LOG_INSTALL 1 ) set(OPENSSL_ROOT_DIR ${STAGED_INSTALL_PREFIX} CACHE INTERNAL "OpenSSL安装目录") file(TO_NATIVE_PATH "${OPENSSL_ROOT_DIR}" OPENSSL_ROOT_DIR) endif()
修改说明:
- 替换原有的
CMAKE_ARGS,改用OpenSSL原生的Configure脚本构建,确保生成正确的头文件和库。 - 针对Windows、macOS、Linux分别设置适配的Configure参数,指定静态库构建(
no-shared)和安装路径。 - 修正变量缓存设置方式,确保
OPENSSL_ROOT_DIR能正确传递给后续子项目。
2. 修改src/CMakeLists.txt
cmake_minimum_required(VERSION 3.6 FATAL_ERROR) project(File_Encrypter_core LANGUAGES CXX) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 必须在find_package之前设置静态库选项 set(OPENSSL_USE_STATIC_LIBS TRUE) # 指定OpenSSL根目录,确保find_package能找到外部安装的版本 set(OPENSSL_ROOT_DIR ${OPENSSL_ROOT_DIR} CACHE PATH "OpenSSL根目录") find_package(OpenSSL REQUIRED) set(SOURCES main.cpp) if(APPLE) add_executable(main MACOSX_BUNDLE ${SOURCES}) set_target_properties(main PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) elseif(WIN32) add_executable(main ${SOURCES}) else() add_executable(main ${SOURCES}) endif() # 直接使用find_package提供的目标,自动包含头文件和库路径 target_link_libraries(main PRIVATE OpenSSL::SSL OpenSSL::Crypto)
修改说明:
- 将
OPENSSL_USE_STATIC_LIBS移至find_package之前,确保CMake能正确查找静态库。 - 显式传递
OPENSSL_ROOT_DIR给find_package,确保能找到外部项目安装的OpenSSL。 - 移除手动设置的
target_include_directories和target_link_directories,改用OpenSSL提供的导入目标OpenSSL::SSL和OpenSSL::Crypto,这些目标已包含正确的头文件路径和库依赖,避免手动拼接路径的错误。
3. 根目录CMakeLists.txt(微调)
cmake_minimum_required(VERSION 3.6) project(File_Encrypter) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) # ExternalProject基础设置 set_property(DIRECTORY PROPERTY EP_BASE ${CMAKE_BINARY_DIR}/subprojects) set(STAGED_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/stage) add_subdirectory(thirdparty) include(ExternalProject) ExternalProject_Add(${PROJECT_NAME}_core DEPENDS OpenSSL_external SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR} BUILD_ALWAYS 1 INSTALL_COMMAND "" )
修改说明:
- 移除冗余的
CMAKE_CACHE_ARGS,确保OPENSSL_ROOT_DIR能正确传递给子项目。
验证步骤
- 删除原有的build目录:
rm -rf build(Windows下执行rmdir /s build) - 重新生成构建文件:
cmake -S . -B build - 编译项目:
cmake --build build
内容的提问来源于stack exchange,提问作者Kingdawnage
相关产品推荐
相关产品推荐

