如何在外部Bash脚本中获取CMake构建的可执行文件路径?
解决方案
方法1:通过CMake查询目标属性(最可靠)
如果项目有明确的可执行目标(哪怕名称会动态变化),可以直接让CMake输出目标的路径信息,不需要硬编码任何内容。
在Bash脚本中执行以下步骤:
# 替换为你的实际构建目录 BUILD_DIR="build" cd "$BUILD_DIR" # 获取项目中所有可执行目标的列表 EXEC_TARGETS=$(cmake -LA -N | grep "^CMAKE_EXECUTABLE_TARGETS:" | cut -d'=' -f2) # 遍历目标,获取可执行文件路径 for TARGET in $EXEC_TARGETS; do # 查询目标的输出目录 OUTPUT_DIR=$(cmake -E get_property TARGET "$TARGET" PROPERTY RUNTIME_OUTPUT_DIRECTORY) # 查询目标的输出文件名(未设置则用目标名本身) EXEC_NAME=$(cmake -E get_property TARGET "$TARGET" PROPERTY OUTPUT_NAME) [ -z "$EXEC_NAME" ] && EXEC_NAME="$TARGET" FULL_PATH="$OUTPUT_DIR/$EXEC_NAME" # 验证文件存在且可执行 if [ -x "$FULL_PATH" ]; then echo "找到可执行文件:$FULL_PATH" "$FULL_PATH" # 直接运行程序 break # 若只需第一个可执行文件,找到后退出循环 fi done
这个方法完全依赖CMake自身的配置信息,不会出现路径误判的情况。
方法2:查找构建目录中最近生成的可执行文件
如果不想依赖CMake的目标查询逻辑,可以直接在构建目录中筛选最近修改的可执行文件:
BUILD_DIR="build" # 递归查找构建目录下所有可执行文件,按修改时间倒序排序后取第一个 RECENT_EXEC=$(find "$BUILD_DIR" -type f -executable -printf "%T@ %p\n" | sort -nr | head -n1 | cut -d' ' -f2-) if [ -n "$RECENT_EXEC" ]; then echo "运行最近生成的可执行文件:$RECENT_EXEC" "$RECENT_EXEC" else echo "未找到可执行文件" fi
注意:如果构建目录中存在多个可执行文件(比如测试工具、辅助程序),可能会误选非主程序文件,适合单可执行目标的项目。
方法3:在CMakeLists.txt中输出路径到文件
可以在CMake配置阶段,将可执行文件的路径写入一个文本文件,让外部脚本直接读取:
在CMakeLists.txt中添加以下代码(替换MyApp为你的实际目标名,若目标名动态生成可根据逻辑调整):
add_executable(MyApp src/main.cpp) # 获取目标的输出路径和文件名 get_target_property(EXEC_PATH MyApp RUNTIME_OUTPUT_DIRECTORY) get_target_property(EXEC_NAME MyApp OUTPUT_NAME) if(NOT EXEC_NAME) set(EXEC_NAME MyApp) endif() # 将完整路径写入构建目录下的exec_path.txt文件 file(WRITE "${CMAKE_BINARY_DIR}/exec_path.txt" "${EXEC_PATH}/${EXEC_NAME}")
然后在Bash脚本中读取该文件并运行:
BUILD_DIR="build" EXEC_PATH=$(cat "$BUILD_DIR/exec_path.txt") if [ -x "$EXEC_PATH" ]; then "$EXEC_PATH" else echo "可执行文件不存在或不可执行" fi
这个方法需要修改CMake配置,但路径信息完全由CMake保证准确性,适合长期维护的项目。
内容的提问来源于stack exchange,提问作者danebidev
相关产品推荐
相关产品推荐

