Skip to content

Commit

Permalink
(#13858) libselinux: Support Conan V2
Browse files Browse the repository at this point in the history
* libselinux: Support Conan V2

* Fix finding pcre2

* Find config

* Use correct FindPackage generator for test v1 package

* Add dl system library
  • Loading branch information
jwillikers authored Nov 3, 2022
1 parent 1fcccb9 commit e50aa14
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 50 deletions.
113 changes: 72 additions & 41 deletions recipes/libselinux/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
from conans import ConanFile, tools, AutoToolsBuildEnvironment
from conans.errors import ConanInvalidConfiguration
from conan import ConanFile
from conan.tools.env import VirtualBuildEnv
from conan.tools.files import apply_conandata_patches, chdir, copy, export_conandata_patches, get
from conan.tools.gnu import Autotools, AutotoolsToolchain, PkgConfigDeps
from conan.tools.layout import basic_layout
from conan.tools.scm import Version
from conan.errors import ConanInvalidConfiguration
import os

required_conan_version = ">=1.32.0"
required_conan_version = ">=1.52.0"


class LibSELinuxConan(ConanFile):
Expand All @@ -15,8 +20,7 @@ class LibSELinuxConan(ConanFile):
topics = ("selinux", "security-enhanced linux")
url = "https://github.com/conan-io/conan-center-index"
homepage = "https://github.com/SELinuxProject/selinux"
license = "Unlicense" # This library (libselinux) is public domain software, i.e. not copyrighted

license = "Unlicense"
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
Expand All @@ -28,74 +32,101 @@ class LibSELinuxConan(ConanFile):
}

