Skip to content

Instantly share code, notes, and snippets.

@liarokapisv
Created January 20, 2023 11:53
Show Gist options
  • Save liarokapisv/d7547e866f4ddf2fc362aa173ce27371 to your computer and use it in GitHub Desktop.
Save liarokapisv/d7547e866f4ddf2fc362aa173ce27371 to your computer and use it in GitHub Desktop.
gcc-arm-none-eabi recipe
from conan import ConanFile
from conan.tools.layout import basic_layout
from conan.tools.files import copy, get
from conan.errors import ConanInvalidConfiguration
import os
class ArmToolchainConan(ConanFile):
name = "arm-toolchain"
settings = "os", "arch"
def validate_build(self):
if self.version not in self.conan_data:
raise ConanInvalidConfiguration(f"recipe does not support version '{self.version}'")
if str(self.settings_build.os) not in self.conan_data[self.version]:
raise ConanInvalidConfiguration(f"recipe does not support os '{self.settings_build.os}' for this version")
if str(self.settings_build.arch) not in self.conan_data[self.version][str(self.settings_build.os)]:
raise ConanInvalidConfiguration(f"recipe does not support arch '{self.settings_build.os}' for this version and os")
def validate(self):
settings_target = getattr(self, "settings_target", None)
if settings_target:
if settings_target.os != "baremetal":
raise ConanInvalidConfiguration("recipe only works for baremetal os")
if settings_target.arch != "gcc-arm":
raise ConanInvalidConfiguration("recipe only works with the gcc-arm custom arch")
if settings_target.compiler != "gcc":
raise ConanInvalidConfiguration("profile compiler conflict - recipe installs gcc compiler")
if settings_target.compiler.version != self.version:
raise ConanInvalidConfiguration(f"profile compiler.version conflict - recipe installs version {self.version}")
if settings_target.compiler.libcxx != "libstdc++11":
raise ConanInvalidConfiguration(f"profile compiler.libcxx conflict - recipe uses libstdc++11")
def _get_url_and_filename(self):
info = self.conan_data[self.version][str(self.settings_build.os)][str(self.settings_build.arch)]
url = info["url"]
filename = info["filename"]
rev = info["rev"]
hash = info["hash"]
return (f"{url}/{filename}?rev={rev}&hash={hash}", filename)
def _get_fake_user_agent(self):
return "1.37: Conan/1.37.0 (Windows 10; Brainfuck 2.7.1; AMD64) python-requests/2.25.1"
def build(self):
(url, filename) = self._get_url_and_filename()
fake_agent = self._get_fake_user_agent()
get(self, url, filename=filename, destination=".", headers={"User-Agent": fake_agent}, verify=False, strip_root=True)
def package(self):
copy(self, "*", src=self.build_folder, dst=self.package_folder)
def package_info(self):
common_flags = [
"-Wall",
"-ffunction-sections",
"-fdata-sections",
"-fno-unroll-loops",
"-ffast-math",
"-ftree-vectorize",
"-specs=nano.specs",
"-specs=nosys.specs"
]
settings_target = getattr(self, "settings_target", None)
if settings_target:
common_flags += [
f"-mcpu={settings_target.arch.cpu}",
f"-mfpu={settings_target.arch.fpu}"
]
if settings_target.arch.instructions == "thumb":
common_flags.append("-mthumb")
c_flags = common_flags
cxx_flags = common_flags + ["-fno-exceptions", "-fno-rtti", "-Wno-write-strings", "-Wno-register"]
link_flags = ["-Wl,--gc-sections"]
make_path = lambda x: os.path.join(self.package_folder, "bin", "arm-none-eabi-"+x)
compiler_executables = {
"c" : make_path("gcc"),
"cpp" : make_path("g++"),
"asm" : make_path("as"),
};
self.conf_info.define("tools.build:sysroot", os.path.join(self.package_folder, "arm-none-eabi"))
self.conf_info.define("tools.cmake.cmaketoolchain:system_name", "Generic")
self.conf_info.define("tools.build:cflags", c_flags)
self.conf_info.define("tools.build:cxxflags", cxx_flags)
self.conf_info.define("tools.build:exelinkflags", link_flags)
self.conf_info.define("tools.build:compiler_executables", compiler_executables)
self.buildenv_info.define_path("SYSROOT", self.package_folder)
self.buildenv_info.define_path("CC", make_path("gcc"))
self.buildenv_info.define_path("CXX", make_path("g++"))
self.buildenv_info.define_path("AR", make_path("ar"))
self.buildenv_info.define_path("AS", make_path("as"))
self.buildenv_info.define_path("STRIP", make_path("strip"))
self.buildenv_info.define_path("ADDR2LINE", make_path("addr2line"))
self.buildenv_info.define_path("NM", make_path("nm"))
self.buildenv_info.define_path("OBJCOPY", make_path("objcopy"))
self.buildenv_info.define_path("OBJDUMP", make_path("objdump"))
self.buildenv_info.define_path("READELF", make_path("readelf"))
self.buildenv_info.define_path("SIZE", make_path("size"))
self.buildenv_info.define_path("LD", make_path("ld"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment