2

I am trying to port a meson project to CMake. I have the following subdirectories in my main CMake file:

add_subdirectory(protos)
add_subdirectory(qtlayershell)
add_subdirectory(demo)

and the following in protos/CMakeLists.txt:

set(PROTOCOLS
    ${WAYLAND_PROTOCOL_DIR}/stable/xdg-shell/xdg-shell.xml
    wlr-layer-shell-unstable-v1.xml'
)

foreach(XML ${PROTOCOLS})
    get_filename_component(BASENAME ${XML} NAME_WE)
    add_custom_command(
        OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/wayland-protos/wayland-${BASENAME}-protocol.c
        COMMAND wayland-scanner private-code ${XML} @OUTPUT@
    )
    add_custom_command(
        OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/wayland-protos/wayland-${BASENAME}-protocol.h
        COMMAND wayland-scanner client-header ${XML} @OUTPUT@
    )

    add_custom_command(
        OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/wayland-protos/qwayland-${BASENAME}.h
        COMMAND qtwaylandscanner client-header ${XML} @OUTPUT@
    )
    add_custom_command(
        OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/wayland-protos/${BASENAME}-protocol.cpp
        COMMAND qtwaylandscanner client-code ${XML} @OUTPUT@
    )

    list(APPEND PROTOCOL_SRC
        ${CMAKE_CURRENT_BINARY_DIR}/wayland-protos/wayland-${BASENAME}-protocol.c
        ${CMAKE_CURRENT_BINARY_DIR}/wayland-protos/${BASENAME}-protocol.cpp
    )

    list(APPEND PROTOCOL_HEADERS
        ${CMAKE_CURRENT_BINARY_DIR}/wayland-protos/qwayland-${BASENAME}.h
        ${CMAKE_CURRENT_BINARY_DIR}/wayland-protos/wayland-${BASENAME}-protocol.h
    )
endforeach()


set(WAYLAND_PROTOCOL_SRC ${PROTOCOL_SRC} PARENT_SCOPE)
set(WAYLAND_PROTOCOL_HEADERS ${PROTOCOL_HEADERS} PARENT_SCOPE)

add_custom_target(wayland_protocols DEPENDS ${WAYLAND_PROTOCOL_SRC} ${WAYLAND_PROTOCOL_HEADERS})

and in qtlayershell/CMakeLists.txt, a target like this:

add_library(qtlayershell SHARED
    ${QTLAYERSHELL_SRC}
    ${WAYLAND_PROTOCOL_SRC}
    DEPENDS wayland_protocols
)

But I am getting an error that somelongbuildpath/protos/wayland-protos/wayland-xdg-shell-protocol.c doesn't exist yet. Here is full error:

  Cannot find source file:

    /home/noone/KDE/my/build-qtlayershell-Desktop-Debug/protos/wayland-protos/wayland-xdg-shell-protocol.c

  Tried extensions .c .C .c++ .cc .cpp .cxx .cu .m .M .mm .h .hh .h++ .hm
  .hpp .hxx .in .txx


CMake Error at qtlayershell/CMakeLists.txt:9 (add_library):
  No SOURCES given to target: qtlayershell
CMake Generate step failed.  Build files cannot be regenerated correctly.
CMake process exited with exit code 1.

1 Answers1

0

The add_library() command does not accept a DEPENDS keyword, so this is not a valid way to specify a target dependency. Try using add_dependencies() instead, to specify that the qtlayershell target depends on the wayland_protocols custom target for generation of the sources:

add_library(qtlayershell SHARED
    ${QTLAYERSHELL_SRC}
    ${WAYLAND_PROTOCOL_SRC}
)
add_dependencies(qtlayershell wayland_protocols)

In addition, the WAYLAND_PROTOCOL_SRC and WAYLAND_PROTOCOL_HEADERS variables are set with PARENT_SCOPE so they are not available to the add_custom_target call. Instead, you can try setting these as CACHE INTERNAL variables so that they are available in all scopes:

set(WAYLAND_PROTOCOL_SRC ${PROTOCOL_SRC} CACHE INTERNAL "Wayland sources" FORCE)
set(WAYLAND_PROTOCOL_HEADERS ${PROTOCOL_HEADERS} CACHE INTERNAL "Wayland headers" FORCE)

add_custom_target(wayland_protocols DEPENDS ${WAYLAND_PROTOCOL_SRC} ${WAYLAND_PROTOCOL_HEADERS})
Kevin
  • 16,549
  • 8
  • 60
  • 74
  • Are you sure the `wayland_protocols` target exists when this is called? Is the custom target created *before* the `add_library` call? – Kevin May 14 '20 at 15:43
  • @ squareskittles custom target is created in protos/CMakeLists.txt which is added as subdirectory before qtlayershell/CMakeLists.txt. qtlayershell/CMakeLists.txt contains add_library call –  May 14 '20 at 15:50
  • Ok, yes, just wanted to be sure. I think the `PARENT_SCOPE` variables may be an issue, perhaps, you could make these `CACHE` variables instead. – Kevin May 14 '20 at 15:59
  • @ I tried setting variables to CACHE like this:- ```set(WAYLAND_PROTOCOL_SRC ${PROTOCOL_SRC} PARENT_SCOPE CACHE PATH "") set(WAYLAND_PROTOCOL_HEADERS ${PROTOCOL_HEADERS} PARENT_SCOPE CACHE PATH "")``` but still getting the same error. Also tried without parent_scope but same error –  May 14 '20 at 16:09
  • @noone Please see the updates to my response. I hope that helps the issue! – Kevin May 14 '20 at 16:20
  • unfortunately, its the same error. here is my full project if that helps https://github.com/VioletSith/qtlayershell –  May 15 '20 at 04:00