Option to link against local libportal and other subprojects (#7469)

* Link against local libei and libportal and use main for both

* Change to `--meson-no-system`

* Add missing libportal dep

* Python trick I learned from Peter Hutterer :D

* Remove qt6-base-private-dev not needed

* Remove unused HAVE_LIBEI_SEQUENCE_NUMBER

* Add hack to force all libportal functions on for local build

* Always wipe instead of reconfigure

* Fixed function name in deps

* Update ChangeLog

* Fixed formatting
This commit is contained in:
Nick Bolton 2024-09-03 19:26:44 +01:00 committed by GitHub
parent b128863c67
commit cd63a29c19
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 159 additions and 64 deletions

View file

@ -11,6 +11,7 @@ Enhancements:
- #7464 Restore `--only-python` arg to only install Python deps - #7464 Restore `--only-python` arg to only install Python deps
- #7465 Also cut `+` char for `SHORT_VERSION` var used on upload - #7465 Also cut `+` char for `SHORT_VERSION` var used on upload
- #7467 Load server or client args from `synergy-config.toml` - #7467 Load server or client args from `synergy-config.toml`
- #7469 Option to link against local `libportal` and other subprojects
# 1.15.1 # 1.15.1

View file

@ -38,6 +38,7 @@ macro(configure_unix_libs)
include(CheckIncludeFileCXX) include(CheckIncludeFileCXX)
include(CheckSymbolExists) include(CheckSymbolExists)
include(CheckCSourceCompiles) include(CheckCSourceCompiles)
include(FindPkgConfig)
check_include_file_cxx(istream HAVE_ISTREAM) check_include_file_cxx(istream HAVE_ISTREAM)
check_include_file_cxx(ostream HAVE_OSTREAM) check_include_file_cxx(ostream HAVE_OSTREAM)
@ -167,32 +168,8 @@ endmacro()
macro(configure_wayland_libs) macro(configure_wayland_libs)
include(FindPkgConfig) configure_libei()
configure_libportal()
pkg_check_modules(LIBEI QUIET "libei-1.0 >= ${LIBEI_MIN_VERSION}")
if(LIBEI_FOUND)
message(STATUS "libei version: ${LIBEI_VERSION}")
add_definitions(-DWINAPI_LIBEI=1)
include_directories(${LIBEI_INCLUDE_DIRS})
else()
message(
WARNING
"libei >= ${LIBEI_MIN_VERSION} not found, Wayland support will be disabled."
)
endif()
pkg_check_modules(LIBPORTAL QUIET "libportal >= ${LIBPORTAL_MIN_VERSION}")
if(LIBPORTAL_FOUND)
message(STATUS "libportal version: ${LIBPORTAL_VERSION}")
add_definitions(-DWINAPI_LIBPORTAL=1)
include_directories(${LIBPORTAL_INCLUDE_DIRS})
check_libportal()
else()
message(
WARNING
"libportal >= ${LIBPORTAL_MIN_VERSION} not found, some Wayland features will be disabled."
)
endif()
pkg_check_modules(LIBXKBCOMMON REQUIRED xkbcommon) pkg_check_modules(LIBXKBCOMMON REQUIRED xkbcommon)
pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0)
@ -202,23 +179,103 @@ macro(configure_wayland_libs)
endmacro() endmacro()
macro(configure_libei)
option(SYSTEM_LIBEI "Use system libei" ON)
if(SYSTEM_LIBEI)
pkg_check_modules(LIBEI QUIET "libei-1.0 >= ${LIBEI_MIN_VERSION}")
if(LIBEI_FOUND)
message(STATUS "libei version: ${LIBEI_VERSION}")
add_definitions(-DWINAPI_LIBEI=1)
include_directories(${LIBEI_INCLUDE_DIRS})
else()
message(WARNING "libei >= ${LIBEI_MIN_VERSION} not found")
endif()
else()
set(libei_bin_dir ${CMAKE_BINARY_DIR}/meson/subprojects/libei/src)
set(libei_src_dir ${CMAKE_SOURCE_DIR}/subprojects/libei)
find_library(
LIBEI_LINK_LIBRARIES
NAMES ei
PATHS ${libei_bin_dir}
NO_DEFAULT_PATH)
if(LIBEI_LINK_LIBRARIES)
message(STATUS "Using local subproject libei")
set(LIBEI_FOUND true)
add_definitions(-DWINAPI_LIBEI=1)
set(LIBEI_INCLUDE_DIRS ${libei_src_dir}/src)
include_directories(${LIBEI_INCLUDE_DIRS})
else()
message(WARNING "Local libei not found")
endif()
endif()
endmacro()
macro(configure_libportal)
option(SYSTEM_LIBPORTAL "Use system libportal" ON)
if(SYSTEM_LIBPORTAL)
pkg_check_modules(LIBPORTAL QUIET "libportal >= ${LIBPORTAL_MIN_VERSION}")
if(LIBPORTAL_FOUND)
message(STATUS "libportal version: ${LIBPORTAL_VERSION}")
check_libportal()
else()
message(WARNING "libportal >= ${LIBPORTAL_MIN_VERSION} not found")
endif()
else()
set(libportal_bin_dir
${CMAKE_BINARY_DIR}/meson/subprojects/libportal/libportal)
set(libportal_src_dir ${CMAKE_SOURCE_DIR}/subprojects/libportal)
find_library(
LIBPORTAL_LINK_LIBRARIES
NAMES portal
PATHS ${libportal_bin_dir}
NO_DEFAULT_PATH)
if(LIBPORTAL_LINK_LIBRARIES)
message(STATUS "Using local subproject libportal")
set(LIBPORTAL_FOUND true)
set(LIBPORTAL_INCLUDE_DIRS ${libportal_src_dir})
# HACK: Somehow `check_symbol_exists` doesn't pick up on the symbols even though
# they are actually there. Since we use master branch of libportal, for now we'll
# assume that the symbols are there.
set(HAVE_LIBPORTAL_SESSION_CONNECT_TO_EIS true)
set(HAVE_LIBPORTAL_CREATE_REMOTE_DESKTOP_SESSION_FULL true)
set(HAVE_LIBPORTAL_INPUTCAPTURE true)
set(HAVE_LIBPORTAL_OUTPUT_NONE true)
else()
message(WARNING "Local libportal not found")
endif()
endif()
if(LIBPORTAL_FOUND)
add_definitions(-DWINAPI_LIBPORTAL=1)
include_directories(${LIBPORTAL_INCLUDE_DIRS})
endif()
endmacro()
# libportal 0.7 has xdp_session_connect_to_eis but it doesn't have remote desktop session restore or
# the inputcapture code, so let's check for explicit functions that bits depending on what we have
macro(check_libportal) macro(check_libportal)
# libportal 0.7 has xdp_session_connect_to_eis but it doesn't have remote desktop session restore or
# the inputcapture code, so let's check for explicit functions that bits depending on what we have
include(CMakePushCheckState) include(CMakePushCheckState)
include(CheckCXXSourceCompiles) include(CheckCXXSourceCompiles)
cmake_push_check_state(RESET) cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_INCLUDES set(CMAKE_REQUIRED_INCLUDES
"${CMAKE_REQUIRED_INCLUDES};${LIBPORTAL_INCLUDE_DIRS};${GLIB2_INCLUDE_DIRS}" "${CMAKE_REQUIRED_INCLUDES};${LIBPORTAL_INCLUDE_DIRS};${GLIB2_INCLUDE_DIRS}"
) )
set(CMAKE_REQUIRED_LIBRARIES set(CMAKE_REQUIRED_LIBRARIES
"${CMAKE_REQUIRED_LIBRARIES};${LIBPORTAL_LINK_LIBRARIES};${GLIB2_LINK_LIBRARIES}" "${CMAKE_REQUIRED_LIBRARIES};${LIBPORTAL_LINK_LIBRARIES};${GLIB2_LINK_LIBRARIES}"
) )
check_symbol_exists(xdp_session_connect_to_eis "libportal/portal.h" check_symbol_exists(xdp_session_connect_to_eis "libportal/portal.h"
HAVE_LIBPORTAL_SESSION_CONNECT_TO_EIS) HAVE_LIBPORTAL_SESSION_CONNECT_TO_EIS)
check_symbol_exists( check_symbol_exists(
xdp_portal_create_remote_desktop_session_full "libportal/portal.h" xdp_portal_create_remote_desktop_session_full "libportal/portal.h"
HAVE_LIBPORTAL_CREATE_REMOTE_DESKTOP_SESSION_FULL) HAVE_LIBPORTAL_CREATE_REMOTE_DESKTOP_SESSION_FULL)
check_symbol_exists(xdp_input_capture_session_connect_to_eis check_symbol_exists(xdp_input_capture_session_connect_to_eis
"libportal/inputcapture.h" HAVE_LIBPORTAL_INPUTCAPTURE) "libportal/inputcapture.h" HAVE_LIBPORTAL_INPUTCAPTURE)
@ -227,8 +284,25 @@ macro(check_libportal)
"#include <libportal/portal.h> "#include <libportal/portal.h>
int main() { XdpOutputType out = XDP_OUTPUT_NONE; } int main() { XdpOutputType out = XDP_OUTPUT_NONE; }
" HAVE_LIBPORTAL_OUTPUT_NONE) " HAVE_LIBPORTAL_OUTPUT_NONE)
cmake_pop_check_state() cmake_pop_check_state()
if(NOT HAVE_LIBPORTAL_SESSION_CONNECT_TO_EIS)
message(WARNING "xdp_session_connect_to_eis not found")
endif()
if(NOT HAVE_LIBPORTAL_CREATE_REMOTE_DESKTOP_SESSION_FULL)
message(WARNING "xdp_portal_create_remote_desktop_session_full not found")
endif()
if(NOT HAVE_LIBPORTAL_INPUTCAPTURE)
message(WARNING "xdp_input_capture_session_connect_to_eis not found")
endif()
if(NOT HAVE_LIBPORTAL_OUTPUT_NONE)
message(WARNING "XDP_OUTPUT_NONE not found")
endif()
endmacro() endmacro()
# #

