Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[gtk]: Enable gtk3 on windows and use shared glib when shared #11308

Closed
wants to merge 9 commits into from
25 changes: 3 additions & 22 deletions recipes/gtk/all/conandata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,15 @@ sources:
"4.7.0":
sha256: "913fcd9d065efb348723e18c3b9113e23b92072e927ebd2f61d32745c8228b94"
url: "https://download.gnome.org/sources/gtk/4.7/gtk-4.7.0.tar.xz"
"4.6.2":
url: "https://download.gnome.org/sources/gtk/4.6/gtk-4.6.2.tar.xz"
sha256: "ff263af609a50eb76056653592d929459aef4819a444c436f6d52c6f63c1faec"
"4.4.0":
url: "https://download.gnome.org/sources/gtk/4.4/gtk-4.4.0.tar.xz"
sha256: "e0a1508f441686c3a20dfec48af533b19a4b2e017c18eaee31dccdb7d292505b"
"4.3.2":
url: "https://download.gnome.org/sources/gtk/4.3/gtk-4.3.2.tar.xz"
sha256: "20639bb2be8b9f58304f14480e3d957abd2c9fa3f671bb7e05193f9a8389d93f"
"4.2.1":
url: "https://download.gnome.org/sources/gtk/4.2/gtk-4.2.1.tar.xz"
sha256: "023169775de43f0a1fde066fbc19d78545ea6a7562c1915abde9b8ae4a7309e6"
"4.1.2":
url: "https://download.gnome.org/sources/gtk/4.1/gtk-4.1.2.tar.xz"
sha256: "33407da437c5e5ac09e7a463ba3bd025da3d80ba1953b8bbe2bce97dd2609677"
"4.0.2":
url: "https://download.gnome.org/sources/gtk/4.0/gtk-4.0.2.tar.xz"
sha256: "626707ac6751426ed76fed49c5b2d052dfee45757ce3827088ba87ca7f1dbc84"
"3.24.34":
url: "https://download.gnome.org/sources/gtk+/3.24/gtk+-3.24.34.tar.xz"
sha256: "dbc69f90ddc821b8d1441f00374dc1da4323a2eafa9078e61edbe5eeefa852ec"
"3.24.24":
url: "https://download.gnome.org/sources/gtk+/3.24/gtk+-3.24.24.tar.xz"
sha256: "cc9d4367c55b724832f6b09ab85481738ea456871f0381768a6a99335a98378a"
Expand All @@ -29,13 +20,3 @@ patches:
base_path: "source_subfolder"
- patch_file: "patches/0002-fix-version-resource-for-Windows-11-sdk.patch"
base_path: "source_subfolder"
"4.3.2":
- patch_file: "patches/0001-fix-UAC-manifest-rc.patch"
base_path: "source_subfolder"
- patch_file: "patches/0002-fix-version-resource-for-Windows-11-sdk.patch"
base_path: "source_subfolder"
"4.2.1":
- patch_file: "patches/0001-fix-UAC-manifest-rc.patch"
base_path: "source_subfolder"
- patch_file: "patches/0002-fix-version-resource-for-Windows-11-sdk.patch"
base_path: "source_subfolder"
167 changes: 129 additions & 38 deletions recipes/gtk/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from conans import ConanFile, Meson, tools
from conan.tools.files import rename
from conans.errors import ConanInvalidConfiguration
from conan.tools.microsoft import is_msvc
import os
import fileinput
import shlex

required_conan_version = ">=1.33.0"

