Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake and Ninja - "missing and no known rule to make it"

I have this CMakeLists.txt file:

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
)

The library shared imported will be created in file Something.cmake, but tt must be built first. It was a add_custom_command(TARGET POST_BUILD...) in file Something.cmake.

I don't have any problem in using CMake builds here, but when I am using Ninja there an error.

ninja: error: 'library.so', needed by 'execute', missing and no known rule to make it

Or do you have any suggestion on how can you do this?

I think Ninja has a requirement that "library.so" must exist first, but CMake it is different. It checks whether the library is there at runtime.

like image 210
Rox Rosales Avatar asked Feb 25 '19 12:02

Rox Rosales


1 Answers

There is indeed a divergence between the way Make and Ninja handle imported targets. What works with Make, may sometimes not work with Ninja.

In particular, the following lines of code work with Make, but not with 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)

The CMake configure step will work fine, but at build time Ninja will complain:

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

But this will work fine with Make.

You need to specify the library as a byproduct of the ExternalProject_Add comment as mentioned by Tsyvarev, as ExternalProject runs at build time.

The following works fine for me:

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)
like image 196
Carlos Segarra Avatar answered Nov 20 '22 00:11

Carlos Segarra