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

glib: conan v2 support #12221

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion recipes/glib/all/conandata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,3 @@ sources:
patches:
"2.73.1":
- patch_file: "patches/f2ea67ae441bc6059b43a1051dd0b750fe5f6301.patch"
base_path: "source_subfolder"
217 changes: 109 additions & 108 deletions recipes/glib/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import functools
import os
import glob
import shutil

from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.build import cross_building
from conan.tools import files, scm
from conan.tools.apple import fix_apple_shared_install_name
from conan.tools.env import VirtualBuildEnv
from conan.tools.files import apply_conandata_patches, copy, get, replace_in_file, rm, rmdir
from conan.tools.gnu import PkgConfigDeps
from conan.tools.layout import basic_layout
from conan.tools.meson import Meson, MesonToolchain
from conan.tools.microsoft import is_msvc
from conans import tools, Meson, VisualStudioBuildEnvironment
from conan.tools.scm import Version
from conans import tools as tools_legacy
import os
import shutil

required_conan_version = ">=1.50.0"

Expand Down Expand Up @@ -40,25 +42,15 @@ 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"

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

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
if scm.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 All @@ -69,14 +61,20 @@ def config_options(self):
def configure(self):
if self.options.shared:
del self.options.fPIC
del self.settings.compiler.libcxx
del self.settings.compiler.cppstd
try:
del self.settings.compiler.libcxx
except Exception:
pass
try:
del self.settings.compiler.cppstd
except Exception:
pass

def requirements(self):
self.requires("zlib/1.2.12")
self.requires("libffi/3.4.2")
if self.options.with_pcre:
if scm.Version(self.version) >= "2.73.2":
if Version(self.version) >= "2.73.2":
self.requires("pcre2/10.40")
else:
self.requires("pcre/8.45")
Expand All @@ -90,91 +88,90 @@ def requirements(self):
# for Linux, gettext is provided by libc
self.requires("libgettext/0.21")

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

def validate(self):
if hasattr(self, 'settings_build') and cross_building(self, skip_x64_x86=True):
raise ConanInvalidConfiguration("Cross-building not implemented")
if scm.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 scm.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 scm.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")

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

@functools.lru_cache(1)
def _configure_meson(self):
meson = Meson(self)
defs = {}
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"
self.tool_requires("meson/0.63.1")
self.tool_requires("pkgconf/1.7.4")

if scm.Version(self.version) < "2.69.0":
defs["internal_pcre"] = not self.options.with_pcre
def layout(self):
basic_layout(self, src_folder="src")

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

def generate(self):
tc = MesonToolchain(self)
if tools_legacy.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 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 scm.Version(self.version) >= "2.67.2":
defs["tests"] = "false"

if scm.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"
# TODO: fixed in conan 1.51.0?
tc.project_options["bindir"] = "bin"
tc.project_options["libdir"] = "lib"
tc.generate()

pkg = PkgConfigDeps(self)
pkg.generate()

buildenv = VirtualBuildEnv(self)
buildenv.generate(scope="build")

def _patch_sources(self):
for patch in self.conan_data.get("patches", {}).get(self.version, []):
tools.patch(**patch)
if scm.Version(self.version) < "2.67.2":
tools.replace_in_file(
os.path.join(self._source_subfolder, "meson.build"),
apply_conandata_patches(self)
meson_build = os.path.join(self.source_folder, "meson.build")
if Version(self.version) < "2.67.2":
replace_in_file(self,
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,
meson_build,
"subdir('fuzzing')",
"#subdir('fuzzing')",
) # https://gitlab.gnome.org/GNOME/glib/-/issues/2152
if scm.Version(self.version) < "2.73.2":
if Version(self.version) < "2.73.2":
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"),
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 scm.Version(self.version) < "2.73.1" \
replace_in_file(self,
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 @@ -184,46 +181,34 @@ 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,
meson_build,
"if cc.has_function('ngettext'",
"if false #cc.has_function('ngettext'",
)

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()

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

def package(self):
if scm.Version(self.version) < "2.73.0":
self.copy(pattern="COPYING", dst="licenses", src=self._source_subfolder)
if Version(self.version) < "2.73.0":
copy(self, "COPYING", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"))
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()
files.rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))
copy(self, "LGPL-2.1-or-later.txt", src=os.path.join(self.source_folder, "LICENSES"),
dst=os.path.join(self.package_folder, "licenses"))
meson = Meson(self)
meson.install()
rm(self, "*.pdb", os.path.join(self.package_folder, "bin"))
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))
shutil.move(
os.path.join(self.package_folder, "share"),
os.path.join(self.package_folder, "res"),
)
for pdb_file in glob.glob(os.path.join(self.package_folder, "bin", "*.pdb")):
os.unlink(pdb_file)
fix_apple_shared_install_name(self)
fix_msvc_libname(self)