View file

@ -36,6 +36,6 @@ if host_machine.system() == 'linux'
dependency('libportal', required: false) dependency('libportal', required: false)
else else
# Using the subproject is only useful for development; it's not intended for normal use. # Using the subproject is only useful for development; it's not intended for normal use.
subproject('libportal', default_options: ['docs=false', 'backend-gtk3=enabled']) subproject('libportal', default_options: ['docs=false', 'backend-gtk3=enabled', 'backend-qt6=disabled'])
endif endif
endif endif

View file

@ -177,6 +177,3 @@
/* Define if libportal has input capture support */ /* Define if libportal has input capture support */
#cmakedefine HAVE_LIBPORTAL_INPUTCAPTURE ${HAVE_LIBPORTAL_INPUTCAPTURE} #cmakedefine HAVE_LIBPORTAL_INPUTCAPTURE ${HAVE_LIBPORTAL_INPUTCAPTURE}
/* Define if libei ei_device_start_emulating takes a sequence number */
#cmakedefine HAVE_LIBEI_SEQUENCE_NUMBER ${HAVE_LIBEI_SEQUENCE_NUMBER}

View file

@ -16,31 +16,7 @@ def main():
if is_ci: if is_ci:
print("CI environment detected") print("CI environment detected")
parser = argparse.ArgumentParser() args = parse_args(is_ci)
parser.add_argument(
"--pause-on-exit", action="store_true", help="Useful on Windows"
)
parser.add_argument(
"--ci-env",
action="store_true",
help="Useful for faking CI env (defaults to true in CI env)",
default=is_ci,
)
parser.add_argument(
"--only-python", action="store_true", help="Only install Python dependencies"
)
parser.add_argument(
"--skip-system",
action="store_true",
help="Do not install system dependencies (apt, dnf, etc)",
)
parser.add_argument(
"--skip-meson", action="store_true", help="Do not setup and install with Meson"
)
parser.add_argument(
"--subproject", type=str, help="Sub-project to install dependencies for"
)
args = parser.parse_args()
env.ensure_dependencies() env.ensure_dependencies()
env.ensure_in_venv(__file__, auto_create=True) env.ensure_in_venv(__file__, auto_create=True)
@ -86,6 +62,44 @@ def main():
sys.exit(1) sys.exit(1)
def parse_args(is_ci):
parser = argparse.ArgumentParser()
parser.add_argument(
"--pause-on-exit", action="store_true", help="Useful on Windows"
)
parser.add_argument(
"--ci-env",
action="store_true",
help="Useful for faking CI env (defaults to true in CI env)",
default=is_ci,
)
parser.add_argument(
"--only-python", action="store_true", help="Only install Python dependencies"
)
parser.add_argument(
"--skip-system",
action="store_true",
help="Do not install system dependencies (apt, dnf, etc)",
)
parser.add_argument(
"--skip-meson", action="store_true", help="Do not setup and compile with Meson"
)
parser.add_argument(
"--subproject", type=str, help="Sub-project to install dependencies for"
)
parser.add_argument(
"--meson-install",
action="store_true",
help="Install built Meson subprojects to system",
)
parser.add_argument(
"--meson-no-system",
nargs="+",
help="Specify which Meson subprojects to use instead of system dependencies",
)
return parser.parse_args()
def run(args): def run(args):
if args.subproject: if args.subproject:
deps = SubprojectDependencies(args.subproject) deps = SubprojectDependencies(args.subproject)
@ -97,20 +111,22 @@ def run(args):
deps.install() deps.install()
if not args.skip_meson: if not args.skip_meson:
run_meson() run_meson(args.meson_install, args.meson_no_system)
# It's a bit weird to use Meson just for installing deps, but it's a stopgap until # It's a bit weird to use Meson just for installing deps, but it's a stopgap until
# we fully switch from CMake to Meson. For the meantime, Meson will install the deps # we fully switch from CMake to Meson. For the meantime, Meson will install the deps
# so that CMake can find them easily. Once we switch to Meson, it might be possible for # so that CMake can find them easily. Once we switch to Meson, it might be possible for
# Meson handle the deps resolution, so that we won't need to install them on the system. # Meson handle the deps resolution, so that we won't need to install them on the system.
def run_meson(): def run_meson(install, no_system_list):
meson.setup() meson.setup(no_system_list)
# Only compile and install on Linux for now, since we're only using Meson to fetch # Only compile and install on Linux for now, since we're only using Meson to fetch
# the deps on Windows and macOS. # the deps on Windows and macOS.
if env.is_linux(): if env.is_linux():
meson.compile() meson.compile()
if install:
meson.install() meson.install()

