-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
What is your question?
I am a conan2 starter, so some concepts may not be clear yet to me.
I am using conan 2.20.1 and trying to build a conan package for our toolchains.
The toolchains should be identified by os.distro = "SW39344E" meaning a part number for a tar.gz containing a buildroot based toolchain.
So os.distro should be the primary key to identify the cross compilation target.
However i am failing to create a toolchain package, since the test_package step always fails:
deuta-toolchain/1.0.0: package(): Packaged 243 '.hpp' files
deuta-toolchain/1.0.0: Created package revision c3dcd9364f09cfa21acbb537e7082d51
deuta-toolchain/1.0.0: Package '9512ff797f287a1542c98c751aa30dd495b02fa4' created
deuta-toolchain/1.0.0: Full package reference: deuta-toolchain/1.0.0#65cf19a8800606e5e842c6ace20cc080:9512ff797f287a1542c98c751aa30dd495b02fa4#c3dcd9364f09cfa21acbb537e7082d51
deuta-toolchain/1.0.0: Package folder /home/hcw/.conan2/p/b/deuta64c91524e200a/p
======== Launching test_package ========
======== Computing dependency graph ========
deuta-toolchain/1.0.0 (test package): Using toolchain build-require: deuta-toolchain/1.0.0#65cf19a8800606e5e842c6ace20cc080%1757490224.9919577 for Linux-SW39-347E-x86_64
Graph root
deuta-toolchain/1.0.0 (test package): /home/hcw/work/Deuta/deuta-packaging/conan-recipies/toolchain/test_package/conanfile.py
Build requirements
deuta-toolchain/1.0.0#65cf19a8800606e5e842c6ace20cc080 - Cache
======== Computing necessary packages ========
Build requirements
deuta-toolchain/1.0.0#65cf19a8800606e5e842c6ace20cc080:63fead0844576fc02943e16909f08fcdddd6f44b - Invalid
ERROR: There are invalid packages:
deuta-toolchain/1.0.0: Invalid: 'settings.os.distro' value not defined
It looks like the test package (or the toolchain package) does not define os.distro, although it does it...?
Maybe i am setting the package_id for the toolchain wrong, so the test_package is unable to find it?
Looks like the package is being built, but later not found when consuming by the test_package.
Here is my
settings.yml:
os:
Linux:
distro: [Ubuntu-22.04, Ubuntu-24.04, SW39-347E, SW39-373A, SW39-382A, SW39-388A]
Windows:
distro: [SW39-409A]
Profile SW39-347E:
[settings]
os=Linux
os.distro=SW39-347E
arch=armv7
compiler=gcc
compiler.version=11
compiler.libcxx=libstdc++11
build_type=Release
[conf]
tools.cmake.cmaketoolchain:generator=Ninja
tools.cmake.cmaketoolchain:system_name=SW39-347E
tools.cmake.cmaketoolchain:toolchain_file=/opt/deuta/SW39-347E/sdk/share/buildroot/toolchainfile.cmake
my toolchain/conanfile.py:
import os
from conan import ConanFile
from conan.tools.files import get, copy, download
from conan.errors import ConanInvalidConfiguration
from conan.tools.scm import Version
class ToolchainInfo:
def __init__(self, url, sdk_sysroot_rel, toolchain_file_rel):
self.url = url
self.sdk_sysroot_rel = sdk_sysroot_rel
self.toolchain_file_rel = toolchain_file_rel
# Where to find a toolchain and what properties it has
DISTROS = {
"SW39-347E": ToolchainInfo("https://XXX.de/repository/device-firmware/DEUTA/DMI%20Image/Linux%204.14.108-ti-rt-r130/released/SW39-347E/sdk/arm-buildroot-linux-gnueabihf_sdk-buildroot.tar.gz",
"arm-buildroot-linux-gnueabihf/sysroot",
"share/buildroot/toolchainfile.cmake"
),
}
class DeutaToolchain(ConanFile):
name = "deuta-toolchain"
version = "1.0.0"
license = "GPL-3.0-only"
homepage = "https://git.XXX.de/shared-tools/deuta-packaging"
description = "Conan package for different toolchains."
settings = "os", "arch"
package_type = "application"
def validate(self):
if not hasattr(self.settings, "os"):
raise ConanInvalidConfiguration("'settings.os' needs to be specified")
if not hasattr(self.settings.os, "distro"):
raise ConanInvalidConfiguration("'settings.os.distro' needs to be specified")
if self.settings.os == "Linux" or self.settings.os == "Windows":
if not hasattr(self.settings.os, 'distro'):
raise ConanInvalidConfiguration("'settings.os.distro' needs to be specified")
else:
raise ConanInvalidConfiguration("'settings.os' must be Linux or Windows")
if self.settings.os != "Linux":
raise ConanInvalidConfiguration(f"This toolchain is not compatible with {self.settings.os}-{self.settings.arch}. "
"It can only run on Linux-x86_64.")
distro = str(self.settings.os.distro);
if distro not in DISTROS:
raise ConanInvalidConfiguration(f"Cross toolchain not available for {distro}")
def source(self):
pass
def build(self):
self.output.info(f"os={self.settings.os}")
if hasattr(self.settings.os, "distro"):
self.output.info(f"os.distro={self.settings.os.distro}")
else:
self.output.info("no os.distro available")
toolchain = DISTROS[str(self.settings.os.distro)]
tgz_url = toolchain.url
get(self, tgz_url, destination=self.source_folder, strip_root=True, verify=False)
# Run the relocate script if it exists
relocate_script = os.path.join(self.source_folder, "relocate-sdk.sh")
if os.path.exists(relocate_script):
# Run the relocate script
self.run(f"cd {self.source_folder} && ./relocate-sdk.sh")
def package(self):
# Copy everything to the package folder
copy(self, "*",
src=self.source_folder,
dst=self.package_folder,
keep_path=True)
def package_id(self):
# For toolchain packages, we care about target architecture and specific Linux distro/SDK
# Remove settings that don't affect the toolchain binary compatibility
self.info.settings.rm_safe("compiler")
self.info.settings.rm_safe("build_type")
# Keep arch as toolchains are architecture-specific
# Keep os.distro as it encodes the concrete Linux image/SDK
# Remove other os sub-settings that aren't relevant
if hasattr(self.info.settings, "os"):
self.info.settings.os.rm_safe("version")
def package_info(self):
distro = str(self.settings.os.distro)
if distro not in DISTROS:
raise ConanInvalidConfiguration(f"No toolchain info for distro {distro}")
toolchain = DISTROS[str(self.settings.os.distro)]
# Add the bin directory to make executables available
self.cpp_info.bindirs.append("bin")
# Set the CMake toolchain file location
cmake_toolchain_path = os.path.join(self.package_folder, toolchain.toolchain_file_rel)
self.conf_info.define("tools.cmake.cmaketoolchain:toolchain_file", cmake_toolchain_path)
# Set environment variables for the toolchain
self.buildenv_info.define_path("TOOLCHAIN_ROOT", self.package_folder)
def deploy(self):
toolchain = DISTROS[str()]
# Deploy to the specific target directory
target_path = f"/opt/deuta/{self.settings.os.distro}/sdk"
# Ensure target directory exists
os.makedirs(target_path, exist_ok=True)
# Copy package contents to target location
copy(self, "*",
src=self.package_folder,
dst=target_path,
keep_path=True)
my toolchain/test_package/conanfile.py:
from io import StringIO
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.cmake import CMake, cmake_layout
import os
class TestPackageConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "CMakeToolchain", "VirtualBuildEnv"
def validate(self):
if self.settings.os == "Linux":
if not hasattr(self.settings.os, "distro"):
raise ConanInvalidConfiguration("'settings.os.distro' must be defined")
def configure(self):
if not hasattr(self.settings.os, "distro"):
raise ConanInvalidConfiguration("'settings.os.distro' must be defined")
if self.settings.os == "Linux":
_ = self.settings.os.distro # touch the subsetting
if self.settings.os == "Windows":
_ = self.settings.os.distro
def build_requirements(self):
if not hasattr(self.settings.os, "distro"):
raise ConanInvalidConfiguration("'settings.os.distro' must be defined")
distro = str(self.settings.os.distro)
self.output.info(
f"Using toolchain build-require: {self.tested_reference_str} "
f"for {self.settings.os}-{distro}-{self.settings.arch}"
)
self.tool_requires(self.tested_reference_str)
def layout(self):
cmake_layout(self)
def build(self):
if not hasattr(self.settings.os, "distro"):
raise ConanInvalidConfiguration("'settings.os.distro' must be defined")
distro = str(self.settings.os.distro)
self.output.info(f"Building test_package for {self.settings.os}-{distro}-{self.settings.arch}")
cmake = CMake(self)
cmake.configure()
cmake.build()
def test(self):
if not hasattr(self.settings.os, "distro"):
raise ConanInvalidConfiguration("'settings.os.distro' must be defined")
if self.settings.arch in ["armv6", "armv7", "armv7hf"]:
toolchain = "arm-none-linux-gnueabihf"
else:
toolchain = "aarch64-none-linux-gnu"
self.run(f"{toolchain}-gcc --version")
test_file = os.path.join(self.cpp.build.bindirs[0], "test_package")
stdout = StringIO()
self.run(f"file {test_file}", stdout=stdout)
if toolchain == "aarch64-none-linux-gnu":
assert "ELF 64-bit" in stdout.getvalue()
else:
assert "ELF 32-bit" in stdout.getvalue()
Aim is to set up something similair to https://docs.conan.io/2/examples/cross_build/toolchain_packages.html
adapted to our toolchain, and our aim to have os.distro as the primary key to identify cross targets.
Have you read the CONTRIBUTING guide?
- [X ] I've read the CONTRIBUTING guide