【问题标题】:CMake and Ninja - "missing and no known rule to make it"CMake 和 Ninja - “缺少并且没有已知的规则来制作它”
【发布时间】:2019-07-18 20:22:30
【问题描述】:

我有这个CMakeLists.txt 文件:

cmake_minimum_required(VERSION 3.8)

include(${CMAKE_CURRENT_SOURCE_DIR}/src/Something.cmake)

add_executable(execute main.cpp)
add_dependencies(somethingInterface Something)
add_dependencies(execute somethingInterface)

include_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}/src
    )
target_compile_options(execute
    PRIVATE
        -std=c++11
        -g
)

add_library(library SHARED IMPORTED)
set_target_properties(library PROPERTIES IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/library.so)
target_link_libraries(execute
    PRIVATE
        library
)

将在文件Something.cmake中创建共享库,但必须先构建tt。 这是文件 Something.cmake 中的 add_custom_command(TARGET POST_BUILD...)。

我在这里使用 CMake 构建没有任何问题,但是当我使用 Ninja 时出现错误

ninja:错误:'library.so','execute' 需要,丢失并且没有已知的规则来制作它

或者您对如何做到这一点有什么建议?

我认为 Ninja 的要求是“library.so”必须首先存在,但 CMake 不同。它在运行时检查库是否存在。

【问题讨论】:

  • "It was a add_custom_command(TARGET POST_BUILD...)" - 此命令的目标的名称是什么? (省略号中的第一个参数)。
  • add_library (somethingInterface empty.cpp) add_custom_command(TARGET somethingInterface POST_BUILD COMMAND ... #creating the "library" in the CMakeLists.txt ) 它只会构建一次。
  • 目标名称是somethingInterface,也是add_library(somethingInterfacer empty.cpp)的目标
  • 好的,您之前的评论只有在我重新打开页面后才会显示更新。这就是为什么我再次要求澄清。
  • 是的,它应该使用目标级别的依赖项自动构建。但在 ninja 中,您可能需要将 library.so 指定为创建它的命令的 BYPRODUCTS。有关此选项,请参阅 add_custom_command 的文档。

标签: cmake build-system ninja


【解决方案1】:

Make 和 Ninja 处理导入目标的方式确实存在差异。适合 Make 的东西,有时可能不适用于 Ninja。

特别是,以下代码行适用于 Make,但适用于 Ninja:

ExternalProject_Add(extProject
    GIT_REPOSITORY <GIT_URL>
    CMAKE_CACHE_ARGS "-
    DCMAKE_INSTALL_PREFIX:STRING=${CMAKE_INSTALL_PREFIX}"
)
add_library(extLib SHARED IMPORTED)
add_dependencies(extLib extProject)
set_target_properties(extLib
    PROPERTIES IMPORTED_LOCATION ${CMAKE_INSTALL_PREFIX}/lib/libext.so
)

target_link_libraries(project extLib)

CMake 配置步骤可以正常工作,但在构建时 Ninja 会抱怨:

ninja: error: '/path/to/libext.so', needed by 'project', missing and no known rule to make it

但这将与 Make 一起正常工作。

您需要将库指定为 ExternalProject_Add 注释的 副产品,因为 ExternalProject 在构建时运行。

以下对我来说很好用:

ExternalProject_Add(extProject
    GIT_REPOSITORY <GIT_URL>
    CMAKE_CACHE_ARGS "-
    DCMAKE_INSTALL_PREFIX:STRING=${CMAKE_INSTALL_PREFIX}"
    BUILD_BYPRODUCTS ${CMAKE_INSTALL_PREFIX}/lib/libext.so
)
add_library(extLib SHARED IMPORTED)
add_dependencies(extLib extProject)
set_target_properties(extLib
    PROPERTIES IMPORTED_LOCATION ${CMAKE_INSTALL_PREFIX}/lib/libext.so
)

target_link_libraries(project extLib)

【讨论】:

  • (你不认为 CMake 是 supported by the syntax highlighting。如果是,它可能是 lang-cmake
  • 是的,就我而言,我添加了 add_library (externalLib SHARED empty.cpp) 只是为了向 ninja 添加依赖项。
  • 只想补充一点,您可以在ExternalProject_Add 中使用&lt;INSTALL_DIR&gt;&lt;BINARY_DIR&gt;(和其他替换)。例如,如果您的外部项目的安装步骤安装在构建目录的子目录中的“lib/libfoo.a”中,则您无需知道该子目录是什么,只需说&lt;INSTALL_DIR&gt;/lib/libfoo.a。这些替换变量记录在 cmake ExternalProject_Add 文档中。
猜你喜欢
  • 2022-12-15
  • 1970-01-01
  • 2023-01-31
  • 2018-08-23
  • 1970-01-01
  • 2015-09-26
  • 2020-01-04
  • 1970-01-01
  • 2016-12-20
相关资源
最近更新 更多