diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 76c487138..46fc588f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -235,6 +235,10 @@ jobs: runs-on: ubuntu-latest extra-packages: true + # Static libportal only needed until libportal is updated to 0.8.x. + extra-dep-args: --meson-no-system libportal --meson-static libportal --subprojects + extra-cmake-args: -DSYSTEM_LIBPORTAL=OFF -DSTATIC_LIBPORTAL=ON + - name: debian-12-arm64 container: symless/synergy-core:debian-12-arm64 runs-on: ubuntu-24.04-8-core-arm64 @@ -249,6 +253,10 @@ jobs: container: symless/synergy-core:ubuntu-24.04-amd64 runs-on: ubuntu-latest + # Static libportal only needed until libportal is updated to 0.8.x. + 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: symless/synergy-core:ubuntu-22.04-amd64 runs-on: ubuntu-latest @@ -305,13 +313,13 @@ jobs: run: git config --global --add safe.directory $GITHUB_WORKSPACE - name: Install dependencies - run: ./scripts/install_deps.py + run: ./scripts/install_deps.py ${{ matrix.distro.extra-dep-args }} env: # Prevent apt prompting for input. DEBIAN_FRONTEND: noninteractive - name: Configure - run: cmake -B build --preset=linux-release + run: cmake -B build --preset=linux-release ${{ matrix.distro.extra-cmake-args }} - name: Build run: cmake --build build -j8 diff --git a/ChangeLog b/ChangeLog index 4b47c4cbe..d336a705d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,7 @@ Enhancements: - #7492 Add warnings for `libei` and `libportal` - #7495 Use 16-CPU CI runner for FreeBSD - #7496 Cache vcpkg local app dir to restore built OpenSSL +- #7498 Option to static link `libportal` ahead of 0.8.x distribution # 1.15.1 diff --git a/cmake/Libraries.cmake b/cmake/Libraries.cmake index 529cab14b..fe16201a8 100644 --- a/cmake/Libraries.cmake +++ b/cmake/Libraries.cmake @@ -248,6 +248,12 @@ macro(configure_libportal) set(libportal_bin_dir ${CMAKE_BINARY_DIR}/meson/subprojects/libportal/libportal) set(libportal_src_dir ${CMAKE_SOURCE_DIR}/subprojects/libportal) + + option(LIBPORTAL_STATIC "Use the static libportal binary" OFF) + if(LIBPORTAL_STATIC) + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() + find_library( LIBPORTAL_LINK_LIBRARIES NAMES portal @@ -259,6 +265,8 @@ macro(configure_libportal) set(LIBPORTAL_FOUND true) set(LIBPORTAL_INCLUDE_DIRS ${libportal_src_dir}) + message(STATUS "libportal library file: ${LIBPORTAL_LINK_LIBRARIES}") + # 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. diff --git a/meson.build b/meson.build index 79784b0ac..b3b2e12c4 100644 --- a/meson.build +++ b/meson.build @@ -12,7 +12,7 @@ if host_machine.system() == 'windows' subproject('wintoast') endif -system_gtest = get_option('system_gtest') +system_gtest = get_option('system-gtest') if system_gtest dependency('gtest', required: false) else @@ -21,7 +21,7 @@ endif if host_machine.system() == 'linux' - system_libei = get_option('system_libei') + system_libei = get_option('system-libei') if system_libei dependency('libei-1.0', required: false) else @@ -31,11 +31,15 @@ if host_machine.system() == 'linux' subproject('libei', default_options: ['tests=disabled', 'liboeffis=disabled']) endif - system_libportal = get_option('system_libportal') + 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']) + subproject('libportal', default_options: [ + 'docs=false', + 'backend-gtk3=enabled', + 'backend-qt6=disabled' + ]) endif endif diff --git a/meson_options.txt b/meson_options.txt index 10145db8a..c83cce109 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,3 +1,3 @@ -option('system_gtest', type: 'boolean', value: true, description: 'Use system gtest') -option('system_libportal', type: 'boolean', value: true, description: 'Use system libportal') -option('system_libei', type: 'boolean', value: true, description: 'Use system libei') +option('system-gtest', type: 'boolean', value: true, description: 'Use system gtest') +option('system-libportal', type: 'boolean', value: true, description: 'Use system libportal') +option('system-libei', type: 'boolean', value: true, description: 'Use system libei') diff --git a/scripts/install_deps.py b/scripts/install_deps.py index 5ec73959a..96611e079 100755 --- a/scripts/install_deps.py +++ b/scripts/install_deps.py @@ -84,7 +84,9 @@ def parse_args(is_ci): "--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" + "--subprojects", + action="store_true", + help="Install dependencies for Meson subprojects (use with --meson-no-system)", ) parser.add_argument( "--meson-install", @@ -96,6 +98,11 @@ def parse_args(is_ci): 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( @@ -162,11 +169,6 @@ def install(args): deps = Dependencies(args) deps.install() - if args.subproject: - deps = SubprojectDependencies(args.subproject) - deps.install() - return - # Only install vcpkg dependencies on Windows, since on other OS it's not needed (yet). # We probably won't ever need this on macOS and Linux since brew and apt/dnf/etc do a # good job of providing dependencies. Where they don't, we can use Meson. @@ -176,15 +178,20 @@ def install(args): vcpkg.install() if not args.skip_meson: - run_meson(args.meson_install, args.meson_no_system) + 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): - meson.setup(no_system_list) +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. diff --git a/scripts/lib/meson.py b/scripts/lib/meson.py index 175dbf798..77f660d02 100644 --- a/scripts/lib/meson.py +++ b/scripts/lib/meson.py @@ -21,14 +21,14 @@ build_dir = "build/meson" meson_bin = env.get_python_executable("meson") -def setup(no_system_list): +def setup(no_system_list, static_list): cmd = [meson_bin, "setup", build_dir] 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") + 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. @@ -39,6 +39,33 @@ def setup(no_system_list): 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_bin, "compile", "-C", build_dir], print_cmd=True) diff --git a/subprojects/.gitignore b/subprojects/.gitignore index 3b6b452bf..bfb099b45 100644 --- a/subprojects/.gitignore +++ b/subprojects/.gitignore @@ -4,7 +4,8 @@ # Except for the wrap files. !.gitignore !*.wrap +!packagefiles/* # Ignore wraps added by subprojects. -/gi-docgen.wrap -/munit.wrap +gi-docgen.wrap +munit.wrap diff --git a/subprojects/libportal.wrap b/subprojects/libportal.wrap index da1ed2c4e..56aa671f2 100644 --- a/subprojects/libportal.wrap +++ b/subprojects/libportal.wrap @@ -1,3 +1,4 @@ [wrap-git] url = https://github.com/flatpak/libportal.git revision = main +patch_directory = libportal diff --git a/subprojects/packagefiles/libportal/static-lib.diff b/subprojects/packagefiles/libportal/static-lib.diff new file mode 100644 index 000000000..5e48ce48b --- /dev/null +++ b/subprojects/packagefiles/libportal/static-lib.diff @@ -0,0 +1,15 @@ +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], diff --git a/subprojects/packagefiles/wintoast-patch/meson.build b/subprojects/packagefiles/wintoast/meson.build similarity index 100% rename from subprojects/packagefiles/wintoast-patch/meson.build rename to subprojects/packagefiles/wintoast/meson.build diff --git a/subprojects/wintoast.wrap b/subprojects/wintoast.wrap index e7a4a6965..90d8e03a9 100644 --- a/subprojects/wintoast.wrap +++ b/subprojects/wintoast.wrap @@ -3,4 +3,4 @@ directory = WinToast-1.3.0 source_url = https://github.com/mohabouje/WinToast/archive/refs/tags/v1.3.0.tar.gz source_filename = wintoast-1.3.0.tar.gz source_hash = 998bd82fb2f49ee4b0df98774424d72c2bc18225188f251a9242af28bb80e6d4 -patch_directory = wintoast-patch +patch_directory = wintoast