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

libcap/2.65 + conan v2 compatibility #12241

Merged
merged 5 commits into from
Aug 24, 2022
Merged
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
48 changes: 20 additions & 28 deletions recipes/libcap/all/conandata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,40 +20,32 @@ sources:
"2.62":
url: "https://www.kernel.org/pub/linux/libs/security/linux-privs/libcap2/libcap-2.62.tar.xz"
sha256: "190c5baac9bee06a129eae20d3e827de62f664fe3507f0bf6c50a9a59fbd83a2"
"2.65":
url: "https://www.kernel.org/pub/linux/libs/security/linux-privs/libcap2/libcap-2.65.tar.xz"
sha256: "73e350020cc31fe15360879d19384ffa3395a825f065fcf6bda3a5cdf965bebd"

patches:
"2.45":
- base_path: "source_subfolder"
patch_file: "patches/2.45/0001-Make.Rules-Remove-hardcoded-fPIC.patch"
- base_path: "source_subfolder"
patch_file: "patches/2.45/0002-Make.Rules-Make-compile-tools-configurable.patch"
- patch_file: "patches/2.45/0001-Make.Rules-Remove-hardcoded-fPIC.patch"
- patch_file: "patches/2.45/0002-Make.Rules-Make-compile-tools-configurable.patch"
"2.46":
- base_path: "source_subfolder"
patch_file: "patches/2.45/0001-Make.Rules-Remove-hardcoded-fPIC.patch"
- base_path: "source_subfolder"
patch_file: "patches/2.45/0002-Make.Rules-Make-compile-tools-configurable.patch"
- patch_file: "patches/2.45/0001-Make.Rules-Remove-hardcoded-fPIC.patch"
- patch_file: "patches/2.45/0002-Make.Rules-Make-compile-tools-configurable.patch"
"2.48":
- base_path: "source_subfolder"
patch_file: "patches/2.45/0001-Make.Rules-Remove-hardcoded-fPIC.patch"
- base_path: "source_subfolder"
patch_file: "patches/2.45/0002-Make.Rules-Make-compile-tools-configurable.patch"
- patch_file: "patches/2.45/0001-Make.Rules-Remove-hardcoded-fPIC.patch"
- patch_file: "patches/2.45/0002-Make.Rules-Make-compile-tools-configurable.patch"
"2.50":
- base_path: "source_subfolder"
patch_file: "patches/2.45/0001-Make.Rules-Remove-hardcoded-fPIC.patch"
- base_path: "source_subfolder"
patch_file: "patches/2.45/0002-Make.Rules-Make-compile-tools-configurable.patch"
- patch_file: "patches/2.45/0001-Make.Rules-Remove-hardcoded-fPIC.patch"
- patch_file: "patches/2.45/0002-Make.Rules-Make-compile-tools-configurable.patch"
"2.57":
- base_path: "source_subfolder"
patch_file: "patches/2.57/0001-libcap-Remove-hardcoded-fPIC.patch"
- base_path: "source_subfolder"
patch_file: "patches/2.57/0002-Make.Rules-Make-compile-tools-configurable.patch"
- patch_file: "patches/2.57/0001-libcap-Remove-hardcoded-fPIC.patch"
- patch_file: "patches/2.57/0002-Make.Rules-Make-compile-tools-configurable.patch"
"2.58":
- base_path: "source_subfolder"
patch_file: "patches/2.57/0001-libcap-Remove-hardcoded-fPIC.patch"
- base_path: "source_subfolder"
patch_file: "patches/2.57/0002-Make.Rules-Make-compile-tools-configurable.patch"
- patch_file: "patches/2.57/0001-libcap-Remove-hardcoded-fPIC.patch"
- patch_file: "patches/2.57/0002-Make.Rules-Make-compile-tools-configurable.patch"
"2.62":
- base_path: "source_subfolder"
patch_file: "patches/2.57/0001-libcap-Remove-hardcoded-fPIC.patch"
- base_path: "source_subfolder"
patch_file: "patches/2.57/0002-Make.Rules-Make-compile-tools-configurable.patch"
- patch_file: "patches/2.57/0001-libcap-Remove-hardcoded-fPIC.patch"
- patch_file: "patches/2.57/0002-Make.Rules-Make-compile-tools-configurable.patch"
"2.65":
- patch_file: "patches/2.57/0001-libcap-Remove-hardcoded-fPIC.patch"
- patch_file: "patches/2.57/0002-Make.Rules-Make-compile-tools-configurable.patch"
110 changes: 56 additions & 54 deletions recipes/libcap/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import os

from conans import ConanFile, tools, AutoToolsBuildEnvironment
from conans.errors import ConanInvalidConfiguration
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.build import cross_building
from conan.tools.files import apply_conandata_patches, copy, chdir, get, rmdir
from conan.tools.layout import basic_layout
from conan.tools.gnu import Autotools, AutotoolsToolchain

