diff --git a/recipes/arm-gnu-toolchain/all/conandata.yml b/recipes/arm-gnu-toolchain/all/conandata.yml new file mode 100644 index 0000000000000..8a48fb178a00b --- /dev/null +++ b/recipes/arm-gnu-toolchain/all/conandata.yml @@ -0,0 +1,58 @@ +sources: + "11.3.0": + "Linux": + "x86_64": + url: "https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/11.3.rel1/binrel/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi.tar.xz" + sha256: "d420d87f68615d9163b99bbb62fe69e85132dc0a8cd69fca04e813597fe06121" + "armv8": + url: "https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/11.3.rel1/binrel/arm-gnu-toolchain-11.3.rel1-aarch64-arm-none-eabi.tar.xz" + sha256: "6c713c11d018dcecc16161f822517484a13af151480bbb722badd732412eb55e" + "Macos": + "x86_64": + url: "https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/11.3.rel1/binrel/arm-gnu-toolchain-11.3.rel1-darwin-x86_64-arm-none-eabi.tar.xz" + sha256: "826353d45e7fbaa9b87c514e7c758a82f349cb7fc3fd949423687671539b29cf" + "armv8": + url: "https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/11.3.rel1/binrel/arm-gnu-toolchain-11.3.rel1-darwin-x86_64-arm-none-eabi.tar.xz" + sha256: "826353d45e7fbaa9b87c514e7c758a82f349cb7fc3fd949423687671539b29cf" + "Windows": + "x86_64": + url: "https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/11.3.rel1/binrel/arm-gnu-toolchain-11.3.rel1-mingw-w64-i686-arm-none-eabi.zip" + sha256: "23f24595aa575fba4fdb0cb086df4b053862af60837502cb7e52bd4fb3d76c36" + "12.2.1": + "Linux": + "x86_64": + url: "https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.2.rel1/binrel/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi.tar.xz" + sha256: "84be93d0f9e96a15addd490b6e237f588c641c8afdf90e7610a628007fc96867" + "armv8": + url: "https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.2.rel1/binrel/arm-gnu-toolchain-12.2.rel1-aarch64-arm-none-eabi.tar.xz" + sha256: "7ee332f7558a984e239e768a13aed86c6c3ac85c90b91d27f4ed38d7ec6b3e8c" + "Macos": + "x86_64": + url: "https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.2.rel1/binrel/arm-gnu-toolchain-12.2.rel1-darwin-x86_64-arm-none-eabi.tar.xz" + sha256: "00c0eeb57ae92332f216151ac66df6ba17d2d3b306dac86f4006006f437b2902" + "armv8": + url: "https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.2.rel1/binrel/arm-gnu-toolchain-12.2.rel1-darwin-arm64-arm-none-eabi.tar.xz" + sha256: "21a9e875250bcb0db8df4cb23dd43c94c00a1d3b98ecba9cdd6ed51586b12248" + "Windows": + "x86_64": + url: "https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.2.rel1/binrel/arm-gnu-toolchain-12.2.rel1-mingw-w64-i686-arm-none-eabi.zip" + sha256: "ad1427496cde9bbe7604bc448ec6e115c6538e04af1c8275795ebb1c2b7b2830" + "12.3.1": + "Linux": + "x86_64": + url: "https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi.tar.xz" + sha256: "12a2815644318ebcceaf84beabb665d0924b6e79e21048452c5331a56332b309" + "armv8": + url: "https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-aarch64-arm-none-eabi.tar.xz" + sha256: "14c0487d5753f6071d24e568881f7c7e67f80dd83165dec5164b3731394af431" + "Macos": + "x86_64": + url: "https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-darwin-x86_64-arm-none-eabi.tar.xz" + sha256: "e6ed8bf930fad9ce33e120ab90b36957b1f779fccaa6de6c9ca9a58982c04291" + "armv8": + url: "https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-darwin-arm64-arm-none-eabi.tar.xz" + sha256: "3b2eee0bdf71c1bbeb3c3b7424fbf7bd9d5c3f0f5a3a4a78159c9e3ad219e7bd" + "Windows": + "x86_64": + url: "https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-mingw-w64-i686-arm-none-eabi.zip" + sha256: "d52888bf59c5262ebf3e6b19b9f9e6270ecb60fd218cf81a4e793946e805a654" diff --git a/recipes/arm-gnu-toolchain/all/conanfile.py b/recipes/arm-gnu-toolchain/all/conanfile.py new file mode 100644 index 0000000000000..eeba121256e8a --- /dev/null +++ b/recipes/arm-gnu-toolchain/all/conanfile.py @@ -0,0 +1,157 @@ +from conan import ConanFile +from conan.tools.files import get, copy, download +from conan.errors import ConanInvalidConfiguration +import os + + +required_conan_version = ">=1.60.2" + + +class ArmGnuToolchain(ConanFile): + name = "arm-gnu-toolchain" + license = ("GPL-3.0-only", "GPL-2.0-only", "BSD-3-Clause", + "BSD-2-Clause-FreeBSD", "AGPL-3.0-only", "BSD-2-Clause") + url = "https://github.com/conan-io/conan-center-index" + homepage = "https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads" + description = ("Conan installer for the GNU Arm Embedded Toolchain") + topics = ("gcc", "compiler", "embedded", "arm", "cortex", "cortex-m", + "cortex-m0", "cortex-m0+", "cortex-m1", "cortex-m3", "cortex-m4", + "cortex-m4f", "cortex-m7", "cortex-m23", "cortex-m55", + "cortex-m35p", "cortex-m33") + settings = "os", "arch", 'compiler', 'build_type' + exports_sources = "toolchain.cmake" + package_type = "application" + short_paths = True + + @property + def download_info(self): + version = self.version + conan_os = str(self._settings_build.os) + arch = str(self._settings_build.arch) + return self.conan_data.get("sources", {}).get(version, {}).get(conan_os, {}).get(arch) + + @property + def license_url(self): + # License URL found from the "EULA" button on the + # https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads + # web page. + if self.version == "11.3.0": + return "https://developer.arm.com/GetEula?Id=ff19df33-da82-491a-ab50-c605d4589a26" + if self.version == "12.2.1": + return "https://developer.arm.com/GetEula?Id=2821586b-44d0-4e75-a06d-4279cd97eaae" + if self.version == "12.3.1": + return "https://developer.arm.com/GetEula?Id=aa3d692d-bc99-4c8c-bce2-588181ddde13" + else: + # This should only happen if the toolchain is packaged with its + # license file. + return None + + @property + def _settings_build(self): + return getattr(self, "settings_build", self.settings) + + def package_id(self): + del self.info.settings.compiler + del self.info.settings.build_type + + def validate(self): + supported_build_operating_systems = ["Linux", "Macos", "Windows"] + if not self._settings_build.os in supported_build_operating_systems: + raise ConanInvalidConfiguration( + f"The build os '{self._settings_build.os}' is not supported. " + "Pre-compiled binaries are only available for " + f"{supported_build_operating_systems}." + ) + + supported_build_architectures = { + "Linux": ["armv8", "x86_64"], + "Macos": ["armv8", "x86_64"], + "Windows": ["x86_64"], + } + + if ( + not self._settings_build.arch + in supported_build_architectures[str(self._settings_build.os)] + ): + build_os = str(self._settings_build.os) + raise ConanInvalidConfiguration( + f"The build architecture '{self._settings_build.arch}' " + f"is not supported for {self._settings_build.os}. " + "Pre-compiled binaries are only available for " + f"{supported_build_architectures[build_os]}." + ) + + compiler_name = str(self.settings.compiler) + if compiler_name != "gcc": + raise ConanInvalidConfiguration( + "The compiler must be set to gcc to use this toolchain.") + + compiler_version = str(self.settings.compiler.version) + supported_compiler_versions = ["11", "11.3", "12", "12.2", "12.3"] + if compiler_version not in supported_compiler_versions: + raise ConanInvalidConfiguration( + "The compiler version must be one of the following: " + f"{supported_compiler_versions}.") + + major_version = str(self.version).split(".")[0] + major_compiler_settings_version = compiler_version.split(".")[0] + if major_version != major_compiler_settings_version: + raise ConanInvalidConfiguration( + f"The compiler version [{major_compiler_settings_version}] and " + f"package version [{major_version}] must be the same.") + + def source(self): + pass + + def build(self): + if self.license_url: + download(self, self.license_url, "LICENSE", verify=False) + + get(self, + **self.conan_data["sources"][self.version][str(self._settings_build.os)][str(self._settings_build.arch)], + destination=self.build_folder, strip_root=True) + + def package(self): + destination = os.path.join(self.package_folder, "bin") + + copy(self, pattern="arm-none-eabi/*", src=self.build_folder, + dst=destination, keep_path=True) + copy(self, pattern="bin/*", src=self.build_folder, + dst=destination, keep_path=True) + copy(self, pattern="include/*", src=self.build_folder, + dst=destination, keep_path=True) + copy(self, pattern="lib/*", src=self.build_folder, + dst=destination, keep_path=True) + copy(self, pattern="libexec/*", src=self.build_folder, + dst=destination, keep_path=True) + copy(self, pattern="share/*", src=self.build_folder, + dst=destination, keep_path=True) + + license_dir = os.path.join(self.package_folder, "licenses/") + copy(self, pattern="LICENSE*", src=self.build_folder, + dst=license_dir, keep_path=True) + + resource_dir = os.path.join(self.package_folder, "res/") + copy(self, pattern="toolchain.cmake", src=self.build_folder, + dst=resource_dir, keep_path=True) + + def package_info(self): + self.cpp_info.includedirs = [] + + bin_folder = os.path.join(self.package_folder, "bin/bin") + self.cpp_info.bindirs = [bin_folder] + self.buildenv_info.append_path("PATH", bin_folder) + + self.conf_info.define( + "tools.cmake.cmaketoolchain:system_name", "Generic") + self.conf_info.define( + "tools.cmake.cmaketoolchain:system_processor", "ARM") + self.conf_info.define("tools.build.cross_building:can_run", False) + self.conf_info.define("tools.build:compiler_executables", { + "c": "arm-none-eabi-gcc", + "cpp": "arm-none-eabi-g++", + "asm": "arm-none-eabi-as", + }) + + f = os.path.join(self.package_folder, "res/toolchain.cmake") + self.conf_info.append("tools.cmake.cmaketoolchain:user_toolchain", f) diff --git a/recipes/arm-gnu-toolchain/all/test_package/CMakeLists.txt b/recipes/arm-gnu-toolchain/all/test_package/CMakeLists.txt new file mode 100644 index 0000000000000..4e10ff0505de5 --- /dev/null +++ b/recipes/arm-gnu-toolchain/all/test_package/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.15) + +project(test_package LANGUAGES CXX) + +# Conan's adds host side flags to the conan_toolchain.cmake file which +# interferes with arm-none-eabi-g++. To fix this, we set CMAKE_CXX_FLAGS +# to an empty string, then provide target specific flags to the +# executable. +set(CMAKE_CXX_FLAGS "") + +set(compiler_flags + -mcpu=cortex-m0plus + -mfloat-abi=soft + --specs=nosys.specs + --specs=nano.specs) + +add_executable(${PROJECT_NAME} main.cpp) +target_compile_options(${PROJECT_NAME} PRIVATE ${compiler_flags}) +target_link_options(${PROJECT_NAME} PRIVATE ${compiler_flags}) diff --git a/recipes/arm-gnu-toolchain/all/test_package/conanfile.py b/recipes/arm-gnu-toolchain/all/test_package/conanfile.py new file mode 100644 index 0000000000000..a1b9a7229fdb5 --- /dev/null +++ b/recipes/arm-gnu-toolchain/all/test_package/conanfile.py @@ -0,0 +1,24 @@ +from conan import ConanFile +from conan.tools.cmake import CMake, cmake_layout + + +class TestPackageConan(ConanFile): + settings = "os", "arch", "compiler", "build_type" + generators = "CMakeDeps", "CMakeToolchain", "VirtualBuildEnv" + + def build_requirements(self): + self.tool_requires("cmake/3.27.1") + self.tool_requires(self.tested_reference_str) + + def layout(self): + cmake_layout(self) + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + # Executables generated by this toolchain will never work on a host + # machine and thus can never be executed. + pass diff --git a/recipes/arm-gnu-toolchain/all/test_package/main.cpp b/recipes/arm-gnu-toolchain/all/test_package/main.cpp new file mode 100644 index 0000000000000..8041a19240c2d --- /dev/null +++ b/recipes/arm-gnu-toolchain/all/test_package/main.cpp @@ -0,0 +1,74 @@ +#include +#include + +#include +#include +#include +#include + +int +main() +{ + int a = 5; + int b = 12; + + return a + b; +} + +// Stub newlib implementations to keep linker happy +extern "C" +{ + /// Dummy implementation of getpid + int _getpid_r() + { + return 1; + } + + /// Dummy implementation of kill + int _kill_r(int, int) + { + return -1; + } + + /// Dummy implementation of fstat, makes the assumption that the "device" + /// representing, in this case STDIN, STDOUT, and STDERR as character devices. + int _fstat_r([[maybe_unused]] int file, struct stat* status) + { + status->st_mode = S_IFCHR; + return 0; + } + + int _write_r([[maybe_unused]] int file, + [[maybe_unused]] const char* ptr, + int length) + { + return length; + } + + int _read_r([[maybe_unused]] FILE* file, + [[maybe_unused]] char* ptr, + int length) + { + return length; + } + + // Dummy implementation of _lseek + int _lseek_r([[maybe_unused]] int file, + [[maybe_unused]] int ptr, + [[maybe_unused]] int dir) + { + return 0; + } + + // Dummy implementation of close + int _close_r([[maybe_unused]] int file) + { + return -1; + } + + // Dummy implementation of isatty + int _isatty_r([[maybe_unused]] int file) + { + return 1; + } +} diff --git a/recipes/arm-gnu-toolchain/all/toolchain.cmake b/recipes/arm-gnu-toolchain/all/toolchain.cmake new file mode 100644 index 0000000000000..c8ba5b9084150 --- /dev/null +++ b/recipes/arm-gnu-toolchain/all/toolchain.cmake @@ -0,0 +1,34 @@ +# Append current directory to CMAKE_MODULE_PATH for making device specific +# cmake modules visible +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}) + +# Skip Working compiler test which tends to fail in CMake due to it using build +# target architecture flags and not host architecture flags. +set(CMAKE_CXX_COMPILER_WORKS TRUE) +set(CMAKE_C_COMPILER_WORKS TRUE) + +# Need to force system to Generic & ARM as leaving this to Conan will result in +# pollution from host profile settings +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR arm) + +# Target definition +set(TOOLCHAIN arm-none-eabi) + +# Perform compiler test with static library +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +# Set toolchain compilers +set(CMAKE_C_COMPILER ${TOOLCHAIN}-gcc${CMAKE_EXECUTABLE_SUFFIX}) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN}-g++${CMAKE_EXECUTABLE_SUFFIX}) +set(CMAKE_ASM_COMPILER ${TOOLCHAIN}-gcc${CMAKE_EXECUTABLE_SUFFIX}) +set(CMAKE_AR ${TOOLCHAIN}-ar${CMAKE_EXECUTABLE_SUFFIX}) +set(CMAKE_SIZE_UTIL ${TOOLCHAIN}-size${CMAKE_EXECUTABLE_SUFFIX}) +set(CMAKE_OBJDUMP ${TOOLCHAIN}-objdump${CMAKE_EXECUTABLE_SUFFIX}) +set(CMAKE_OBJCOPY ${TOOLCHAIN}-objcopy${CMAKE_EXECUTABLE_SUFFIX}) +set(CMAKE_FIND_ROOT_PATH ${CMAKE_PREFIX_PATH} ${CMAKE_BINARY_DIR}) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/recipes/arm-gnu-toolchain/config.yml b/recipes/arm-gnu-toolchain/config.yml new file mode 100644 index 0000000000000..dfb33109d42f1 --- /dev/null +++ b/recipes/arm-gnu-toolchain/config.yml @@ -0,0 +1,7 @@ +versions: + "11.3.0": + folder: "all" + "12.2.1": + folder: "all" + "12.3.1": + folder: "all"