def export_sources(self):
for patch in self.conan_data.get("patches", {}).get(self.version, []):
self.copy(patch["patch_file"])
export_conandata_patches(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("pcre2/10.40")

def validate(self):
if self.settings.os != "Linux":
raise ConanInvalidConfiguration("Only Linux is supported")
if self.info.settings.os != "Linux":
raise ConanInvalidConfiguration(f"{self.ref} only supports Linux")

def build_requirements(self):
self.build_requires("flex/2.6.4")
self.tool_requires("flex/2.6.4")
if not self.conf.get("tools.gnu:pkg_config", default=False, check_type=str):
self.tool_requires("pkgconf/1.9.3")

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

def source(self):
for download in self.conan_data["sources"][self.version]:
tools.get(**download)
get(self, **download, destination=self.source_folder)

@property
def _sepol_soversion(self):
return "2" if tools.Version(self.version) >= "3.2" else "1"
return "2" if Version(self.version) >= "3.2" else "1"

@property
def _selinux_soversion(self):
return "1"

@property
def _subfolders(self):
_sepol_subfolder = "libsepol-%s" % self.version
_selinux_subfolder = "libselinux-%s" % self.version
return _sepol_subfolder, _selinux_subfolder
def _sepol_library_target(self):
return f"libsepol.so.{self._sepol_soversion}" if self.options.shared else "libsepol.a"

@property
def _selinux_library_target(self):
return f"libselinux.so.{self._selinux_soversion}" if self.options.shared else "libselinux.a"

@property
def _sepol_source_folder(self):
return os.path.join(self.source_folder, f"libsepol-{self.version}")

@property
def _selinux_source_folder(self):
return os.path.join(self.source_folder, f"libselinux-{self.version}")

def generate(self):
virtual_build_env = VirtualBuildEnv(self)
virtual_build_env.generate()
pkg_config_deps = PkgConfigDeps(self)
pkg_config_deps.generate()
tc = AutotoolsToolchain(self)
sepol_include_folder = os.path.join(self._sepol_source_folder, "include")
tc.extra_cflags.append(f"-I{sepol_include_folder}")
sepol_lib_folder = os.path.join(self._sepol_source_folder, "src")
tc.extra_ldflags.append(f"-L{sepol_lib_folder}")
tc.make_args.append("USE_PCRE2=y")
tc.generate()

def build(self):
for patch in self.conan_data.get("patches", {}).get(self.version, []):
tools.patch(**patch)
_sepol_subfolder, _selinux_subfolder = self._subfolders
pcre_inc = os.path.join(self.deps_cpp_info["pcre2"].rootpath,
self.deps_cpp_info["pcre2"].includedirs[0])
pcre_libs = ' '.join(["-l%s" % lib for lib in self.deps_cpp_info["pcre2"].libs])
sepol_inc = os.path.join(self.source_folder, _sepol_subfolder, "include")
with tools.chdir(os.path.join(_sepol_subfolder, "src")):
args = ["libsepol.so.{}".format(self._sepol_soversion) if self.options.shared else "libsepol.a"]
env_build = AutoToolsBuildEnvironment(self)
env_build.make(args=args)
with tools.chdir(os.path.join(_selinux_subfolder, "src")):
args = ["libselinux.so.{}".format(self._selinux_soversion) if self.options.shared else "libselinux.a",
'PCRE_CFLAGS=-DPCRE2_CODE_UNIT_WIDTH=8 -DUSE_PCRE2=1 -I%s -I%s' % (pcre_inc, sepol_inc),
'PCRE_LDLIBS=%s' % pcre_libs]
env_build = AutoToolsBuildEnvironment(self)
env_build.make(args=args)
apply_conandata_patches(self)
autotools = Autotools(self)
with chdir(self, os.path.join(self._sepol_source_folder, "src")):
autotools.make(self._sepol_library_target)
with chdir(self, os.path.join(self._selinux_source_folder)):
autotools.make()

def package(self):
_sepol_subfolder, _selinux_subfolder = self._subfolders
self.copy(pattern="LICENSE", dst="licenses", src=_selinux_subfolder)
for library in [_sepol_subfolder, _selinux_subfolder]:
self.copy(pattern="*.h", dst="include", src=os.path.join(library, "include"), keep_path=True)
self.copy(pattern="*.so*", dst="lib", src=library, keep_path=False, symlinks=True)
self.copy(pattern="*.a", dst="lib", src=library, keep_path=False)
copy(self, "LICENSE", self._selinux_source_folder, os.path.join(self.package_folder, "licenses"))
for library in [self._sepol_source_folder, self._selinux_source_folder]:
copy(self, "*.h", os.path.join(library, "include"), os.path.join(self.package_folder, "include"))
if self.options.shared:
copy(self, "*.so*", library, os.path.join(self.package_folder, "lib"), keep_path=False)
else:
copy(self, "*.a", library, os.path.join(self.package_folder, "lib"), keep_path=False)

def package_info(self):
self.cpp_info.components["selinux"].set_property("pkg_config_name", "libselinux")
self.cpp_info.components["selinux"].names["pkg_config"] = "libselinux"
self.cpp_info.components["selinux"].libs = ["selinux"]
self.cpp_info.components["selinux"].requires = ["sepol", "pcre2::pcre2"]
if self.options.shared:
self.cpp_info.components["selinux"].system_libs = ["dl"]

self.cpp_info.components["sepol"].set_property("pkg_config_name", "libsepol")
self.cpp_info.components["sepol"].names["pkg_config"] = "libsepol"
self.cpp_info.components["sepol"].libs = ["sepol"]
7 changes: 3 additions & 4 deletions recipes/libselinux/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
cmake_minimum_required(VERSION 3.1)
project(test_package C)
project(test_package LANGUAGES C)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
find_package(libselinux REQUIRED CONFIG)

add_executable(${PROJECT_NAME} test_package.c)
target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
target_link_libraries(${PROJECT_NAME} PRIVATE libselinux::libselinux)
19 changes: 14 additions & 5 deletions recipes/libselinux/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
from conans import ConanFile, CMake, tools
from conan import ConanFile
from conan.tools.build import can_run
from conan.tools.cmake import cmake_layout, CMake
import os


class TestPackageConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "cmake"
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 not tools.cross_building(self):
bin_path = os.path.join("bin", "test_package")
self.run(bin_path, run_environment=True)
if can_run(self):
bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package")
self.run(bin_path, env="conanrun")
8 changes: 8 additions & 0 deletions recipes/libselinux/all/test_v1_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.1)
project(test_package)

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

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../test_package/
${CMAKE_CURRENT_BINARY_DIR}/test_package/)
17 changes: 17 additions & 0 deletions recipes/libselinux/all/test_v1_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from conans import ConanFile, CMake, tools
import os


class TestPackageConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "cmake", "cmake_find_package_multi"

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

def test(self):
if not tools.cross_building(self):
bin_path = os.path.join("bin", "test_package")
self.run(bin_path, run_environment=True)

0 comments on commit e50aa14

Please sign in to comment.