Expand All @@ -20,7 +24,6 @@ class GtkConan(ConanFile):
"fPIC": [True, False],
"with_wayland": [True, False],
"with_x11": [True, False],
"with_pango": [True, False],
"with_ffmpeg": [True, False],
"with_gstreamer": [True, False],
"with_cups": [True, False],
Expand All @@ -31,7 +34,6 @@ class GtkConan(ConanFile):
"fPIC": True,
"with_wayland": False,
"with_x11": True,
"with_pango": True,
"with_ffmpeg": False,
"with_gstreamer": False,
"with_cups": False,
Expand Down Expand Up @@ -63,10 +65,6 @@ def export_sources(self):
def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
# Fix duplicate definitions of DllMain
self.options["gdk-pixbuf"].shared = True
# Fix segmentation fault
self.options["cairo"].shared = True
if tools.Version(self.version) >= "4.1.0":
# The upstream meson file does not create a static library
# See https://github.com/GNOME/gtk/commit/14f0a0addb9a195bad2f8651f93b95450b186bd6
Expand All @@ -78,26 +76,36 @@ def config_options(self):
def validate(self):
if self.settings.compiler == "gcc" and tools.Version(self.settings.compiler.version) < "5":
raise ConanInvalidConfiguration("this recipes does not support GCC before version 5. contributions are welcome")
if str(self.settings.compiler) in ["Visual Studio", "msvc"]:
if tools.Version(self.version) < "4.2":
if is_msvc(self):
# TODO: Remove once gtk 4.1.2 is removed
if self._gtk4 and tools.Version(self.version) < "4.2":
raise ConanInvalidConfiguration("MSVC support of this recipe requires at least gtk/4.2")
if not self.options["gdk-pixbuf"].shared:
raise ConanInvalidConfiguration("MSVC build requires shared gdk-pixbuf")
if not self.options["cairo"].shared:
raise ConanInvalidConfiguration("MSVC build requires shared cairo")
# TODO: Remove once gtk 3.24.24 is removed
if self._gtk3 and tools.Version(self.version) < "3.24.34":
raise ConanInvalidConfiguration("MSVC support of this recipe requires at least gtk/3.24.34")
if tools.Version(self.version) >= "4.1.0":
if not self.options.shared:
raise ConanInvalidConfiguration("gtk supports only shared since 4.1.0")
if self.settings.os == "Linux" and (self.options.with_wayland or self.options.with_x11) and not self.options["pango"].with_freetype:
raise ConanInvalidConfiguration(
"gtk requires pango with freetype when built with wayland/x11 support")

def configure(self):
if self.options.shared:
del self.options.fPIC
del self.settings.compiler.libcxx
del self.settings.compiler.cppstd
if self.settings.os == "Linux":
if self.options.with_wayland or self.options.with_x11:
if not self.options.with_pango:
raise ConanInvalidConfiguration("with_pango option is mandatory when with_wayland or with_x11 is used")
if self.options.shared:
self.options["glib"].shared = True
self.options["cairo"].shared = True
self.options["pango"].shared = True
self.options["gdk-pixbuf"].shared = True
if self._gtk3:
self.options["atk"].shared = True
if self.settings.os == "Linux" and self.options.with_x11:
self.options["at-spi2-atk"].shared = True
if self._gtk4:
self.options["graphene"].shared = True

def build_requirements(self):
self.build_requires("meson/0.62.2")
Expand All @@ -108,32 +116,27 @@ def build_requirements(self):
self.build_requires("sassc/3.6.2")

def requirements(self):
self.requires("gdk-pixbuf/2.42.6")
self.requires("gdk-pixbuf/2.42.8")
self.requires("glib/2.73.0")
if self._gtk4 or self.settings.compiler != "Visual Studio":
self.requires("cairo/1.17.4")
self.requires("cairo/1.17.4")
if self._gtk4:
self.requires("graphene/1.10.8")
self.requires("fribidi/1.0.12")
self.requires("libpng/1.6.37")
self.requires("libtiff/4.3.0")
self.requires("libjpeg/9d")
if self.settings.os == "Linux":
if self._gtk4:
self.requires("xkbcommon/1.4.1")
if self._gtk3:
self.requires("at-spi2-atk/2.38.0")
if self.options.with_wayland:
if self._gtk3:
self.requires("xkbcommon/1.4.1")
self.requires("xkbcommon/1.4.1")
self.requires("wayland/1.20.0")
if self.options.with_x11:
self.requires("xorg/system")
if self._gtk3:
self.requires("at-spi2-atk/2.38.0")
if self._gtk3:
self.requires("atk/2.38.0")
self.requires("libepoxy/1.5.10")
if self.options.with_pango:
self.requires("pango/1.50.7")
self.requires("pango/1.50.7")
if self.options.with_ffmpeg:
self.requires("ffmpeg/5.0")
if self.options.with_gstreamer:
Expand All @@ -157,9 +160,9 @@ def _configure_meson(self):
defs["datadir"] = os.path.join(self.package_folder, "res", "share")
defs["localedir"] = os.path.join(self.package_folder, "res", "share", "locale")
defs["sysconfdir"] = os.path.join(self.package_folder, "res", "etc")

