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

libudev: add a non-system recipe #26162

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
9 changes: 9 additions & 0 deletions recipes/libudev/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
sources:
"255.15":
url: "https://github.com/systemd/systemd-stable/archive/refs/tags/v255.15.tar.gz"
sha256: "f9c1754d65b6ab12c658e832292b3d3dd26722d016f9d065f85fe6f9747e51d2"
patches:
"255.15":
- patch_file: "patches/255.13/0001-fix-format-overflow.patch"
patch_type: "bugfix"
patch_description: "Fix a format overflow fatal compiler warning"
131 changes: 104 additions & 27 deletions recipes/libudev/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,54 +1,131 @@
import os
import tarfile

from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.system import package_manager
from conan.tools.gnu import PkgConfig
from conan.tools.env import VirtualBuildEnv
from conan.tools.files import download, move_folder_contents, copy, export_conandata_patches, apply_conandata_patches
from conan.tools.gnu import PkgConfigDeps
from conan.tools.layout import basic_layout
from conan.tools.meson import MesonToolchain, Meson
from conan.tools.scm import Version

required_conan_version = ">=1.50.0"


class LibUDEVConan(ConanFile):
class LibUdevConan(ConanFile):
name = "libudev"
version = "system"
description = "API for enumerating and introspecting local devices"
topics = ("udev", "devices", "enumerating")
url = "https://github.com/conan-io/conan-center-index"
homepage = "https://www.freedesktop.org/software/systemd/man/udev.html"
license = "GPL-2.0-or-later", "LGPL-2.1-or-later"
license = "GPL-2.0-or-later AND LGPL-2.1-or-later"
package_type = "shared-library"
settings = "os", "arch", "compiler", "build_type"

def configure(self):
self.settings.rm_safe("compiler.cppstd")
self.settings.rm_safe("compiler.libcxx")

def export_sources(self):
export_conandata_patches(self)

def layout(self):
pass
basic_layout(self, src_folder="src")

@property
def _compilers_minimum_version(self):
return {
"gcc": "7",
"clang": "10"
}

def requirements(self):
self.requires("libcap/2.69")
# These are not actually linked into the final library.
self.requires("libmount/2.39.2", libs=False)
self.requires("libxcrypt/4.4.36", libs=False)

def validate(self):
if self.settings.os != "Linux":
raise ConanInvalidConfiguration("libudev is only supported on Linux.")
minimum_version = self._compilers_minimum_version.get(str(self.settings.compiler), False)
if minimum_version and Version(self.settings.compiler.version) < minimum_version:
raise ConanInvalidConfiguration(
f"{self.ref} requires {str(self.settings.compiler)} >= {minimum_version}."
)

def build_requirements(self):
self.tool_requires("meson/[>=1.2.3 <2]")
self.tool_requires("m4/1.4.19")
self.tool_requires("gperf/3.1")
if not self.conf.get("tools.gnu:pkg_config", check_type=str):
self.tool_requires("pkgconf/[>=2.2 <3]")

def source(self):
# Extract using standard Python tools due to Conan's unzip() not handling backslashes in
# 'units/system-systemd\x2dcryptsetup.slice', etc. correctly.
download(self, **self.conan_data["sources"][self.version], filename="sources.tar.gz")
with tarfile.open("sources.tar.gz", "r:gz") as tar:
tar.extractall()
move_folder_contents(self, os.path.join(self.source_folder, f"systemd-stable-{self.version}"), self.source_folder)
apply_conandata_patches(self)

def generate(self):
env = VirtualBuildEnv(self)
env.generate()

def package_id(self):
self.info.clear()
tc = MesonToolchain(self)
tc.project_options["tests"] = "false"
tc.project_options["selinux"] = "false"
tc.project_options["lz4"] = "false"
tc.project_options["xz"] = "false"
tc.project_options["zstd"] = "false"
tc.project_options["static-libudev"] = "false"
# sys/capability.h is treated as a system header by meson.build
tc.extra_cflags.append(f"-I{self.dependencies['libcap'].cpp_info.includedirs[0]}")

