From f171f6ffecbf91f4f2b4aac70e34501f58b4d072 Mon Sep 17 00:00:00 2001 From: Jordan Williams Date: Sat, 9 Jul 2022 13:31:25 -0500 Subject: [PATCH] xkbcommon: Switch to MesonToolchain to allow cross-compilation --- recipes/xkbcommon/all/conanfile.py | 132 ++++++++++-------- .../xkbcommon/all/test_package/CMakeLists.txt | 11 +- .../xkbcommon/all/test_package/conanfile.py | 20 ++- .../all/test_v1_package/CMakeLists.txt | 8 ++ .../all/test_v1_package/conanfile.py | 19 +++ 5 files changed, 119 insertions(+), 71 deletions(-) create mode 100644 recipes/xkbcommon/all/test_v1_package/CMakeLists.txt create mode 100644 recipes/xkbcommon/all/test_v1_package/conanfile.py diff --git a/recipes/xkbcommon/all/conanfile.py b/recipes/xkbcommon/all/conanfile.py index 19621077451e77..88077ccdd7ca0f 100644 --- a/recipes/xkbcommon/all/conanfile.py +++ b/recipes/xkbcommon/all/conanfile.py @@ -1,7 +1,11 @@ +import os + from conan import ConanFile -from conan.tools import scm, files +from conan.tools.files import copy, get, replace_in_file, rmdir +from conan.tools.layout import basic_layout +from conan.tools.meson import Meson, MesonToolchain +from conan.tools.scm import Version from conan.errors import ConanInvalidConfiguration -from conans import Meson, tools required_conan_version = ">=1.50.0" @@ -30,20 +34,11 @@ class XkbcommonConan(ConanFile): "xkbregistry": True, } - generators = "pkg_config" - _meson = None - - @property - def _source_subfolder(self): - return "source_subfolder" - - @property - def _build_subfolder(self): - return "build_subfolder" + generators = "PkgConfigDeps", "VirtualBuildEnv", "VirtualRunEnv" @property def _has_xkbregistry_option(self): - return scm.Version(self.version) >= "1.0.0" + return Version(self.version) >= "1.0.0" def config_options(self): if not self._has_xkbregistry_option: @@ -70,80 +65,97 @@ def validate(self): raise ConanInvalidConfiguration("This library is only compatible with Linux or FreeBSD") def build_requirements(self): - self.build_requires("meson/0.63.1") - self.build_requires("bison/3.7.6") - if hasattr(self, "settings_build") and self.options.get_safe("wayland"): - self.build_requires("wayland/1.21.0") + self.tool_requires("meson/0.63.0") + self.tool_requires("bison/3.7.6") + self.tool_requires("pkgconf/1.7.4") + if self.options.get_safe("with_wayland"): + self.tool_requires("wayland/1.21.0") + + def layout(self): + basic_layout(self, src_folder="src") def source(self): - files.get(self, **self.conan_data["sources"][self.version], strip_root=True, destination=self._source_subfolder) + get(self, **self.conan_data["sources"][self.version], strip_root=True) - # Conan doesn't provide a `wayland-scanner.pc` file for the package in the _build_ context - files.replace_in_file(self, f"{self._source_subfolder}/meson.build", - "wayland_scanner_dep = dependency('wayland-scanner', required: false, native: true)", - "# wayland_scanner_dep = dependency('wayland-scanner', required: false, native: true)") - - files.replace_in_file(self, f"{self._source_subfolder}/meson.build", - "if not wayland_client_dep.found() or not wayland_protocols_dep.found() or not wayland_scanner_dep.found()", - "if not wayland_client_dep.found() or not wayland_protocols_dep.found()") - - files.replace_in_file(self, f"{self._source_subfolder}/meson.build", - "wayland_scanner = find_program(wayland_scanner_dep.get_pkgconfig_variable('wayland_scanner'))", - "wayland_scanner = find_program('wayland-scanner')") - - def _configure_meson(self): - if self._meson: - return self._meson - defs={ - "enable-wayland": self.options.get_safe("with_wayland", False), - "enable-docs": False, - "enable-x11": self.options.with_x11, - "libdir": f"{self.package_folder}/lib", - "default_library": ("shared" if self.options.shared else "static")} - if self._has_xkbregistry_option: - defs["enable-xkbregistry"] = self.options.xkbregistry + def generate(self): + tc = MesonToolchain(self) + + tc.project_options["libexecdir"] = "bin" + tc.project_options["libdir"] = "lib" + tc.project_options["datadir"] = "res" + tc.project_options["mandir"] = "res/man" - self._meson = Meson(self) - self._meson.configure( - defs=defs, - source_folder=self._source_subfolder, - build_folder=self._build_subfolder, - pkg_config_paths=self.build_folder) - return self._meson + tc.project_options["enable-docs"] = False + tc.project_options["enable-wayland"] = self.options.get_safe("with_wayland", False) + tc.project_options["enable-x11"] = self.options.with_x11 + + if self._has_xkbregistry_option: + tc.project_options["enable-xkbregistry"] = self.options.xkbregistry + tc.generate() def build(self): - with tools.run_environment(self): - meson = self._configure_meson() - meson.build() + # Conan doesn't provide a `wayland-scanner.pc` file for the package in the _build_ context + meson_build_file = os.path.join(self.source_folder, "meson.build") + replace_in_file(self, meson_build_file, + "wayland_scanner_dep = dependency('wayland-scanner', required: false, native: true)", + "# wayland_scanner_dep = dependency('wayland-scanner', required: false, native: true)") + + replace_in_file(self, meson_build_file, + "if not wayland_client_dep.found() or not wayland_protocols_dep.found() or not wayland_scanner_dep.found()", + "if not wayland_client_dep.found() or not wayland_protocols_dep.found()") + + replace_in_file(self, meson_build_file, + "wayland_scanner = find_program(wayland_scanner_dep.get_pkgconfig_variable('wayland_scanner'))", + "wayland_scanner = find_program('wayland-scanner')") + + meson = Meson(self) + meson.configure() + meson.build() def package(self): - self.copy(pattern="LICENSE", dst="licenses", src=self._source_subfolder) - meson = self._configure_meson() + copy(self, "LICENSE", self.source_folder, "licenses") + meson = Meson(self) meson.install() - files.rmdir(self, f"{self.package_folder}/lib/pkgconfig") - files.rmdir(self, f"{self.package_folder}/share") + rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig")) def package_info(self): self.cpp_info.components["libxkbcommon"].set_property("pkg_config_name", "xkbcommon") self.cpp_info.components["libxkbcommon"].libs = ["xkbcommon"] self.cpp_info.components["libxkbcommon"].requires = ["xorg::xkeyboard-config"] + self.cpp_info.components["libxkbcommon"].resdirs = ["res"] + + # todo Remove in Conan version 1.50.0 where these are set by default for the PkgConfigDeps generator. + self.cpp_info.components["libxkbcommon"].includedirs = ["include"] + self.cpp_info.components["libxkbcommon"].libdirs = ["lib"] + if self.options.with_x11: self.cpp_info.components["libxkbcommon-x11"].set_property("pkg_config_name", "xkbcommon-x11") self.cpp_info.components["libxkbcommon-x11"].libs = ["xkbcommon-x11"] self.cpp_info.components["libxkbcommon-x11"].requires = ["libxkbcommon", "xorg::xcb", "xorg::xcb-xkb"] + + # todo Remove in Conan version 1.50.0 where these are set by default for the PkgConfigDeps generator. + self.cpp_info.components["libxkbcommon-x11"].includedirs = ["include"] + self.cpp_info.components["libxkbcommon-x11"].libdirs = ["lib"] if self.options.get_safe("xkbregistry"): self.cpp_info.components["libxkbregistry"].set_property("pkg_config_name", "xkbregistry") self.cpp_info.components["libxkbregistry"].libs = ["xkbregistry"] self.cpp_info.components["libxkbregistry"].requires = ["libxml2::libxml2"] + + # todo Remove in Conan version 1.50.0 where these are set by default for the PkgConfigDeps generator. + self.cpp_info.components["libxkbregistry"].includedirs = ["include"] + self.cpp_info.components["libxkbregistry"].libdirs = ["lib"] if self.options.get_safe("with_wayland", False): # FIXME: This generates just executable, but I need to use the requirements to pass Conan checks self.cpp_info.components["xkbcli-interactive-wayland"].libs = [] + self.cpp_info.components["xkbcli-interactive-wayland"].includedirs = [] self.cpp_info.components["xkbcli-interactive-wayland"].requires = ["wayland::wayland", "wayland-protocols::wayland-protocols"] - if scm.Version(self.version) >= "1.0.0": - bin_path = f"{self.package_folder}/bin" - self.output.info(f"Appending PATH environment variable: {bin_path}") - self.env_info.PATH.append(bin_path) + if Version(self.version) >= "1.0.0": + bindir = os.path.join(self.package_folder, "bin") + self.buildenv_info.prepend_path("PATH", bindir) + self.runenv_info.prepend_path("PATH", bindir) + self.output.info(f"Appending PATH environment variable: {bindir}") + self.env_info.PATH.append(bindir) # unofficial, but required to avoid side effects (libxkbcommon component # "steals" the default global pkg_config name) diff --git a/recipes/xkbcommon/all/test_package/CMakeLists.txt b/recipes/xkbcommon/all/test_package/CMakeLists.txt index 196188113685c8..0b0b6cb9fe82d0 100644 --- a/recipes/xkbcommon/all/test_package/CMakeLists.txt +++ b/recipes/xkbcommon/all/test_package/CMakeLists.txt @@ -1,8 +1,7 @@ -cmake_minimum_required(VERSION 3.1) -project(test_package) +cmake_minimum_required(VERSION 3.15) +project(test_package LANGUAGES CXX) -include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) -conan_basic_setup() +find_package(xkbcommon REQUIRED COMPONENTS libxkbcommon) -add_executable(${PROJECT_NAME} test_package.cpp) -target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS}) +add_executable(test_package test_package.cpp) +target_link_libraries(test_package PRIVATE xkbcommon::libxkbcommon) diff --git a/recipes/xkbcommon/all/test_package/conanfile.py b/recipes/xkbcommon/all/test_package/conanfile.py index 5c09494bc67c01..eecad0444878e9 100644 --- a/recipes/xkbcommon/all/test_package/conanfile.py +++ b/recipes/xkbcommon/all/test_package/conanfile.py @@ -1,10 +1,20 @@ -from conans import ConanFile, CMake, tools import os +from conan import ConanFile +from conan.tools.build import can_run +from conan.tools.cmake import CMake +from conan.tools.layout import cmake_layout + class TestPackageConan(ConanFile): settings = "os", "arch", "compiler", "build_type" - generators = "cmake" + generators = "CMakeToolchain", "CMakeDeps", "VirtualBuildEnv", "VirtualRunEnv" + + def requirements(self): + self.requires(self.tested_reference_str) + + def layout(self): + cmake_layout(self) def build(self): cmake = CMake(self) @@ -12,6 +22,6 @@ def build(self): 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): + cmd = os.path.join(self.cpp.build.bindirs[0], "test_package") + self.run(cmd, env="conanrun") diff --git a/recipes/xkbcommon/all/test_v1_package/CMakeLists.txt b/recipes/xkbcommon/all/test_v1_package/CMakeLists.txt new file mode 100644 index 00000000000000..16dc0ecfa5a2ea --- /dev/null +++ b/recipes/xkbcommon/all/test_v1_package/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.1) +project(test_package) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() + +add_executable(${PROJECT_NAME} test_package.cpp) +target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS}) \ No newline at end of file diff --git a/recipes/xkbcommon/all/test_v1_package/conanfile.py b/recipes/xkbcommon/all/test_v1_package/conanfile.py new file mode 100644 index 00000000000000..e532c741b9e198 --- /dev/null +++ b/recipes/xkbcommon/all/test_v1_package/conanfile.py @@ -0,0 +1,19 @@ +import os + +from conans import ConanFile, CMake +from conan.tools.build import cross_building + + +class TestPackageConan(ConanFile): + settings = "os", "arch", "compiler", "build_type" + generators = "cmake" + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + if not cross_building(self): + bin_path = os.path.join("bin", "test_package") + self.run(bin_path, run_environment=True) \ No newline at end of file