if self._gtk4:
enabled_disabled = lambda opt : "enabled" if opt else "disabled"
enabled_disabled = lambda opt : "enabled" if opt else "disabled"
defs["media-ffmpeg"] = enabled_disabled(self.options.with_ffmpeg)
defs["media-gstreamer"] = enabled_disabled(self.options.with_gstreamer)
defs["print-cups"] = enabled_disabled(self.options.with_cups)
Expand All @@ -185,28 +188,74 @@ def build(self):
"dependency(false ? ")
with tools.environment_append(tools.RunEnvironment(self).vars):
meson = self._configure_meson()

cwd = os.path.join(os.getcwd(), self._build_subfolder).replace("\\", "/")
for line in fileinput.input(os.path.join(self._build_subfolder, "build.ninja"), inplace=True):
# the command response file for linking gtk exceeds msvc linker limit
# this hack fixes this by removing duplicates in the link arguments
# inside the build.ninja file
# see https://docs.microsoft.com/en-us/cpp/error-messages/tool-errors/linker-tools-error-lnk1170?view=msvc-170
idx = line.find("LINK_ARGS =")
if idx >= 0:
parts = shlex.split(line[idx + len("LINK_ARGS ="):])
print("{} {}".format(
line[: idx + len("LINK_ARGS =")],
" ".join((f'"{v}"' for v in dict.fromkeys(parts)))), end='')
continue

# in windows, ninja uses CreateProcess which has a limit of 32767 chars
# gnome.mkenums uses absolute paths, which increases the command length
# see: https://github.com/mesonbuild/meson/issues/6710
# this hack replaces all absolute paths of the build subfolder
# with relative paths to decrease the length of the command
idx = line.find("COMMAND = ")
if idx >= 0:
parts = shlex.split(line[idx + len("COMMAND ="):])
print("{} {}".format(
line[: idx + len("COMMAND =")],
" ".join((f'"{v.replace(cwd, ".")}"' for v in parts))))
continue

print(line, end='')

meson.build()

def package(self):
self.copy(pattern="LICENSE", dst="licenses", src=self._source_subfolder)
meson = self._configure_meson()
with tools.environment_append({
"PKG_CONFIG_PATH": self.install_folder,
"PATH": [os.path.join(self.package_folder, "bin")]}):
with tools.environment_append({**tools.RunEnvironment(self).vars,
"PKG_CONFIG_PATH": self.install_folder}):
meson.install()

self.copy(pattern="COPYING", src=self._source_subfolder, dst="licenses")
tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig"))
tools.remove_files_by_mask(os.path.join(self.package_folder, "bin"), "*.pdb")
tools.remove_files_by_mask(os.path.join(self.package_folder, "lib"), "*.pdb")

if self._gtk3 and is_msvc(self) and not self.options.shared:
rename(
self,
os.path.join(self.package_folder, "lib", "libgtk-3.a"),
os.path.join(self.package_folder, "lib", "gtk-3.lib"),
)
rename(
self,
os.path.join(self.package_folder, "lib", "libgdk-3.a"),
os.path.join(self.package_folder, "lib", "gdk-3.lib"),
)
rename(
self,
os.path.join(self.package_folder, "lib", "libgailutil-3.a"),
os.path.join(self.package_folder, "lib", "gailutil-3.lib"),
)


def package_info(self):
if self._gtk3:
self.cpp_info.components["gdk-3.0"].libs = ["gdk-3"]
self.cpp_info.components["gdk-3.0"].includedirs = [os.path.join("include", "gtk-3.0")]
self.cpp_info.components["gdk-3.0"].requires = []
if self.options.with_pango:
self.cpp_info.components["gdk-3.0"].requires.extend(["pango::pango_", "pango::pangocairo"])
self.cpp_info.components["gdk-3.0"].requires.extend(["pango::pango_", "pango::pangocairo"])
self.cpp_info.components["gdk-3.0"].requires.append("gdk-pixbuf::gdk-pixbuf")
if self.settings.compiler != "Visual Studio":
self.cpp_info.components["gdk-3.0"].requires.extend(["cairo::cairo", "cairo::cairo-gobject"])
Expand All @@ -216,17 +265,23 @@ def package_info(self):
self.cpp_info.components["gdk-3.0"].requires.append("xorg::xorg")
self.cpp_info.components["gdk-3.0"].requires.append("libepoxy::libepoxy")
self.cpp_info.components["gdk-3.0"].names["pkg_config"] = "gdk-3.0"
if self.settings.os == "Windows":
self.cpp_info.components["gdk-3.0"].system_libs = [
"imm32", "gdi32", "shell32", "ole32", "winmm", "dwmapi",
"setupapi", "cfgmgr32", "hid", "winspool", "comctl32",
"comdlg32"
]