def system_requirements(self):
dnf = package_manager.Dnf(self)
dnf.install(["systemd-devel"], update=True, check=True)
# options unrelated to libsystemd
unrelated = [
"fdisk", "seccomp", "pwquality", "apparmor", "polkit", "audit",
"kmod", "microhttpd", "libcryptsetup", "libcurl", "libidn",
"libidn2", "qrencode", "openssl", "libfido2", "zlib", "xkbcommon",
"pcre2", "glib", "dbus", "blkid", "gcrypt", "p11kit", "ima",
"smack", "bzip2", "gnutls", "idn", "initrd", "binfmt", "vconsole",
"quotacheck", "tmpfiles", "environment-d", "sysusers", "firstboot",
"randomseed", "backlight", "rfkill", "xdg-autostart", "logind",
"hibernate", "machined", "portabled", "userdb", "hostnamed",
"timedated", "timesyncd", "localed", "networkd", "resolve",
"coredump", "pstore", "efi", "nss-myhostname", "nss-mymachines",
"nss-resolve", "nss-systemd", "hwdb", "tpm", "man", "html", "utmp",
"ldconfig", "adm-group", "wheel-group", "gshadow", "install-tests",
"link-udev-shared", "link-systemctl-shared", "analyze", "pam",
"link-networkd-shared", "link-timesyncd-shared", "kernel-install",
"libiptc", "elfutils", "repart", "homed", "importd", "acl",
"dns-over-tls", "log-trace", "oomd", "sysext", "nscd",
"link-boot-shared", "link-journalctl-shared", "passwdqc", "bootloader",
"link-portabled-shared"]
for opt in unrelated:
tc.project_options[opt] = "false"

yum = package_manager.Yum(self)
yum.install(["systemd-devel"], update=True, check=True)
tc.generate()

apt = package_manager.Apt(self)
apt.install(["libudev-dev"], update=True, check=True)
deps = PkgConfigDeps(self)
deps.generate()

pacman = package_manager.PacMan(self)
pacman.install(["systemd-libs"], update=True, check=True)
def build(self):
meson = Meson(self)
meson.configure()
meson.build(target="udev:shared_library")

zypper = package_manager.Zypper(self)
zypper.install_substitutes(["libudev-devel"], ["systemd-devel"], update=True, check=True)
def package(self):
copy(self, "LICENSE.GPL2", self.source_folder, os.path.join(self.package_folder, "licenses"))
copy(self, "LICENSE.LGPL2.1", self.source_folder, os.path.join(self.package_folder, "licenses"))
copy(self, "libudev.h", os.path.join(self.source_folder, "src", "libudev"), os.path.join(self.package_folder, "include"))
copy(self, "libudev.so*", self.build_folder, os.path.join(self.package_folder, "lib"))

def package_info(self):
self.cpp_info.includedirs = []
self.cpp_info.libdirs = []
pkg_config = PkgConfig(self, "libudev")
pkg_config.fill_cpp_info(self.cpp_info)
self.cpp_info.set_property("system_package_version", str(pkg_config.version))

# todo Remove this workaround for Conan v1
self.cpp_info.set_property("component_version", str(pkg_config.version))
self.cpp_info.set_property("pkg_config_name", "libudev")
self.cpp_info.set_property("component_version", str(Version(self.version).major))
self.cpp_info.libs = ["udev"]
self.cpp_info.system_libs = ["rt", "pthread"]
26 changes: 26 additions & 0 deletions recipes/libudev/all/patches/255.13/0001-fix-format-overflow.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Fixes

../src/src/shared/condition.c: In function ‘condition_dump_list’:
../src/src/shared/condition.c:1269:33: error: ‘%s’ directive argument is null [-Werror=format-overflow=]
1269 | "%s\t%s: %s%s%s %s\n",
| ^~

--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -1266,6 +1266,7 @@

prefix = strempty(prefix);

+ const char* result = condition_result_to_string(c->result);
fprintf(f,
"%s\t%s: %s%s%s %s\n",
prefix,
@@ -1273,7 +1274,7 @@
c->trigger ? "|" : "",
c->negate ? "!" : "",
c->parameter,
- condition_result_to_string(c->result));
+ result ? result : "");
}

void condition_dump_list(Condition *first, FILE *f, const char *prefix, condition_to_string_t to_string) {
1 change: 0 additions & 1 deletion recipes/libudev/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@ project(test_package C)

find_package(libudev REQUIRED CONFIG)


add_executable(${PROJECT_NAME} test_package.c)
target_link_libraries(${PROJECT_NAME} libudev::libudev)
5 changes: 2 additions & 3 deletions recipes/libudev/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@

class TestPackageConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv"
test_type = "explicit"
generators = "CMakeDeps", "CMakeToolchain"

def requirements(self):
self.requires(self.tested_reference_str)
Expand All @@ -21,5 +20,5 @@ def build(self):

def test(self):
if can_run(self):
bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package")
bin_path = os.path.join(self.cpp.build.bindir, "test_package")
self.run(bin_path, env="conanrun")
4 changes: 3 additions & 1 deletion recipes/libudev/config.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
versions:
"system":
"255.15":
folder: all
"system":
folder: system
54 changes: 54 additions & 0 deletions recipes/libudev/system/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.system import package_manager
from conan.tools.gnu import PkgConfig

required_conan_version = ">=1.50.0"


class LibUDEVConan(ConanFile):
name = "libudev"
version = "system"
description = "API for enumerating and introspecting local devices"
topics = ("udev", "devices", "enumerating")
url = "https://github.com/conan-io/conan-center-index"
homepage = "https://www.freedesktop.org/software/systemd/man/udev.html"
license = "GPL-2.0-or-later", "LGPL-2.1-or-later"
package_type = "shared-library"
settings = "os", "arch", "compiler", "build_type"

def layout(self):
pass

def validate(self):
if self.settings.os != "Linux":
raise ConanInvalidConfiguration("libudev is only supported on Linux.")

def package_id(self):
self.info.clear()

def system_requirements(self):
dnf = package_manager.Dnf(self)
dnf.install(["systemd-devel"], update=True, check=True)

yum = package_manager.Yum(self)
yum.install(["systemd-devel"], update=True, check=True)

apt = package_manager.Apt(self)
apt.install(["libudev-dev"], update=True, check=True)

pacman = package_manager.PacMan(self)
pacman.install(["systemd-libs"], update=True, check=True)

zypper = package_manager.Zypper(self)
zypper.install_substitutes(["libudev-devel"], ["systemd-devel"], update=True, check=True)

def package_info(self):
self.cpp_info.includedirs = []
self.cpp_info.libdirs = []
pkg_config = PkgConfig(self, "libudev")
pkg_config.fill_cpp_info(self.cpp_info)
self.cpp_info.set_property("system_package_version", str(pkg_config.version))

# todo Remove this workaround for Conan v1
self.cpp_info.set_property("component_version", str(pkg_config.version))
8 changes: 8 additions & 0 deletions recipes/libudev/system/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.15)
project(test_package C)

find_package(libudev REQUIRED CONFIG)


add_executable(${PROJECT_NAME} test_package.c)
target_link_libraries(${PROJECT_NAME} libudev::libudev)
25 changes: 25 additions & 0 deletions recipes/libudev/system/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from conan import ConanFile
from conan.tools.cmake import cmake_layout, CMake
from conan.tools.build import can_run
import os

class TestPackageConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv"
test_type = "explicit"

def requirements(self):
self.requires(self.tested_reference_str)

def layout(self):
cmake_layout(self)

def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()

def test(self):
if can_run(self):
bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package")
self.run(bin_path, env="conanrun")
25 changes: 25 additions & 0 deletions recipes/libudev/system/test_package/test_package.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <stdio.h>
#include <stdlib.h>
#include <libudev.h>


int main() {
struct udev *udev;
struct udev_enumerate *enumerate;

udev = udev_new();
if (!udev) {
fprintf(stderr, "Cannot create udev context.\n");
return 1;
}

enumerate = udev_enumerate_new(udev);
if (!enumerate) {
fprintf(stderr, "Cannot create enumerate context.\n");
}

udev_enumerate_unref(enumerate);
udev_unref(udev);

return EXIT_SUCCESS;
}