gpt4 book ai didi

c++ - 在 CMakeLists.txt 中执行 cmake 与在终端中执行 cmake 有什么区别,我们如何使其行为相同?

转载 作者:行者123 更新时间:2023-12-04 13:50:59 25 4
gpt4 key购买 nike

好的,我不确定如何准确解释这个问题,但基本上,在我的项目 X 的​​ CMakeLists.txt 中,我正在构建外部库依赖项,这些依赖项本身就是单独的项目(例如,项目 A、项目 B、项目 C , 项目 D) - 然后我使用 catkin_make 构建.
我使用 CMake 的 ExternalProject_Add()对于每个项目 A、B、C、D;接着是 add_dependencies() 的声明在主项目 X 之前先构建项目 A、B、C、D。
现在,我特别有项目 D 的问题,需要设置多个路径到 CMAKE_PREFIX_PATH (例如, CMAKE_PREFIX_PATH=/addrA;/addrB;addrC )。

  • 错误 #1 : 如果我使用 ExternalProject_Add() , 它识别分号路径分隔符 ';'作为“命令结束”,因此,它通过第一个路径剪切 cmake 命令(仅识别 CMAKE_PREFIX_PATH=/addrA)。我已经尝试了很多东西 - 使用 LIST_SEPARATOR , 设置 CMAKE_PREFIX_PATH在此之前使用 set() ,甚至使用 $<SEMICOLON> - 没有任何效果,同样的问题。
  • 错误 #2 :我接下来做的 - 而不是使用 ExternalProject_Add()下载和构建项目 D - 我使用了 ExternalProject_Add()只做下载(例如,BUILD_COMMAND 将被设置为“”),然后通过 add_custom_target() 单独进行构建.现在来自那里的 cmake 命令也不起作用 - 因为出于某种我不知道的原因/限制,它没有正确映射 CMAKE_INSTALL_*标志,即使 CMAKE_PREFIX_PATH是正确的,它并没有真正识别应该在 CMAKE_PREFIX_PATH 中的路径中自动识别的 bin/lib/include 目录。 .当我尝试在结果 CMakeCache.txt 中替换这些标志的正确值时并通过 catkin_make 重建,它工作正常。但如果我不这样做,就像我只依赖初始 CMakeCache.txt 一样它生成了,它不会工作。

  • 请注意,当我尝试在终端中运行 Project D 的 cmake 时,我根本没有遇到任何问题。
    作为一种解决方法,我做了一个 execute_process()它创建了一个 bash 脚本,其中包含项目 D 的 cmake 和 make 命令,然后我只是在 ExternalProject_Add() 处调用该 bash 脚本。的 BUILD_COMMANDadd_custom_target()COMMAND . 这些作品中的任何一个 - 只是表明,cmake 在 COMMAND 中执行任一 ExternalProject_Add()add_custom_target()与在终端或通过 bash 脚本执行 cmake 有某种不同。
    我已经在这里搜索了所有内容,但找不到与我有相同问题的人,因此我现在的解决方法是。
    这是有效的粗略代码(我的解决方法):
    ### Project A 
    include(ExternalProject)
    ExternalProject_Add(ProjectA
    PREFIX /tmp/ProjectA
    GIT_REPOSITORY https://github.com/ProjectA
    GIT_TAG v0.0.1
    CONFIGURE_COMMAND ""
    BUILD_COMMAND cmake -DWITH_GFLAGS=off -DCMAKE_INSTALL_PREFIX=/opt/ProjectA <SOURCE_DIR>
    COMMAND sudo cmake --build . --target install
    INSTALL_COMMAND ""
    TEST_COMMAND ""
    )

    ### Project B
    include(ExternalProject)
    ExternalProject_Add(ProjectB
    PREFIX /tmp/ProjectB
    GIT_REPOSITORY https://github.com/ProjectB
    GIT_TAG v0.0.1
    CONFIGURE_COMMAND ""
    BUILD_COMMAND cmake -DLWS_STATIC_PIC=ON -DCMAKE_INSTALL_PREFIX=/opt/ProjectB <SOURCE_DIR>
    COMMAND sudo cmake --build . --target install
    INSTALL_COMMAND ""
    TEST_COMMAND ""
    )

    ### Project C
    include(ExternalProject)
    ExternalProject_Add(ProjectC
    PREFIX /tmp/ProjectC
    GIT_REPOSITORY https://github.com/ProjectC
    GIT_TAG v0.0.1
    CONFIGURE_COMMAND ""
    BUILD_COMMAND cmake -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_PREFIX=/opt/ProjectC <SOURCE_DIR>
    COMMAND sudo cmake --build . --target install
    INSTALL_COMMAND ""
    TEST_COMMAND ""
    )

    ### Project D
    execute_process (
    COMMAND bash -c "echo '#!/bin/bash\ncmake -DCMAKE_PREFIX_PATH=\"/opt/ProjectA;/opt/ProjectB;/opt/ProjectC\" /tmp/ProjectD/src/ProjectD\nmake' > /tmp/projectD_build.sh"
    COMMAND bash -c "chmod 777 /tmp/projectD_build.sh"
    )
    include(ExternalProject)
    ExternalProject_Add(ProjectD
    PREFIX /tmp/ProjectD
    GIT_REPOSITORY https://github.com/ProjectD
    GIT_TAG master
    CONFIGURE_COMMAND ""
    BUILD_COMMAND /tmp/projectD_build.sh
    INSTALL_COMMAND ""
    TEST_COMMAND ""
    )

    ### Set dependencies to force build Project A, B, C, D before Project X is build
    add_library (ProjectX SHARED IMPORTED)
    set_target_properties (ProjectX PROPERTIES IMPORTED_LOCATION ${ProjectX_LIBS})
    add_dependencies(ProjectX ProjectA)
    add_dependencies(ProjectX ProjectB)
    add_dependencies(ProjectX ProjectC)
    add_dependencies(ProjectX ProjectD)

    ### Project X build commands here (snipped)
    这些是/tmp/ProjecD_build.txt 中的 cmake + make 命令:
    cmake -DCMAKE_PREFIX_PATH="/opt/ProjectA;/opt/ProjectB;/opt/ProjectC" /tmp/ProjectD/src/ProjectD
    make
    如果我用这个替换整个“### Project D”部分,我会遇到 错误 #1 我上面讨论过的那个错误(多路径 CMAKE_PREFIX_PATH 的问题):
    ### Project D
    include(ExternalProject)
    ExternalProject_Add(ProjectD
    PREFIX /tmp/ProjectD
    GIT_REPOSITORY https://github.com/ProjectD
    GIT_TAG master
    CONFIGURE_COMMAND ""
    BUILD_COMMAND cmake -DCMAKE_PREFIX_PATH="/opt/ProjectA;/opt/ProjectB;/opt/ProjectC" /tmp/ProjectD/src/ProjectD
    INSTALL_COMMAND make
    TEST_COMMAND ""
    )
    ...或者像这样添加一个post-ProjectD,它仍然不起作用并导致 错误 #2 我在上面讨论过(CMAKE 标志未正确设置,如 CMakeCache.txt 中所示)。请注意,使用此解决方案,我的项目 D ExternalProject_Add()BUILD_COMMAND将仅设置为 ""因为构建将由添加的 add_custom_target() 完成反而:
    ExternalProject_Get_Property(ProjectD install_dir)
    ExternalProject_Get_Property(ProjectD source_dir)
    ExternalProject_Get_Property(ProjectD binary_dir)
    message(STATUS "install_dir is: " ${install_dir})
    message(STATUS "source_dir is: " ${source_dir})
    message(STATUS "binary_dir is: " ${binary_dir})

    add_custom_target(ProjectD_part2 ALL
    cmake -DCMAKE_PREFIX_PATH="/opt/ProjectA;/opt/ProjectB;/opt/ProjectC" ${source_dir}
    COMMAND make
    WORKING_DIRECTORY ${binary_dir}
    )

    add_dependencies(ProjectD_part2 ProjectA)
    add_dependencies(ProjectD_part2 ProjectB)
    add_dependencies(ProjectD_part2 ProjectC)
    add_dependencies(ProjectD_part2 ProjectD)
    解决方法有效。但是有没有更好的方法来做到这一点?谢谢你。

    最佳答案

    看起来好复杂!你能试试吗https://github.com/floooh/fips这使很多 cmake 事情变得更容易。
    Fips 是一个 Python 命令行工具,它通过将现有构建工具连接在一起,为 C/C++ 项目提供“集成构建环境”。它支持类似于 Rust 的 Cargo 或 Javascript 的 NPM 的工作流,但适用于 C/C++ 项目。

    关于c++ - 在 CMakeLists.txt 中执行 cmake 与在终端中执行 cmake 有什么区别,我们如何使其行为相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69448843/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com