required_conan_version = ">=1.33.0"
required_conan_version = ">=1.47.0"


class LibcapConan(ConanFile):
Expand All @@ -13,7 +17,7 @@ class LibcapConan(ConanFile):
homepage = "https://git.kernel.org/pub/scm/libs/libcap/libcap.git"
description = "This is a library for getting and setting POSIX.1e" \
" (formerly POSIX 6) draft 15 capabilities"
topics = ("conan", "libcap", "capabilities")
topics = ("libcap", "capabilities")
settings = "os", "compiler", "build_type", "arch"
options = {
"shared": [True, False],
Expand All @@ -27,81 +31,79 @@ class LibcapConan(ConanFile):
}
exports_sources = "patches/**"

_autotools = None
_autotools_env = None

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

def configure(self):
if self.settings.os != "Linux":
raise ConanInvalidConfiguration("Only Linux supported")
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 validate(self):
if self.info.settings.os != "Linux":
raise ConanInvalidConfiguration("Only Linux supported")

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

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

def _configure_autotools(self):
if self._autotools:
return self._autotools, self._autotools_env
self._autotools = AutoToolsBuildEnvironment(self)
self._autotools.fpic = self.options.get_safe("fPIC", True)
self._autotools_env = self._autotools.vars
self._autotools_env["SHARED"] = \
"yes" if self.options.shared else "no"
self._autotools_env["PTHREADS"] = \
"yes" if self.options.psx_syscals else "no"
self._autotools_env["DESTDIR"] = self.package_folder
self._autotools_env["prefix"] = "/"
self._autotools_env["lib"] = "lib"

if tools.cross_building(self.settings) and not tools.get_env("BUILD_CC"):
native_cc = tools.which("cc")
get(self, **self.conan_data["sources"][self.version], strip_root=True)

def generate(self):
tc = AutotoolsToolchain(self)
tc.fpic = self.options.get_safe("fPIC", True)
env = tc.environment()
env.define("SHARED", "yes" if self.options.shared else "no")
env.define("PTHREADS", "yes" if self.options.psx_syscals else "no")
env.define("DESTDIR", self.package_folder)
env.define("prefix", "/")
env.define("lib", "lib")

if cross_building(self) and not env.vars(self).get("BUILD_CC"):
native_cc = "cc"
self.output.info("Using native compiler '{}'".format(native_cc))
self._autotools_env["BUILD_CC"] = native_cc

return self._autotools, self._autotools_env
env.define("BUILD_CC", native_cc)

def _patch_sources(self):
for patch in self.conan_data.get("patches", {}).get(self.version, []):
tools.patch(**patch)
tc.generate(env)

def build(self):
self._patch_sources()
apply_conandata_patches(self)

with tools.chdir(os.path.join(self._source_subfolder, self.name)):
env_build, env_build_vars = self._configure_autotools()
env_build.make(vars=env_build_vars)
autotools = Autotools(self)
with chdir(self, os.path.join(self.source_folder, self.name)):
autotools.make()

def package(self):
self.copy("License", dst="licenses", src=self._source_subfolder)

with tools.chdir(os.path.join(self._source_subfolder, self.name)):
env_build, env_build_vars = self._configure_autotools()
copy(self, "License", self.source_folder,
os.path.join(self.package_folder, "licenses"), keep_path=False)

env_build.make(target="install-common-cap", vars=env_build_vars)
autotools = Autotools(self)
with chdir(self, os.path.join(self.source_folder, self.name)):
autotools.make(target="install-common-cap")
install_cap = ("install-shared-cap" if self.options.shared
else "install-static-cap")
env_build.make(target=install_cap, vars=env_build_vars)
autotools.make(target=install_cap)

if self.options.psx_syscals:
env_build.make(target="install-common-psx",
vars=env_build_vars)
autotools.make(target="install-common-psx")
install_psx = ("install-shared-psx" if self.options.shared
else "install-static-psx")
env_build.make(target=install_psx, vars=env_build_vars)
autotools.make(target=install_psx)

tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig"))
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))

def package_info(self):
self.cpp_info.components["cap"].set_property("pkg_config_name",
Copy link
Contributor Author

@bobrofon bobrofon Aug 15, 2022

Choose a reason for hiding this comment

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

When I'm trying to build a test package with this line, I get a warning: "(test package): WARN: [libcap/2.65] The PC package name libcap.pc already exists and it matches with another component one. Please, review all the component's pkg_config_name defined. Skipping it!". But I don't know how to figure out what's wrong here.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's because there's a global one by default for v1 generators.

You need to set a root level one like AFAIK (not an expert just say that in another PR I reviewed recently)

self.cpp_info.set_property("pkg_config_name", "libcap-all-do-not-use")

"libcap")
self.cpp_info.components["cap"].names["pkg_config"] = "libcap"
self.cpp_info.components["cap"].libs = ["cap"]
if self.options.psx_syscals:
self.cpp_info.components["psx"].set_property("pkg_config_name",
"libpsx")
self.cpp_info.components["psx"].names["pkg_config"] = "libpsx"
self.cpp_info.components["psx"].libs = ["psx"]
self.cpp_info.components["psx"].system_libs = ["pthread"]
Expand Down
10 changes: 5 additions & 5 deletions recipes/libcap/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
cmake_minimum_required(VERSION 3.1)
project(PackageTest C)
cmake_minimum_required(VERSION 3.15)
project(PackageTest LANGUAGES C)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
find_package(PkgConfig REQUIRED)
Copy link
Contributor

