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

[util-linux-libuuid] Add util-linux-libuuid package #17664

Merged
Merged
4 changes: 4 additions & 0 deletions recipes/util-linux-libuuid/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
sources:
"2.39":
url: "https://github.com/util-linux/util-linux/archive/refs/tags/v2.39.tar.gz"
sha256: "186cb427cd6b4654f381357b60af7ffb0ae9bb50d7af7d87e0723858f7318b80"
134 changes: 134 additions & 0 deletions recipes/util-linux-libuuid/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.apple import fix_apple_shared_install_name
from conan.tools.env import VirtualBuildEnv
from conan.tools.files import copy, get, rm, rmdir, chdir
from conan.tools.gnu import Autotools, AutotoolsToolchain, AutotoolsDeps
from conan.tools.layout import basic_layout
from conan.tools.scm import Version
import os

required_conan_version = ">=1.53.0"


class UtilLinuxLibuuidConan(ConanFile):
name = "util-linux-libuuid"
description = "Universally unique id library"
url = "https://github.com/conan-io/conan-center-index"
homepage = "https://github.com/util-linux/util-linux.git"
license = "BSD-3-Clause"
topics = "id", "identifier", "unique", "uuid"
package_type = "library"
provides = "libuuid"
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
"fPIC": [True, False],
}
default_options = {
"shared": False,
"fPIC": True,
}

@property
def _has_sys_file_header(self):
return self.settings.os in ["FreeBSD", "Linux", "Macos"]

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC

def configure(self):
if self.options.shared:
self.options.rm_safe("fPIC")
self.settings.rm_safe("compiler.cppstd")
self.settings.rm_safe("compiler.libcxx")

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

def _minimum_compiler_version(self, compiler, build_type):
min_version = {
"gcc": {
"Release": "4",
"Debug": "8",
},
"clang": {
"Release": "3",
"Debug": "3",
},
"apple-clang": {
"Release": "5",
"Debug": "5",
},
}
return min_version.get(str(compiler), {}).get(str(build_type), "0")

def validate(self):
min_version = self._minimum_compiler_version(self.settings.compiler, self.settings.build_type)
if Version(self.settings.compiler.version) < min_version:
raise ConanInvalidConfiguration(f"{self.settings.compiler} {self.settings.compiler.version} does not meet the minimum version requirement of version {min_version}")
if self.settings.os == "Windows":
raise ConanInvalidConfiguration(f"{self.ref} is not supported on Windows")
if self.settings.os == "Macos":
# FIXME: Add Macos compatibility. This is currently breaking because builds are unable to find libtool-2
# This is a bit puzzling given `libtool` is a tool_requires, and I haven't been able to replicate this error
# locally.
raise ConanInvalidConfiguration(f"{self.ref} is not currently supported on Macos. Please contribute this functionality if you require it.")

def requirements(self):
if self.settings.os == "Macos":
# Required because libintl.{a,dylib} is not distributed via libc on Macos
self.requires("libgettext/0.21")

def build_requirements(self):
self.tool_requires("libtool/2.4.7")
self.tool_requires("m4/1.4.19")
self.tool_requires("pkgconf/1.9.3")
self.tool_requires("bison/3.8.2")
self.tool_requires("autoconf/2.71")
self.tool_requires("automake/1.16.5")
Comment on lines +85 to +90
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very bad idea to explicitly reference automake, autoconf and m4, it doesn't scale in build requirements, it's well known. Why this recipe doesn't follow other autoconf recipes guidelines?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not experienced with automake. I used a few other recipes as guidelines but they obviously haven't incorporated the practices you're talking about and it didn't come up in review. It would be useful if those were documented somewhere easily discoverable. Feel free to submit a new PR with the necessary changes if that's a better way of managing these.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A good reference is autotools recipes template.

(sorry, I won't fix this, I don't have the time. It will break when someone will bump automake version in libtool recipe)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know, but it wouldn't have addressed this - it has an explicit example requiring automake, and no discussion of when it shouldn't be required.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it has an explicit example requiring automake, and no discussion of when it shouldn't be required.

