如何在CMake中调用ExternalProject构建的可执行文件并正确获取路径
问题解决方案
一、获取CMAKE_BINARY_DIR的绝对路径
CMake原生的CMAKE_BINARY_DIR在项目配置阶段本身存储的就是绝对路径,你之前遇到的路径被解析为../bin/flatc这类相对路径的情况,本质是add_custom_target、add_custom_command在生成构建系统时,会自动将路径转换为相对于当前构建工作目录的相对形式,并非变量本身存储的是相对值。
如果需要强制拿到指定路径的绝对形式,避免被自动转换,可以使用CMake内置的get_filename_component做显式解析,示例代码:
# 强制解析得到绝对路径形式的CMAKE_BINARY_DIR get_filename_component(ABS_CMAKE_BINARY_DIR "${CMAKE_BINARY_DIR}" ABSOLUTE) # 对flatc可执行文件路径做同样的绝对路径强制解析 get_filename_component(FLATC "${CMAKE_BINARY_DIR}/bin/flatc" ABSOLUTE)
经过该函数解析的路径会保留绝对形式,不会再出现被自动转换为相对路径的问题。
二、ExternalProject生成可执行文件的正确调用方式
当前的配置存在两个常见的自定义命令写法错误,按以下规则调整即可正常运行:
- 修正自定义命令的参数结构
不要将整条命令用一层双引号整体包裹,CMake会把被整体引号包裹的内容识别为单个可执行文件路径,不会自动拆分可执行程序和后续参数。正确写法是将可执行文件、每个参数独立列出,不额外套外层引号。 - 优化可执行文件的路径获取逻辑
不要硬编码写死flatc的路径,不同平台、不同构建配置下flatc的安装路径会存在差异。可以通过ExternalProject_Get_Property获取flatbuffers项目的实际安装目录,再拼接平台对应的可执行文件名,适配性远好于硬编码路径:# 获取googleflatbuf ExternalProject的安装目录 ExternalProject_Get_Property(googleflatbuf INSTALL_DIR) # 匹配不同平台的flatc可执行文件名 if(WIN32) set(FLATC_EXEC_NAME flatc.exe) else() set(FLATC_EXEC_NAME flatc) endif() # 拼接完整路径并强制解析为绝对路径 get_filename_component(FLATC "${INSTALL_DIR}/bin/${FLATC_EXEC_NAME}" ABSOLUTE) - 修正后的完整自定义目标配置
# 收集项目下所有.fbs协议文件 file(GLOB PROTOCOL_SRC "${CMAKE_CURRENT_SOURCE_DIR}/*.fbs") add_custom_target( protocol_src_gen # 参数独立拆分,不套外层整体引号 COMMAND ${FLATC} --cpp -o ${CMAKE_CURRENT_BINARY_DIR} ${PROTOCOL_SRC} # 依赖flatbuffers项目构建完成、所有fbs源文件就绪 DEPENDS googleflatbuf ${PROTOCOL_SRC} SOURCES ${PROTOCOL_SRC} COMMENT "运行flatc从fbs文件生成C++代码" )
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

