如何通过CMake为Crypto++库头文件添加目录前缀引入?
问题
在C项目中通过FetchContent引入Crypto库,现有CMake代码如下:
cmake_minimum_required(VERSION 3.24) project(CMakeAddLibraryPrefixIncludes) set(CMAKE_CXX_STANDARD 23) include(FetchContent) FetchContent_Declare(CryptoPP GIT_REPOSITORY https://github.com/weidai11/cryptopp.git GIT_TAG master) FetchContent_MakeAvailable(CryptoPP) add_executable(${PROJECT_NAME} main.cpp) add_library(CryptoPP INTERFACE) target_include_directories(CryptoPP INTERFACE ${CMAKE_BINARY_DIR}/_deps/cryptopp-src) target_link_libraries(${PROJECT_NAME} CryptoPP)
当前Crypto++的所有头文件都放在源码顶层目录,代码里可以直接用#include <aes.h>引入。现在需要调整设置,让代码只能通过#include <cryptopp/aes.h>这种带目录前缀的形式引入头文件,该怎么实现?
解决方案
完全可以实现,核心思路是调整头文件的目录结构和CMake的包含路径设置,具体操作如下:
步骤1:调整头文件目录结构
由于Crypto++默认把所有头文件放在源码根目录,我们需要在CMake中添加操作,将这些头文件统一放到源码根目录下的cryptopp子目录中。可以用CMake的文件操作命令自动完成:
# 创建cryptopp子目录 file(MAKE_DIRECTORY ${cryptopp_SOURCE_DIR}/cryptopp) # 匹配所有顶层头文件 file(GLOB CRYPTOPP_TOP_HEADERS ${cryptopp_SOURCE_DIR}/*.h) # 复制头文件到cryptopp子目录 file(COPY ${CRYPTOPP_TOP_HEADERS} DESTINATION ${cryptopp_SOURCE_DIR}/cryptopp)
这里cryptopp_SOURCE_DIR是FetchContent自动生成的变量,指向拉取到的Crypto++源码根目录,比硬编码路径更可靠。
步骤2:修改CMake包含路径
不要直接把Crypto++的源码根目录设为包含目录,而是将它的父目录(也就是_deps目录)设为包含路径。这样代码中必须通过cryptopp/xxx.h的形式才能找到头文件:
add_library(CryptoPP INTERFACE) # 调整包含目录到_deps,而非cryptopp-src本身 target_include_directories(CryptoPP INTERFACE ${CMAKE_BINARY_DIR}/_deps) target_link_libraries(${PROJECT_NAME} CryptoPP)
完整修改后的CMake代码
cmake_minimum_required(VERSION 3.24) project(CMakeAddLibraryPrefixIncludes) set(CMAKE_CXX_STANDARD 23) include(FetchContent) FetchContent_Declare(CryptoPP GIT_REPOSITORY https://github.com/weidai11/cryptopp.git GIT_TAG master) FetchContent_MakeAvailable(CryptoPP) # 自动整理Crypto++头文件到cryptopp子目录 file(MAKE_DIRECTORY ${cryptopp_SOURCE_DIR}/cryptopp) file(GLOB CRYPTOPP_TOP_HEADERS ${cryptopp_SOURCE_DIR}/*.h) file(COPY ${CRYPTOPP_TOP_HEADERS} DESTINATION ${cryptopp_SOURCE_DIR}/cryptopp) add_executable(${PROJECT_NAME} main.cpp) add_library(CryptoPP INTERFACE) # 设置包含目录为_deps,要求代码用cryptopp/前缀引入头文件 target_include_directories(CryptoPP INTERFACE ${CMAKE_BINARY_DIR}/_deps) target_link_libraries(${PROJECT_NAME} CryptoPP)
验证效果
修改完成后,代码中必须写#include <cryptopp/aes.h>才能正确引入头文件,如果直接写#include <aes.h>会触发编译错误,完全符合需求。
另外,如果担心复制文件占用空间,也可以用file(CREATE_LINK ...)创建符号链接替代复制,不过Windows系统下可能需要管理员权限才能创建符号链接,复制文件的方式兼容性更好。
内容的提问来源于stack exchange,提问作者SamG101
相关产品推荐
相关产品推荐