There is a comment explaining when it's required: https://github.com/conan-io/conan-center-index/blob/60fa77f44eafacf99b7f1d43650f13dd8db5d971/docs/package_templates/autotools_package/all/conanfile.py#L93C1-L96


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

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

tc = AutotoolsToolchain(self)
tc.configure_args.append("--disable-all-programs")
tc.configure_args.append("--enable-libuuid")
if self._has_sys_file_header:
tc.extra_defines.append("HAVE_SYS_FILE_H")
if "x86" in self.settings.arch:
tc.extra_cflags.append("-mstackrealign")
tc.generate()

deps = AutotoolsDeps(self)
deps.generate()

def build(self):
with chdir(self, self.source_folder):
self.run("./autogen.sh")
autotools = Autotools(self)
autotools.configure()
autotools.make()

def package(self):
copy(self, "COPYING.BSD-3-Clause", src=os.path.join(self.source_folder, "Documentation", "licenses"), dst=os.path.join(self.package_folder, "licenses"))
autotools = Autotools(self)
autotools.install()
rm(self, "*.la", os.path.join(self.package_folder, "lib"))
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))
rmdir(self, os.path.join(self.package_folder, "bin"))
rmdir(self, os.path.join(self.package_folder, "sbin"))
rmdir(self, os.path.join(self.package_folder, "share"))
fix_apple_shared_install_name(self)

def package_info(self):
self.cpp_info.set_property("pkg_config_name", "uuid")
self.cpp_info.set_property("cmake_target_name", "LibUUID::LibUUID")
self.cpp_info.set_property("cmake_file_name", "LibUUID")
Comment on lines +131 to +132
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does it come from?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@SpaceIm SpaceIm Jul 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's an internal file of CMake source code, not some official FindLIBUUID.cmake file shipped in CMake program, so it shouldn't be used as a reference. This recipe shouldn't override cmake names since there is no official Find file (someone asked for it, but it will likely be rejected by CMake team: https://gitlab.kitware.com/cmake/cmake/-/issues/24607), and util-linux project doesn't provide any config file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I'd missed that detail. Knowing that a convention has been used by CMake though (even though it's internal), wouldn't that still be the sensible choice for Conan? Since util-linux provides no config file, I would imagine people will take what already exists. Seems like this might be a sensible convention to standardise on..

self.cpp_info.libs = ["uuid"]
self.cpp_info.includedirs.append(os.path.join("include", "uuid"))
8 changes: 8 additions & 0 deletions recipes/util-linux-libuuid/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.8)
project(test_package LANGUAGES C)

find_package(LibUUID REQUIRED CONFIG)

add_executable(${PROJECT_NAME} test_package.c)
target_link_libraries(${PROJECT_NAME} PRIVATE LibUUID::LibUUID)
target_compile_features(${PROJECT_NAME} PRIVATE c_std_99)
26 changes: 26 additions & 0 deletions recipes/util-linux-libuuid/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from conan import ConanFile
from conan.tools.build import can_run
from conan.tools.cmake import CMake, cmake_layout
import os


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

def layout(self):
cmake_layout(self)

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

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")
33 changes: 33 additions & 0 deletions recipes/util-linux-libuuid/all/test_package/test_package.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <stdio.h>

#include "uuid/uuid.h"

int main(int argc, char *argv[]) {
uuid_t uuid;
uuid_generate_time_safe(uuid);

char uuid_str[37];
uuid_unparse_lower(uuid, uuid_str);
printf("generate uuid=%s\n", uuid_str);

uuid_t uuid2;
uuid_parse(uuid_str, uuid2);

int rv;
rv = uuid_compare(uuid, uuid2);
printf("uuid_compare() result=%d\n", rv);

uuid_t uuid3;
uuid_parse("1b4e28ba-2fa1-11d2-883f-0016d3cca427", uuid3);
rv = uuid_compare(uuid, uuid3);
printf("uuid_compare() result=%d\n", rv);

rv = uuid_is_null(uuid);
printf("uuid_null() result=%d\n", rv);

uuid_clear(uuid);
rv = uuid_is_null(uuid);
printf("uuid_null() result=%d\n", rv);

return 0;
}
3 changes: 3 additions & 0 deletions recipes/util-linux-libuuid/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
versions:
"2.39":
folder: all