【问题标题】:prompting for input and output to a file in cmake提示输入和输出到 cmake 中的文件
【发布时间】:2019-01-20 04:57:34
【问题描述】:

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

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

【问题讨论】:

    标签: cmake


    【解决方案1】:

    CMake 不提供交互式对话框,因此您无法提示用户输入。使用图形前端(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”),让用户更清楚他们必须做什么才能使其正常运行。

    【讨论】:

    • 我相信这会很好。我不希望用户必须以任何方式编辑 CMakeList.txt,这样最终用户就不会推送可能会破坏它的更改,但我可以在某处留下特定说明,如果你在一个奇怪的地方有一个库,只需在 cmake-gui 中设置缓存的变量。我发现他们提供的 FindSFML.cmake 文件有一个你可以设置的变量,SFML_ROOT,它工作得很好。非常感谢。
    【解决方案2】:

    如果您希望 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)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多