include(RustLibrary)

# The Rust build script parses every protocol XML in this directory, so a change
# to any of them must trigger a rebuild. CONFIGURE_DEPENDS re-globs at build time
# so that adding or removing a protocol is picked up.
file(GLOB wayland_rs_protocols CONFIGURE_DEPENDS
  ${PROJECT_SOURCE_DIR}/wayland-protocols/*.xml)

# Cargo.lock is a build input, but downstream packaging can remove it
# before the build (Fedora's %cargo_prep deletes it to force an offline,
# distro-provided crate resolution). Only depend on it when it is actually
# present, otherwise Ninja aborts with a missing, unbuildable dependency.
set(wayland_rs_cargo_lock)
if(EXISTS ${PROJECT_SOURCE_DIR}/Cargo.lock)
  set(wayland_rs_cargo_lock ${PROJECT_SOURCE_DIR}/Cargo.lock)
endif()

add_rust_cxx_library(mirwayland_rs
  CRATE wayland_rs
  CXX_BRIDGE_SOURCE_FILE src/ffi.rs
  DEPENDS
    Cargo.toml
    ${wayland_rs_cargo_lock}
    build_script/cpp_builder.rs
    build_script/cpp_protocol_generation.rs
    build_script/dispatch_generator.rs
    build_script/ffi_generation.rs
    build_script/helpers.rs
    build_script/main.rs
    build_script/protocol_generator.rs
    build_script/protocol_middleware_generation.rs
    build_script/protocol_parser.rs
    build_script/wayland_server_generation.rs
    src/lib.rs
    src/wayland_client.rs
    src/wayland_server_core.rs
    ${wayland_rs_protocols}
  INCLUDES
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/include
    ${PROJECT_SOURCE_DIR}/include/common
)

set(wayland_rs_generated_sources
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/ext_data_control_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/ext_foreign_toplevel_list_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/ext_image_capture_source_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/ext_image_copy_capture_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/ext_input_trigger_action_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/ext_input_trigger_registration_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/ext_session_lock_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/fractional_scale_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/global_factory.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/idle_inhibit_unstable_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/input_method_unstable_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/input_method_unstable_v2.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/linux_dmabuf_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/linux_drm_syncobj_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/mir_shell_unstable_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/pointer_constraints_unstable_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/relative_pointer_unstable_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/server_decoration.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/text_input_unstable_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/text_input_unstable_v2.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/text_input_unstable_v3.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/viewporter.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/virtual_keyboard_unstable_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/wayland.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/wlr_foreign_toplevel_management_unstable_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/wlr_layer_shell_unstable_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/wlr_screencopy_unstable_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/wlr_virtual_pointer_unstable_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/wp_primary_selection_unstable_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/xdg_activation_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/xdg_decoration_unstable_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/xdg_output_unstable_v1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/xdg_shell.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/xdg_shell_unstable_v6.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/xdg_dialog_v1.cpp
)

set_source_files_properties(${wayland_rs_generated_sources} PROPERTIES GENERATED TRUE)

target_sources(mirwayland_rs-cxxbridge
  PRIVATE
    ${wayland_rs_generated_sources}
    ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/lifetime_tracker.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/protocol_error.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/wayland_client_registry.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/wayland_rs_cpp/src/wayland_executor.cpp
)

add_executable(
  mirwayland_rs-demo
  ${CMAKE_CURRENT_SOURCE_DIR}/example/main.cpp
)

target_include_directories(mirwayland_rs-demo
  PRIVATE
  "$<TARGET_PROPERTY:mirwayland_rs,INTERFACE_INCLUDE_DIRECTORIES>")

target_link_libraries(mirwayland_rs-demo
  PRIVATE
  mirwayland_rs
  PkgConfig::WAYLAND_CLIENT)

# The Rust static archive (via mirwayland_rs) is not a GCC LTO object.
target_link_options(mirwayland_rs INTERFACE $<$<CXX_COMPILER_ID:GNU>:-fno-lto>)
