build: Require libei and libportal from the system on linux

Removing remaining meson parts
This commit is contained in:
sithlord48 2024-10-21 16:39:15 -04:00 committed by Chris Rizzitello
parent 2136af68b5
commit 7b7ff81a9f
22 changed files with 17 additions and 441 deletions

View file

@ -32,30 +32,6 @@ jobs:
base-image: debian:trixie-slim
platform: amd64
- name: debian-12-amd64
runs-on: ubuntu-latest
config-dir: debian
base-image: debian:12-slim
platform: amd64
- name: debian-12-arm64
runs-on: ubuntu-24.04-2-core-arm64
config-dir: debian
base-image: arm64v8/debian:12-slim
platform: arm64
- name: ubuntu-24.04-amd64
runs-on: ubuntu-latest
config-dir: debian
base-image: ubuntu:24.04
platform: amd64
- name: ubuntu-22.04-amd64
runs-on: ubuntu-latest
config-dir: debian
base-image: ubuntu:22.04
platform: amd64
- name: fedora-40-amd64
runs-on: ubuntu-latest
config-dir: fedora
@ -68,24 +44,6 @@ jobs:
base-image: arm64v8/fedora:40
platform: arm64
- name: fedora-39-amd64
runs-on: ubuntu-latest
config-dir: fedora
base-image: fedora:39
platform: amd64
- name: rockylinux-9-amd64
runs-on: ubuntu-latest
config-dir: fedora
base-image: rockylinux:9
platform: amd64
- name: almalinux-9-amd64
runs-on: ubuntu-latest
config-dir: fedora
base-image: almalinux:9
platform: amd64
- name: opensuse-amd64
runs-on: ubuntu-latest
config-dir: opensuse
@ -98,12 +56,6 @@ jobs:
base-image: archlinux:latest
platform: amd64
- name: manjaro-amd64
config-dir: archlinux
runs-on: ubuntu-latest
base-image: manjarolinux/base:latest
platform: amd64
steps:
- name: Checkout
uses: actions/checkout@v4

View file

@ -4,31 +4,6 @@
"name": "debian-13-amd64",
"container": "deskflow/deskflow:debian-13-amd64",
"runs-on": "ubuntu-latest",
"extra-packages": false
},
{
"name": "debian-12-arm64",
"container": "deskflow/deskflow:debian-12-arm64",
"runs-on": "ubuntu-24.04-4-core-arm64",
"extra-packages": false
},
{
"name": "debian-12-amd64",
"container": "deskflow/deskflow:debian-12-amd64",
"runs-on": "ubuntu-latest",
"extra-packages": false
},
{
"name": "ubuntu-24.04-amd64",
"container": "deskflow/deskflow:ubuntu-24.04-amd64",
"runs-on": "ubuntu-latest",
"extra-dep-args": "--meson-no-system libportal --meson-static libportal --subprojects",
"extra-cmake-args": "-DSYSTEM_LIBPORTAL=OFF -DSTATIC_LIBPORTAL=ON"
},
{
"name": "ubuntu-22.04-amd64",
"container": "deskflow/deskflow:ubuntu-22.04-amd64",
"runs-on": "ubuntu-latest"
},
{
"name": "fedora-40-arm64",
@ -40,37 +15,16 @@
"container": "deskflow/deskflow:fedora-40-amd64",
"runs-on": "ubuntu-latest"
},
{
"name": "fedora-39-amd64",
"container": "deskflow/deskflow:fedora-39-amd64",
"runs-on": "ubuntu-latest"
},
{
"name": "opensuse-amd64",
"container": "deskflow/deskflow:opensuse-amd64",
"runs-on": "ubuntu-latest"
},
{
"name": "rockylinux-9-amd64",
"container": "deskflow/deskflow:rockylinux-9-amd64",
"runs-on": "ubuntu-latest"
},
{
"name": "almalinux-9-amd64",
"container": "deskflow/deskflow:almalinux-9-amd64",
"runs-on": "ubuntu-latest"
},
{
"name": "archlinux-amd64",
"container": "deskflow/deskflow:archlinux-amd64",
"runs-on": "ubuntu-latest",
"arch-like": "true"
},
{
"name": "manjaro-amd64",
"container": "deskflow/deskflow:manjaro-amd64",
"runs-on": "ubuntu-latest",
"arch-like": "true"
}
]
}

View file

@ -200,7 +200,6 @@ macro(configure_wayland_libs)
include(FindPkgConfig)
if(PKG_CONFIG_FOUND)
configure_libei()
configure_libportal()
pkg_check_modules(LIBXKBCOMMON REQUIRED xkbcommon)
@ -214,41 +213,10 @@ macro(configure_wayland_libs)
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 ${PROJECT_BINARY_DIR}/meson/subprojects/libei/src)
set(libei_src_dir ${PROJECT_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}")
pkg_check_modules(LIBPORTAL REQUIRED QUIET "libportal >= ${LIBPORTAL_MIN_VERSION}")
if(LIBPORTAL_FOUND)
message(STATUS "libportal version: ${LIBPORTAL_VERSION}")
check_libportal()

View file

@ -1,31 +0,0 @@
# For now, we're only using Meson to resolve dependencies. CMake is called separately.
# In future, we may completely replace CMake with Meson.
# Where available, we use system packages, otherwise we use subprojects.
# Subprojects are also used to get the latest version during development.
project('deskflow', 'cpp')
if host_machine.system() == 'linux'
system_libei = get_option('system-libei')
if system_libei
dependency('libei-1.0', required: false)
else
# Using the subproject is only useful for development; it's not intended for normal use.
# GNOME46 or above is required as this has the required bits for libei.
# Building on anything older is pointless as you won't be able to actually connect to anything.
subproject('libei', default_options: ['tests=disabled', 'liboeffis=disabled'])
endif
system_libportal = get_option('system-libportal')
if system_libportal
dependency('libportal', required: false)
else
# Using the subproject is only useful for development; it's not intended for normal use.
subproject('libportal', default_options: [
'docs=false',
'backend-gtk3=enabled',
'backend-qt6=disabled'
])
endif
endif

View file

@ -1,2 +0,0 @@
option('system-libportal', type: 'boolean', value: true, description: 'Use system libportal')
option('system-libei', type: 'boolean', value: true, description: 'Use system libei')

View file

@ -20,7 +20,6 @@ import lib.env as env
import lib.cmd_utils as cmd_utils
import lib.qt_utils as qt_utils
import lib.github as github
import lib.meson as meson
path_env_var = "PATH"
cmake_prefix_env_var = "CMAKE_PREFIX_PATH"
@ -80,29 +79,6 @@ def parse_args(is_ci):
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(
"--subprojects",
action="store_true",
help="Install dependencies for Meson subprojects (use with --meson-no-system)",
)
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",
)
parser.add_argument(
"--meson-static",
nargs="+",
help="Specify which Meson subprojects to build as static libraries",
)
if env.is_windows():
parser.add_argument(
@ -177,30 +153,6 @@ def install(args):
vcpkg.install(args.ci_env)
if not args.skip_meson:
if args.subprojects:
for subproject in args.meson_no_system or []:
deps = SubprojectDependencies(subproject)
deps.install()
run_meson(args.meson_install, args.meson_no_system, args.meson_static)
# 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
# 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.
def run_meson(install, no_system_list, static_list):
meson.setup(no_system_list, static_list)
# Only compile and install on Linux for now, since we're only using Meson to fetch
# the deps on Windows and macOS.
if env.is_linux():
meson.compile()
if install:
meson.install()
class Dependencies:
@ -318,38 +270,5 @@ class Dependencies:
linux.run_command(command, check=True)
subprojects = self.config.get_os_subprojects()
if subprojects:
for subproject in subprojects:
deps = SubprojectDependencies(subproject)
deps.install()
class SubprojectDependencies:
def __init__(self, subproject):
from lib.config import Config
self.subproject = subproject
self.config = Config()
def install(self):
"""Installs dependencies for the current platform."""
print(f"Installing dependencies for sub-project: {self.subproject}")
if env.is_linux():
self.linux()
else:
raise RuntimeError(f"Unsupported platform: {os}")
def linux(self):
"""Installs dependencies on Linux."""
import lib.linux as linux
command = self.config.get_subproject_deps_command(self.subproject)
linux.run_command(command, check=True)
if __name__ == "__main__":
main()

View file

@ -1,84 +0,0 @@
# Deskflow -- mouse and keyboard sharing utility
# Copyright (C) 2024 Symless Ltd.
#
# This package is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# found in the file LICENSE that should have accompanied this file.
#
# This package 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/>.
import os, sys
import lib.cmd_utils as cmd_utils
import lib.env as env
build_dir = "build/meson"
def meson_venv_bin():
if not env.in_venv():
raise RuntimeError("Not in a virtual environment")
return os.path.join(os.path.dirname(sys.executable), "meson")
def setup(no_system_list, static_list):
cmd = [meson_venv_bin(), "setup", build_dir]
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):
cmd.append("--wipe")
cmd_utils.run(cmd, print_cmd=True)
for subproject in static_list or []:
static_subproject(subproject)
def static_subproject(subproject):
if subproject == "libportal":
# HACK: This is a bit horrible. Ideally, Meson would take care of applying this patch,
# but it only seems to copy the .diff over and not apply the patch.
#
# Important: Static linking is not intended for package maintainers, only for beta testers.
# Static linking is also pretty horrible, but many distros will be slow to pick up 0.8.x
# which has input capture support. The sooner we can remove this patching code the better.
cmd_utils.run(
[
"patch",
"-d",
"subprojects/libportal",
"-p1",
"-i",
"static-lib.diff",
],
print_cmd=True,
check=False,
)
else:
raise RuntimeError(f"Unknown subproject: {subproject}")
def compile():
cmd_utils.run([meson_venv_bin(), "compile", "-C", build_dir], print_cmd=True)
def install():
cmd = [meson_venv_bin(), "install", "-C", build_dir]
has_sudo = cmd_utils.has_command("sudo")
if has_sudo:
cmd.insert(0, "sudo")
cmd_utils.run(cmd, print_cmd=True)

