blob: 66686552d20c7b7b709e11504c28fbdbe0551bf0 [file] [log] [blame] [edit]
# Copyright © 2017 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Authored by: Thomas Voss <thomas.voss@canonical.com>,
# Alan Griffiths <alan@octopull.co.uk>,
# Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
cmake_minimum_required(VERSION 3.5)
cmake_policy(SET CMP0015 NEW)
cmake_policy(SET CMP0022 NEW)
project(wlcs VERSION 1.5.0)
add_definitions(-D_GNU_SOURCE)
add_definitions(-D_FILE_OFFSET_BITS=64)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include(GNUInstallDirs)
find_package(PkgConfig)
#include (Doxygen.cmake)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread -g -Werror -Wall -pedantic -Wextra -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -g -Werror -Wall -fno-strict-aliasing -pedantic -Wnon-virtual-dtor -Wextra -fPIC")
if ("${CMAKE_SHARED_LINKER_FLAGS}" MATCHES ".*-fsanitize=.*")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
else()
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--as-needed -Wl,--no-undefined")
endif()
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-Wgnu-zero-variadic-macro-arguments HAVE_W_GNU_VARIADIC_MACROS)
if (HAVE_W_GNU_VARIADIC_MACROS)
# GTest's parametrised test macro tweaks this warning
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=gnu-zero-variadic-macro-arguments")
endif ()
include(CheckCXXSymbolExists)
list(APPEND CMAKE_REQUIRED_HEADERS ${GTEST_INCLUDE_DIRECTORIES})
check_cxx_symbol_exists(INSTANTIATE_TEST_SUITE_P "gtest/gtest.h" HAVE_INSTANTIATE_TEST_SUITE_P)
if (NOT HAVE_INSTANTIATE_TEST_SUITE_P)
#GTest conveniently renamed INSTANTIATE_TEST_CASE_P and then deprecated it.
add_definitions(-DINSTANTIATE_TEST_SUITE_P=INSTANTIATE_TEST_CASE_P)
endif()
find_package(Boost)
find_package(GtestGmock)
pkg_check_modules(WAYLAND_CLIENT REQUIRED wayland-client)
pkg_check_modules(WAYLAND_SERVER REQUIRED wayland-server)
pkg_check_modules(WAYLAND_SCANNER REQUIRED wayland-scanner)
include_directories(include)
include_directories(${Boost_INCLUDE_DIRS})
include_directories(${GMOCK_INCLUDE_DIR} ${GTEST_INCLUDE_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
set(PROTOCOL_SOURCES "")
execute_process(
COMMAND wayland-scanner --version
OUTPUT_VARIABLE WAYLAND_SCANNER_VERSION_OUTPUT
ERROR_VARIABLE WAYLAND_SCANNER_VERSION_OUTPUT
)
separate_arguments(WAYLAND_SCANNER_VERSION_OUTPUT)
list(LENGTH WAYLAND_SCANNER_VERSION_OUTPUT VERSION_STRING_COMPONENTS)
list(GET WAYLAND_SCANNER_VERSION_OUTPUT 1 VERSION_STRING)
string(STRIP ${VERSION_STRING} VERSION_STRING)
if (NOT(VERSION_STRING_COMPONENTS EQUAL 2))
message(AUTHOR_WARNING "Failed to parse wayland-scanner --version output")
endif()
if (VERSION_STRING VERSION_GREATER 1.14.91)
message(STATUS "Found wayland-scanner version ${VERSION_STRING}, using private-code mode")
set(WAYLAND_SCANNER_CODE_GENERATION_TYPE "private-code")
else()
message(STATUS "Found wayland-scanner version ${VERSION_STRING}, using (old) code mode")
set(WAYLAND_SCANNER_CODE_GENERATION_TYPE "code")
endif()
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/generated)
macro(GENERATE_PROTOCOL PROTOCOL_NAME)
set(PROTOCOL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src/protocol/${PROTOCOL_NAME}.xml")
set(OUTPUT_PATH_C "${CMAKE_CURRENT_BINARY_DIR}/generated/${PROTOCOL_NAME}.c")
set(OUTPUT_PATH_SERVER_H "${CMAKE_CURRENT_BINARY_DIR}/generated/${PROTOCOL_NAME}-server.h")
set(OUTPUT_PATH_CLIENT_H "${CMAKE_CURRENT_BINARY_DIR}/generated/${PROTOCOL_NAME}-client.h")
add_custom_command(OUTPUT "${OUTPUT_PATH_C}"
VERBATIM
COMMAND "wayland-scanner" "--include-core-only" ${WAYLAND_SCANNER_CODE_GENERATION_TYPE} "${PROTOCOL_PATH}" "${OUTPUT_PATH_C}"
DEPENDS "${PROTOCOL_PATH}"
)
add_custom_command(OUTPUT "${OUTPUT_PATH_SERVER_H}"
VERBATIM
COMMAND "wayland-scanner" "--include-core-only" "server-header" "${PROTOCOL_PATH}" "${OUTPUT_PATH_SERVER_H}"
DEPENDS "${PROTOCOL_PATH}"
)
add_custom_command(OUTPUT "${OUTPUT_PATH_CLIENT_H}"
VERBATIM
COMMAND "wayland-scanner" "--include-core-only" "client-header" "${PROTOCOL_PATH}" "${OUTPUT_PATH_CLIENT_H}"
DEPENDS "${PROTOCOL_PATH}"
)
list(APPEND PROTOCOL_SOURCES ${OUTPUT_PATH_C} ${OUTPUT_PATH_CLIENT_H})
endmacro()
GENERATE_PROTOCOL(gtk-primary-selection)
GENERATE_PROTOCOL(primary-selection-unstable-v1)
GENERATE_PROTOCOL(wayland)
GENERATE_PROTOCOL(xdg-shell-unstable-v6)
GENERATE_PROTOCOL(xdg-shell)
GENERATE_PROTOCOL(wlr-layer-shell-unstable-v1)
GENERATE_PROTOCOL(xdg-output-unstable-v1)
GENERATE_PROTOCOL(wlr-foreign-toplevel-management-unstable-v1)
GENERATE_PROTOCOL(pointer-constraints-unstable-v1)
GENERATE_PROTOCOL(relative-pointer-unstable-v1)
GENERATE_PROTOCOL(text-input-unstable-v3)
GENERATE_PROTOCOL(input-method-unstable-v2)
GENERATE_PROTOCOL(wlr-virtual-pointer-unstable-v1)
option(WLCS_BUILD_ASAN "Build a test runner with AddressSanitizer annotations" ON)
option(WLCS_BUILD_TSAN "Build a test runner with ThreadSanitizer annotations" ON)
option(WLCS_BUILD_UBSAN "Build a test runner with UndefinedBehaviourSanitizer annotations" ON)
set(WLCS_TESTS
tests/test_bad_buffer.cpp
tests/pointer_constraints.cpp
tests/copy_cut_paste.cpp
tests/gtk_primary_selection.cpp
tests/test_surface_events.cpp
tests/touches.cpp
tests/wl_output.cpp
tests/surface_input_regions.cpp
tests/frame_submission.cpp
tests/primary_selection.cpp
tests/relative_pointer.cpp
tests/subsurfaces.cpp
tests/xdg_surface_v6.cpp
tests/xdg_toplevel_v6.cpp
tests/xdg_surface_stable.cpp
tests/xdg_toplevel_stable.cpp
tests/xdg_popup.cpp
tests/wlr_layer_shell_v1.cpp
tests/xdg_output_v1.cpp
tests/wlr_foreign_toplevel_management_v1.cpp
tests/self_test.cpp
tests/text_input_v3_with_input_method_v2.cpp
tests/wlr_virtual_pointer_v1.cpp
)
set(
WLCS_SOURCES
include/wlcs/display_server.h
include/wlcs/pointer.h
include/wlcs/touch.h
include/helpers.h
include/wl_handle.h
include/in_process_server.h
include/pointer_constraints_unstable_v1.h
include/primary_selection.h
include/relative_pointer_unstable_v1.h
include/xdg_shell_v6.h
include/xdg_shell_stable.h
include/xdg_output_v1.h
include/version_specifier.h
include/wl_interface_descriptor.h
include/layer_shell_v1.h
include/surface_builder.h
include/input_method.h
src/data_device.cpp
src/gtk_primary_selection.cpp
src/helpers.cpp
src/in_process_server.cpp
src/xdg_shell_v6.cpp
src/xdg_shell_stable.cpp
src/layer_shell_v1.cpp
src/main.cpp
src/pointer_constraints_unstable_v1.cpp
src/primary_selection.cpp
src/shared_library.cpp
src/relative_pointer_unstable_v1.cpp
src/xfail_supporting_test_listener.h
src/xfail_supporting_test_listener.cpp
src/termcolor.hpp
src/thread_proxy.h
src/xdg_output_v1.cpp
src/version_specifier.cpp
src/surface_builder.cpp
src/input_method.cpp
${PROTOCOL_SOURCES}
${WLCS_TESTS}
)
# g++ 9.4 (on 20.04) hates the MOCK_METHOD macro
if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10)
# Neither gnu-zero-variadic-macro-arguments nor variadic-macro help,
# we just have to drop pedantic...
set_property(SOURCE ${WLCS_TESTS} PROPERTY COMPILE_OPTIONS -Wno-pedantic)
endif()
add_library(test_c_compile OBJECT src/test_c_compile.c)
add_executable(wlcs ${WLCS_SOURCES})
set(EXECUTABLE_TARGETS wlcs)
if (WLCS_BUILD_ASAN)
add_executable(wlcs.asan ${WLCS_SOURCES})
target_compile_options(wlcs.asan PUBLIC -fsanitize=address -fno-omit-frame-pointer)
set_target_properties(
wlcs.asan
PROPERTIES
LINK_FLAGS -fsanitize=address)
# Explicitly linking with the sanitiser is harmless
target_link_libraries(wlcs.asan asan)
list(APPEND EXECUTABLE_TARGETS wlcs.asan)
endif()
if (WLCS_BUILD_TSAN)
add_executable(wlcs.tsan ${WLCS_SOURCES})
target_compile_options(wlcs.tsan PUBLIC -fsanitize=thread -fno-omit-frame-pointer)
set_target_properties(
wlcs.tsan
PROPERTIES
LINK_FLAGS -fsanitize=thread)
# Explicitly linking with the sanitiser is harmless.
target_link_libraries(wlcs.tsan tsan)
list(APPEND EXECUTABLE_TARGETS wlcs.tsan)
endif()
if (WLCS_BUILD_UBSAN)
add_executable(wlcs.ubsan ${WLCS_SOURCES})
target_compile_options(wlcs.ubsan PUBLIC -fsanitize=undefined)
set_target_properties(
wlcs.ubsan
PROPERTIES
LINK_FLAGS -fsanitize=undefined)
# Unsure quite why explicitly linking with ubsan is required, but here we are…
target_link_libraries(wlcs.ubsan ubsan)
list(APPEND EXECUTABLE_TARGETS wlcs.ubsan)
endif()
foreach(TARGET IN LISTS EXECUTABLE_TARGETS)
target_link_libraries(
${TARGET}
${WAYLAND_CLIENT_LDFLAGS} ${WAYLAND_CLIENT_LIBRARIES}
${WAYLAND_SERVER_LDFLAGS} ${WAYLAND_CLIENT_LIBRARIES}
dl
${GMOCK_LIBRARY}
${GTEST_LIBRARY}
)
endforeach(TARGET)
install(
TARGETS ${EXECUTABLE_TARGETS}
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/wlcs
)
install(
DIRECTORY include/wlcs
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
include(JoinPaths)
join_paths(PKGCONFIG_BINDIR "\${prefix}" "${CMAKE_INSTALL_BINDIR}")
join_paths(PKGCONFIG_LIBEXECDIR "\${prefix}" "${CMAKE_INSTALL_LIBEXECDIR}")
join_paths(PKGCONFIG_INCLUDEDIR "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
configure_file(
wlcs.pc.in
${CMAKE_CURRENT_BINARY_DIR}/wlcs.pc
@ONLY
)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/wlcs.pc
DESTINATION
${CMAKE_INSTALL_LIBDIR}/pkgconfig/
)