提示输入和输出到cmake中的文件

时间:2014-02-10 17:59:14

标签: cmake

我第一次使用cmake,我正在尝试做一些简单的事情。假设项目所需的某些依赖项安装在库的异常目录中,但用户确切知道它们的位置。例如,我有一个我正在处理的项目需要SFML,但我总是将所有API和库安装在同一目录c:/ dev中。这样,我的计算机周围没有大量的图书馆杂乱无章。问题是我想让cmake找到那个库,但是find_module不会看那里而且找不到它。我的问题是这个。如果有人把他们所有的API和库放在一个不同的文件夹中,无论如何,当他们通过git或者其他东西下拉我的项目并尝试构建时,我可以只查询一次该路径吗?

我一步一步想要这个。运行cmake,cmake尝试find_module查找所需的依赖项,如果失败,它会询问用户是否知道并输入路径。如果它仍然无法找到它,它就会失败,如果确实如此,它会将该路径存储在某个文件中,以便后续调用cmake不会查询它,我会为每个依赖项执行此操作。这可能吗?这在unix系统上从来都不是问题,但对于我而言,这对我来说是一个真正的问题,因为每个库似乎都希望安装在不同的随机位置。

2 个答案:

答案 0 :(得分:2)

CMake不提供交互式对话框,因此您无法提示用户输入。使用grapgical前端(ccmakecmake-gui),用户可以手动将库路径输入正确的变量,但这不是很方便,并且已经需要一些CMake知识和查找脚本使用

我个人发现使用环境变量是Windows上最舒适的解决方案。 CMake附带的大多数查找脚本都支持此功能。您为每个库设置了一个环境变量,指向该库所在的路径。您只需在每台计算机上执行此操作一次,然后就可以自动运行CMake。它仍然不如Linux上的默认路径那么舒服,但这和它在Windows上一样好。

您可以添加一些自定义message输出(例如“SFML could not be found - set the SFML_DIR environment variable to point to the correct location”),以便让用户更明显地了解他们必须做些什么来使其正常运行。

答案 1 :(得分:0)

如果您希望cmake execute_process具有交互性,并提示用户输入一些数据,那绝对有可能。这是一个使用bash的示例。

cmake_minimum_required(VERSION 3.12)

project(go LANGUAGES NONE)

find_program(BASH NAMES bash bash.exe
PATHS "c:/msys64/usr/bin" "$ENV{PROGRAMFILES}/Git/bin"
)

# message("#BASH ${BASH}")

execute_process(COMMAND "${BASH}" "-c"
[=[
>&2 echo ""
names=("aaa"
       "bbb"
       "ccc")

num=-1
for x in "${names[@]}"; do
    ((num++))
    >&2 echo "$num. $x"
done
>&2 echo -n "Choose (0-$num) -> "
read var
re_number='^[0-9]+$'
if [[ ( "$var" =~ $re_number ) &&  ( "$var" -ge 0 ) && ( "$var" -le "$num" ) ]]; then
    echo "${names[$var]}"
else
    echo "error"
    exit 1
fi
]=]
                WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
                OUTPUT_VARIABLE output
                #OUTPUT_FILE /dev/stdout
                RESULT_VARIABLE ret_code
                OUTPUT_STRIP_TRAILING_WHITESPACE
                ERROR_STRIP_TRAILING_WHITESPACE
                )


message("### output == ${output}")
message("### ret_code == ${ret_code}")

诀窍是在stderr上输出所有内容,这就是>& echo "this goes to stderr"的作用,并使要通过OUTPUT_VARIABLE捕获的内容进入stdout(使用普通的echo)。