View file

@ -542,13 +542,9 @@ void MainWindow::open()
void MainWindow::onCoreProcessStarting()
{
#if defined(WINAPI_XWINDOWS) or defined(WINAPI_LIBEI)
if (deskflow::platform::isWayland()) {
m_WaylandWarnings.showOnce(this, m_CoreProcess.mode());
}
#endif
saveSettings();
}

View file

@ -188,13 +188,4 @@
/* Define to `unsigned int` if <sys/types.h> does not define. */
#cmakedefine size_t @size_t@
/* Define if libportal has xdp_session_connect_to_eis */
#cmakedefine HAVE_LIBPORTAL_SESSION_CONNECT_TO_EIS @HAVE_LIBPORTAL_SESSION_CONNECT_TO_EIS@
/* Define if libportal has xdp_portal_create_remote_desktop_session_full */
#cmakedefine HAVE_LIBPORTAL_CREATE_REMOTE_DESKTOP_SESSION_FULL @HAVE_LIBPORTAL_CREATE_REMOTE_DESKTOP_SESSION_FULL@
/* Define if libportal has input capture support */
#cmakedefine HAVE_LIBPORTAL_INPUTCAPTURE @HAVE_LIBPORTAL_INPUTCAPTURE@
// clang-format on

View file

@ -44,6 +44,7 @@ add_library(${target} STATIC ${sources} ${ui_files} ${qrc_file})
target_link_libraries(
${target}
${DESKFLOW_GUI_HOOK_LIB}
platform
Qt6::Core
Qt6::Widgets
Qt6::Network)

View file

@ -13,6 +13,13 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
if(UNIX AND NOT APPLE)
pkg_check_modules(LIBEI REQUIRED QUIET "libei-1.0 >= 1.3")
message(STATUS "libei version: ${LIBEI_VERSION}")
pkg_check_modules(LIBPORTAL REQUIRED QUIET "libportal >= 0.8")
message(STATUS "libportal version: ${LIBPORTAL_VERSION}")
endif()
if(WIN32)
file(GLOB headers "MSWindows*.h")
@ -68,16 +75,15 @@ add_library(platform STATIC ${sources})
target_link_libraries(platform client ${libs})
macro(link_wayland_libs)
target_compile_definitions(platform PUBLIC WINAPI_LIBEI WINAPI_LIBPORTAL HAVE_LIBPORTAL_INPUTCAPTURE)
target_link_libraries(platform ${LIBXKBCOMMON_LINK_LIBRARIES}
${GLIB2_LINK_LIBRARIES} ${LIBM_LIBRARIES})
${GLIB2_LINK_LIBRARIES} ${LIBM_LIBRARIES}
${LIBEI_LINK_LIBRARIES} ${LIBPORTAL_LINK_LIBRARIES}
)
if(LIBEI_FOUND)
target_link_libraries(platform ${LIBEI_LINK_LIBRARIES})
endif()
target_include_directories(platform PUBLIC ${LIBEI_INCLUDE_DIRS} ${LIBPORTAL_INCLUDE_DIRS})
if(LIBPORTAL_FOUND)
target_link_libraries(platform ${LIBPORTAL_LINK_LIBRARIES})
endif()
endmacro()
if(UNIX)

