Skip to content

Commit

Permalink
glib: Convert to MesonToolchain to enable cross-compiling
Browse files Browse the repository at this point in the history
  • Loading branch information
jwillikers committed Jul 9, 2022
1 parent f2cc0be commit ee0a5cd
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 126 deletions.
1 change: 0 additions & 1 deletion recipes/glib/all/conandata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,3 @@ sources:
patches:
"2.73.1":
- patch_file: "patches/f2ea67ae441bc6059b43a1051dd0b750fe5f6301.patch"
base_path: "source_subfolder"
229 changes: 130 additions & 99 deletions recipes/glib/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
from conans import ConanFile, tools, Meson, VisualStudioBuildEnvironment
from conans.errors import ConanInvalidConfiguration
from conan.tools.microsoft import is_msvc
import functools
import os
import glob
import shutil
import os
import re

from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.apple.apple import is_apple_os
from conan.tools.files import apply_conandata_patches, chdir, get, load, rename, replace_in_file, rmdir, save
from conan.tools.layout import basic_layout
from conan.tools.meson import Meson, MesonToolchain
from conan.tools.microsoft import is_msvc
from conan.tools.scm import Version
from conans.tools import remove_files_by_mask

required_conan_version = ">=1.45.0"
required_conan_version = ">=1.47.0"


class GLibConan(ConanFile):
Expand All @@ -23,8 +29,8 @@ class GLibConan(ConanFile):
"fPIC": [True, False],
"with_pcre": [True, False],
"with_elf": [True, False],
"with_selinux": [True, False],
"with_mount": [True, False],
"with_selinux": [True, False],
}
default_options = {
"shared": False,
Expand All @@ -36,25 +42,16 @@ class GLibConan(ConanFile):
}

short_paths = True
generators = "pkg_config"

@property
def _source_subfolder(self):
return "source_subfolder"

@property
def _build_subfolder(self):
return "build_subfolder"
generators = "PkgConfigDeps", "VirtualBuildEnv", "VirtualRunEnv"

def export_sources(self):
self.copy("CMakeLists.txt")
for patch in self.conan_data.get("patches", {}).get(self.version, []):
self.copy(patch["patch_file"])

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
if tools.Version(self.version) < "2.71.1":
if Version(self.version) < "2.71.1":
self.options.shared = True
if self.settings.os != "Linux":
del self.options.with_mount
Expand Down Expand Up @@ -83,90 +80,89 @@ def requirements(self):
# for Linux, gettext is provided by libc
self.requires("libgettext/0.21")

if tools.is_apple_os(self.settings.os):
if is_apple_os(self.settings.os):
self.requires("libiconv/1.16")

def validate(self):
if hasattr(self, 'settings_build') and tools.cross_building(self, skip_x64_x86=True):
raise ConanInvalidConfiguration("Cross-building not implemented")
if tools.Version(self.version) >= "2.69.0" and not self.options.with_pcre:
if Version(self.version) >= "2.69.0" and not self.options.with_pcre:
raise ConanInvalidConfiguration("option glib:with_pcre must be True for glib >= 2.69.0")
if self.settings.os == "Windows" and not self.options.shared and tools.Version(self.version) < "2.71.1":
if self.settings.os == "Windows" and not self.options.shared and Version(self.version) < "2.71.1":
raise ConanInvalidConfiguration(
"glib < 2.71.1 can not be built as static library on Windows. "
"see https://gitlab.gnome.org/GNOME/glib/-/issues/692"
)
if tools.Version(self.version) < "2.67.0" and not is_msvc(self) and not self.options.with_elf:
if Version(self.version) < "2.67.0" and not is_msvc(self) and not self.options.with_elf:
raise ConanInvalidConfiguration("libelf dependency can't be disabled in glib < 2.67.0")

def build_requirements(self):
self.build_requires("meson/0.61.2")
self.build_requires("pkgconf/1.7.4")
self.tool_requires("meson/0.62.2")
self.tool_requires("pkgconf/1.7.4")

def layout(self):
basic_layout(self)

def source(self):
tools.get(**self.conan_data["sources"][self.version], strip_root=True, destination=self._source_subfolder)
get(self, **self.conan_data["sources"][self.version], strip_root=True)