View file

@ -6,14 +6,21 @@ build_dir = "build/meson"
meson_bin = env.get_python_executable("meson") meson_bin = env.get_python_executable("meson")
def setup(): def setup(no_system_list):
cmd = [meson_bin, "setup", build_dir] cmd = [meson_bin, "setup", build_dir]
if env.is_windows(): if env.is_windows():
cmd.append("-Dsystem_gtest=false") cmd.append("-Dsystem_gtest=false")
for subproject in no_system_list or []:
cmd.append(f"-Dsystem_{subproject}=false")
# This might be a bit rude, but Meson seems to cache a lot (like CMake),
# so wiping every time is the easiest way to ensure that the build is clean.
# Plus, the way we're using Meson (at the moment) is just for satisfying
# dependencies, so this script is run infrequently enough to not matter.
if os.path.exists(build_dir): if os.path.exists(build_dir):
cmd.append("--reconfigure") cmd.append("--wipe")
cmd_utils.run(cmd, print_cmd=True) cmd_utils.run(cmd, print_cmd=True)

View file

@ -1,3 +1,3 @@
[wrap-git] [wrap-git]
url = https://gitlab.freedesktop.org/libinput/libei.git url = https://gitlab.freedesktop.org/libinput/libei.git
revision = tags/1.3.0 revision = main

View file

@ -1,3 +1,3 @@
[wrap-git] [wrap-git]
url = https://github.com/flatpak/libportal.git url = https://github.com/flatpak/libportal.git
revision = a1530a9 revision = main