def package_info(self):
self.cpp_info.components["glib-2.0"].set_property("pkg_config_name", "glib-2.0")
Expand Down Expand Up @@ -281,11 +266,11 @@ def package_info(self):
self.cpp_info.components["glib-2.0"].frameworks += ["Foundation", "CoreServices", "CoreFoundation"]
self.cpp_info.components["gio-2.0"].frameworks.append("AppKit")

if tools.is_apple_os(self.settings.os):
if tools_legacy.is_apple_os(self.settings.os):
self.cpp_info.components["glib-2.0"].requires.append("libiconv::libiconv")

if self.options.with_pcre:
if scm.Version(self.version) >= "2.73.2":
if Version(self.version) >= "2.73.2":
self.cpp_info.components["glib-2.0"].requires.append("pcre2::pcre2")
else:
self.cpp_info.components["glib-2.0"].requires.append("pcre::pcre")
Expand Down Expand Up @@ -313,7 +298,7 @@ def package_info(self):
'datadir': '${prefix}/res',
'schemasdir': '${datadir}/glib-2.0/schemas',
'bindir': '${prefix}/bin',
'giomoduledir': '${libdir}/gio/modules',
'giomoduledir': '${prefix}/lib/gio/modules',
'gio': '${bindir}/gio',
'gio_querymodules': '${bindir}/gio-querymodules',
'glib_compile_schemas': '${bindir}/glib-compile-schemas',
Expand All @@ -336,3 +321,19 @@ def package_info(self):
self.cpp_info.components["glib-2.0"].set_property(
"pkg_config_custom_content",
"\n".join(f"{key}={value}" for key, value in pkgconfig_variables.items()))

def fix_msvc_libname(conanfile, remove_lib_prefix=True):
"""remove lib prefix & change extension to .lib"""
from conan.tools.files import rename
import glob
if not is_msvc(conanfile):
return
libdirs = getattr(conanfile.cpp.package, "libdirs")
for libdir in libdirs:
for ext in [".dll.a", ".dll.lib", ".a"]:
full_folder = os.path.join(conanfile.package_folder, libdir)
for filepath in glob.glob(os.path.join(full_folder, f"*{ext}")):
libname = os.path.basename(filepath)[0:-len(ext)]
if remove_lib_prefix and libname[0:3] == "lib":
libname = libname[3:]
rename(conanfile, filepath, os.path.join(os.path.dirname(filepath), f"{libname}.lib"))
9 changes: 3 additions & 6 deletions recipes/glib/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
cmake_minimum_required(VERSION 3.1)
project(test_package C)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(TARGETS)
project(test_package LANGUAGES C)

add_executable(${PROJECT_NAME} test_package.c)

if (WIN32)
find_package(glib CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} glib::glib-2.0 glib::gio-2.0 glib::gmodule-2.0 glib::gobject-2.0 glib::gthread-2.0)
target_link_libraries(${PROJECT_NAME} PRIVATE glib::glib-2.0 glib::gio-2.0 glib::gmodule-2.0 glib::gobject-2.0 glib::gthread-2.0)
else()
find_package(PkgConfig REQUIRED)
pkg_check_modules(glib-2.0 REQUIRED IMPORTED_TARGET glib-2.0)
pkg_check_modules(gio-2.0 REQUIRED IMPORTED_TARGET gio-2.0)
pkg_check_modules(gmodule-2.0 REQUIRED IMPORTED_TARGET gmodule-2.0)
pkg_check_modules(gobject-2.0 REQUIRED IMPORTED_TARGET gobject-2.0)
pkg_check_modules(gthread-2.0 REQUIRED IMPORTED_TARGET gthread-2.0)
target_link_libraries(${PROJECT_NAME} PkgConfig::glib-2.0 PkgConfig::gio-2.0 PkgConfig::gmodule-2.0 PkgConfig::gobject-2.0 PkgConfig::gthread-2.0)
target_link_libraries(${PROJECT_NAME} PRIVATE PkgConfig::glib-2.0 PkgConfig::gio-2.0 PkgConfig::gmodule-2.0 PkgConfig::gobject-2.0 PkgConfig::gthread-2.0)
endif()
Loading