@functools.lru_cache(1)
def _configure_meson(self):
meson = Meson(self)
defs = dict()
if tools.is_apple_os(self.settings.os):
defs["iconv"] = "external" # https://gitlab.gnome.org/GNOME/glib/issues/1557
defs["selinux"] = "enabled" if self.options.get_safe("with_selinux") else "disabled"
defs["libmount"] = "enabled" if self.options.get_safe("with_mount") else "disabled"
def generate(self):
tc = MesonToolchain(self)
tc.project_options["libdir"] = "lib"
tc.project_options["localedir"] = "res"
tc.project_options["datadir"] = "res"
if is_apple_os(self.settings.os):
tc.project_options["iconv"] = "external" # https://gitlab.gnome.org/GNOME/glib/issues/1557
tc.project_options["selinux"] = "enabled" if self.options.get_safe("with_selinux") else "disabled"
tc.project_options["libmount"] = "enabled" if self.options.get_safe("with_mount") else "disabled"

if tools.Version(self.version) < "2.69.0":
defs["internal_pcre"] = not self.options.with_pcre
if Version(self.version) < "2.69.0":
tc.project_options["internal_pcre"] = not self.options.with_pcre

if self.settings.os == "FreeBSD":
defs["xattr"] = "false"
if tools.Version(self.version) >= "2.67.2":
defs["tests"] = "false"

if tools.Version(self.version) >= "2.67.0":
defs["libelf"] = "enabled" if self.options.get_safe("with_elf") else "disabled"

meson.configure(
source_folder=self._source_subfolder,
args=["--wrap-mode=nofallback"],
build_folder=self._build_subfolder,
defs=defs,
)
return meson
tc.project_options["xattr"] = False
if Version(self.version) >= "2.67.2":
tc.project_options["tests"] = False

if Version(self.version) >= "2.67.0":
tc.project_options["libelf"] = "enabled" if self.options.get_safe("with_elf") else "disabled"

tc.generate()