Choose a reason for hiding this comment

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

please add pkgconf to build_requirements of test_package

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

pkg_check_modules(CAP REQUIRED IMPORTED_TARGET libcap)

add_executable(example example.c)
target_link_libraries(example ${CONAN_LIBS})
target_link_libraries(example PRIVATE PkgConfig::CAP)
32 changes: 27 additions & 5 deletions recipes/libcap/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,40 @@
import os

from conans import ConanFile, CMake, tools
from conan import ConanFile
from conan.tools.build import can_run
from conan.tools.cmake import CMake
from conan.tools.env import Environment
from conan.tools.cmake import cmake_layout

required_conan_version = ">=1.38.0"


class LibcapTestConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "cmake"
generators = "CMakeToolchain", "PkgConfigDeps", "VirtualBuildEnv"
test_type = "explicit"

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

def build_requirements(self):
self.tool_requires("pkgconf/1.7.4")

def layout(self):
cmake_layout(self)

def generate(self):
env = Environment()
env.prepend_path("PKG_CONFIG_PATH", self.generators_folder)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For some reason, pkg_check_modules tries to find .pc files not in the generator_folder, but in the generator_folder/lib/pkgconfig. I thought the PkgConfigDeps generator should resolve that (via env vars maybe), but it doesn't. Not sure if I am doing something wrong or if it is a bug. I didn't find any examples of using CMakeToolchain and PkgConfigDeps generators together.

Copy link
Contributor

Choose a reason for hiding this comment

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

👋 @franramirez688 @czoido is this the right way to use CMakeToolchain and PkgConfigDeps generators together?

Copy link
Contributor

Choose a reason for hiding this comment

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

For some reason, pkg_check_modules tries to find .pc files not in the generator_folder, but in the generator_folder/lib/pkgconfig.

After digging deeper into it, I figured out that CMake is adding the suffix lib/pkgconfig to the CMAKE_PREFIX_PATH (pointing to the package_folder where the *.pc files are created). You can have a look at the issue https://gitlab.kitware.com/cmake/cmake/-/issues/18150

I thought the PkgConfigDeps generator should resolve that (via env vars maybe), but it doesn't

Yes, you're right, but it should not be necessary as far as CMake should use that CMAKE_PREFIX_PATH by default. As I said above, CMake is adding that suffix, so it's getting failed because there are no PC files there.

is this the right way to use CMakeToolchain and PkgConfigDeps generators together?

Given that information, I tend to say that yes, it could be one way to solve that issue, and I think there could be another workaround like:

    def build(self):
        pkg_lib_folder = os.path.join(self.generators_folder, "lib", "pkgconfig")
        copy(self, "*.pc", self.generators_folder, pkg_lib_folder)
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

Anyway, we could discuss if it could be a chance to create a mechanism to add the PKG_CONFIG_PATH via CMake build helper or even CMakeToolchain to avoid those workarounds.

envvars = env.vars(self)
envvars.save_script("pkg_config")

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

def test(self):
if not tools.cross_building(self.settings):
bin_path = os.path.join("bin", "example")
self.run(bin_path, run_environment=True)
if can_run(self):
bin_path = os.path.join(self.cpp.build.bindirs[0], "example")
self.run(bin_path, env="conanrun")
11 changes: 11 additions & 0 deletions recipes/libcap/all/test_v1_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.1)
project(PackageTest C)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()

find_package(PkgConfig REQUIRED)
pkg_check_modules(CAP REQUIRED IMPORTED_TARGET libcap)

add_executable(example ../test_package/example.c)
target_link_libraries(example PRIVATE PkgConfig::CAP)
23 changes: 23 additions & 0 deletions recipes/libcap/all/test_v1_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import os

from conan import ConanFile
from conan.tools.build import cross_building
from conans import CMake


class LibcapTestConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "cmake", "pkg_config"

def build_requirements(self):
self.tool_requires("pkgconf/1.7.4")

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

def test(self):
if not cross_building(self):
bin_path = os.path.join("bin", "example")
self.run(bin_path, run_environment=True)
2 changes: 2 additions & 0 deletions recipes/libcap/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ versions:
folder: all
"2.62":
folder: all
"2.65":
folder: all