self.cpp_info.components["gtk+-3.0"].libs = ["gtk-3"]
self.cpp_info.components["gtk+-3.0"].requires = ["gdk-3.0", "atk::atk"]
if self.settings.compiler != "Visual Studio":
self.cpp_info.components["gtk+-3.0"].requires.extend(["cairo::cairo", "cairo::cairo-gobject"])
self.cpp_info.components["gtk+-3.0"].requires.extend(["cairo::cairo", "cairo::cairo-gobject"])
self.cpp_info.components["gtk+-3.0"].requires.extend(["gdk-pixbuf::gdk-pixbuf", "glib::gio-2.0"])
if self.settings.os == "Linux":
self.cpp_info.components["gtk+-3.0"].requires.append("at-spi2-atk::at-spi2-atk")
self.cpp_info.components["gtk+-3.0"].requires.append("libepoxy::libepoxy")
if self.options.with_pango:
self.cpp_info.components["gtk+-3.0"].requires.append('pango::pangoft2')
if (self.settings.os == "Linux" and (self.options.with_wayland
or self.options.with_x11)) or self.options["pango"].with_freetype:
self.cpp_info.components["gtk+-3.0"].requires.append("pango::pangoft2")
if self.settings.os == "Linux":
self.cpp_info.components["gtk+-3.0"].requires.append("glib::gio-unix-2.0")
self.cpp_info.components["gtk+-3.0"].includedirs = [os.path.join("include", "gtk-3.0")]
Expand All @@ -240,3 +295,39 @@ def package_info(self):
self.cpp_info.names["pkg_config"] = "gtk4"
self.cpp_info.libs = ["gtk-4"]
self.cpp_info.includedirs.append(os.path.join("include", "gtk-4.0"))

self.cpp_info.requires.extend([
"gdk-pixbuf::gdk-pixbuf", "glib::gobject-2.0", "glib::gmodule-2.0",
"cairo::cairo", "cairo:::cairo-gobjec", "pango::pangocairo",
"libpng::libpng", "libtiff::libtiff", "libjpeg::libjpeg",
"libepoxy::libepoxy", "graphene::graphene-gobject-1.0",
"fribidi::fribidi"
])
if self.settings.os == "Windows":
self.cpp_info.system_libs = [
"advapi32", "comctl32", "crypt32", "dwmapi", "imm32",
"setupapi", "winmm"
]

if self.settings.os == "Linux":
if self.options.with_x11:
self.cpp_info.requires.append("xorg::xorg")
if self.options.with_wayland:
self.cpp_info.requires.append("xkbcommon::libxkbcommon")

if (self.settings.os == "Linux" and (self.options.with_wayland
or self.options.with_x11)) or self.options["pango"].with_freetype:
self.cpp_info.requires.append("pango::pangoft2")

def package_id(self):
self.info.requires["glib"].full_package_mode()
self.info.requires["cairo"].full_package_mode()
self.info.requires["pango"].full_package_mode()
self.info.requires["gdk-pixbuf"].full_package_mode()
if self._gtk3:
self.info.requires["atk"].full_package_mode()
if self.settings.os == "Linux" and self.options.with_x11:
self.info.requires["at-spi2-atk"].full_package_mode()

if self._gtk4:
self.info.requires["graphene"].full_package_mode()
8 changes: 1 addition & 7 deletions recipes/gtk/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,11 @@ versions:
folder: "system"
"4.7.0":
folder: all
"4.6.2":
folder: all
"4.4.0":
folder: all
"4.3.2":
folder: all
"4.2.1":
folder: all
"4.1.2":
folder: all
"4.0.2":
"3.24.34":
folder: all
"3.24.24":
folder: all