from conan import ConanFile from conan.errors import ConanInvalidConfiguration from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout from conan.tools.env import VirtualBuildEnv from conan.tools.files import copy, get, replace_in_file, rm, rmdir from conan.tools.gnu import Autotools, AutotoolsToolchain from conan.tools.layout import basic_layout from conan.tools.microsoft import unix_path import os required_conan_version = ">=1.54.0" class LibelfConan(ConanFile): name = "libelf" description = "ELF object file access library" url = "https://github.com/conan-io/conan-center-index" homepage = "https://directory.fsf.org/wiki/Libelf" license = "LGPL-2.0" topics = ("elf", "fsf", "libelf", "object-file") package_type = "library" settings = "os", "arch", "compiler", "build_type" options = { "shared": [True, False], "fPIC": [True, False], } default_options = { "shared": False, "fPIC": True, } exports_sources = "CMakeLists.txt" def config_options(self): if self.settings.os == "Windows": del self.options.fPIC def configure(self): if self.settings.os not in ["Linux", "FreeBSD", "Windows"]: self.options.rm_safe("shared") self.package_type = "static-library" if self.options.get_safe("shared"): self.options.rm_safe("fPIC") self.settings.rm_safe("compiler.cppstd") self.settings.rm_safe("compiler.libcxx") def layout(self): if self.settings.os == "Windows": cmake_layout(self, src_folder="src") else: basic_layout(self, src_folder="src") def build_requirements(self): if self.settings.os != "Windows": # self.tool_requires("autoconf/2.71") # self.tool_requires("gnu-config/cci.20210814") if self.settings_build.os == "Windows": self.win_bash = True if not self.conf.get("tools.microsoft.bash:path", check_type=str): self.tool_requires("msys2/cci.latest") def source(self): get(self, **self.conan_data["sources"][self.version], strip_root=True) def generate(self): if self.settings.os == "Windows": tc = CMakeToolchain(self) tc.variables["LIBELF_SRC_DIR"] = self.source_folder.replace("\\", "/") tc.generate() else: env = VirtualBuildEnv(self) env.generate() tc = AutotoolsToolchain(self) tc.configure_args.extend([ # it's required, libelf doesnt seem to understand DESTDIR f"--prefix={unix_path(self, self.package_folder)}", ]) tc.generate() def build(self): if self.settings.os == "Windows": cmake = CMake(self) cmake.configure(build_script_folder=os.path.join(self.source_folder, os.pardir)) cmake.build() else: replace_in_file(self, os.path.join(self.source_folder, "lib", "Makefile.in"), "$(LINK_SHLIB)", "$(LINK_SHLIB) $(LDFLAGS)") # libelf sources contains really outdated 'config.sub' and # 'config.guess' files. It not allows to build libelf for armv8 arch. for gnu_config in [ self.conf.get("user.gnu-config:config_guess", check_type=str), self.conf.get("user.gnu-config:config_sub", check_type=str), ]: if gnu_config: copy(self, os.path.basename(gnu_config), src=os.path.dirname(gnu_config), dst=self.source_folder) autotools = Autotools(self) autotools.autoreconf() autotools.configure() autotools.make() def package(self): copy(self, "COPYING.LIB", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) if self.settings.os == "Windows": cmake = CMake(self) cmake.install() else: autotools = Autotools(self) autotools.install() rmdir(self, os.path.join(self.package_folder, "lib", "locale")) if self.options.get_safe("shared"): rm(self, "*.a", 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, "share")) def package_info(self): self.cpp_info.set_property("pkg_config_name", "libelf") self.cpp_info.libs = ["elf"] self.cpp_info.includedirs.append(os.path.join("include", "libelf"))