View file

@ -18,8 +18,6 @@
#pragma once
#include "config.h"
#include "base/IEventQueueBuffer.h"
#include "deskflow/IScreen.h"
#include "mt/Thread.h"

View file

@ -29,11 +29,8 @@
#include "deskflow/XScreen.h"
#include "platform/EiEventQueueBuffer.h"
#include "platform/EiKeyState.h"
#if WINAPI_LIBPORTAL
#include "platform/PortalInputCapture.h"
#include "platform/PortalRemoteDesktop.h"
#endif
#include <algorithm>
#include <cmath>
@ -70,21 +67,13 @@ EiScreen::EiScreen(bool is_primary, IEventQueue *events, bool use_portal)
new TMethodEventJob<EiScreen>(this, &EiScreen::handle_connected_to_eis_event)
);
if (is_primary) {
#if HAVE_LIBPORTAL_INPUTCAPTURE
portal_input_capture_ = new PortalInputCapture(this, events_);
#else
throw std::invalid_argument("missing libportal input capture support");
#endif // HAVE_LIBPORTAL_INPUTCAPTURE
} else {
#if WINAPI_LIBPORTAL
events_->adoptHandler(
events_->forEi().sessionClosed(), getEventTarget(),
new TMethodEventJob<EiScreen>(this, &EiScreen::handle_portal_session_closed)
);
portal_remote_desktop_ = new PortalRemoteDesktop(this, events_);
#else
throw std::invalid_argument("missing libportal remote desktop support");
#endif // WINAPI_LIBPORTAL
}
} else {
// Note: socket backend does not support reconnections
@ -105,12 +94,8 @@ EiScreen::~EiScreen()
delete key_state_;
#if WINAPI_LIBPORTAL
delete portal_remote_desktop_;
#endif
#if HAVE_LIBPORTAL_INPUTCAPTURE
delete portal_input_capture_;
#endif
}
void EiScreen::handle_ei_log_event(ei *ei, ei_log_priority priority, const char *message, ei_log_context *context)
@ -365,13 +350,10 @@ void EiScreen::enter()
ei_device_start_emulating(ei_abs_, sequence_number_);
fakeMouseMove(cursor_x_, cursor_y_);
}
}
#if HAVE_LIBPORTAL_INPUTCAPTURE
else {
} else {
LOG_DEBUG("releasing input capture at x=%i y=%i", cursor_x_, cursor_y_);
portal_input_capture_->release(cursor_x_, cursor_y_);
}
#endif
}
bool EiScreen::canLeave()
@ -699,12 +681,9 @@ void EiScreen::on_motion_event(ei_event *event)
if (is_on_screen_) {
LOG_DEBUG("event: motion on primary x=%i y=%i)", cursor_x_, cursor_y_);
sendEvent(events_->forIPrimaryScreen().motionOnPrimary(), MotionInfo::alloc(cursor_x_, cursor_y_));
#if HAVE_LIBPORTAL_INPUTCAPTURE
if (portal_input_capture_->is_active()) {
portal_input_capture_->release();
}
#endif
} else {
buffer_dx += dx;
buffer_dy += dy;

View file

@ -18,7 +18,6 @@
#pragma once
#include "config.h"
#include "deskflow/KeyMap.h"
#include "deskflow/PlatformScreen.h"
@ -37,9 +36,7 @@ namespace deskflow {
class EiClipboard;
class EiKeyState;
class PortalRemoteDesktop;
#if HAVE_LIBPORTAL_INPUTCAPTURE
class PortalInputCapture;
#endif
//! Implementation of IPlatformScreen for X11
class EiScreen : public PlatformScreen
@ -159,9 +156,7 @@ private:
mutable std::mutex mutex_;
PortalRemoteDesktop *portal_remote_desktop_ = nullptr;
#if HAVE_LIBPORTAL_INPUTCAPTURE
PortalInputCapture *portal_input_capture_ = nullptr;
#endif
struct HotKeyItem
{

View file

@ -16,14 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#if HAVE_LIBPORTAL_INPUTCAPTURE
#include "platform/PortalInputCapture.h"
#include "base/Event.h"
#include "base/Log.h"
#include "base/TMethodJob.h"
#include "platform/PortalInputCapture.h"
#include <sys/socket.h> // for EIS fd hack, remove
#include <sys/un.h> // for EIS fd hack, remove
@ -395,5 +391,3 @@ void PortalInputCapture::glib_thread(void *)
}
} // namespace deskflow
#endif

View file

@ -18,10 +18,6 @@
#pragma once
#include "config.h"
#if HAVE_LIBPORTAL_INPUTCAPTURE
#include "mt/Thread.h"
#include "platform/EiScreen.h"
@ -104,5 +100,3 @@ private:
};
} // namespace deskflow
#endif // HAVE_LIBPORTAL_INPUTCAPTURE