def _patch_sources(self):
for patch in self.conan_data.get("patches", {}).get(self.version, []):
tools.patch(**patch)
if tools.Version(self.version) < "2.67.2":
tools.replace_in_file(
os.path.join(self._source_subfolder, "meson.build"),
apply_conandata_patches(self)
if Version(self.version) < "2.67.2":
replace_in_file(
self,
os.path.join(self.source_folder, "meson.build"),
"build_tests = not meson.is_cross_build() or (meson.is_cross_build() and meson.has_exe_wrapper())",
"build_tests = false",
)
tools.replace_in_file(
os.path.join(self._source_subfolder, "meson.build"),
replace_in_file(
self,
os.path.join(self.source_folder, "meson.build"),
"subdir('fuzzing')",
"#subdir('fuzzing')",
) # https://gitlab.gnome.org/GNOME/glib/-/issues/2152
for filename in [
os.path.join(self._source_subfolder, "meson.build"),
os.path.join(self._source_subfolder, "glib", "meson.build"),
os.path.join(self._source_subfolder, "gobject", "meson.build"),
os.path.join(self._source_subfolder, "gio", "meson.build"),
os.path.join(self.source_folder, "meson.build"),
os.path.join(self.source_folder, "glib", "meson.build"),
os.path.join(self.source_folder, "gobject", "meson.build"),
os.path.join(self.source_folder, "gio", "meson.build"),
]:
tools.replace_in_file(filename, "subdir('tests')", "#subdir('tests')")
replace_in_file(self, filename, "subdir('tests')", "#subdir('tests')")
if self.settings.os != "Linux":
# allow to find gettext
tools.replace_in_file(
os.path.join(self._source_subfolder, "meson.build"),
"libintl = cc.find_library('intl', required : false)" if tools.Version(self.version) < "2.73.1" \
replace_in_file(
self,
os.path.join(self.source_folder, "meson.build"),
"libintl = cc.find_library('intl', required : false)" if Version(self.version) < "2.73.1" \
else "libintl = dependency('intl', required: false)",
"libintl = dependency('libgettext', method : 'pkg-config', required : false)",
)

tools.replace_in_file(

replace_in_file(
self,
os.path.join(
self._source_subfolder,
self.source_folder,
"gio",
"gdbus-2.0",
"codegen",
Expand All @@ -176,51 +172,62 @@ def _patch_sources(self):
"'res'",
)
if self.settings.os != "Linux":
tools.replace_in_file(
os.path.join(self._source_subfolder, "meson.build"),
replace_in_file(
self,
os.path.join(self.source_folder, "meson.build"),
"if cc.has_function('ngettext'",
"if false #cc.has_function('ngettext'",
)

def _patch_pkgconfig(self):
with chdir(self, self.generators_folder):
for filename in glob.glob("*.pc"):
self.output.info(f"processing {filename}")
content = load(self, filename)
results = re.findall(r"-F (.*)[ \n]", content)
for result in results:
if not os.path.isdir(result):
self.output.info(f"removing bad framework path {result}")
content = content.replace(f"-F {result}", "")
save(self, filename, content)

def build(self):
self._patch_sources()
with tools.environment_append(
VisualStudioBuildEnvironment(self).vars
) if is_msvc(self) else tools.no_op():
meson = self._configure_meson()
meson.build()
self._patch_pkgconfig()
meson = Meson(self)
meson.configure()
meson.build()

def _fix_library_names(self):
if self.settings.compiler == "Visual Studio":
with tools.chdir(os.path.join(self.package_folder, "lib")):
with chdir(self, os.path.join(self.package_folder, "lib")):
for filename_old in glob.glob("*.a"):
filename_new = filename_old[3:-2] + ".lib"
self.output.info("rename %s into %s" % (filename_old, filename_new))
shutil.move(filename_old, filename_new)
self.output.info("rename {filename_old} into {filename_new}")
rename(self, filename_old, filename_new)

def package(self):
if tools.Version(self.version) < "2.73.0":
self.copy(pattern="COPYING", dst="licenses", src=self._source_subfolder)
if Version(self.version) < "2.73.0":
self.copy(pattern="COPYING", dst="licenses", src=self.source_folder)
else:
self.copy(pattern="LGPL-2.1-or-later.txt", dst="licenses", src=os.path.join(self._source_subfolder, "LICENSES"))
with tools.environment_append(
VisualStudioBuildEnvironment(self).vars
) if is_msvc(self) else tools.no_op():
meson = self._configure_meson()
meson.install()
self._fix_library_names()
tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig"))
shutil.move(
os.path.join(self.package_folder, "share"),
os.path.join(self.package_folder, "res"),
)
self.copy(pattern="LGPL-2.1-or-later.txt", dst="licenses", src=os.path.join(self.source_folder, "LICENSES"))
meson = Meson(self)
meson.install()
self._fix_library_names()
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))
for pdb_file in glob.glob(os.path.join(self.package_folder, "bin", "*.pdb")):
os.unlink(pdb_file)
remove_files_by_mask(os.path.join(self.package_folder, "lib"), "*.pdb")
remove_files_by_mask(os.path.join(self.package_folder, "lib"), "*.pc")

def package_info(self):
self.cpp_info.components["glib-2.0"].libs = ["glib-2.0"]
self.cpp_info.components["glib-2.0"].names["pkg_config"] = "glib-2.0"
self.cpp_info.components["glib-2.0"].set_property("pkg_config_name", "glib-2.0")

# todo Remove when using Conan 1.50.0.
self.cpp_info.components["glib-2.0"].libdirs = ["lib"]

if self.settings.os in ["Linux", "FreeBSD"]:
self.cpp_info.components["glib-2.0"].system_libs.append("pthread")
if self.settings.os == "Windows":
Expand All @@ -244,11 +251,15 @@ def package_info(self):
self.cpp_info.components["glib-2.0"].requires.append(
"libgettext::libgettext"
)
if tools.is_apple_os(self.settings.os):
if is_apple_os(self.settings.os):
self.cpp_info.components["glib-2.0"].requires.append("libiconv::libiconv")

self.cpp_info.components["gmodule-no-export-2.0"].libs = ["gmodule-2.0"]
self.cpp_info.components["gmodule-no-export-2.0"].set_property("pkg_config_name", "gmodule-no-export-2.0")

# todo Remove when using Conan 1.50.0.
self.cpp_info.components["gmodule-no-export-2.0"].libdirs = ["lib"]

if self.settings.os in ["Linux", "FreeBSD"]:
self.cpp_info.components["gmodule-no-export-2.0"].system_libs.append(
"pthread"
Expand Down Expand Up @@ -276,17 +287,29 @@ def package_info(self):

self.cpp_info.components["gobject-2.0"].set_property("pkg_config_name", "gobject-2.0")
self.cpp_info.components["gobject-2.0"].libs = ["gobject-2.0"]

# todo Remove when using Conan 1.50.0.
self.cpp_info.components["gobject-2.0"].libdirs = ["lib"]

self.cpp_info.components["gobject-2.0"].requires.append("glib-2.0")
self.cpp_info.components["gobject-2.0"].requires.append("libffi::libffi")

self.cpp_info.components["gthread-2.0"].set_property("pkg_config_name", "gthread-2.0")
self.cpp_info.components["gthread-2.0"].libs = ["gthread-2.0"]

# todo Remove when using Conan 1.50.0.
self.cpp_info.components["gthread-2.0"].libdirs = ["lib"]

if self.settings.os in ["Linux", "FreeBSD"]:
self.cpp_info.components["gthread-2.0"].system_libs.append("pthread")
self.cpp_info.components["gthread-2.0"].requires.append("glib-2.0")

self.cpp_info.components["gio-2.0"].set_property("pkg_config_name", "gio-2.0")
self.cpp_info.components["gio-2.0"].libs = ["gio-2.0"]

# todo Remove when using Conan 1.50.0.
self.cpp_info.components["gio-2.0"].libdirs = ["lib"]

if self.settings.os == "Linux":
self.cpp_info.components["gio-2.0"].system_libs.append("resolv")
if self.settings.os in ["Linux", "FreeBSD"]:
Expand All @@ -313,13 +336,20 @@ def package_info(self):
self.cpp_info.components["gio-windows-2.0"].includedirs = [
os.path.join("include", "gio-win32-2.0")
]

# todo Remove when using Conan 1.50.0.
self.cpp_info.components["gio-windows-2.0"].libdirs = ["lib"]
else:
self.cpp_info.components["gio-unix-2.0"].requires.extend(
["gobject-2.0", "gio-2.0"]
)
self.cpp_info.components["gio-unix-2.0"].includedirs = [
os.path.join("include", "gio-unix-2.0")
]

# todo Remove when using Conan 1.50.0.
self.cpp_info.components["gio-unix-2.0"].libdirs = ["lib"]

self.env_info.GLIB_COMPILE_SCHEMAS = os.path.join(
self.package_folder, "bin", "glib-compile-schemas"
)
Expand All @@ -332,13 +362,14 @@ def package_info(self):
) # this is actually an executable

bin_path = os.path.join(self.package_folder, "bin")
self.output.info("Appending PATH env var with: {}".format(bin_path))
self.env_info.PATH.append(bin_path)
self.output.info("Prepending PATH env var with: {bin_path}")
self.runenv_info.prepend_path("PATH", bin_path)

pkgconfig_variables = {
'datadir': '${prefix}/res',
'schemasdir': '${datadir}/glib-2.0/schemas',
'bindir': '${prefix}/bin',
'libdir': '${prefix}/lib',
'giomoduledir': '${libdir}/gio/modules',
'gio': '${bindir}/gio',
'gio_querymodules': '${bindir}/gio-querymodules',
Expand All @@ -351,7 +382,7 @@ def package_info(self):
}
self.cpp_info.components["gio-2.0"].set_property(
"pkg_config_custom_content",
"\n".join("%s=%s" % (key, value) for key,value in pkgconfig_variables.items()))
"\n".join(f"{key}={value}" for key, value in pkgconfig_variables.items()))

pkgconfig_variables = {
'bindir': '${prefix}/bin',
Expand All @@ -361,4 +392,4 @@ def package_info(self):
}
self.cpp_info.components["glib-2.0"].set_property(
"pkg_config_custom_content",
"\n".join("%s=%s" % (key, value) for key,value in pkgconfig_variables.items()))
"\n".join(f"{key}={value}" for key, value in pkgconfig_variables.items()))
Loading

0 comments on commit ee0a5cd

Please sign in to comment.