View file

@ -108,9 +108,7 @@ void PortalRemoteDesktop::cb_session_started(GObject *object, GAsyncResult *res)
// version in the impl.portal), i.e. you'll need an updated compositor on
// top of everything...
auto fd = -1;
#if HAVE_LIBPORTAL_SESSION_CONNECT_TO_EIS
fd = xdp_session_connect_to_eis(session, &error);
#endif
if (fd < 0) {
g_main_loop_quit(glib_main_loop_);
events_->addEvent(Event::kQuit);
@ -159,17 +157,6 @@ void PortalRemoteDesktop::cb_init_remote_desktop_session(GObject *object, GAsync
);
}
#if !defined(HAVE_LIBPORTAL_CREATE_REMOTE_DESKTOP_SESSION_FULL)
static inline void xdp_portal_create_remote_desktop_session_full(
XdpPortal *portal, XdpDeviceType devices, XdpOutputType outputs, XdpRemoteDesktopFlags flags,
XdpCursorMode cursor_mode, XdpPersistMode _unused1, const char *_unused2, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer data
)
{
xdp_portal_create_remote_desktop_session(portal, devices, outputs, flags, cursor_mode, cancellable, callback, data);
}
#endif
gboolean PortalRemoteDesktop::init_remote_desktop_session()
{
LOG_DEBUG("setting up remote desktop session with restore token %s", session_restore_token_);

View file

@ -18,20 +18,12 @@
#pragma once
#include "config.h"
#include "mt/Thread.h"
#include "platform/EiScreen.h"
#include <glib.h>
#include <libportal/portal.h>
#if !HAVE_LIBPORTAL_OUTPUT_NONE
// Added in libportal ad82a74 Jun 2022, not yet released in libportal 0.6
// should be used as a patch on ≤ 0.6, and non-git
#define XDP_OUTPUT_NONE (XdpOutputType)0
#endif
namespace deskflow {
class PortalRemoteDesktop

View file

@ -1,11 +0,0 @@
# Ignore all files in the subprojects directory.
*
# Except for the wrap files.
!.gitignore
!*.wrap
!packagefiles/*
# Ignore wraps added by subprojects.
gi-docgen.wrap
munit.wrap

View file

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

View file

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

View file

@ -1,15 +0,0 @@
diff --git a/libportal/meson.build b/libportal/meson.build
index 316bd9c..37a17f7 100644
--- a/libportal/meson.build
+++ b/libportal/meson.build
@@ -73,9 +73,8 @@ gio_unix_dep = dependency('gio-unix-2.0')
install_headers(headers, subdir: 'libportal')
-libportal = library('portal',
+libportal = static_library('portal',
src,
- version: version,
include_directories: [top_inc, libportal_inc],
install: true,
dependencies: [gio_dep, gio_unix_dep],