From 32ce30fe8eb8a8fd7a7b175d232c8f2eb829dea4 Mon Sep 17 00:00:00 2001 From: Daniel Brondani Date: Mon, 25 Sep 2023 09:42:12 +0200 Subject: [PATCH] [projmgr] External Generator PoC - Initial commit --- tools/projmgr/CMakeLists.txt | 4 +- tools/projmgr/include/ProjMgr.h | 1 + tools/projmgr/include/ProjMgrExtGenerator.h | 143 +++++++++ tools/projmgr/include/ProjMgrParser.h | 36 +++ tools/projmgr/include/ProjMgrWorker.h | 44 ++- tools/projmgr/include/ProjMgrYamlEmitter.h | 18 +- tools/projmgr/include/ProjMgrYamlParser.h | 21 ++ .../include/ProjMgrYamlSchemaChecker.h | 7 +- .../schemas/cbuild-gen-idx.schema.json | 13 + tools/projmgr/schemas/cbuild-gen.schema.json | 13 + tools/projmgr/schemas/cbuild-idx.schema.json | 13 + tools/projmgr/schemas/cgen.schema.json | 13 + tools/projmgr/schemas/common.schema.json | 151 +++++++++- tools/projmgr/schemas/generator.schema.json | 13 + tools/projmgr/src/ProjMgr.cpp | 28 +- tools/projmgr/src/ProjMgrExtGenerator.cpp | 106 +++++++ tools/projmgr/src/ProjMgrParser.cpp | 9 + tools/projmgr/src/ProjMgrWorker.cpp | 278 +++++++++++++++--- tools/projmgr/src/ProjMgrYamlEmitter.cpp | 161 ++++++---- tools/projmgr/src/ProjMgrYamlParser.cpp | 48 ++- .../projmgr/src/ProjMgrYamlSchemaChecker.cpp | 15 + tools/projmgr/templates/global.generator.yml | 5 + .../test/data/ExternalGenerator/bridge.sh | 4 + .../ExternalGenerator/extgen.csolution.yml | 30 ++ .../ExternalGenerator/global.generator.yml | 5 + .../multi_0/core0.cproject.yml | 6 + .../multi_1/core1.cproject.yml | 6 + .../ExternalGenerator/no-gendir.generator.yml | 4 + .../core0.Debug+MultiCore.cbuild-gen.yml | 50 ++++ .../core1.Debug+MultiCore.cbuild-gen.yml | 50 ++++ .../ref/MultiCore/extgen.cbuild-gen-idx.yml | 16 + .../ref/SingleCore/extgen.cbuild-gen-idx.yml | 11 + .../single-core.Debug+CM0.cbuild-gen.yml | 46 +++ .../single-core.Debug+CM0.cbuild.yml | 82 ++++++ .../ref/TrustZone/extgen.cbuild-gen-idx.yml | 16 + .../ref/TrustZone/ns.Debug+CM0.cbuild-gen.yml | 42 +++ .../ref/TrustZone/s.Debug+CM0.cbuild-gen.yml | 44 +++ .../single/generated/generated.c | 1 + .../single/generated/single-core.cgen.yml | 14 + .../single/generated/wrong.cgen.yml | 23 ++ .../test/data/ExternalGenerator/single/main.c | 1 + .../single/single-core.cproject.yml | 16 + .../single/wrong.cproject.yml | 16 + .../ExternalGenerator/tz_ns/ns.cproject.yml | 7 + .../ExternalGenerator/tz_s/s.cproject.yml | 7 + .../wrong-gendir.generator.yml | 5 + .../ExternalGenerator/wrong.csolution.yml | 24 ++ .../project.Debug+TEST_TARGET.cbuild.yml | 1 + .../project.Release+TEST_TARGET.cbuild.yml | 1 + .../multiple-components.Debug+CM0.cbuild.yml | 2 + .../ref/test-gpdsc-layer.Debug+CM0.cbuild.yml | 2 + ...c-multiple-generators.Debug+CM0.cbuild.yml | 2 + .../ref/test-gpdsc.Debug+CM0.cbuild.yml | 2 + .../project1.Debug+RteTest_ARMCM3.cbuild.yml | 1 + ...project1.Release+RteTest_ARMCM3.cbuild.yml | 1 + .../project2.Debug+RteTest_ARMCM3.cbuild.yml | 1 + ...project2.Release+RteTest_ARMCM3.cbuild.yml | 1 + ...-scope.Debug_AC6+RteTest_ARMCM3.cbuild.yml | 1 + ...linker.Debug_AC6+RteTest_ARMCM3.cbuild.yml | 1 + ...linker.Debug_GCC+RteTest_ARMCM3.cbuild.yml | 1 + ....PriorityDefines+RteTest_ARMCM3.cbuild.yml | 1 + ....PriorityRegions+RteTest_ARMCM3.cbuild.yml | 1 + .../library.Debug+RteTest_ARMCM3.cbuild.yml | 1 + .../TestProject3_1.Debug+TypeA.cbuild-gen.yml | 10 +- .../ref/TestProject3_1.Debug+TypeA.cbuild.yml | 4 +- .../ref/cbuild/test1.Debug+CM0.cbuild.yml | 1 + .../ref/cbuild/test1.Release+CM0.cbuild.yml | 1 + .../ref/cbuild/test2.Debug+CM0.cbuild.yml | 1 + .../ref/cbuild/test2.Debug+CM3.cbuild.yml | 1 + .../ref/outputFiles.Debug+Target.cbuild.yml | 1 + .../ref/outputFiles.Library+Target.cbuild.yml | 1 + .../ref/pre-include+CM0.cbuild.yml | 1 + .../ref/rtedir.Debug+CM0.cbuild.yml | 1 + .../ref/rtedir.Release+CM0.cbuild.yml | 1 + tools/projmgr/test/src/ProjMgrUnitTests.cpp | 262 ++++++++++++++++- .../test/src/ProjMgrWorkerUnitTests.cpp | 7 +- 76 files changed, 1826 insertions(+), 152 deletions(-) create mode 100644 tools/projmgr/include/ProjMgrExtGenerator.h create mode 100644 tools/projmgr/schemas/cbuild-gen-idx.schema.json create mode 100644 tools/projmgr/schemas/cbuild-gen.schema.json create mode 100644 tools/projmgr/schemas/cbuild-idx.schema.json create mode 100644 tools/projmgr/schemas/cgen.schema.json create mode 100644 tools/projmgr/schemas/generator.schema.json create mode 100644 tools/projmgr/src/ProjMgrExtGenerator.cpp create mode 100644 tools/projmgr/templates/global.generator.yml create mode 100755 tools/projmgr/test/data/ExternalGenerator/bridge.sh create mode 100644 tools/projmgr/test/data/ExternalGenerator/extgen.csolution.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/global.generator.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/multi_0/core0.cproject.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/multi_1/core1.cproject.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/no-gendir.generator.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/ref/MultiCore/core0.Debug+MultiCore.cbuild-gen.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/ref/MultiCore/core1.Debug+MultiCore.cbuild-gen.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/ref/MultiCore/extgen.cbuild-gen-idx.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/ref/SingleCore/extgen.cbuild-gen-idx.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/ref/SingleCore/single-core.Debug+CM0.cbuild-gen.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/ref/SingleCore/single-core.Debug+CM0.cbuild.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/ref/TrustZone/extgen.cbuild-gen-idx.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/ref/TrustZone/ns.Debug+CM0.cbuild-gen.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/ref/TrustZone/s.Debug+CM0.cbuild-gen.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/single/generated/generated.c create mode 100644 tools/projmgr/test/data/ExternalGenerator/single/generated/single-core.cgen.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/single/generated/wrong.cgen.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/single/main.c create mode 100644 tools/projmgr/test/data/ExternalGenerator/single/single-core.cproject.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/single/wrong.cproject.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/tz_ns/ns.cproject.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/tz_s/s.cproject.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/wrong-gendir.generator.yml create mode 100644 tools/projmgr/test/data/ExternalGenerator/wrong.csolution.yml diff --git a/tools/projmgr/CMakeLists.txt b/tools/projmgr/CMakeLists.txt index fe54361fe..09604e9dc 100644 --- a/tools/projmgr/CMakeLists.txt +++ b/tools/projmgr/CMakeLists.txt @@ -13,12 +13,12 @@ set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT projmgr) SET(PROJMGR_SOURCE_FILES ProjMgr.cpp ProjMgrKernel.cpp ProjMgrCallback.cpp ProjMgrParser.cpp ProjMgrWorker.cpp ProjMgrGenerator.cpp ProjMgrXmlParser.cpp ProjMgrYamlParser.cpp ProjMgrLogger.cpp ProjMgrYamlSchemaChecker.cpp - ProjMgrYamlEmitter.cpp ProjMgrUtils.cpp + ProjMgrYamlEmitter.cpp ProjMgrUtils.cpp ProjMgrExtGenerator.cpp ) SET(PROJMGR_HEADER_FILES ProjMgr.h ProjMgrKernel.h ProjMgrCallback.h ProjMgrParser.h ProjMgrWorker.h ProjMgrGenerator.h ProjMgrXmlParser.h ProjMgrYamlParser.h ProjMgrLogger.h ProjMgrYamlSchemaChecker.h - ProjMgrYamlEmitter.h ProjMgrUtils.h + ProjMgrYamlEmitter.h ProjMgrUtils.h ProjMgrExtGenerator.h ) list(TRANSFORM PROJMGR_SOURCE_FILES PREPEND src/) diff --git a/tools/projmgr/include/ProjMgr.h b/tools/projmgr/include/ProjMgr.h index 705db5c53..2e47855a7 100644 --- a/tools/projmgr/include/ProjMgr.h +++ b/tools/projmgr/include/ProjMgr.h @@ -85,6 +85,7 @@ class ProjMgr { protected: ProjMgrParser m_parser; + ProjMgrExtGenerator m_extGenerator; ProjMgrWorker m_worker; ProjMgrGenerator m_generator; ProjMgrYamlEmitter m_emitter; diff --git a/tools/projmgr/include/ProjMgrExtGenerator.h b/tools/projmgr/include/ProjMgrExtGenerator.h new file mode 100644 index 000000000..af3bf8654 --- /dev/null +++ b/tools/projmgr/include/ProjMgrExtGenerator.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2020-2023 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef PROJMGREXTGENERATOR_H +#define PROJMGREXTGENERATOR_H + +#include "ProjMgrParser.h" +#include "ProjMgrUtils.h" + + /** + * @brief external generator item containing + * component identifier + * directory for generated files + * project type + */ +struct ExtGeneratorItem { + std::string componentId; + std::string genDir; + std::string projectType; +}; + + +struct CbuildGenItem { + StrVec forContext; + std::string device; + std::string board; + std::string projectPart; +}; + +/** + * @brief map of used generators, directories and contexts +*/ +typedef std::map GeneratorContextVecMap; + +/** + * @brief vector of external generator items +*/ +typedef std::vector ExtGeneratorVec; + +/** + * @brief map of vector of external generator items +*/ +typedef std::map ExtGeneratorVecMap; + +/** + * @brief solution/project types +*/ +static constexpr const char* TYPE_SINGLE_CORE = "single-core"; +static constexpr const char* TYPE_MULTI_CORE = "multi-core"; +static constexpr const char* TYPE_TRUSTZONE = "trustzone"; + +/** + * @brief projmgr external generator class responsible for handling global generators +*/ +class ProjMgrExtGenerator { +public: + /** + * @brief class constructor + */ + ProjMgrExtGenerator(ProjMgrParser* parser); + + + /** + * @brief class destructor + */ + ~ProjMgrExtGenerator(void); + + /** + * @brief set check schema + * @param boolean check schema + */ + void SetCheckSchema(bool checkSchema); + + /** + * @brief retrieve globally registered generators + * @return true if successful + */ + bool RetrieveGlobalGenerators(void); + + /** + * @brief verify if generator is global + * @param generatorId generator identifier + * @return true if generator is global + */ + bool IsGlobalGenerator(const std::string& generatorId); + + /** + * @brief verify if generator required by a given component is valid + * @param generatorId generator identifier + * @param componentId component identifier + * @return true if generator is valid + */ + bool CheckGeneratorId(const std::string& generatorId, const std::string& componentId); + + /** + * @brief get directory for generated files + * @param generatorId generator identifier + * @return string directory for generated files + */ + const std::string& GetGlobalGenDir(const std::string& generatorId); + + /** + * @brief get run command for generator call + * @param generatorId generator identifier + * @return string with run command for generator call + */ + const std::string& GetGlobalGenRunCmd(const std::string& generatorId); + + /** + * @brief add generator to the list of used generators of a given context + * @param generatorId generator identifier + * @param genDir directory for generated files + * @param contextId context identifier + */ + void AddUsedGenerator(const std::string& generatorId, const std::string& genDir, const std::string& contextId); + + /** + * @brief get map of used generators + * @return map of used generators + */ + const GeneratorContextVecMap& GetUsedGenerators(void); + + /** + * @brief get layer item with generator-import file data + * @param contextId context identifier + * @param boolean reference, true if successful + * @return layer item + */ + ClayerItem* GetGeneratorImport(const std::string& contextId, bool& success); + +protected: + ProjMgrParser* m_parser = nullptr; + StrVec m_globalGeneratorFiles; + std::map m_globalGenerators; + GeneratorContextVecMap m_usedGenerators; + bool m_checkSchema; + std::string m_compilerRoot; +}; + +#endif // PROJMGREXTGENERATOR_H diff --git a/tools/projmgr/include/ProjMgrParser.h b/tools/projmgr/include/ProjMgrParser.h index 460166707..08f0e3470 100644 --- a/tools/projmgr/include/ProjMgrParser.h +++ b/tools/projmgr/include/ProjMgrParser.h @@ -140,12 +140,14 @@ struct TargetType { * @brief directories item containing * intdir directory, * outdir directory, + * cbuild directory, * cprj directory, * rte directory, */ struct DirectoriesItem { std::string intdir; std::string outdir; + std::string cbuild; std::string cprj; std::string rte; }; @@ -413,6 +415,20 @@ struct CbuildSetItem { std::string compiler; }; +/** + * @brief global generator item containing + * generator id, + * download url, + * bridge program, + * path for generated files +*/ +struct GlobalGeneratorItem { + std::string id; + std::string downloadUrl; + std::string run; + std::string path; +}; + /** * @brief projmgr parser class for public interfacing */ @@ -430,6 +446,7 @@ class ProjMgrParser { /** * @brief parse cdefault + * @param checkSchema false to skip schema validation * @param input cdefault.yml file */ bool ParseCdefault(const std::string& input, bool checkSchema); @@ -437,24 +454,28 @@ class ProjMgrParser { /** * @brief parse cproject * @param input cproject.yml file + * @param checkSchema false to skip schema validation * @param boolean parse single project, default false */ bool ParseCproject(const std::string& input, bool checkSchema, bool single = false); /** * @brief parse csolution + * @param checkSchema false to skip schema validation * @param input csolution.yml file */ bool ParseCsolution(const std::string& input, bool checkSchema); /** * @brief parse clayer + * @param checkSchema false to skip schema validation * @param input clayer.yml file */ bool ParseClayer(const std::string& input, bool checkSchema); /** * @brief parse generic clayer files + * @param checkSchema false to skip schema validation * @param input clayer.yml file */ bool ParseGenericClayer(const std::string& input, bool checkSchema); @@ -465,6 +486,13 @@ class ProjMgrParser { */ bool ParseCbuildSet(const std::string& input); + /** + * @brief parse global generator + * @param input generator.yml file + * @param checkSchema false to skip schema validation + */ + bool ParseGlobalGenerator(const std::string& input, bool checkSchema); + /** * @brief get cdefault * @return cdefault item @@ -500,6 +528,13 @@ class ProjMgrParser { * @return cbuildset item */ CbuildSetItem& GetCbuildSetItem(void); + + /** + * @brief get global generators + * @return global generators map + */ + std::map& GetGlobalGenerators(void); + protected: CdefaultItem m_cdefault; CsolutionItem m_csolution; @@ -507,6 +542,7 @@ class ProjMgrParser { std::map m_cprojects; std::map m_clayers; std::map m_genericClayers; + std::map m_globalGenerators; }; #endif // PROJMGRPARSER_H diff --git a/tools/projmgr/include/ProjMgrWorker.h b/tools/projmgr/include/ProjMgrWorker.h index 32fe5ca72..1391a4287 100644 --- a/tools/projmgr/include/ProjMgrWorker.h +++ b/tools/projmgr/include/ProjMgrWorker.h @@ -7,6 +7,7 @@ #ifndef PROJMGRWORKER_H #define PROJMGRWORKER_H +#include "ProjMgrExtGenerator.h" #include "ProjMgrKernel.h" #include "ProjMgrParser.h" #include "ProjMgrUtils.h" @@ -252,6 +253,7 @@ struct ContextTypesItem { * output type, * device selection, * board selection, + * device item struct, * list of package requirements, * map of required pdsc files and optionally its local path * list of component requirements, @@ -269,6 +271,7 @@ struct ContextTypesItem { * valid connections, * linker options, * map of variables, + * external generator directory, * boolean processed precedences */ struct ContextItem { @@ -289,6 +292,7 @@ struct ContextItem { OutputTypes outputTypes; std::string device; std::string board; + DeviceItem deviceItem; std::vector packRequirements; std::map> pdscFiles; std::vectormissingPacks; @@ -310,6 +314,7 @@ struct ContextItem { std::vector validConnections; LinkerContextItem linker; std::map variables; + StrMap extGenDir; bool precedences; }; @@ -362,28 +367,22 @@ class ProjMgrWorker { /** * @brief class constructor */ - ProjMgrWorker(void); + ProjMgrWorker(ProjMgrParser* parser, ProjMgrExtGenerator* extGenerator); /** * @brief class destructor */ ~ProjMgrWorker(void); - /** - * @brief set parser - * @param pointer to parser - */ - void SetParser(ProjMgrParser* parser); - /** * @brief process context * @param reference to context - * @param loadGpdsc boolean automatically load gpdsc, default true + * @param loadGenFiles boolean automatically load generated files, default true * @param resolveDependencies boolean automatically resolve dependencies, default true * @param updateRteFiles boolean update RTE files, default true * @return true if executed successfully */ - bool ProcessContext(ContextItem& context, bool loadGpdsc = true, bool resolveDependencies = true, bool updateRteFiles = true); + bool ProcessContext(ContextItem& context, bool loadGenFiles = true, bool resolveDependencies = true, bool updateRteFiles = true); /** * @brief list available packs @@ -554,6 +553,13 @@ class ProjMgrWorker { */ bool ExecuteGenerator(std::string& generatorId); + /** + * @brief execute external generator of a given context + * @param generator identifier + * @return true if executed successfully + */ + bool ExecuteExtGenerator(std::string& generatorId); + /** * @brief initialize model * @return true if executed successfully @@ -612,10 +618,22 @@ class ProjMgrWorker { */ std::string GetSelectedToochain(void); + /** + * @brief process global generators for a given context + * @param context selected context item + * @param generator identifier + * @param reference to project type + * @param reference to sibling contexts + * @return true if executed successfully + */ + bool ProcessGlobalGenerators(ContextItem* context, const std::string& generatorId, + std::string& projectType, StrVec& siblings); + protected: ProjMgrParser* m_parser = nullptr; ProjMgrKernel* m_kernel = nullptr; RteGlobalModel* m_model = nullptr; + ProjMgrExtGenerator* m_extGenerator = nullptr; std::list m_loadedPacks; std::vector m_toolchains; StrVec m_toolchainConfigFiles; @@ -647,7 +665,7 @@ class ProjMgrWorker { bool GetProjectSetup(ContextItem& context); bool InitializeTarget(ContextItem& context); bool SetTargetAttributes(ContextItem& context, std::map& attributes); - bool ProcessPrecedences(ContextItem& context); + bool ProcessPrecedences(ContextItem& context, bool rerun = false); bool ProcessPrecedence(StringCollection& item); bool ProcessCompilerPrecedence(StringCollection& item, bool acceptRedefinition = false); bool ProcessDevice(ContextItem& context); @@ -661,7 +679,7 @@ class ProjMgrWorker { bool ProcessConfigFiles(ContextItem& context); bool ProcessComponentFiles(ContextItem& context); bool ProcessGroups(ContextItem& context); - bool ProcessSequencesRelatives(ContextItem& context); + bool ProcessSequencesRelatives(ContextItem& context, bool rerun); bool ProcessSequencesRelatives(ContextItem& context, std::vector& src, const std::string& ref = std::string(), bool withHeadingDot = false); bool ProcessSequencesRelatives(ContextItem& context, BuildType& build, const std::string& ref = std::string()); bool ProcessSequenceRelative(ContextItem& context, std::string& item, const std::string& ref = std::string(), bool withHeadingDot = false); @@ -729,10 +747,14 @@ class ProjMgrWorker { void UpdatePartialReferencedContext(ContextItem& context, std::string& contextName); void ExpandAccessSequence(const ContextItem& context, const ContextItem& refContext, const std::string& sequence, std::string& item, bool withHeadingDot); bool GetGeneratorDir(const RteGenerator* generator, ContextItem& context, const std::string& layer, std::string& genDir); + bool GetGeneratorDir(const std::string& generatorId, ContextItem& context, const std::string& layer, std::string& genDir); + bool GetExtGeneratorDir(const std::string& generatorId, ContextItem& context, const std::string& layer, std::string& genDir); bool ParseContextLayers(ContextItem& context); bool AddPackRequirements(ContextItem& context, const std::vector packRequirements); + void InsertPackRequirements(const std::vector& src, std::vector& dst, std::string base); void CheckTypeFilterSpelling(const TypeFilter& typeFilter); void CheckCompilerFilterSpelling(const std::string& compiler); + bool ProcessGeneratedLayers(ContextItem& context); }; #endif // PROJMGRWORKER_H diff --git a/tools/projmgr/include/ProjMgrYamlEmitter.h b/tools/projmgr/include/ProjMgrYamlEmitter.h index 00c604e6f..0d4242483 100644 --- a/tools/projmgr/include/ProjMgrYamlEmitter.h +++ b/tools/projmgr/include/ProjMgrYamlEmitter.h @@ -34,11 +34,25 @@ class ProjMgrYamlEmitter { static bool GenerateCbuildIndex(ProjMgrParser& parser, const std::vector contexts, const std::string& outputDir); /** - * @brief generate cbuild.yml file + * @brief generate cbuild-gen-idx.yml file + * @param parser reference + * @param contexts vector with pointers to sibling contexts + * @param type project type + * @param outdir output directory + * @param gendir generated files directory + * @return true if executed successfully + */ + static bool GenerateCbuildGenIndex(ProjMgrParser& parser, const std::vector siblings, + const std::string& type, const std::string& outdir, const std::string& gendir); + + /** + * @brief generate cbuild.yml or cbuild-gen.yml file * @param context pointer to the context + * @param reference to generator identifier + * @param reference to generator pack * @return true if executed successfully */ - static bool GenerateCbuild(ContextItem* context, const RteGenerator* generator = nullptr); + static bool GenerateCbuild(ContextItem* context, const std::string& generatorId = std::string(), const std::string& generatorPack = std::string()); /** * @brief generate cbuild set file diff --git a/tools/projmgr/include/ProjMgrYamlParser.h b/tools/projmgr/include/ProjMgrYamlParser.h index 08131b51e..5337e25ad 100644 --- a/tools/projmgr/include/ProjMgrYamlParser.h +++ b/tools/projmgr/include/ProjMgrYamlParser.h @@ -21,11 +21,15 @@ static constexpr const char* YAML_BASE_DIR = "base-dir"; static constexpr const char* YAML_BASE_NAME = "base-name"; static constexpr const char* YAML_BOARD = "board"; static constexpr const char* YAML_BUILD = "build"; +static constexpr const char* YAML_BUILD_GEN = "build-gen"; static constexpr const char* YAML_BUILD_IDX = "build-idx"; +static constexpr const char* YAML_BUILD_GEN_IDX = "build-gen-idx"; static constexpr const char* YAML_BUILDTYPES = "build-types"; static constexpr const char* YAML_CATEGORY = "category"; static constexpr const char* YAML_CBUILDS = "cbuilds"; static constexpr const char* YAML_CBUILD = "cbuild"; +static constexpr const char* YAML_CBUILD_GENS = "cbuild-gens"; +static constexpr const char* YAML_CBUILD_GEN = "cbuild-gen"; static constexpr const char* YAML_CBUILD_SET = "cbuild-set"; static constexpr const char* YAML_CDEFAULT = "cdefault"; static constexpr const char* YAML_CLAYERS = "clayers"; @@ -55,6 +59,7 @@ static constexpr const char* YAML_DEFINE = "define"; static constexpr const char* YAML_DELPATH = "del-path"; static constexpr const char* YAML_DESCRIPTION = "description"; static constexpr const char* YAML_DEVICE = "device"; +static constexpr const char* YAML_DOWNLOAD_URL = "download-url"; static constexpr const char* YAML_ENDIAN = "endian"; static constexpr const char* YAML_FILE = "file"; static constexpr const char* YAML_FILES = "files"; @@ -63,10 +68,12 @@ static constexpr const char* YAML_FORBOARD = "for-board"; static constexpr const char* YAML_FORCOMPILER = "for-compiler"; static constexpr const char* YAML_FORCONTEXT = "for-context"; static constexpr const char* YAML_FORDEVICE = "for-device"; +static constexpr const char* YAML_FORPROJECTPART = "for-project-part"; static constexpr const char* YAML_FPU = "fpu"; static constexpr const char* YAML_GENERATED_BY = "generated-by"; static constexpr const char* YAML_GENERATOR = "generator"; static constexpr const char* YAML_GENERATORS = "generators"; +static constexpr const char* YAML_GENERATOR_IMPORT = "generator-import"; static constexpr const char* YAML_GPDSC = "gpdsc"; static constexpr const char* YAML_GROUP = "group"; static constexpr const char* YAML_GROUPS = "groups"; @@ -108,9 +115,11 @@ static constexpr const char* YAML_PATH = "path"; static constexpr const char* YAML_PROCESSOR = "processor"; static constexpr const char* YAML_PROJECT = "project"; static constexpr const char* YAML_PROJECTS = "projects"; +static constexpr const char* YAML_PROJECT_TYPE = "project-type"; static constexpr const char* YAML_PROVIDES = "provides"; static constexpr const char* YAML_REGIONS = "regions"; static constexpr const char* YAML_RTE = "rte"; +static constexpr const char* YAML_RUN = "run"; static constexpr const char* YAML_SCOPE = "scope"; static constexpr const char* YAML_SCRIPT = "script"; static constexpr const char* YAML_SOLUTION = "solution"; @@ -121,6 +130,7 @@ static constexpr const char* YAML_SET = "set"; static constexpr const char* YAML_SWITCH = "switch"; static constexpr const char* YAML_TARGETTYPES = "target-types"; static constexpr const char* YAML_TRUSTZONE = "trustzone"; +static constexpr const char* YAML_CORE = "core"; static constexpr const char* YAML_TYPE = "type"; static constexpr const char* YAML_UNDEFINE = "undefine"; static constexpr const char* YAML_VARIABLES = "variables"; @@ -186,6 +196,17 @@ class ProjMgrYamlParser { * @return true if executed successfully */ bool ParseCbuildSet(const std::string& input, CbuildSetItem& cbuildSet); + + /** + * @brief parse global generator registry + * @param input generator.yml file + * @param reference to store parsed generator items + * @param checkSchema false to skip schema validation + * @return true if executed successfully + */ + bool ParseGlobalGenerator(const std::string& input, + std::map& generators, bool checkSchema); + protected: void ParseMisc(const YAML::Node& parent, std::vector& misc); void ParseDefine(const YAML::Node& parent, std::vector& define); diff --git a/tools/projmgr/include/ProjMgrYamlSchemaChecker.h b/tools/projmgr/include/ProjMgrYamlSchemaChecker.h index 266d861f5..ea2d8264f 100644 --- a/tools/projmgr/include/ProjMgrYamlSchemaChecker.h +++ b/tools/projmgr/include/ProjMgrYamlSchemaChecker.h @@ -21,7 +21,12 @@ class ProjMgrYamlSchemaChecker { PROJECT, LAYER, BUILD, - BUILDSET + BUILDIDX, + BUILDSET, + GENERATOR, + BUILDGEN, + BUILDGENIDX, + GENERATOR_IMPORT }; /** * @brief class constructor diff --git a/tools/projmgr/schemas/cbuild-gen-idx.schema.json b/tools/projmgr/schemas/cbuild-gen-idx.schema.json new file mode 100644 index 000000000..7965c9b3d --- /dev/null +++ b/tools/projmgr/schemas/cbuild-gen-idx.schema.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/schemas/projmgr/2.1.0/tools/projmgr/schemas/cbuild-gen-idx.schema.json", + "title": "CMSIS cbuild-gen-idx", + "description": "defines sibling contexts description for a generator call", + "version": "2.1.0", + "properties": { + "build": { + "$ref": "./common.schema.json#/definitions/BuildGenIdxDescType" + } + }, + "required": [ "build-gen-idx" ] +} diff --git a/tools/projmgr/schemas/cbuild-gen.schema.json b/tools/projmgr/schemas/cbuild-gen.schema.json new file mode 100644 index 000000000..784f6d29e --- /dev/null +++ b/tools/projmgr/schemas/cbuild-gen.schema.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/schemas/projmgr/2.1.0/tools/projmgr/schemas/cbuild-gen.schema.json", + "title": "CMSIS cbuild-gen", + "description": "defines an individual context description for a generator call", + "version": "2.1.0", + "properties": { + "build-gen": { + "$ref": "./common.schema.json#/definitions/BuildDescType" + } + }, + "required": [ "build-gen" ] +} diff --git a/tools/projmgr/schemas/cbuild-idx.schema.json b/tools/projmgr/schemas/cbuild-idx.schema.json new file mode 100644 index 000000000..c0ae5b29c --- /dev/null +++ b/tools/projmgr/schemas/cbuild-idx.schema.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/schemas/projmgr/2.1.0/tools/projmgr/schemas/cbuild-idx.schema.json", + "title": "CMSIS cbuild-idx", + "description": "defines a build description for a solution", + "version": "2.1.0", + "properties": { + "build": { + "$ref": "./common.schema.json#/definitions/BuildIdxDescType" + } + }, + "required": [ "build-idx" ] +} diff --git a/tools/projmgr/schemas/cgen.schema.json b/tools/projmgr/schemas/cgen.schema.json new file mode 100644 index 000000000..4208da69d --- /dev/null +++ b/tools/projmgr/schemas/cgen.schema.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/schemas/projmgr/2.1.0/tools/projmgr/schemas/cgen.schema.json", + "title": "CMSIS cgen", + "description": "set of source files and pre-configured components generated by external program", + "version": "2.1.0", + "properties": { + "layer": { + "$ref": "./common.schema.json#/definitions/GeneratorImportDescType" + } + }, + "required": [ "generator-import" ] +} diff --git a/tools/projmgr/schemas/common.schema.json b/tools/projmgr/schemas/common.schema.json index 31b03f613..4fd0a5cdd 100644 --- a/tools/projmgr/schemas/common.schema.json +++ b/tools/projmgr/schemas/common.schema.json @@ -159,8 +159,8 @@ "items": { "$ref": "#/definitions/ArtifactType" } }, "ArtifactType": { - "enum": [ "elf", "hex", "bin", "lib" ], - "description": "Output type: elf (default), hex, bin or lib" + "enum": [ "elf", "hex", "bin", "lib", "cmse-lib" ], + "description": "Output type: elf (default), hex, bin, lib or cmse-lib" }, "ArtifactsType": { "oneOf": [ @@ -254,11 +254,16 @@ "items": { "type": "string" } }, "MiscTypes": { - "type": "array", - "description": "List of miscellaneous literal tool-specific controls that are passed directly to the tools depending on the file type", - "uniqueItems": true, - "minItems": 1, - "items": { "$ref": "#/definitions/MiscType" } + "oneOf": [ + { + "type": "array", + "description": "List of miscellaneous literal tool-specific controls that are passed directly to the tools depending on the file type", + "uniqueItems": true, + "minItems": 1, + "items": { "$ref": "#/definitions/MiscType" } + }, + { "$ref": "#/definitions/MiscType" } + ] }, "MiscType": { "type": ["object", "null"], @@ -730,6 +735,47 @@ }, "additionalProperties": false }, + "BuildIdxDescType": { + "type": "object", + "properties": { + "generated-by": { "type": "string", "description": "Tool name along with version information used to generate this file" }, + "csolution": { "type": "string", "description": "Path to csolution.yml file" }, + "cprojects": { "$ref": "#/definitions/BuildProjectsType" }, + "cbuilds": { "$ref": "#/definitions/BuildContextsType" } + }, + "additionalProperties": false, + "required": ["generated-by", "csolution", "cprojects"] + }, + "BuildProjectsType": { + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { "$ref": "#/definitions/BuildProjectType", "description": "Paths to cproject.yml files" } + }, + "BuildProjectType": { + "type": "object", + "properties": { + "cproject": { "type": "string", "description": "Path to cproject.yml file" } + }, + "additionalProperties": false, + "required": ["cproject"] + }, + "BuildContextsType": { + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { "$ref": "#/definitions/BuildContextType", "description": "List of context related build information" } + }, + "BuildContextType": { + "type": "object", + "properties": { + "cbuild": { "type": "string", "description": "Path to .cbuild.yml file" }, + "project": { "type": "string", "description": "Project name" }, + "configuration": { "$ref": "#/definitions/BuildContext" } + }, + "additionalProperties": false, + "required": ["cproject"] + }, "BuildDescType": { "description": "The lock info that describes the resolved state of contexts and also can be used as input for generators", "type": "object", @@ -741,12 +787,12 @@ "current-generator": { "type": "object", "description": "What generator configuration to use", - "prorperties": { + "properties": { "from-pack": { "$ref": "#/definitions/PackID" }, "id": { "type": "string" } }, "additionalProperties": false, - "required": [ "from-pack", "id" ] + "required": [ "id" ] }, "solution": { "type": "string", @@ -761,6 +807,9 @@ "device": { "$ref": "#/definitions/DeviceType" }, "processor": { "$ref": "#/definitions/BuildProcessorType" }, "packs": { "$ref": "#/definitions/BuildPacksType" }, + "optimize": { "$ref": "#/definitions/OptimizeType" }, + "debug": { "$ref": "#/definitions/DebugType" }, + "warnings": { "$ref": "#/definitions/WarningsType" }, "misc": { "$ref": "#/definitions/MiscType" }, "define": { "$ref": "#/definitions/DefinesType" }, "add-path": { "$ref": "#/definitions/AddpathsType" }, @@ -1046,6 +1095,90 @@ }, "additionalProperties": false, "required": ["generated-by", "contexts"] + }, + "GeneratorRegistryDescType": { + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { "$ref": "#/definitions/GeneratorRegistryType", "description": "List of global generator description" } + }, + "GeneratorRegistryType": { + "type": "object", + "properties": { + "id": { "type": "string", "description": "Generator identifier" }, + "download-url": { "type": "string", "description": "URL for downloading generator tool" }, + "run": { "type": "string", "description": "Related bridge program" }, + "path": { "type": "string", "description": "Specifies the directory for generated files" } + }, + "additionalProperties": false, + "required": ["id", "run", "path"] + }, + "BuildGenIdxDescType": { + "type": "object", + "properties": { + "generated-by": { "type": "string", "description": "Tool name along with version information used to generate this file" }, + "generators": { "$ref": "#/definitions/BuildGeneratorsType", "description": "List of generators to be run" }, + "compiler": { "type": "string", "description": "Selection of compiler used" } + }, + "additionalProperties": false, + "required": ["generated-by", "generators"] + }, + "BuildGeneratorsType": { + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { "$ref": "#/definitions/BuildGeneratorType", "description": "Build Generator solution related information" } + }, + "BuildGeneratorType": { + "type": "object", + "properties": { + "id": { "type": "string", "description": "Generator identifier" }, + "output": { "type": "string", "description": "Specifies the directory for generated files" }, + "board": { "$ref": "#/definitions/BoardType" }, + "device": { "$ref": "#/definitions/DeviceType" }, + "project-type": { "$ref": "#/definitions/BuildGeneratorProjectType" }, + "cbuild-gens": { "$ref": "#/definitions/BuildGeneratorContextsType" } + }, + "additionalProperties": false, + "required": ["id", "output", "project-type", "cbuild-gens"] + }, + "BuildGeneratorProjectType": { + "enum": [ "single-core", "multi-core", "trustzone" ], + "description": "Project type (single-core, multi-core, trustzone)." + }, + "BuildGeneratorContextsType": { + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { "$ref": "#/definitions/BuildGeneratorContextType", "description": "Build Generator context related information" } + }, + "BuildGeneratorContextType": { + "type": "object", + "properties": { + "cbuild-gen": { "type": "string", "description": "Path to .cbuild-gen.yml file" }, + "project": { "type": "string", "description": "Project name" }, + "configuration": { "$ref": "#/definitions/BuildContext" }, + "for-project-part": { "type": "string", "description": "For project part (secure, non-secure, )" } + }, + "additionalProperties": false, + "required": ["id", "output", "project-type", "cbuild-gens"] + }, + "GeneratorImportDescType": { + "type": "object", + "description": "This section describes generated contents", + "properties": { + "generated-by": { "type": "string", "description": "Tool name along with version information used to generate this file" }, + "for-board": { "$ref": "#/definitions/BoardType" }, + "for-device": { "$ref": "#/definitions/DeviceType" }, + "packs": { "$ref": "#/definitions/PacksType" }, + "define": { "$ref": "#/definitions/DefinesType" }, + "undefine": { "$ref": "#/definitions/UndefinesType" }, + "add-path": { "$ref": "#/definitions/AddpathsType" }, + "del-path": { "$ref": "#/definitions/DelpathsType" }, + "groups": { "$ref": "#/definitions/GroupsType" }, + "components": { "$ref": "#/definitions/ComponentsType" } + }, + "additionalProperties": false } } } diff --git a/tools/projmgr/schemas/generator.schema.json b/tools/projmgr/schemas/generator.schema.json new file mode 100644 index 000000000..cba5cb790 --- /dev/null +++ b/tools/projmgr/schemas/generator.schema.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/schemas/projmgr/2.1.0/tools/projmgr/schemas/generator.schema.json", + "title": "CMSIS generator registry", + "description": "defines global generator registry", + "version": "2.1.0", + "properties": { + "generator": { + "$ref": "./common.schema.json#/definitions/GeneratorRegistryDescType" + } + }, + "required": [ "generator" ] +} diff --git a/tools/projmgr/src/ProjMgr.cpp b/tools/projmgr/src/ProjMgr.cpp index e47c9d933..2417d9493 100644 --- a/tools/projmgr/src/ProjMgr.cpp +++ b/tools/projmgr/src/ProjMgr.cpp @@ -56,8 +56,13 @@ Options:\n\ Use 'csolution -h' for more information about a command.\n\ "; -ProjMgr::ProjMgr(void) : m_checkSchema(false), m_updateRteFiles(true) { - m_worker.SetParser(&m_parser); +ProjMgr::ProjMgr(void) : + m_parser(), + m_extGenerator(&m_parser), + m_worker(&m_parser, &m_extGenerator), + m_checkSchema(false), + m_updateRteFiles(true) { + // Reserved } ProjMgr::~ProjMgr(void) { @@ -170,6 +175,7 @@ int ProjMgr::RunProjMgr(int argc, char **argv, char** envp) { parseResult = options.parse(argc, argv); manager.m_checkSchema = !parseResult.count("n"); manager.m_worker.SetCheckSchema(manager.m_checkSchema); + manager.m_extGenerator.SetCheckSchema(manager.m_checkSchema); manager.m_missingPacks = parseResult.count("m"); manager.m_updateRteFiles = !parseResult.count("no-update-rte"); manager.m_verbose = parseResult.count("v"); @@ -430,6 +436,11 @@ bool ProjMgr::PopulateContexts(void) { // Retrieve all context types m_worker.RetrieveAllContextTypes(); + // Retrieve global generators + if (!m_extGenerator.RetrieveGlobalGenerators()) { + return false; + } + return true; } @@ -739,9 +750,16 @@ bool ProjMgr::RunCodeGenerator(void) { if (!m_worker.ParseContextSelection(m_context, m_contextReplacement)) { return false; } - // Run code generator - if (!m_worker.ExecuteGenerator(m_codeGenerator)) { - return false; + if (m_extGenerator.IsGlobalGenerator(m_codeGenerator)) { + // Run global code generator + if (!m_worker.ExecuteExtGenerator(m_codeGenerator)) { + return false; + } + } else { + // Run legacy code generator + if (!m_worker.ExecuteGenerator(m_codeGenerator)) { + return false; + } } return true; } diff --git a/tools/projmgr/src/ProjMgrExtGenerator.cpp b/tools/projmgr/src/ProjMgrExtGenerator.cpp new file mode 100644 index 000000000..49ca2cee9 --- /dev/null +++ b/tools/projmgr/src/ProjMgrExtGenerator.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2020-2023 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ProjMgrExtGenerator.h" +#include "ProjMgrLogger.h" +#include "ProjMgrYamlEmitter.h" + +#include "RteFsUtils.h" + +using namespace std; + +ProjMgrExtGenerator::ProjMgrExtGenerator(ProjMgrParser* parser) : + m_parser(parser), + m_checkSchema(false) { +} + +ProjMgrExtGenerator::~ProjMgrExtGenerator(void) { + // Reserved +} + +void ProjMgrExtGenerator::SetCheckSchema(bool checkSchema) { + m_checkSchema = checkSchema; +} + +bool ProjMgrExtGenerator::RetrieveGlobalGenerators(void) { + if (m_globalGeneratorFiles.empty()) { + // get global generator files + ProjMgrUtils::GetCompilerRoot(m_compilerRoot); + StrVec toolchainConfigFiles; + error_code ec; + for (auto const& entry : fs::recursive_directory_iterator(m_compilerRoot, ec)) { + if (entry.path().filename().string().find(".generator.yml") == string::npos) { + continue; + } + m_globalGeneratorFiles.push_back(entry.path().generic_string()); + } + // parse global generator files + for (auto const& generatorFile : m_globalGeneratorFiles) { + if (!m_parser->ParseGlobalGenerator(generatorFile, m_checkSchema)) { + return false; + } + } + m_globalGenerators = m_parser->GetGlobalGenerators(); + } + return true; +} + +bool ProjMgrExtGenerator::IsGlobalGenerator(const string& generatorId) { + if (m_globalGenerators.find(generatorId) == m_globalGenerators.end()) { + return false; + } + return true; +} + +bool ProjMgrExtGenerator::CheckGeneratorId(const string& generatorId, const string& componentId) { + if (!IsGlobalGenerator(generatorId)) { + ProjMgrLogger::Error("generator '" + generatorId + "' required by component '" + + componentId + "' was not found in global register"); + return false; + } + return true; +} + +const string& ProjMgrExtGenerator::GetGlobalGenDir(const string& generatorId) { + return(m_globalGenerators[generatorId].path); +} + +const string& ProjMgrExtGenerator::GetGlobalGenRunCmd(const string& generatorId) { + return(m_globalGenerators[generatorId].run); +} + + +void ProjMgrExtGenerator::AddUsedGenerator(const string& generatorId, const string& genDir, const string& contextId) { + m_usedGenerators[generatorId][genDir].push_back(contextId); +} + +const GeneratorContextVecMap& ProjMgrExtGenerator::GetUsedGenerators(void) { + return m_usedGenerators; +} + +ClayerItem* ProjMgrExtGenerator::GetGeneratorImport(const string& contextId, bool& success) { + ContextName context; + ProjMgrUtils::ParseContextEntry(contextId, context); + success = true; + for (const auto& [generator, genDirs] : GetUsedGenerators()) { + for (const auto& [genDir, contexts] : genDirs) { + if (find(contexts.begin(), contexts.end(), contextId) != contexts.end()) { + const string cgenFile = fs::path(genDir).append(context.project + ".cgen.yml").generic_string(); + if (!RteFsUtils::Exists(cgenFile)) { + ProjMgrLogger::Error(cgenFile, "cgen file was not found, run generator '" + generator + "' for context '" + contextId + "'"); + success = false; + return nullptr; + } + if (!m_parser->ParseClayer(cgenFile, m_checkSchema)) { + success = false; + return nullptr; + } + return &m_parser->GetClayers().at(cgenFile); + } + } + } + return nullptr; +} diff --git a/tools/projmgr/src/ProjMgrParser.cpp b/tools/projmgr/src/ProjMgrParser.cpp index c633f7050..cb3205b07 100644 --- a/tools/projmgr/src/ProjMgrParser.cpp +++ b/tools/projmgr/src/ProjMgrParser.cpp @@ -54,6 +54,11 @@ bool ProjMgrParser::ParseCbuildSet(const string& input) { return ProjMgrYamlParser().ParseCbuildSet(input, m_cbuildSet); } +bool ProjMgrParser::ParseGlobalGenerator(const string& input, bool checkSchema) { + // Parse generic layer file + return ProjMgrYamlParser().ParseGlobalGenerator(input, m_globalGenerators, checkSchema); +} + CdefaultItem& ProjMgrParser::GetCdefault(void) { return m_cdefault; } @@ -77,3 +82,7 @@ map& ProjMgrParser::GetGenericClayers(void) { CbuildSetItem& ProjMgrParser::GetCbuildSetItem(void) { return m_cbuildSet; } + +map& ProjMgrParser::GetGlobalGenerators(void) { + return m_globalGenerators; +} diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index 764b02011..e91dc13a7 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -37,7 +37,9 @@ static const map> { "IAR", {ProjMgrUtils::IAR_ELF_SUFFIX , ProjMgrUtils::IAR_LIB_PREFIX , ProjMgrUtils::IAR_LIB_SUFFIX }}, }; -ProjMgrWorker::ProjMgrWorker(void) : +ProjMgrWorker::ProjMgrWorker(ProjMgrParser* parser, ProjMgrExtGenerator* extGenerator) : + m_parser(parser), + m_extGenerator(extGenerator), m_loadPacksPolicy(LoadPacksPolicy::DEFAULT), m_checkSchema(false), m_verbose(false), @@ -57,10 +59,6 @@ ProjMgrWorker::~ProjMgrWorker(void) { } } -void ProjMgrWorker::SetParser(ProjMgrParser* parser) { - m_parser = parser; -} - bool ProjMgrWorker::AddContexts(ProjMgrParser& parser, ContextDesc& descriptor, const string& cprojectFile) { error_code ec; ContextItem context; @@ -287,7 +285,6 @@ bool ProjMgrWorker::GetRequiredPdscFiles(ContextItem& context, const std::string + "' specified with 'path' must not have a version"); } string packPath = packItem.path; - RteFsUtils::NormalizePath(packPath, context.csolution->directory + "/"); if (!RteFsUtils::Exists(packPath)) { errMsgs.insert("pack path: " + packItem.path + " does not exist"); break; @@ -627,7 +624,7 @@ bool ProjMgrWorker::ProcessCandidateLayers(ContextItem& context, LayersDiscoveri for (const auto& clayer : clayers) { const ClayerItem& clayerItem = m_parser->GetGenericClayers()[clayer]; if (!clayerItem.forBoard.empty() || !clayerItem.forDevice.empty()) { - packRequirements.insert(packRequirements.end(), clayerItem.packs.begin(), clayerItem.packs.end()); + InsertPackRequirements(clayerItem.packs, packRequirements, clayerItem.directory); } } } @@ -1260,6 +1257,9 @@ bool ProjMgrWorker::ProcessDevice(ContextItem& context) { } context.packages.insert({ matchedDevice->GetPackageID(true), matchedDevice->GetPackage() }); + GetDeviceItem(context.device, context.deviceItem); + context.variables[ProjMgrUtils::AS_DNAME] = context.deviceItem.name; + context.variables[ProjMgrUtils::AS_PNAME] = context.deviceItem.pname; return true; } @@ -1302,20 +1302,29 @@ bool ProjMgrWorker::ProcessPackages(ContextItem& context) { // Solution package requirements if (context.csolution) { - packRequirements.insert(packRequirements.end(), context.csolution->packs.begin(), context.csolution->packs.end()); + InsertPackRequirements(context.csolution->packs, packRequirements, context.csolution->directory); } // Project package requirements if (context.cproject) { - packRequirements.insert(packRequirements.end(), context.cproject->packs.begin(), context.cproject->packs.end()); + InsertPackRequirements(context.cproject->packs, packRequirements, context.cproject->directory); } // Layers package requirements for (const auto& [_, clayer] : context.clayers) { - packRequirements.insert(packRequirements.end(), clayer->packs.begin(), clayer->packs.end()); + InsertPackRequirements(clayer->packs, packRequirements, clayer->directory); } AddPackRequirements(context, packRequirements); return true; } +void ProjMgrWorker::InsertPackRequirements(const vector& src, vector& dst, string base) { + for (auto item : src) { + if (!item.path.empty()) { + RteFsUtils::NormalizePath(item.path, base); + } + dst.push_back(item); + } +} + bool ProjMgrWorker::AddPackRequirements(ContextItem& context, const vector packRequirements) { // Filter context specific package requirements vector packages; @@ -1431,6 +1440,22 @@ bool ProjMgrWorker::ProcessComponents(ContextItem& context) { error_code ec; const string& gpdsc = fs::weakly_canonical(generator->GetExpandedGpdsc(context.rteActiveTarget, genDir), ec).generic_string(); context.gpdscs.insert({ gpdsc, {componentId, generatorId, genDir} }); + } else { + // Get external generator id + const string extGenId = matchedComponent->GetGeneratorName(); + if (!extGenId.empty()) { + // check if required global generator is registered + if (!m_extGenerator->CheckGeneratorId(extGenId, componentId)) { + return false; + } + string genDir; + if (!GetExtGeneratorDir(extGenId, context, layer, genDir)) { + return false; + } + // keep track of used generators + m_extGenerator->AddUsedGenerator(extGenId, genDir, context.name); + context.extGenDir[extGenId] = genDir; + } } // Insert matched component into context list @@ -1945,17 +1970,20 @@ void ProjMgrWorker::MergeStringVector(StringVectorCollection& item) { } } -bool ProjMgrWorker::ProcessPrecedences(ContextItem& context) { +bool ProjMgrWorker::ProcessPrecedences(ContextItem& context, bool rerun) { // Notes: defines, includes and misc are additive. All other keywords overwrite previous settings. // The target-type and build-type definitions are additive, but an attempt to // redefine an already existing type results in an error. // The settings of the target-type are processed first; then the settings of the // build-type that potentially overwrite the target-type settings. - if (context.precedences) { + if (!rerun && context.precedences) { return true; } context.precedences = true; + context.components.clear(); + context.componentRequirements.clear(); + context.groups.clear(); // Get content of build and target types if (!GetTypeContent(context)) { @@ -2050,7 +2078,7 @@ bool ProjMgrWorker::ProcessPrecedences(ContextItem& context) { // after board, device and compiler precedences (due to $Bname$, $Dname$ and $Compiler$) // after output filenames (due to $Output$) // but before processing misc, defines and includes precedences - if (!ProcessSequencesRelatives(context)) { + if (!ProcessSequencesRelatives(context, rerun)) { return false; } @@ -2359,16 +2387,16 @@ bool ProjMgrWorker::ProcessLinkerOptions(ContextItem& context, const LinkerItem& return true; } - -bool ProjMgrWorker::ProcessSequencesRelatives(ContextItem& context) { - - // directories - const string ref = m_outputDir.empty() ? context.csolution->directory : RteFsUtils::AbsolutePath(m_outputDir).generic_string(); - if (!ProcessSequenceRelative(context, context.directories.cprj) || +bool ProjMgrWorker::ProcessSequencesRelatives(ContextItem & context, bool rerun) { + if (!rerun) { + // directories + const string ref = m_outputDir.empty() ? context.csolution->directory : RteFsUtils::AbsolutePath(m_outputDir).generic_string(); + if (!ProcessSequenceRelative(context, context.directories.cprj) || !ProcessSequenceRelative(context, context.directories.rte, context.cproject->directory) || !ProcessSequenceRelative(context, context.directories.outdir, ref) || !ProcessSequenceRelative(context, context.directories.intdir, ref)) { - return false; + return false; + } } // project, solution, target-type and build-type translation controls @@ -2492,6 +2520,9 @@ bool ProjMgrWorker::ProcessSequenceRelative(ContextItem& context, string& item, auto& refContext = m_contexts.at(contextName); // process referenced context precedences if needed if (!refContext.precedences) { + if (!ParseContextLayers(refContext)) { + return false; + } if (!ProcessPrecedences(refContext)) { return false; } @@ -2783,7 +2814,7 @@ void ProjMgrWorker::PrintMissingFilters(void) { } } -bool ProjMgrWorker::ProcessContext(ContextItem& context, bool loadGpdsc, bool resolveDependencies, bool updateRteFiles) { +bool ProjMgrWorker::ProcessContext(ContextItem& context, bool loadGenFiles, bool resolveDependencies, bool updateRteFiles) { if (!LoadPacks(context)) { return false; } @@ -2806,10 +2837,13 @@ bool ProjMgrWorker::ProcessContext(ContextItem& context, bool loadGpdsc, bool re if (!ProcessComponents(context)) { return false; } - if (loadGpdsc) { + if (loadGenFiles) { if (!ProcessGpdsc(context)) { return false; } + if (!ProcessGeneratedLayers(context)) { + return false; + } } if (!ProcessConfigFiles(context)) { return false; @@ -3193,6 +3227,9 @@ bool ProjMgrWorker::ListGenerators(vector& generators) { generatorsSet.insert(id + " (" + generator->GetDescription() + ")"); } } + for (const auto& [id, _] : m_extGenerator->GetUsedGenerators()) { + generatorsSet.insert(id + " (Global Registered Generator)"); + } generators.assign(generatorsSet.begin(), generatorsSet.end()); return true; } @@ -3423,7 +3460,8 @@ bool ProjMgrWorker::ExecuteGenerator(std::string& generatorId) { generatorDestination += '/'; } - if (!ProjMgrYamlEmitter::GenerateCbuild(&context, generator)) { + if (!ProjMgrYamlEmitter::GenerateCbuild(&context, generator->GetGeneratorName(), + RtePackage::GetPackageIDfromAttributes(*generator->GetPackage()))) { return false; } @@ -3863,6 +3901,50 @@ bool ProjMgrWorker::GetGeneratorDir(const RteGenerator* generator, ContextItem& const string generatorId = generator->GetID(); genDir.clear(); + // from 'generators' node + if (!GetGeneratorDir(generatorId, context, layer, genDir)) { + return false; + } + + if (!genDir.empty()) { + genDir = RteFsUtils::RelativePath(genDir, context.cproject->directory); + } else { + // original working dir from PDSC + if (!generator->GetWorkingDir().empty()) { + genDir = RteFsUtils::RelativePath(generator->GetExpandedWorkingDir(context.rteActiveTarget), context.cproject->directory); + if (!layer.empty()) { + // adjust genDir if component belongs to layer + genDir = RteFsUtils::RelativePath(fs::path(context.clayers.at(layer)->directory).append(genDir).generic_string(), context.cproject->directory); + } + } else { + // default: $ProjectDir()$/generated/ + genDir = fs::path("generated").append(generatorId).generic_string(); + } + } + return true; +} + +bool ProjMgrWorker::GetExtGeneratorDir(const string& generatorId, ContextItem& context, const string& layer, string& genDir) { + // from 'generators' node + if (!GetGeneratorDir(generatorId, context, layer, genDir)) { + return false; + } + if (genDir.empty()) { + // from global register + genDir = m_extGenerator->GetGlobalGenDir(generatorId); + if (!ProcessSequenceRelative(context, genDir, layer.empty() ? context.cproject->directory : context.clayers.at(layer)->directory)) { + return false; + } + } + if (genDir.empty()) { + ProjMgrLogger::Error("generator output directory was not set"); + return false; + } + RteFsUtils::NormalizePath(genDir, context.directories.cprj); + return true; +} + +bool ProjMgrWorker::GetGeneratorDir(const string& generatorId, ContextItem& context, const string& layer, string& genDir) { // map with GeneratorsItem and base reference (clayer, cproject or csolution directory) const vector> generatorsList = { layer.empty() ? pair() : make_pair(context.clayers.at(layer)->generators, context.clayers.at(layer)->directory), @@ -3878,7 +3960,7 @@ bool ProjMgrWorker::GetGeneratorDir(const RteGenerator* generator, ContextItem& if (!ProcessSequenceRelative(context, genDir, ref)) { return false; } - genDir = RteFsUtils::RelativePath(fs::path(context.directories.cprj).append(genDir).generic_string(), context.cproject->directory); + RteFsUtils::NormalizePath(genDir, context.directories.cprj); break; } } @@ -3891,24 +3973,12 @@ bool ProjMgrWorker::GetGeneratorDir(const RteGenerator* generator, ContextItem& if (!ProcessSequenceRelative(context, genDir, ref)) { return false; } - genDir = RteFsUtils::RelativePath(fs::path(context.directories.cprj).append(genDir).append(generatorId).generic_string(), context.cproject->directory); + genDir = fs::path(genDir).append(generatorId).generic_string(); + RteFsUtils::NormalizePath(genDir, context.directories.cprj); break; } } } - if (genDir.empty()) { - // original working dir from PDSC - if (!generator->GetWorkingDir().empty()) { - genDir = RteFsUtils::RelativePath(generator->GetExpandedWorkingDir(context.rteActiveTarget), context.cproject->directory); - if (!layer.empty()) { - // adjust genDir if component belongs to layer - genDir = RteFsUtils::RelativePath(fs::path(context.clayers.at(layer)->directory).append(genDir).generic_string(), context.cproject->directory); - } - } else { - // default: $ProjectDir()$/generated/ - genDir = fs::path("generated").append(generatorId).generic_string(); - } - } return true; } @@ -3941,3 +4011,135 @@ bool ProjMgrWorker::ListConfigFiles(vector& configFiles) { std::string ProjMgrWorker::GetSelectedToochain(void) { return m_selectedToolchain; } + +bool ProjMgrWorker::ProcessGlobalGenerators(ContextItem* selectedContext, const string& generatorId, + string& projectType, StrVec& siblings) { + + // iterate over contexts with same build and target types + for (auto& [_, context] : m_contexts) { + if ((context.type.build != selectedContext->type.build) || + (context.type.target != selectedContext->type.target)) { + continue; + } + if (!ParseContextLayers(context)) { + return false; + } + if (!ProcessContext(context, false, true, false)) { + return false; + } + } + const string& genDir = selectedContext->extGenDir[generatorId]; + const auto& contextVec = m_extGenerator->GetUsedGenerators().at(generatorId).at(genDir); + + // classify generator contexts according to device, processor and project name + map> classifiedMap; + for (const auto& contextId : contextVec) { + auto& context = m_contexts[contextId]; + DeviceItem deviceItem; + GetDeviceItem(context.device, deviceItem); + classifiedMap[deviceItem.name][deviceItem.pname][context.cproject->name] = contextId; + } + + // find project-type related contexts + StrVecMap projectTypeMap; + for (const auto& [device, processors] : classifiedMap) { + for (const auto& [processor, projects] : processors) { + for (const auto& [project, context] : projects) { + string type; + if (processors.size() >= 2) { + type = TYPE_MULTI_CORE; + } else { + const auto& trustzone = m_contexts[context].controls.processed.processor.trustzone; + type = (trustzone.empty() || trustzone == "off") ? TYPE_SINGLE_CORE : TYPE_TRUSTZONE; + } + projectTypeMap[type].push_back(context); + } + } + } + + // get selected context project-type and siblings + for (const auto& [type, contexts] : projectTypeMap) { + if (find(contexts.begin(), contexts.end(), selectedContext->name) != contexts.end()) { + projectType = type; + siblings = contexts; + return true; + } + } + return false; +} + +bool ProjMgrWorker::ExecuteExtGenerator(std::string& generatorId) { + if (m_selectedContexts.size() != 1) { + ProjMgrLogger::Error("a single context must be specified"); + return false; + } + const string& selectedContextId = m_selectedContexts.front(); + ContextItem* selectedContext = &m_contexts[selectedContextId]; + string projectType; + StrVec siblings; + if (!ProcessGlobalGenerators(selectedContext, generatorId, projectType, siblings)) { + return false; + } + const string& genDir = selectedContext->extGenDir[generatorId]; + vector siblingContexts; + for (const auto& sibling : siblings) { + siblingContexts.push_back(&m_contexts[sibling]); + } + + // Generate cbuild-gen files + string cbuildgenOutput = selectedContext->directories.intdir; + RteFsUtils::NormalizePath(cbuildgenOutput, selectedContext->directories.cprj); + if (!ProjMgrYamlEmitter::GenerateCbuildGenIndex(*m_parser, siblingContexts, projectType, cbuildgenOutput, genDir)) { + return false; + } + for (const auto& siblingContext : siblingContexts) { + if (!ProjMgrYamlEmitter::GenerateCbuild(siblingContext, generatorId)) { + return false; + } + } + + // Execute generator command + string runCmd = m_extGenerator->GetGlobalGenRunCmd(generatorId); + RteFsUtils::NormalizePath(runCmd, m_compilerRoot); + runCmd += " " + fs::path(cbuildgenOutput).append(m_parser->GetCsolution().name + ".cbuild-gen-idx.yml").generic_string(); + error_code ec; + const auto& workingDir = fs::current_path(ec); + fs::current_path(genDir, ec); + ProjMgrUtils::Result result = ProjMgrUtils::ExecCommand(runCmd); + fs::current_path(workingDir, ec); + ProjMgrLogger::Info("generator '" + generatorId + "' for context '" + selectedContextId + "' reported:\n" + result.first); + if (result.second) { + ProjMgrLogger::Error("executing generator '" + generatorId + "' for context '" + selectedContextId + "' failed"); + return false; + } + return true; +} + +bool ProjMgrWorker::ProcessGeneratedLayers(ContextItem& context) { + bool success; + ClayerItem* cgen = m_extGenerator->GetGeneratorImport(context.name, success); + if (!success) { + return false; + } + if (cgen) { + context.clayers[cgen->path] = cgen; + if (cgen->packs.size() > 0) { + vector packRequirements; + InsertPackRequirements(cgen->packs, packRequirements, cgen->directory); + AddPackRequirements(context, packRequirements); + if (!LoadAllRelevantPacks() || !LoadPacks(context)) { + return false; + } + } + if (!ProcessPrecedences(context, true)) { + return false; + } + if (!ProcessGroups(context)) { + return false; + } + if (!ProcessComponents(context)) { + return false; + } + } + return true; +} diff --git a/tools/projmgr/src/ProjMgrYamlEmitter.cpp b/tools/projmgr/src/ProjMgrYamlEmitter.cpp index 5e824d9b5..6879d1928 100644 --- a/tools/projmgr/src/ProjMgrYamlEmitter.cpp +++ b/tools/projmgr/src/ProjMgrYamlEmitter.cpp @@ -43,8 +43,9 @@ class ProjMgrYamlCbuild : public ProjMgrYamlBase { private: friend class ProjMgrYamlEmitter; ProjMgrYamlCbuild(YAML::Node node, const vector processedContexts, const string& selectedCompiler); - ProjMgrYamlCbuild(YAML::Node node, const ContextItem* context, const RteGenerator* generator); - void SetContextNode(YAML::Node node, const ContextItem* context); + ProjMgrYamlCbuild(YAML::Node node, const ContextItem* context, const string& generatorId, const string& generatorPack); + ProjMgrYamlCbuild(YAML::Node node, const vector siblings, const string& type, const string& output, const string& gendir); + void SetContextNode(YAML::Node node, const ContextItem* context, const string& generatorId, const string& generatorPack); void SetComponentsNode(YAML::Node node, const ContextItem* context); void SetComponentFilesNode(YAML::Node node, const ContextItem* context, const string& componentId); void SetGeneratorsNode(YAML::Node node, const ContextItem* context); @@ -62,7 +63,6 @@ class ProjMgrYamlCbuild : public ProjMgrYamlBase { void SetMiscNode(YAML::Node miscNode, const MiscItem& misc); void SetMiscNode(YAML::Node miscNode, const vector& misc); void SetDefineNode(YAML::Node node, const vector& vec); - const RteGenerator* m_generator; }; class ProjMgrYamlCbuildIdx : public ProjMgrYamlBase { @@ -126,12 +126,10 @@ ProjMgrYamlCbuildIdx::ProjMgrYamlCbuildIdx(YAML::Node node, const vectorGetGeneratorName()); - SetNodeValue(node[YAML_FROM_PACK], RtePackage::GetPackageIDfromAttributes(*m_generator->GetPackage())); + if (!generatorId.empty()) { + YAML::Node generatorNode = contextNode[YAML_CURRENT_GENERATOR]; + SetNodeValue(generatorNode[YAML_ID], generatorId); + SetNodeValue(generatorNode[YAML_FROM_PACK], generatorPack); } - - SetNodeValue(contextNode[YAML_SOLUTION], FormatPath(context->csolution->path, context->directories.cprj)); - SetNodeValue(contextNode[YAML_PROJECT], FormatPath(context->cproject->path, context->directories.cprj)); + SetNodeValue(contextNode[YAML_SOLUTION], FormatPath(context->csolution->path, context->directories.cbuild)); + SetNodeValue(contextNode[YAML_PROJECT], FormatPath(context->cproject->path, context->directories.cbuild)); SetNodeValue(contextNode[YAML_CONTEXT], context->name); SetNodeValue(contextNode[YAML_COMPILER], context->compiler); SetNodeValue(contextNode[YAML_BOARD], context->board); @@ -183,7 +179,7 @@ void ProjMgrYamlCbuild::SetContextNode(YAML::Node contextNode, const ContextItem }) { for (auto include : targetIncludes) { RteFsUtils::NormalizePath(include, context->cproject->directory); - ProjMgrUtils::PushBackUniquely(includes, FormatPath(include, context->directories.cprj)); + ProjMgrUtils::PushBackUniquely(includes, FormatPath(include, context->directories.cbuild)); } } SetNodeValue(contextNode[YAML_ADDPATH], includes); @@ -208,7 +204,7 @@ void ProjMgrYamlCbuild::SetComponentsNode(YAML::Node node, const ContextItem* co SetNodeValue(componentNode[YAML_SELECTED_BY], componentItem->component); const string& rteDir = rteComponent->GetAttribute("rtedir"); if (!rteDir.empty()) { - SetNodeValue(componentNode[YAML_OUTPUT_RTEDIR], FormatPath(context->cproject->directory + "/" + rteDir, context->directories.cprj)); + SetNodeValue(componentNode[YAML_OUTPUT_RTEDIR], FormatPath(context->cproject->directory + "/" + rteDir, context->directories.cbuild)); } SetControlsNode(componentNode, context, componentItem->build); SetComponentFilesNode(componentNode[YAML_FILES], context, componentId); @@ -230,7 +226,7 @@ void ProjMgrYamlCbuild::SetComponentFilesNode(YAML::Node node, const ContextItem if (context->componentFiles.find(componentId) != context->componentFiles.end()) { for (const auto& [file, attr, category, language, scope, version] : context->componentFiles.at(componentId)) { YAML::Node fileNode; - SetNodeValue(fileNode[YAML_FILE], FormatPath(file, context->directories.cprj)); + SetNodeValue(fileNode[YAML_FILE], FormatPath(file, context->directories.cbuild)); SetNodeValue(fileNode[YAML_CATEGORY], category); SetNodeValue(fileNode[YAML_ATTR], attr); SetNodeValue(fileNode[YAML_LANGUAGE], language); @@ -246,7 +242,7 @@ void ProjMgrYamlCbuild::SetGeneratorFiles(YAML::Node node, const ContextItem* co YAML::Node filesNode; for (const auto& [file, attr, category, language, scope, version] : context->generatorInputFiles.at(componentId)) { YAML::Node fileNode; - SetNodeValue(fileNode[YAML_FILE], FormatPath(file, context->directories.cprj)); + SetNodeValue(fileNode[YAML_FILE], FormatPath(file, context->directories.cbuild)); SetNodeValue(fileNode[YAML_CATEGORY], category); SetNodeValue(fileNode[YAML_ATTR], attr); SetNodeValue(fileNode[YAML_LANGUAGE], language); @@ -272,8 +268,8 @@ void ProjMgrYamlCbuild::SetGeneratorsNode(YAML::Node node, const ContextItem* co } } SetNodeValue(genNode[YAML_FROM_PACK], RtePackage::GetPackageIDfromAttributes(*generator->GetPackage())); - SetNodeValue(genNode[YAML_PATH], FormatPath(workingDir, context->directories.cprj)); - SetNodeValue(genNode[YAML_GPDSC], FormatPath(gpdscFile, context->directories.cprj)); + SetNodeValue(genNode[YAML_PATH], FormatPath(workingDir, context->directories.cbuild)); + SetNodeValue(genNode[YAML_GPDSC], FormatPath(gpdscFile, context->directories.cbuild)); for (const string host : {"win", "linux", "mac", "other"}) { YAML::Node commandNode; @@ -282,7 +278,7 @@ void ProjMgrYamlCbuild::SetGeneratorsNode(YAML::Node node, const ContextItem* co const string exe = generator->GetExecutable(context->rteActiveTarget, host); if (exe.empty()) continue; - commandNode[YAML_FILE] = FormatPath(exe, context->directories.cprj); + commandNode[YAML_FILE] = FormatPath(exe, context->directories.cbuild); // Arguments YAML::Node argumentsNode; @@ -307,7 +303,7 @@ void ProjMgrYamlCbuild::SetPacksNode(YAML::Node node, const ContextItem* context for (const auto& [packId, package] : context->packages) { YAML::Node packNode; SetNodeValue(packNode[YAML_PACK], packId); - const string& pdscFilename = FormatPath(package->GetPackageFileName(), context->directories.cprj); + const string& pdscFilename = FormatPath(package->GetPackageFileName(), context->directories.cbuild); SetNodeValue(packNode[YAML_PATH], fs::path(pdscFilename).parent_path().generic_string()); node.push_back(packNode); } @@ -345,7 +341,7 @@ void ProjMgrYamlCbuild::SetConstructedFilesNode(YAML::Node node, const ContextIt const string& filename = context->rteActiveProject->GetProjectPath() + context->rteActiveProject->GetRteHeader(file, context->rteActiveTarget->GetName(), ""); YAML::Node fileNode; - SetNodeValue(fileNode[YAML_FILE], FormatPath(filename, context->directories.cprj)); + SetNodeValue(fileNode[YAML_FILE], FormatPath(filename, context->directories.cbuild)); SetNodeValue(fileNode[YAML_CATEGORY], "preIncludeGlobal"); node.push_back(fileNode); } @@ -356,7 +352,7 @@ void ProjMgrYamlCbuild::SetConstructedFilesNode(YAML::Node node, const ContextIt const auto& rteComponents = context->rteActiveProject->GetProjectPath() + context->rteActiveProject->GetRteComponentsH(context->rteActiveTarget->GetName(), ""); YAML::Node rteComponentsNode; - SetNodeValue(rteComponentsNode[YAML_FILE], FormatPath(rteComponents, context->directories.cprj)); + SetNodeValue(rteComponentsNode[YAML_FILE], FormatPath(rteComponents, context->directories.cbuild)); SetNodeValue(rteComponentsNode[YAML_CATEGORY], "header"); node.push_back(rteComponentsNode); } @@ -368,8 +364,9 @@ void ProjMgrYamlCbuild::SetOutputDirsNode(YAML::Node node, const ContextItem* co {YAML_OUTPUT_OUTDIR, dirs.outdir}, {YAML_OUTPUT_RTEDIR, dirs.rte}, }; - for (const auto& [name, dirPath] : outputDirs) { - SetNodeValue(node[name], dirPath); + for (auto [name, dirPath] : outputDirs) { + RteFsUtils::NormalizePath(dirPath, context->directories.cprj); + SetNodeValue(node[name], FormatPath(dirPath, context->directories.cbuild)); } } @@ -395,9 +392,9 @@ void ProjMgrYamlCbuild::SetOutputNode(YAML::Node node, const ContextItem* contex void ProjMgrYamlCbuild::SetLinkerNode(YAML::Node node, const ContextItem* context) { const string script = context->linker.script.empty() ? "" : fs::path(context->linker.script).is_absolute() ? FormatPath(context->linker.script, "") : - FormatPath(context->directories.cprj + "/" + context->linker.script, context->directories.cprj); + FormatPath(context->directories.cprj + "/" + context->linker.script, context->directories.cbuild); const string regions = context->linker.regions.empty() ? "" : - FormatPath(context->directories.cprj + "/" + context->linker.regions, context->directories.cprj); + FormatPath(context->directories.cprj + "/" + context->linker.regions, context->directories.cbuild); SetNodeValue(node[YAML_SCRIPT], script); SetNodeValue(node[YAML_REGIONS], regions); SetDefineNode(node[YAML_DEFINE], context->linker.defines); @@ -441,10 +438,10 @@ void ProjMgrYamlCbuild::SetControlsNode(YAML::Node node, const ContextItem* cont SetDefineNode(node[YAML_DEFINE], controls.defines); SetNodeValue(node[YAML_UNDEFINE], controls.undefines); for (const auto& addpath : controls.addpaths) { - node[YAML_ADDPATH].push_back(FormatPath(context->directories.cprj + "/" + addpath, context->directories.cprj)); + node[YAML_ADDPATH].push_back(FormatPath(context->directories.cprj + "/" + addpath, context->directories.cbuild)); } for (const auto& addpath : controls.delpaths) { - node[YAML_DELPATH].push_back(FormatPath(context->directories.cprj + "/" + addpath, context->directories.cprj)); + node[YAML_DELPATH].push_back(FormatPath(context->directories.cprj + "/" + addpath, context->directories.cbuild)); } } @@ -467,6 +464,10 @@ void ProjMgrYamlCbuild::SetProcessorNode(YAML::Node node, const map& miscVec) { @@ -535,13 +536,15 @@ const string ProjMgrYamlBase::FormatPath(const string& original, const string& d size_t index = path.find(packRoot); if (index != string::npos) { path.replace(index, packRoot.length(), "${CMSIS_PACK_ROOT}"); - } else { + } + else { string compilerRoot; ProjMgrUtils::GetCompilerRoot(compilerRoot); index = path.find(compilerRoot); if (!compilerRoot.empty() && index != string::npos) { path.replace(index, compilerRoot.length(), "${CMSIS_COMPILER_ROOT}"); - } else { + } + else { path = fs::relative(path, directory, ec).generic_string(); } } @@ -620,21 +623,27 @@ bool ProjMgrYamlEmitter::GenerateCbuildIndex(ProjMgrParser& parser, const vector return cbuild.WriteFile(rootNode, filename); } -bool ProjMgrYamlEmitter::GenerateCbuild(ContextItem* context, const RteGenerator* generator) { - // generate cbuild.yml for each context - - // intdir is relative to cprjdir, which in turn is absolute - string genInputFileDir = context->directories.intdir; - RteFsUtils::NormalizePath(genInputFileDir, context->directories.cprj); - const string generatorInputFilename = genInputFileDir + "/" + context->name + ".cbuild-gen.yml"; - const string filename = generator ? generatorInputFilename : context->directories.cprj + "/" + context->name + ".cbuild.yml"; +bool ProjMgrYamlEmitter::GenerateCbuild(ContextItem* context, const string& generatorId, const string& generatorPack) { + // generate cbuild.yml or cbuild-gen.yml for each context + context->directories.cbuild = context->directories.cprj; + string tmpDir = context->directories.intdir; + RteFsUtils::NormalizePath(tmpDir, context->directories.cbuild); + const string cbuildGenFilename = fs::path(tmpDir).append(context->name + ".cbuild-gen.yml").generic_string(); // Make sure $G (generator input file) is up to date - context->rteActiveTarget->SetGeneratorInputFile(generatorInputFilename); + context->rteActiveTarget->SetGeneratorInputFile(cbuildGenFilename); + string filename, rootKey; + if (generatorId.empty()) { + rootKey = YAML_BUILD; + filename = fs::path(context->directories.cbuild).append(context->name + ".cbuild.yml").generic_string(); + } else { + rootKey = YAML_BUILD_GEN; + filename = cbuildGenFilename; + } YAML::Node rootNode; - ProjMgrYamlCbuild cbuild(rootNode[YAML_BUILD], context, generator); - + ProjMgrYamlCbuild cbuild(rootNode[rootKey], context, generatorId, generatorPack); + RteFsUtils::CreateDirectories(RteFsUtils::ParentPath(filename)); return cbuild.WriteFile(rootNode, filename); } @@ -647,23 +656,45 @@ bool ProjMgrYamlEmitter::GenerateCbuildSet(ProjMgrParser& parser, YAML::Node rootNode; ProjMgrYamlCbuild cbuild(rootNode[YAML_CBUILD_SET], contexts, selectedCompiler); - // Compare yaml contents - if (!cbuild.CompareFile(filename, rootNode)) { - ofstream fileStream(filename); - if (!fileStream) { - ProjMgrLogger::Error(filename, "file cannot be written"); - return false; - } - YAML::Emitter emitter; - emitter << rootNode; - fileStream << emitter.c_str(); - fileStream << endl; - fileStream << flush; - fileStream.close(); - ProjMgrLogger::Info(filename, "file generated successfully"); - } - else { - ProjMgrLogger::Info(filename, "file is already up-to-date"); - } - return true; + return cbuild.WriteFile(rootNode, filename); +} + +ProjMgrYamlCbuild::ProjMgrYamlCbuild(YAML::Node node, const vector siblings, + const string& type, const string& output, const string& gendir) : ProjMgrYamlBase(true) { + // construct cbuild-gen-idx.yml content + SetNodeValue(node[YAML_GENERATED_BY], ORIGINAL_FILENAME + string(" version ") + VERSION_STRING); + const auto& context = siblings.front(); + const auto& generator = context->extGenDir.begin(); + YAML::Node generatorNode; + SetNodeValue(generatorNode[YAML_ID], generator->first); + SetNodeValue(generatorNode[YAML_OUTPUT], FormatPath(gendir, output)); + SetNodeValue(generatorNode[YAML_DEVICE], context->deviceItem.name); + SetNodeValue(generatorNode[YAML_BOARD], context->board); + SetNodeValue(generatorNode[YAML_PROJECT_TYPE], type); + for (const auto& sibling : siblings) { + YAML::Node cbuildGenNode; + string tmpDir = sibling->directories.intdir; + RteFsUtils::NormalizePath(tmpDir, context->directories.cprj); + string cbuildGenFilename = fs::path(tmpDir).append(sibling->name + ".cbuild-gen.yml").generic_string(); + SetNodeValue(cbuildGenNode[YAML_CBUILD_GEN], FormatPath(cbuildGenFilename, output)); + SetNodeValue(cbuildGenNode[YAML_PROJECT], sibling->cproject->name); + SetNodeValue(cbuildGenNode[YAML_CONFIGURATION], (sibling->type.build.empty() ? "" : + ("." + sibling->type.build)) + "+" + sibling->type.target); + SetNodeValue(cbuildGenNode[YAML_FORPROJECTPART], + (type == TYPE_MULTI_CORE ? sibling->deviceItem.pname : + (type == TYPE_TRUSTZONE ? sibling->controls.processed.processor.trustzone : ""))); + generatorNode[YAML_CBUILD_GENS].push_back(cbuildGenNode); + } + node[YAML_GENERATORS].push_back(generatorNode); +} + +bool ProjMgrYamlEmitter::GenerateCbuildGenIndex(ProjMgrParser& parser, const vector siblings, + const string& type, const string& output, const string& gendir) { + // generate cbuild-gen-idx.yml as input for external generator + RteFsUtils::CreateDirectories(output); + const string& filename = output + "/" + parser.GetCsolution().name + ".cbuild-gen-idx.yml"; + + YAML::Node rootNode; + ProjMgrYamlCbuild cbuild(rootNode[YAML_BUILD_GEN_IDX], siblings, type, output, gendir); + return cbuild.WriteFile(rootNode, filename); } diff --git a/tools/projmgr/src/ProjMgrYamlParser.cpp b/tools/projmgr/src/ProjMgrYamlParser.cpp index 25656947d..4a4ebe3fd 100644 --- a/tools/projmgr/src/ProjMgrYamlParser.cpp +++ b/tools/projmgr/src/ProjMgrYamlParser.cpp @@ -175,14 +175,17 @@ bool ProjMgrYamlParser::ParseClayer(const string& input, ClayerItem clayer; try { // Validate file schema - if (checkSchema && - !ProjMgrYamlSchemaChecker().Validate( - input, ProjMgrYamlSchemaChecker::FileType::LAYER)) { - return false; + const bool cgen = fs::path(input).stem().extension().generic_string() == ".cgen"; + if (checkSchema) { + if (!ProjMgrYamlSchemaChecker().Validate(input, cgen ? + ProjMgrYamlSchemaChecker::FileType::GENERATOR_IMPORT : + ProjMgrYamlSchemaChecker::FileType::LAYER)) { + return false; + } } const YAML::Node& root = YAML::LoadFile(input); - if (!ValidateClayer(input, root)) { + if (!cgen && !ValidateClayer(input, root)) { return false; } @@ -190,7 +193,7 @@ bool ProjMgrYamlParser::ParseClayer(const string& input, clayer.directory = RteFsUtils::ParentPath(clayer.path); clayer.name = fs::path(input).stem().stem().generic_string(); - const YAML::Node& layerNode = root[YAML_LAYER]; + const YAML::Node& layerNode = root[cgen ? YAML_GENERATOR_IMPORT : YAML_LAYER]; map projectChildren = { {YAML_FORBOARD, clayer.forBoard}, {YAML_FORDEVICE, clayer.forDevice}, @@ -250,6 +253,39 @@ bool ProjMgrYamlParser::ParseCbuildSet(const string& input, CbuildSetItem& cbuil return true; } +bool ProjMgrYamlParser::ParseGlobalGenerator(const string& input, + std::map& generators, bool checkSchema) { + + try { + // Validate file schema + if (checkSchema && !ProjMgrYamlSchemaChecker().Validate( + input, ProjMgrYamlSchemaChecker::FileType::GENERATOR)) { + return false; + } + + const YAML::Node& root = YAML::LoadFile(input); + const YAML::Node& generatorNode = root[YAML_GENERATOR]; + for (const auto& generatorEntry : generatorNode) { + GlobalGeneratorItem generator; + map generatorChildren = { + {YAML_ID, generator.id}, + {YAML_DOWNLOAD_URL, generator.downloadUrl}, + {YAML_RUN, generator.run}, + }; + for (const auto& item : generatorChildren) { + ParseString(generatorEntry, item.first, item.second); + } + ParsePortablePath(generatorEntry, input, YAML_PATH, generator.path, false); + generators[generator.id] = generator; + } + } + catch (YAML::Exception& e) { + ProjMgrLogger::Error(input, e.mark.line + 1, e.mark.column + 1, e.msg); + return false; + } + return true; +} + // EnsurePortability checks the presence of backslash, case inconsistency and absolute path // It clears the string 'value' when it is an absolute path void ProjMgrYamlParser::EnsurePortability(const string& file, const YAML::Mark& mark, const string& key, string& value, bool checkExist) { diff --git a/tools/projmgr/src/ProjMgrYamlSchemaChecker.cpp b/tools/projmgr/src/ProjMgrYamlSchemaChecker.cpp index 55b4af05e..81b4fade8 100644 --- a/tools/projmgr/src/ProjMgrYamlSchemaChecker.cpp +++ b/tools/projmgr/src/ProjMgrYamlSchemaChecker.cpp @@ -74,9 +74,24 @@ bool ProjMgrYamlSchemaChecker::GetSchemaFile(string& schemaFile, const ProjMgrYa case ProjMgrYamlSchemaChecker::FileType::BUILD: schemaFileName = "cbuild.schema.json"; break; + case ProjMgrYamlSchemaChecker::FileType::BUILDIDX: + schemaFileName = "cbuild-idx.schema.json"; + break; case ProjMgrYamlSchemaChecker::FileType::BUILDSET: schemaFileName = "cbuildset.schema.json"; break; + case ProjMgrYamlSchemaChecker::FileType::GENERATOR: + schemaFileName = "generator.schema.json"; + break; + case ProjMgrYamlSchemaChecker::FileType::BUILDGEN: + schemaFileName = "cbuild-gen.schema.json"; + break; + case ProjMgrYamlSchemaChecker::FileType::BUILDGENIDX: + schemaFileName = "cbuild-gen-idx.schema.json"; + break; + case ProjMgrYamlSchemaChecker::FileType::GENERATOR_IMPORT: + schemaFileName = "cgen.schema.json"; + break; default: ProjMgrLogger::Error("Unknown file type"); return false; diff --git a/tools/projmgr/templates/global.generator.yml b/tools/projmgr/templates/global.generator.yml new file mode 100644 index 000000000..4b6750f8c --- /dev/null +++ b/tools/projmgr/templates/global.generator.yml @@ -0,0 +1,5 @@ +generator: + - id: CubeMX + download-url: https://www.st.com/en/development-tools/stm32cubemx.html#st-get-software + run: ../bin/cbridge + path: $SolutionDir()$/STM32CubeMX/$Dname$ diff --git a/tools/projmgr/test/data/ExternalGenerator/bridge.sh b/tools/projmgr/test/data/ExternalGenerator/bridge.sh new file mode 100755 index 000000000..1289c7252 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/bridge.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +echo "bridge tool argument: $1" +exit 0 diff --git a/tools/projmgr/test/data/ExternalGenerator/extgen.csolution.yml b/tools/projmgr/test/data/ExternalGenerator/extgen.csolution.yml new file mode 100644 index 000000000..915222a9e --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/extgen.csolution.yml @@ -0,0 +1,30 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/csolution.schema.json + +solution: + compiler: AC6 + + packs: + - pack: ARM::RteTestGenerator@0.1.0 + - pack: ARM::RteTest_DFP@0.2.0 + + target-types: + - type: CM0 + device: RteTestGen_ARMCM0 + - type: MultiCore + device: RteTest_ARMCM0_Dual + + build-types: + - type: Debug + - type: Release + + projects: + - project: single/single-core.cproject.yml + for-context: +CM0 + - project: tz_s/s.cproject.yml + for-context: +CM0 + - project: tz_ns/ns.cproject.yml + for-context: +CM0 + - project: multi_0/core0.cproject.yml + for-context: +MultiCore + - project: multi_1/core1.cproject.yml + for-context: +MultiCore diff --git a/tools/projmgr/test/data/ExternalGenerator/global.generator.yml b/tools/projmgr/test/data/ExternalGenerator/global.generator.yml new file mode 100644 index 000000000..29b6c54fc --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/global.generator.yml @@ -0,0 +1,5 @@ +generator: + - id: RteTestExternalGenerator + download-url: https://raw.githubusercontent.com/Open-CMSIS-Pack + run: ./bridge.sh + path: $SolutionDir()$/generated/$TargetType$ diff --git a/tools/projmgr/test/data/ExternalGenerator/multi_0/core0.cproject.yml b/tools/projmgr/test/data/ExternalGenerator/multi_0/core0.cproject.yml new file mode 100644 index 000000000..2cc80cc18 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/multi_0/core0.cproject.yml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/cproject.schema.json + +project: + device: :cm0_core0 + components: + - component: RteTestGenerator:Check Global Generator diff --git a/tools/projmgr/test/data/ExternalGenerator/multi_1/core1.cproject.yml b/tools/projmgr/test/data/ExternalGenerator/multi_1/core1.cproject.yml new file mode 100644 index 000000000..db81801cb --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/multi_1/core1.cproject.yml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/cproject.schema.json + +project: + device: :cm0_core1 + components: + - component: RteTestGenerator:Check Global Generator diff --git a/tools/projmgr/test/data/ExternalGenerator/no-gendir.generator.yml b/tools/projmgr/test/data/ExternalGenerator/no-gendir.generator.yml new file mode 100644 index 000000000..beb9e7e98 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/no-gendir.generator.yml @@ -0,0 +1,4 @@ +generator: + - id: RteTestExternalGenerator + download-url: https://raw.githubusercontent.com/Open-CMSIS-Pack + run: ./bridge.sh diff --git a/tools/projmgr/test/data/ExternalGenerator/ref/MultiCore/core0.Debug+MultiCore.cbuild-gen.yml b/tools/projmgr/test/data/ExternalGenerator/ref/MultiCore/core0.Debug+MultiCore.cbuild-gen.yml new file mode 100644 index 000000000..bb522989e --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/ref/MultiCore/core0.Debug+MultiCore.cbuild-gen.yml @@ -0,0 +1,50 @@ +build-gen: + generated-by: csolution version 0.0.0+g8b0e14a8 + current-generator: + id: RteTestExternalGenerator + solution: ${DEVTOOLS(data)}/ExternalGenerator/extgen.csolution.yml + project: ${DEVTOOLS(data)}/ExternalGenerator/multi_0/core0.cproject.yml + context: core0.Debug+MultiCore + compiler: AC6 + device: RteTest_ARMCM0_Dual:cm0_core0 + processor: + fpu: off + core: Cortex-M0 + packs: + - pack: ARM::RteTestGenerator@0.1.0 + path: ${DEVTOOLS(packs)}/ARM/RteTestGenerator/0.1.0 + - pack: ARM::RteTest_DFP@0.2.0 + path: ${DEVTOOLS(packs)}/ARM/RteTest_DFP/0.2.0 + define: + - ARMCM0 + - _RTE_ + add-path: + - ${DEVTOOLS(data)}/ExternalGenerator/multi_0/RTE/_Debug_MultiCore + - ${DEVTOOLS(packs)}/ARM/RteTest_DFP/0.2.0/Device/ARM/ARMCM0/Include + output-dirs: + intdir: ${DEVTOOLS(data)}/ExternalGenerator/tmp/core0/MultiCore/Debug + outdir: ${DEVTOOLS(data)}/ExternalGenerator/out/core0/MultiCore/Debug + rtedir: ${DEVTOOLS(data)}/ExternalGenerator/multi_0/RTE + output: + - type: elf + file: core0.axf + components: + - component: ARM::RteTestGenerator:Check Global Generator@0.9.0 + from-pack: ARM::RteTestGenerator@0.1.0 + selected-by: RteTestGenerator:Check Global Generator + linker: + script: ${DEVTOOLS(data)}/TestToolchains/ac6_linker_script.sct + regions: ${DEVTOOLS(data)}/ExternalGenerator/multi_0/RTE/Device/RteTest_ARMCM0_Dual_cm0_core0/regions_RteTest_ARMCM0_Dual_cm0_core0.h + constructed-files: + - file: ${DEVTOOLS(data)}/ExternalGenerator/multi_0/RTE/_Debug_MultiCore/RTE_Components.h + category: header + licenses: + - license: + packs: + - pack: ARM::RteTestGenerator@0.1.0 + components: + - component: ARM::RteTestGenerator:Check Global Generator@0.9.0 + - license: + license-agreement: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0/Doc/license.txt + packs: + - pack: ARM::RteTest_DFP@0.2.0 diff --git a/tools/projmgr/test/data/ExternalGenerator/ref/MultiCore/core1.Debug+MultiCore.cbuild-gen.yml b/tools/projmgr/test/data/ExternalGenerator/ref/MultiCore/core1.Debug+MultiCore.cbuild-gen.yml new file mode 100644 index 000000000..a6e3ed267 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/ref/MultiCore/core1.Debug+MultiCore.cbuild-gen.yml @@ -0,0 +1,50 @@ +build-gen: + generated-by: csolution version 0.0.0+g8b0e14a8 + current-generator: + id: RteTestExternalGenerator + solution: ${DEVTOOLS(data)}/ExternalGenerator/extgen.csolution.yml + project: ${DEVTOOLS(data)}/ExternalGenerator/multi_1/core1.cproject.yml + context: core1.Debug+MultiCore + compiler: AC6 + device: RteTest_ARMCM0_Dual:cm0_core1 + processor: + fpu: off + core: Cortex-M0 + packs: + - pack: ARM::RteTestGenerator@0.1.0 + path: ${DEVTOOLS(packs)}/ARM/RteTestGenerator/0.1.0 + - pack: ARM::RteTest_DFP@0.2.0 + path: ${DEVTOOLS(packs)}/ARM/RteTest_DFP/0.2.0 + define: + - ARMCM0 + - _RTE_ + add-path: + - ${DEVTOOLS(data)}/ExternalGenerator/multi_1/RTE/_Debug_MultiCore + - ${DEVTOOLS(packs)}/ARM/RteTest_DFP/0.2.0/Device/ARM/ARMCM0/Include + output-dirs: + intdir: ${DEVTOOLS(data)}/ExternalGenerator/tmp/core1/MultiCore/Debug + outdir: ${DEVTOOLS(data)}/ExternalGenerator/out/core1/MultiCore/Debug + rtedir: ${DEVTOOLS(data)}/ExternalGenerator/multi_1/RTE + output: + - type: elf + file: core1.axf + components: + - component: ARM::RteTestGenerator:Check Global Generator@0.9.0 + from-pack: ARM::RteTestGenerator@0.1.0 + selected-by: RteTestGenerator:Check Global Generator + linker: + script: ${DEVTOOLS(data)}/TestToolchains/ac6_linker_script.sct + regions: ${DEVTOOLS(data)}/ExternalGenerator/multi_1/RTE/Device/RteTest_ARMCM0_Dual_cm0_core1/regions_RteTest_ARMCM0_Dual_cm0_core1.h + constructed-files: + - file: ${DEVTOOLS(data)}/ExternalGenerator/multi_1/RTE/_Debug_MultiCore/RTE_Components.h + category: header + licenses: + - license: + packs: + - pack: ARM::RteTestGenerator@0.1.0 + components: + - component: ARM::RteTestGenerator:Check Global Generator@0.9.0 + - license: + license-agreement: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0/Doc/license.txt + packs: + - pack: ARM::RteTest_DFP@0.2.0 diff --git a/tools/projmgr/test/data/ExternalGenerator/ref/MultiCore/extgen.cbuild-gen-idx.yml b/tools/projmgr/test/data/ExternalGenerator/ref/MultiCore/extgen.cbuild-gen-idx.yml new file mode 100644 index 000000000..69f94132b --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/ref/MultiCore/extgen.cbuild-gen-idx.yml @@ -0,0 +1,16 @@ +build-gen-idx: + generated-by: csolution version 0.0.0+gf14e09a4 + generators: + - id: RteTestExternalGenerator + output: ${DEVTOOLS(data)}/ExternalGenerator/generated/MultiCore + device: RteTest_ARMCM0_Dual + project-type: multi-core + cbuild-gens: + - cbuild-gen: ${DEVTOOLS(data)}/ExternalGenerator/tmp/core0/MultiCore/Debug/core0.Debug+MultiCore.cbuild-gen.yml + project: core0 + configuration: .Debug+MultiCore + for-project-part: cm0_core0 + - cbuild-gen: ${DEVTOOLS(data)}/ExternalGenerator/tmp/core1/MultiCore/Debug/core1.Debug+MultiCore.cbuild-gen.yml + project: core1 + configuration: .Debug+MultiCore + for-project-part: cm0_core1 diff --git a/tools/projmgr/test/data/ExternalGenerator/ref/SingleCore/extgen.cbuild-gen-idx.yml b/tools/projmgr/test/data/ExternalGenerator/ref/SingleCore/extgen.cbuild-gen-idx.yml new file mode 100644 index 000000000..dd6f07cb3 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/ref/SingleCore/extgen.cbuild-gen-idx.yml @@ -0,0 +1,11 @@ +build-gen-idx: + generated-by: csolution version 0.0.0+gf14e09a4 + generators: + - id: RteTestExternalGenerator + output: ${DEVTOOLS(data)}/ExternalGenerator/single/generated + device: RteTestGen_ARMCM0 + project-type: single-core + cbuild-gens: + - cbuild-gen: ${DEVTOOLS(data)}/ExternalGenerator/tmp/single-core/CM0/Debug/single-core.Debug+CM0.cbuild-gen.yml + project: single-core + configuration: .Debug+CM0 diff --git a/tools/projmgr/test/data/ExternalGenerator/ref/SingleCore/single-core.Debug+CM0.cbuild-gen.yml b/tools/projmgr/test/data/ExternalGenerator/ref/SingleCore/single-core.Debug+CM0.cbuild-gen.yml new file mode 100644 index 000000000..c3492f774 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/ref/SingleCore/single-core.Debug+CM0.cbuild-gen.yml @@ -0,0 +1,46 @@ +build-gen: + generated-by: csolution version 0.0.0+g8b0e14a8 + current-generator: + id: RteTestExternalGenerator + solution: ${DEVTOOLS(data)}/ExternalGenerator/extgen.csolution.yml + project: ${DEVTOOLS(data)}/ExternalGenerator/single/single-core.cproject.yml + context: single-core.Debug+CM0 + compiler: AC6 + device: RteTestGen_ARMCM0 + processor: + core: Cortex-M0 + packs: + - pack: ARM::RteTestGenerator@0.1.0 + path: ${DEVTOOLS(packs)}/ARM/RteTestGenerator/0.1.0 + define: + - _RTE_ + add-path: + - ${DEVTOOLS(data)}/ExternalGenerator/single/RTE/_Debug_CM0 + output-dirs: + intdir: ${DEVTOOLS(data)}/ExternalGenerator/tmp/single-core/CM0/Debug + outdir: ${DEVTOOLS(data)}/ExternalGenerator/out/single-core/CM0/Debug + rtedir: ${DEVTOOLS(data)}/ExternalGenerator/single/RTE + output: + - type: elf + file: single-core.axf + components: + - component: ARM::RteTestGenerator:Check Global Generator@0.9.0 + from-pack: ARM::RteTestGenerator@0.1.0 + selected-by: RteTestGenerator:Check Global Generator + linker: + script: ${DEVTOOLS(data)}/TestToolchains/ac6_linker_script.sct + regions: ${DEVTOOLS(data)}/ExternalGenerator/single/RTE/Device/RteTestGen_ARMCM0/regions_RteTestGen_ARMCM0.h + groups: + - group: sources + files: + - file: main.c + category: sourceC + constructed-files: + - file: ${DEVTOOLS(data)}/ExternalGenerator/single/RTE/_Debug_CM0/RTE_Components.h + category: header + licenses: + - license: + packs: + - pack: ARM::RteTestGenerator@0.1.0 + components: + - component: ARM::RteTestGenerator:Check Global Generator@0.9.0 diff --git a/tools/projmgr/test/data/ExternalGenerator/ref/SingleCore/single-core.Debug+CM0.cbuild.yml b/tools/projmgr/test/data/ExternalGenerator/ref/SingleCore/single-core.Debug+CM0.cbuild.yml new file mode 100644 index 000000000..0287e0135 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/ref/SingleCore/single-core.Debug+CM0.cbuild.yml @@ -0,0 +1,82 @@ +build: + generated-by: csolution version 0.0.0+gf14e09a4 + solution: ../extgen.csolution.yml + project: single-core.cproject.yml + context: single-core.Debug+CM0 + compiler: AC6 + device: RteTestGen_ARMCM0 + processor: + core: Cortex-M0 + packs: + - pack: ARM::RteTest@0.1.0 + path: ${CMSIS_PACK_ROOT}/ARM/RteTest/0.1.0 + - pack: ARM::RteTestGenerator@0.1.0 + path: ${CMSIS_PACK_ROOT}/ARM/RteTestGenerator/0.1.0 + define: + - _RTE_ + add-path: + - RTE/_Debug_CM0 + - generated/RTE/RteTest + - ${CMSIS_PACK_ROOT}/ARM/RteTest/0.1.0/GlobalLevel + - ${CMSIS_PACK_ROOT}/ARM/RteTest/0.1.0/Include + output-dirs: + intdir: ../tmp/single-core/CM0/Debug + outdir: ../out/single-core/CM0/Debug + rtedir: RTE + output: + - type: elf + file: single-core.axf + components: + - component: ARM::RteTest:GlobalLevel@0.0.2 + from-pack: ARM::RteTest@0.1.0 + selected-by: RteTest:GlobalLevel + files: + - file: ${CMSIS_PACK_ROOT}/ARM/RteTest/0.1.0/GlobalLevel/GlobalLevel.c + category: sourceC + - file: ${CMSIS_PACK_ROOT}/ARM/RteTest/0.1.0/GlobalLevel/GlobalLevel.h + category: preIncludeGlobal + version: 0.0.2 + - file: generated/RTE/RteTest/GlobalLevelConfig.h + category: preIncludeGlobal + attr: config + version: 0.0.2 + - file: generated/RTE/RteTest/Config/ConfigInclude.h + category: header + attr: config + version: 0.0.2 + - component: ARM::RteTestGenerator:Check Global Generator@0.9.0 + from-pack: ARM::RteTestGenerator@0.1.0 + selected-by: RteTestGenerator:Check Global Generator + linker: + script: ${CMSIS_COMPILER_ROOT}/ac6_linker_script.sct + regions: RTE/Device/RteTestGen_ARMCM0/regions_RteTestGen_ARMCM0.h + groups: + - group: sources + files: + - file: main.c + category: sourceC + - group: generated sources + files: + - file: generated/generated.c + category: sourceC + constructed-files: + - file: RTE/_Debug_CM0/Pre_Include_Global.h + category: preIncludeGlobal + - file: RTE/_Debug_CM0/RTE_Components.h + category: header + licenses: + - license: + packs: + - pack: ARM::RteTestGenerator@0.1.0 + components: + - component: ARM::RteTestGenerator:Check Global Generator@0.9.0 + - license: BSD-3-Clause + packs: + - pack: ARM::RteTest@0.1.0 + components: + - component: ARM::RteTest:GlobalLevel@0.0.2 + - license: MIT + packs: + - pack: ARM::RteTest@0.1.0 + components: + - component: ARM::RteTest:GlobalLevel@0.0.2 diff --git a/tools/projmgr/test/data/ExternalGenerator/ref/TrustZone/extgen.cbuild-gen-idx.yml b/tools/projmgr/test/data/ExternalGenerator/ref/TrustZone/extgen.cbuild-gen-idx.yml new file mode 100644 index 000000000..783105d7d --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/ref/TrustZone/extgen.cbuild-gen-idx.yml @@ -0,0 +1,16 @@ +build-gen-idx: + generated-by: csolution version 0.0.0+gf14e09a4 + generators: + - id: RteTestExternalGenerator + output: ${DEVTOOLS(data)}/ExternalGenerator/generated/CM0 + device: RteTestGen_ARMCM0 + project-type: trustzone + cbuild-gens: + - cbuild-gen: ${DEVTOOLS(data)}/ExternalGenerator/tmp/ns/CM0/Debug/ns.Debug+CM0.cbuild-gen.yml + project: ns + configuration: .Debug+CM0 + for-project-part: non-secure + - cbuild-gen: ${DEVTOOLS(data)}/ExternalGenerator/tmp/s/CM0/Debug/s.Debug+CM0.cbuild-gen.yml + project: s + configuration: .Debug+CM0 + for-project-part: secure diff --git a/tools/projmgr/test/data/ExternalGenerator/ref/TrustZone/ns.Debug+CM0.cbuild-gen.yml b/tools/projmgr/test/data/ExternalGenerator/ref/TrustZone/ns.Debug+CM0.cbuild-gen.yml new file mode 100644 index 000000000..570397ade --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/ref/TrustZone/ns.Debug+CM0.cbuild-gen.yml @@ -0,0 +1,42 @@ +build-gen: + generated-by: csolution version 0.0.0+g8b0e14a8 + current-generator: + id: RteTestExternalGenerator + solution: ${DEVTOOLS(data)}/ExternalGenerator/extgen.csolution.yml + project: ${DEVTOOLS(data)}/ExternalGenerator/tz_ns/ns.cproject.yml + context: ns.Debug+CM0 + compiler: AC6 + device: RteTestGen_ARMCM0 + processor: + trustzone: non-secure + core: Cortex-M0 + packs: + - pack: ARM::RteTestGenerator@0.1.0 + path: ${DEVTOOLS(packs)}/ARM/RteTestGenerator/0.1.0 + define: + - _RTE_ + add-path: + - ${DEVTOOLS(data)}/ExternalGenerator/tz_ns/RTE/_Debug_CM0 + output-dirs: + intdir: ${DEVTOOLS(data)}/ExternalGenerator/tmp/ns/CM0/Debug + outdir: ${DEVTOOLS(data)}/ExternalGenerator/out/ns/CM0/Debug + rtedir: ${DEVTOOLS(data)}/ExternalGenerator/tz_ns/RTE + output: + - type: elf + file: ns.axf + components: + - component: ARM::RteTestGenerator:Check Global Generator@0.9.0 + from-pack: ARM::RteTestGenerator@0.1.0 + selected-by: RteTestGenerator:Check Global Generator + linker: + script: ${DEVTOOLS(data)}/TestToolchains/ac6_linker_script.sct + regions: ${DEVTOOLS(data)}/ExternalGenerator/tz_ns/RTE/Device/RteTestGen_ARMCM0/regions_RteTestGen_ARMCM0.h + constructed-files: + - file: ${DEVTOOLS(data)}/ExternalGenerator/tz_ns/RTE/_Debug_CM0/RTE_Components.h + category: header + licenses: + - license: + packs: + - pack: ARM::RteTestGenerator@0.1.0 + components: + - component: ARM::RteTestGenerator:Check Global Generator@0.9.0 diff --git a/tools/projmgr/test/data/ExternalGenerator/ref/TrustZone/s.Debug+CM0.cbuild-gen.yml b/tools/projmgr/test/data/ExternalGenerator/ref/TrustZone/s.Debug+CM0.cbuild-gen.yml new file mode 100644 index 000000000..78173a0c3 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/ref/TrustZone/s.Debug+CM0.cbuild-gen.yml @@ -0,0 +1,44 @@ +build-gen: + generated-by: csolution version 0.0.0+g8b0e14a8 + current-generator: + id: RteTestExternalGenerator + solution: ${DEVTOOLS(data)}/ExternalGenerator/extgen.csolution.yml + project: ${DEVTOOLS(data)}/ExternalGenerator/tz_s/s.cproject.yml + context: s.Debug+CM0 + compiler: AC6 + device: RteTestGen_ARMCM0 + processor: + trustzone: secure + core: Cortex-M0 + packs: + - pack: ARM::RteTestGenerator@0.1.0 + path: ${DEVTOOLS(packs)}/ARM/RteTestGenerator/0.1.0 + define: + - _RTE_ + add-path: + - ${DEVTOOLS(data)}/ExternalGenerator/tz_s/RTE/_Debug_CM0 + output-dirs: + intdir: ${DEVTOOLS(data)}/ExternalGenerator/tmp/s/CM0/Debug + outdir: ${DEVTOOLS(data)}/ExternalGenerator/out/s/CM0/Debug + rtedir: ${DEVTOOLS(data)}/ExternalGenerator/tz_s/RTE + output: + - type: elf + file: s.axf + - type: cmse-lib + file: s_CMSE_Lib.o + components: + - component: ARM::RteTestGenerator:Check Global Generator@0.9.0 + from-pack: ARM::RteTestGenerator@0.1.0 + selected-by: RteTestGenerator:Check Global Generator + linker: + script: ${DEVTOOLS(data)}/TestToolchains/ac6_linker_script.sct + regions: ${DEVTOOLS(data)}/ExternalGenerator/tz_s/RTE/Device/RteTestGen_ARMCM0/regions_RteTestGen_ARMCM0.h + constructed-files: + - file: ${DEVTOOLS(data)}/ExternalGenerator/tz_s/RTE/_Debug_CM0/RTE_Components.h + category: header + licenses: + - license: + packs: + - pack: ARM::RteTestGenerator@0.1.0 + components: + - component: ARM::RteTestGenerator:Check Global Generator@0.9.0 diff --git a/tools/projmgr/test/data/ExternalGenerator/single/generated/generated.c b/tools/projmgr/test/data/ExternalGenerator/single/generated/generated.c new file mode 100644 index 000000000..72aaaf4cc --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/single/generated/generated.c @@ -0,0 +1 @@ +// generated.c diff --git a/tools/projmgr/test/data/ExternalGenerator/single/generated/single-core.cgen.yml b/tools/projmgr/test/data/ExternalGenerator/single/generated/single-core.cgen.yml new file mode 100644 index 000000000..61912ce79 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/single/generated/single-core.cgen.yml @@ -0,0 +1,14 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/cgen.schema.json + +generator-import: + + packs: + - pack: ARM::RteTest@0.1.0 + + components: + - component: RteTest:GlobalLevel + + groups: + - group: generated sources + files: + - file: generated.c diff --git a/tools/projmgr/test/data/ExternalGenerator/single/generated/wrong.cgen.yml b/tools/projmgr/test/data/ExternalGenerator/single/generated/wrong.cgen.yml new file mode 100644 index 000000000..6af7cee6c --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/single/generated/wrong.cgen.yml @@ -0,0 +1,23 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/cgen.schema.json + +generator-import: + + packs: + - pack: ARM::RteTest@0.1.0 + - pack: UnknownVendor::UnknownPack + for-context: .WrongPack + + components: + - component: RteTest:GlobalLevel + - component: UnknownVendor::UnknownComponent + for-context: .WrongComponent + + groups: + - group: generated sources + files: + - file: generated.c + - group: sources + for-context: .WrongGroup + files: + - file: generated.c + \ No newline at end of file diff --git a/tools/projmgr/test/data/ExternalGenerator/single/main.c b/tools/projmgr/test/data/ExternalGenerator/single/main.c new file mode 100644 index 000000000..99b684458 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/single/main.c @@ -0,0 +1 @@ +// main.c diff --git a/tools/projmgr/test/data/ExternalGenerator/single/single-core.cproject.yml b/tools/projmgr/test/data/ExternalGenerator/single/single-core.cproject.yml new file mode 100644 index 000000000..012352290 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/single/single-core.cproject.yml @@ -0,0 +1,16 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/cproject.schema.json + +project: + components: + - component: RteTestGenerator:Check Global Generator + + groups: + - group: sources + files: + - file: main.c + + generators: + options: + - generator: RteTestExternalGenerator + path: $ProjectDir()$/generated/ + diff --git a/tools/projmgr/test/data/ExternalGenerator/single/wrong.cproject.yml b/tools/projmgr/test/data/ExternalGenerator/single/wrong.cproject.yml new file mode 100644 index 000000000..012352290 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/single/wrong.cproject.yml @@ -0,0 +1,16 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/cproject.schema.json + +project: + components: + - component: RteTestGenerator:Check Global Generator + + groups: + - group: sources + files: + - file: main.c + + generators: + options: + - generator: RteTestExternalGenerator + path: $ProjectDir()$/generated/ + diff --git a/tools/projmgr/test/data/ExternalGenerator/tz_ns/ns.cproject.yml b/tools/projmgr/test/data/ExternalGenerator/tz_ns/ns.cproject.yml new file mode 100644 index 000000000..bbf19781a --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/tz_ns/ns.cproject.yml @@ -0,0 +1,7 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/cproject.schema.json + +project: + processor: + trustzone: non-secure + components: + - component: RteTestGenerator:Check Global Generator diff --git a/tools/projmgr/test/data/ExternalGenerator/tz_s/s.cproject.yml b/tools/projmgr/test/data/ExternalGenerator/tz_s/s.cproject.yml new file mode 100644 index 000000000..241d3e162 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/tz_s/s.cproject.yml @@ -0,0 +1,7 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/cproject.schema.json + +project: + processor: + trustzone: secure + components: + - component: RteTestGenerator:Check Global Generator diff --git a/tools/projmgr/test/data/ExternalGenerator/wrong-gendir.generator.yml b/tools/projmgr/test/data/ExternalGenerator/wrong-gendir.generator.yml new file mode 100644 index 000000000..b3a7feaf3 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/wrong-gendir.generator.yml @@ -0,0 +1,5 @@ +generator: + - id: RteTestExternalGenerator + download-url: https://raw.githubusercontent.com/Open-CMSIS-Pack + run: ./bridge.sh + path: $UnknownAccessSequence()$ diff --git a/tools/projmgr/test/data/ExternalGenerator/wrong.csolution.yml b/tools/projmgr/test/data/ExternalGenerator/wrong.csolution.yml new file mode 100644 index 000000000..a3c38a4c8 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/wrong.csolution.yml @@ -0,0 +1,24 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/csolution.schema.json + +solution: + compiler: AC6 + + packs: + - pack: ARM::RteTestGenerator@0.1.0 + - pack: ARM::RteTest_DFP@0.2.0 + + target-types: + - type: CM0 + device: RteTestGen_ARMCM0 + + build-types: + - type: WrongPack + - type: WrongComponent + - type: WrongGroup + + projects: + - project: single/wrong.cproject.yml + for-context: + - .WrongPack + - .WrongComponent + - .WrongGroup diff --git a/tools/projmgr/test/data/TestDefault/ref/empty/project.Debug+TEST_TARGET.cbuild.yml b/tools/projmgr/test/data/TestDefault/ref/empty/project.Debug+TEST_TARGET.cbuild.yml index 1579ddb39..349428209 100644 --- a/tools/projmgr/test/data/TestDefault/ref/empty/project.Debug+TEST_TARGET.cbuild.yml +++ b/tools/projmgr/test/data/TestDefault/ref/empty/project.Debug+TEST_TARGET.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM0 processor: fpu: off + core: Cortex-M0 packs: - pack: ARM::RteTest_DFP@0.1.1 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.1.1 diff --git a/tools/projmgr/test/data/TestDefault/ref/empty/project.Release+TEST_TARGET.cbuild.yml b/tools/projmgr/test/data/TestDefault/ref/empty/project.Release+TEST_TARGET.cbuild.yml index 437f4ceb2..74e0d18be 100644 --- a/tools/projmgr/test/data/TestDefault/ref/empty/project.Release+TEST_TARGET.cbuild.yml +++ b/tools/projmgr/test/data/TestDefault/ref/empty/project.Release+TEST_TARGET.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM0 processor: fpu: off + core: Cortex-M0 packs: - pack: ARM::RteTest_DFP@0.1.1 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.1.1 diff --git a/tools/projmgr/test/data/TestGenerator/ref/multiple-components.Debug+CM0.cbuild.yml b/tools/projmgr/test/data/TestGenerator/ref/multiple-components.Debug+CM0.cbuild.yml index 2095801c4..70ba5343b 100644 --- a/tools/projmgr/test/data/TestGenerator/ref/multiple-components.Debug+CM0.cbuild.yml +++ b/tools/projmgr/test/data/TestGenerator/ref/multiple-components.Debug+CM0.cbuild.yml @@ -5,6 +5,8 @@ build: context: multiple-components.Debug+CM0 compiler: AC6 device: RteTestGen_ARMCM0 + processor: + core: Cortex-M0 packs: - pack: ARM::RteTestGenerator@0.1.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTestGenerator/0.1.0 diff --git a/tools/projmgr/test/data/TestGenerator/ref/test-gpdsc-layer.Debug+CM0.cbuild.yml b/tools/projmgr/test/data/TestGenerator/ref/test-gpdsc-layer.Debug+CM0.cbuild.yml index 6dda8ee7c..b75a49eaa 100644 --- a/tools/projmgr/test/data/TestGenerator/ref/test-gpdsc-layer.Debug+CM0.cbuild.yml +++ b/tools/projmgr/test/data/TestGenerator/ref/test-gpdsc-layer.Debug+CM0.cbuild.yml @@ -5,6 +5,8 @@ build: context: test-gpdsc-layer.Debug+CM0 compiler: AC6 device: RteTestGen_ARMCM0 + processor: + core: Cortex-M0 packs: - pack: ARM::RteTestGenerator@0.1.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTestGenerator/0.1.0 diff --git a/tools/projmgr/test/data/TestGenerator/ref/test-gpdsc-multiple-generators.Debug+CM0.cbuild.yml b/tools/projmgr/test/data/TestGenerator/ref/test-gpdsc-multiple-generators.Debug+CM0.cbuild.yml index aa6f3bea7..73f727233 100644 --- a/tools/projmgr/test/data/TestGenerator/ref/test-gpdsc-multiple-generators.Debug+CM0.cbuild.yml +++ b/tools/projmgr/test/data/TestGenerator/ref/test-gpdsc-multiple-generators.Debug+CM0.cbuild.yml @@ -5,6 +5,8 @@ build: context: test-gpdsc-multiple-generators.Debug+CM0 compiler: AC6 device: RteTestGen_ARMCM0 + processor: + core: Cortex-M0 packs: - pack: ARM::RteTestGenerator@0.1.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTestGenerator/0.1.0 diff --git a/tools/projmgr/test/data/TestGenerator/ref/test-gpdsc.Debug+CM0.cbuild.yml b/tools/projmgr/test/data/TestGenerator/ref/test-gpdsc.Debug+CM0.cbuild.yml index 3a3f84359..8af85a487 100644 --- a/tools/projmgr/test/data/TestGenerator/ref/test-gpdsc.Debug+CM0.cbuild.yml +++ b/tools/projmgr/test/data/TestGenerator/ref/test-gpdsc.Debug+CM0.cbuild.yml @@ -5,6 +5,8 @@ build: context: test-gpdsc.Debug+CM0 compiler: AC6 device: RteTestGen_ARMCM0 + processor: + core: Cortex-M0 packs: - pack: ARM::RteTestGenerator@0.1.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTestGenerator/0.1.0 diff --git a/tools/projmgr/test/data/TestSolution/ContextMap/ref/project1.Debug+RteTest_ARMCM3.cbuild.yml b/tools/projmgr/test/data/TestSolution/ContextMap/ref/project1.Debug+RteTest_ARMCM3.cbuild.yml index 5132116d4..e9cfd6833 100644 --- a/tools/projmgr/test/data/TestSolution/ContextMap/ref/project1.Debug+RteTest_ARMCM3.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/ContextMap/ref/project1.Debug+RteTest_ARMCM3.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM3 processor: fpu: off + core: Cortex-M3 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/ContextMap/ref/project1.Release+RteTest_ARMCM3.cbuild.yml b/tools/projmgr/test/data/TestSolution/ContextMap/ref/project1.Release+RteTest_ARMCM3.cbuild.yml index adaec585e..874e9ee4d 100644 --- a/tools/projmgr/test/data/TestSolution/ContextMap/ref/project1.Release+RteTest_ARMCM3.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/ContextMap/ref/project1.Release+RteTest_ARMCM3.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM3 processor: fpu: off + core: Cortex-M3 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/ContextMap/ref/project2.Debug+RteTest_ARMCM3.cbuild.yml b/tools/projmgr/test/data/TestSolution/ContextMap/ref/project2.Debug+RteTest_ARMCM3.cbuild.yml index 4ca45bf49..4c3ae5512 100644 --- a/tools/projmgr/test/data/TestSolution/ContextMap/ref/project2.Debug+RteTest_ARMCM3.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/ContextMap/ref/project2.Debug+RteTest_ARMCM3.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM3 processor: fpu: off + core: Cortex-M3 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/ContextMap/ref/project2.Release+RteTest_ARMCM3.cbuild.yml b/tools/projmgr/test/data/TestSolution/ContextMap/ref/project2.Release+RteTest_ARMCM3.cbuild.yml index d2fdb165b..0ed3aa844 100644 --- a/tools/projmgr/test/data/TestSolution/ContextMap/ref/project2.Release+RteTest_ARMCM3.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/ContextMap/ref/project2.Release+RteTest_ARMCM3.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM3 processor: fpu: off + core: Cortex-M3 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/LanguageAndScope/ref/lang-scope.Debug_AC6+RteTest_ARMCM3.cbuild.yml b/tools/projmgr/test/data/TestSolution/LanguageAndScope/ref/lang-scope.Debug_AC6+RteTest_ARMCM3.cbuild.yml index 380257442..cf531d56c 100644 --- a/tools/projmgr/test/data/TestSolution/LanguageAndScope/ref/lang-scope.Debug_AC6+RteTest_ARMCM3.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/LanguageAndScope/ref/lang-scope.Debug_AC6+RteTest_ARMCM3.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM3 processor: fpu: off + core: Cortex-M3 packs: - pack: ARM::RteTest@0.1.0-alpha0 path: ../data/TestSolution/LanguageAndScope/pack diff --git a/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.Debug_AC6+RteTest_ARMCM3.cbuild.yml b/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.Debug_AC6+RteTest_ARMCM3.cbuild.yml index ad7ab9b92..4a4708750 100644 --- a/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.Debug_AC6+RteTest_ARMCM3.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.Debug_AC6+RteTest_ARMCM3.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM3 processor: fpu: off + core: Cortex-M3 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.Debug_GCC+RteTest_ARMCM3.cbuild.yml b/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.Debug_GCC+RteTest_ARMCM3.cbuild.yml index 91673b8ed..bf3d15722 100644 --- a/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.Debug_GCC+RteTest_ARMCM3.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.Debug_GCC+RteTest_ARMCM3.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM3 processor: fpu: off + core: Cortex-M3 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.PriorityDefines+RteTest_ARMCM3.cbuild.yml b/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.PriorityDefines+RteTest_ARMCM3.cbuild.yml index 0a9965155..cc6eaf096 100644 --- a/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.PriorityDefines+RteTest_ARMCM3.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.PriorityDefines+RteTest_ARMCM3.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM3 processor: fpu: off + core: Cortex-M3 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.PriorityRegions+RteTest_ARMCM3.cbuild.yml b/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.PriorityRegions+RteTest_ARMCM3.cbuild.yml index 86053df38..f9d217d3f 100644 --- a/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.PriorityRegions+RteTest_ARMCM3.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/LinkerOptions/ref/linker.PriorityRegions+RteTest_ARMCM3.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM3 processor: fpu: off + core: Cortex-M3 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/StandardLibrary/ref/library.Debug+RteTest_ARMCM3.cbuild.yml b/tools/projmgr/test/data/TestSolution/StandardLibrary/ref/library.Debug+RteTest_ARMCM3.cbuild.yml index 51c5afc9f..96be1f070 100644 --- a/tools/projmgr/test/data/TestSolution/StandardLibrary/ref/library.Debug+RteTest_ARMCM3.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/StandardLibrary/ref/library.Debug+RteTest_ARMCM3.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM3 processor: fpu: off + core: Cortex-M3 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/ref/TestProject3_1.Debug+TypeA.cbuild-gen.yml b/tools/projmgr/test/data/TestSolution/ref/TestProject3_1.Debug+TypeA.cbuild-gen.yml index d9ec69531..f373f3c96 100644 --- a/tools/projmgr/test/data/TestSolution/ref/TestProject3_1.Debug+TypeA.cbuild-gen.yml +++ b/tools/projmgr/test/data/TestSolution/ref/TestProject3_1.Debug+TypeA.cbuild-gen.yml @@ -1,4 +1,4 @@ -build: +build-gen: generated-by: csolution version 2.1.0+p16-gf314eb6d current-generator: id: RteTestGeneratorIdentifier @@ -8,6 +8,8 @@ build: context: TestProject3_1.Debug+TypeA compiler: GCC@0.0.0 device: RteTestGen_ARMCM0 + processor: + core: Cortex-M0 packs: - pack: ARM::RteTestGenerator@0.1.0 path: ${DEVTOOLS(packs)}/ARM/RteTestGenerator/0.1.0 @@ -20,9 +22,9 @@ build: - ${DEVTOOLS(packs)}/ARM/RteTestGenerator/0.1.0/Include - ${DEVTOOLS(packs)}/ARM/RteTest_DFP/0.2.0/Device/ARM/ARMCM0/Include output-dirs: - intdir: ../tmp/TestProject3_1/TypeA/Debug - outdir: outdir/ - rtedir: RTE + intdir: ${DEVTOOLS(data)}/TestSolution/tmp/TestProject3_1/TypeA/Debug + outdir: ${DEVTOOLS(data)}/TestSolution/TestProject3_1/outdir + rtedir: ${DEVTOOLS(data)}/TestSolution/TestProject3_1/RTE output: - type: elf file: TestProject3_1.elf diff --git a/tools/projmgr/test/data/TestSolution/ref/TestProject3_1.Debug+TypeA.cbuild.yml b/tools/projmgr/test/data/TestSolution/ref/TestProject3_1.Debug+TypeA.cbuild.yml index 664ba587a..b63c397ac 100644 --- a/tools/projmgr/test/data/TestSolution/ref/TestProject3_1.Debug+TypeA.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/ref/TestProject3_1.Debug+TypeA.cbuild.yml @@ -5,6 +5,8 @@ build: context: TestProject3_1.Debug+TypeA compiler: GCC@0.0.0 device: RteTestGen_ARMCM0 + processor: + core: Cortex-M0 packs: - pack: ARM::RteTestGenerator@0.1.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTestGenerator/0.1.0 @@ -18,7 +20,7 @@ build: - ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0/Device/ARM/ARMCM0/Include output-dirs: intdir: ../tmp/TestProject3_1/TypeA/Debug - outdir: outdir/ + outdir: outdir rtedir: RTE output: - type: elf diff --git a/tools/projmgr/test/data/TestSolution/ref/cbuild/test1.Debug+CM0.cbuild.yml b/tools/projmgr/test/data/TestSolution/ref/cbuild/test1.Debug+CM0.cbuild.yml index 511f334f1..cd64bf203 100644 --- a/tools/projmgr/test/data/TestSolution/ref/cbuild/test1.Debug+CM0.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/ref/cbuild/test1.Debug+CM0.cbuild.yml @@ -9,6 +9,7 @@ build: fpu: off endian: little trustzone: non-secure + core: Cortex-M0 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/ref/cbuild/test1.Release+CM0.cbuild.yml b/tools/projmgr/test/data/TestSolution/ref/cbuild/test1.Release+CM0.cbuild.yml index 98a7365ed..e8cf2a0a4 100644 --- a/tools/projmgr/test/data/TestSolution/ref/cbuild/test1.Release+CM0.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/ref/cbuild/test1.Release+CM0.cbuild.yml @@ -9,6 +9,7 @@ build: fpu: off endian: little trustzone: non-secure + core: Cortex-M0 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/ref/cbuild/test2.Debug+CM0.cbuild.yml b/tools/projmgr/test/data/TestSolution/ref/cbuild/test2.Debug+CM0.cbuild.yml index 248c5f20d..0ce26846b 100644 --- a/tools/projmgr/test/data/TestSolution/ref/cbuild/test2.Debug+CM0.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/ref/cbuild/test2.Debug+CM0.cbuild.yml @@ -9,6 +9,7 @@ build: fpu: off endian: little trustzone: non-secure + core: Cortex-M0 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/ref/cbuild/test2.Debug+CM3.cbuild.yml b/tools/projmgr/test/data/TestSolution/ref/cbuild/test2.Debug+CM3.cbuild.yml index c0abee2b7..481fd9ffb 100644 --- a/tools/projmgr/test/data/TestSolution/ref/cbuild/test2.Debug+CM3.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/ref/cbuild/test2.Debug+CM3.cbuild.yml @@ -9,6 +9,7 @@ build: fpu: off endian: little trustzone: non-secure + core: Cortex-M3 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/ref/outputFiles.Debug+Target.cbuild.yml b/tools/projmgr/test/data/TestSolution/ref/outputFiles.Debug+Target.cbuild.yml index 1d3d92a26..9afc697d7 100644 --- a/tools/projmgr/test/data/TestSolution/ref/outputFiles.Debug+Target.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/ref/outputFiles.Debug+Target.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM3 processor: fpu: off + core: Cortex-M3 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/ref/outputFiles.Library+Target.cbuild.yml b/tools/projmgr/test/data/TestSolution/ref/outputFiles.Library+Target.cbuild.yml index 3f6462d1f..09087d4bc 100644 --- a/tools/projmgr/test/data/TestSolution/ref/outputFiles.Library+Target.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/ref/outputFiles.Library+Target.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM3 processor: fpu: off + core: Cortex-M3 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/ref/pre-include+CM0.cbuild.yml b/tools/projmgr/test/data/TestSolution/ref/pre-include+CM0.cbuild.yml index 28e62d354..8fb5f6abf 100644 --- a/tools/projmgr/test/data/TestSolution/ref/pre-include+CM0.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/ref/pre-include+CM0.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM0 processor: fpu: off + core: Cortex-M0 packs: - pack: ARM::RteTest@0.1.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest/0.1.0 diff --git a/tools/projmgr/test/data/TestSolution/ref/rtedir.Debug+CM0.cbuild.yml b/tools/projmgr/test/data/TestSolution/ref/rtedir.Debug+CM0.cbuild.yml index f77365d5e..25cea1f4c 100644 --- a/tools/projmgr/test/data/TestSolution/ref/rtedir.Debug+CM0.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/ref/rtedir.Debug+CM0.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM0 processor: fpu: off + core: Cortex-M0 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/data/TestSolution/ref/rtedir.Release+CM0.cbuild.yml b/tools/projmgr/test/data/TestSolution/ref/rtedir.Release+CM0.cbuild.yml index 44a541207..036143c64 100644 --- a/tools/projmgr/test/data/TestSolution/ref/rtedir.Release+CM0.cbuild.yml +++ b/tools/projmgr/test/data/TestSolution/ref/rtedir.Release+CM0.cbuild.yml @@ -7,6 +7,7 @@ build: device: RteTest_ARMCM0 processor: fpu: off + core: Cortex-M0 packs: - pack: ARM::RteTest_DFP@0.2.0 path: ${CMSIS_PACK_ROOT}/ARM/RteTest_DFP/0.2.0 diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 3ef28afa4..ba9767ea9 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -560,6 +560,20 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution) { testinput_folder + "/TestSolution/ref/cbuild/test2.Debug+CM0.cbuild.yml"); ProjMgrTestEnv:: CompareFile(testoutput_folder + "/test2.Debug+CM3.cbuild.yml", testinput_folder + "/TestSolution/ref/cbuild/test2.Debug+CM3.cbuild.yml"); + + // Check schema + EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testoutput_folder + "/test.cbuild-idx.yml", + ProjMgrYamlSchemaChecker::FileType::BUILDIDX)); + EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testoutput_folder + "/test1.Debug+CM0.cbuild.yml", + ProjMgrYamlSchemaChecker::FileType::BUILD)); + EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testoutput_folder + "/test1.Release+CM0.cbuild.yml", + ProjMgrYamlSchemaChecker::FileType::BUILD)); + EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testoutput_folder + "/test1.Debug+CM0.cbuild.yml", + ProjMgrYamlSchemaChecker::FileType::BUILD)); + EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testoutput_folder + "/test2.Debug+CM0.cbuild.yml", + ProjMgrYamlSchemaChecker::FileType::BUILD)); + EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testoutput_folder + "/test2.Debug+CM3.cbuild.yml", + ProjMgrYamlSchemaChecker::FileType::BUILD)); } TEST_F(ProjMgrUnitTests, RunProjMgrSolution_PositionalArguments) { @@ -2484,7 +2498,7 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_Local_Multiple_Pack_Files) { TEST_F(ProjMgrUnitTests, RunProjMgrSolution_Local_Pack_Path_Not_Found) { char* argv[7]; StdStreamRedirect streamRedirect; - const string errExpected = "pack path: ./SolutionSpecificPack/ARM does not exist"; + const string errExpected = "/SolutionSpecificPack/ARM does not exist"; const string& csolution = testinput_folder + "/TestSolution/test_local_pack_path_not_found.csolution.yml"; // convert --solution solution.yml @@ -2502,7 +2516,7 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_Local_Pack_Path_Not_Found) { TEST_F(ProjMgrUnitTests, RunProjMgrSolution_Local_Pack_File_Not_Found) { char* argv[7]; StdStreamRedirect streamRedirect; - const string errExpected = "pdsc file was not found in: ../SolutionSpecificPack/Device"; + const string errExpected = "pdsc file was not found in: .*/SolutionSpecificPack/Device"; const string& csolution = testinput_folder + "/TestSolution/test_local_pack_file_not_found.csolution.yml"; // convert --solution solution.yml @@ -2514,7 +2528,7 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_Local_Pack_File_Not_Found) { EXPECT_EQ(1, RunProjMgr(6, argv, 0)); auto errStr = streamRedirect.GetErrorString(); - EXPECT_NE(string::npos, errStr.find(errExpected)); + EXPECT_TRUE(regex_search(errStr, regex(errExpected))); } TEST_F(ProjMgrUnitTests, RunProjMgrSolution_List_Board_Pack) { @@ -3981,3 +3995,245 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_cbuildset_file) { EXPECT_TRUE(RteFsUtils::Exists(outputDir + "/test2.Debug+CM3.cbuild.yml")); EXPECT_TRUE(RteFsUtils::Exists(outputDir + "/test1.Release+CM0.cbuild.yml")); } + +TEST_F(ProjMgrUnitTests, ExternalGenerator) { + const string& srcGlobalGenerator = testinput_folder + "/ExternalGenerator/global.generator.yml"; + const string& dstGlobalGenerator = testcmsiscompiler_folder + "/global.generator.yml"; + RteFsUtils::CopyCheckFile(srcGlobalGenerator, dstGlobalGenerator, false); + + const string& srcBridgeTool = testinput_folder + "/ExternalGenerator/bridge.sh"; + const string& dstBridgeTool = testcmsiscompiler_folder + "/bridge.sh"; + RteFsUtils::CopyCheckFile(srcBridgeTool, dstBridgeTool, false); + + // list generators + char* argv[7]; + const string& csolution = testinput_folder + "/ExternalGenerator/extgen.csolution.yml"; + argv[1] = (char*)csolution.c_str(); + argv[2] = (char*)"list"; + argv[3] = (char*)"generators"; + EXPECT_EQ(0, RunProjMgr(4, argv, 0)); + + // run multi-core + argv[1] = (char*)csolution.c_str(); + argv[2] = (char*)"run"; + argv[3] = (char*)"-g"; + argv[4] = (char*)"RteTestExternalGenerator"; + argv[5] = (char*)"-c"; + argv[6] = (char*)"core0.Debug+MultiCore"; + EXPECT_EQ(0, RunProjMgr(7, argv, 0)); + + EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testinput_folder + "/ExternalGenerator/tmp/core0/MultiCore/Debug/extgen.cbuild-gen-idx.yml", + ProjMgrYamlSchemaChecker::FileType::BUILDGENIDX)); + EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testinput_folder + "/ExternalGenerator/tmp/core0/MultiCore/Debug/core0.Debug+MultiCore.cbuild-gen.yml", + ProjMgrYamlSchemaChecker::FileType::BUILDGEN)); + EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testinput_folder + "/ExternalGenerator/tmp/core1/MultiCore/Debug/core1.Debug+MultiCore.cbuild-gen.yml", + ProjMgrYamlSchemaChecker::FileType::BUILDGEN)); + + auto stripAbsoluteFunc = [](const std::string& in) { + std::string str = in; + RteUtils::ReplaceAll(str, testinput_folder, "${DEVTOOLS(data)}"); + RteUtils::ReplaceAll(str, testcmsispack_folder, "${DEVTOOLS(packs)}"); + return str; + }; + + ProjMgrTestEnv::CompareFile(testinput_folder + "/ExternalGenerator/ref/MultiCore/extgen.cbuild-gen-idx.yml", + testinput_folder + "/ExternalGenerator/tmp/core0/MultiCore/Debug/extgen.cbuild-gen-idx.yml", stripAbsoluteFunc); + ProjMgrTestEnv::CompareFile(testinput_folder + "/ExternalGenerator/ref/MultiCore/core0.Debug+MultiCore.cbuild-gen.yml", + testinput_folder + "/ExternalGenerator/tmp/core0/MultiCore/Debug/core0.Debug+MultiCore.cbuild-gen.yml", stripAbsoluteFunc); + ProjMgrTestEnv::CompareFile(testinput_folder + "/ExternalGenerator/ref/MultiCore/core1.Debug+MultiCore.cbuild-gen.yml", + testinput_folder + "/ExternalGenerator/tmp/core1/MultiCore/Debug/core1.Debug+MultiCore.cbuild-gen.yml", stripAbsoluteFunc); + + // run single-core + argv[6] = (char*)"single-core.Debug+CM0"; + EXPECT_EQ(0, RunProjMgr(7, argv, 0)); + + EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testinput_folder + "/ExternalGenerator/tmp/single-core/CM0/Debug/extgen.cbuild-gen-idx.yml", + ProjMgrYamlSchemaChecker::FileType::BUILDGENIDX)); + EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testinput_folder + "/ExternalGenerator/tmp/single-core/CM0/Debug/single-core.Debug+CM0.cbuild-gen.yml", + ProjMgrYamlSchemaChecker::FileType::BUILDGEN)); + + ProjMgrTestEnv::CompareFile(testinput_folder + "/ExternalGenerator/ref/SingleCore/extgen.cbuild-gen-idx.yml", + testinput_folder + "/ExternalGenerator/tmp/single-core/CM0/Debug/extgen.cbuild-gen-idx.yml", stripAbsoluteFunc); + ProjMgrTestEnv::CompareFile(testinput_folder + "/ExternalGenerator/ref/SingleCore/single-core.Debug+CM0.cbuild-gen.yml", + testinput_folder + "/ExternalGenerator/tmp/single-core/CM0/Debug/single-core.Debug+CM0.cbuild-gen.yml", stripAbsoluteFunc); + + // run trustzone + argv[6] = (char*)"ns.Debug+CM0"; + EXPECT_EQ(0, RunProjMgr(7, argv, 0)); + + EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testinput_folder + "/ExternalGenerator/tmp/ns/CM0/Debug/extgen.cbuild-gen-idx.yml", + ProjMgrYamlSchemaChecker::FileType::BUILDGENIDX)); + EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testinput_folder + "/ExternalGenerator/tmp/ns/CM0/Debug/ns.Debug+CM0.cbuild-gen.yml", + ProjMgrYamlSchemaChecker::FileType::BUILDGEN)); + EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testinput_folder + "/ExternalGenerator/tmp/s/CM0/Debug/s.Debug+CM0.cbuild-gen.yml", + ProjMgrYamlSchemaChecker::FileType::BUILDGEN)); + + ProjMgrTestEnv::CompareFile(testinput_folder + "/ExternalGenerator/ref/TrustZone/extgen.cbuild-gen-idx.yml", + testinput_folder + "/ExternalGenerator/tmp/ns/CM0/Debug/extgen.cbuild-gen-idx.yml", stripAbsoluteFunc); + ProjMgrTestEnv::CompareFile(testinput_folder + "/ExternalGenerator/ref/TrustZone/ns.Debug+CM0.cbuild-gen.yml", + testinput_folder + "/ExternalGenerator/tmp/ns/CM0/Debug/ns.Debug+CM0.cbuild-gen.yml", stripAbsoluteFunc); + ProjMgrTestEnv::CompareFile(testinput_folder + "/ExternalGenerator/ref/TrustZone/s.Debug+CM0.cbuild-gen.yml", + testinput_folder + "/ExternalGenerator/tmp/s/CM0/Debug/s.Debug+CM0.cbuild-gen.yml", stripAbsoluteFunc); + + // convert single core + argv[2] = (char*)"convert"; + argv[3] = (char*)"-c"; + argv[4] = (char*)"single-core.Debug+CM0"; + EXPECT_EQ(0, RunProjMgr(5, argv, 0)); + + ProjMgrTestEnv::CompareFile(testinput_folder + "/ExternalGenerator/single/single-core.Debug+CM0.cbuild.yml", + testinput_folder + "/ExternalGenerator/ref/SingleCore/single-core.Debug+CM0.cbuild.yml"); + + RteFsUtils::RemoveFile(dstGlobalGenerator); + RteFsUtils::RemoveFile(dstBridgeTool); +} + +TEST_F(ProjMgrUnitTests, ExternalGenerator_NotRegistered) { + StdStreamRedirect streamRedirect; + char* argv[7]; + const string& csolution = testinput_folder + "/ExternalGenerator/extgen.csolution.yml"; + argv[1] = (char*)csolution.c_str(); + argv[2] = (char*)"run"; + argv[3] = (char*)"-g"; + argv[4] = (char*)"RteTestExternalGenerator"; + argv[5] = (char*)"-c"; + argv[6] = (char*)"single-core.Debug+CM0"; + EXPECT_EQ(1, RunProjMgr(7, argv, 0)); + + const string expected = "\ +error csolution: generator 'RteTestExternalGenerator' required by component 'ARM::RteTestGenerator:Check Global Generator@0.9.0' was not found in global register\n\ +"; + auto errStr = streamRedirect.GetErrorString(); + EXPECT_TRUE(errStr.find(expected) != string::npos); +} + +TEST_F(ProjMgrUnitTests, ExternalGenerator_WrongGenDir) { + const string& srcGlobalGenerator = testinput_folder + "/ExternalGenerator/wrong-gendir.generator.yml"; + const string& dstGlobalGenerator = testcmsiscompiler_folder + "/global.generator.yml"; + RteFsUtils::CopyCheckFile(srcGlobalGenerator, dstGlobalGenerator, false); + + StdStreamRedirect streamRedirect; + char* argv[8]; + const string& csolution = testinput_folder + "/ExternalGenerator/extgen.csolution.yml"; + argv[1] = (char*)csolution.c_str(); + argv[2] = (char*)"run"; + argv[3] = (char*)"-g"; + argv[4] = (char*)"RteTestExternalGenerator"; + argv[5] = (char*)"-c"; + argv[6] = (char*)"core0.Debug+MultiCore"; + argv[7] = (char*)"-n"; + EXPECT_EQ(1, RunProjMgr(8, argv, 0)); + + const string expected = "\ +warning csolution: unknown access sequence: 'UnknownAccessSequence()'\n\ +"; + auto errStr = streamRedirect.GetErrorString(); + EXPECT_TRUE(errStr.find(expected) != string::npos); + + RteFsUtils::RemoveFile(dstGlobalGenerator); +} + +TEST_F(ProjMgrUnitTests, ExternalGenerator_NoGenDir) { + const string& srcGlobalGenerator = testinput_folder + "/ExternalGenerator/no-gendir.generator.yml"; + const string& dstGlobalGenerator = testcmsiscompiler_folder + "/global.generator.yml"; + RteFsUtils::CopyCheckFile(srcGlobalGenerator, dstGlobalGenerator, false); + + StdStreamRedirect streamRedirect; + const string expected = "\ +error csolution: generator output directory was not set\n\ +"; + char* argv[8]; + const string& csolution = testinput_folder + "/ExternalGenerator/extgen.csolution.yml"; + argv[1] = (char*)csolution.c_str(); + argv[2] = (char*)"-c"; + argv[3] = (char*)"core0.Debug+MultiCore"; + argv[4] = (char*)"-n"; + argv[5] = (char*)"run"; + argv[6] = (char*)"-g"; + argv[7] = (char*)"RteTestExternalGenerator"; + EXPECT_EQ(1, RunProjMgr(8, argv, 0)); + + auto errStr = streamRedirect.GetErrorString(); + EXPECT_TRUE(errStr.find(expected) != string::npos); + + RteFsUtils::RemoveFile(dstGlobalGenerator); +} + +TEST_F(ProjMgrUnitTests, ExternalGenerator_MultipleContexts) { + StdStreamRedirect streamRedirect; + char* argv[7]; + const string& csolution = testinput_folder + "/ExternalGenerator/extgen.csolution.yml"; + argv[1] = (char*)csolution.c_str(); + argv[2] = (char*)"run"; + argv[3] = (char*)"-g"; + argv[4] = (char*)"RteTestExternalGenerator"; + argv[5] = (char*)"-c"; + argv[6] = (char*)"+MultiCore"; + EXPECT_EQ(1, RunProjMgr(7, argv, 0)); + + const string expected = "\ +error csolution: a single context must be specified\n\ +"; + auto errStr = streamRedirect.GetErrorString(); + EXPECT_TRUE(errStr.find(expected) != string::npos); +} + +TEST_F(ProjMgrUnitTests, ExternalGenerator_WrongGeneratedData) { + const string& srcGlobalGenerator = testinput_folder + "/ExternalGenerator/global.generator.yml"; + const string& dstGlobalGenerator = testcmsiscompiler_folder + "/global.generator.yml"; + RteFsUtils::CopyCheckFile(srcGlobalGenerator, dstGlobalGenerator, false); + + StdStreamRedirect streamRedirect; + char* argv[5]; + const string& csolution = testinput_folder + "/ExternalGenerator/wrong.csolution.yml"; + argv[1] = (char*)csolution.c_str(); + argv[2] = (char*)"convert"; + argv[3] = (char*)"-c"; + argv[4] = (char*)"wrong.WrongPack+CM0"; + EXPECT_EQ(1, RunProjMgr(5, argv, 0)); + auto errStr = streamRedirect.GetErrorString(); + EXPECT_TRUE(errStr.find("error csolution: required pack: UnknownVendor::UnknownPack not installed") != string::npos); + + streamRedirect.ClearStringStreams(); + argv[4] = (char*)"wrong.WrongComponent+CM0"; + EXPECT_EQ(1, RunProjMgr(5, argv, 0)); + errStr = streamRedirect.GetErrorString(); + EXPECT_TRUE(errStr.find("error csolution: no component was found with identifier 'UnknownVendor::UnknownComponent'") != string::npos); + + streamRedirect.ClearStringStreams(); + argv[4] = (char*)"wrong.WrongGroup+CM0"; + EXPECT_EQ(1, RunProjMgr(5, argv, 0)); + errStr = streamRedirect.GetErrorString(); + EXPECT_TRUE(errStr.find("error csolution: conflict: group 'sources' is declared multiple times") != string::npos); + + streamRedirect.ClearStringStreams(); + argv[4] = (char*)"wrong.Debug+WrongDevice"; + EXPECT_EQ(1, RunProjMgr(5, argv, 0)); + errStr = streamRedirect.GetErrorString(); + + RteFsUtils::RemoveFile(dstGlobalGenerator); +} + +TEST_F(ProjMgrUnitTests, ExternalGenerator_NoCgenFile) { + const string& srcGlobalGenerator = testinput_folder + "/ExternalGenerator/global.generator.yml"; + const string& dstGlobalGenerator = testcmsiscompiler_folder + "/global.generator.yml"; + RteFsUtils::CopyCheckFile(srcGlobalGenerator, dstGlobalGenerator, false); + + const string genDir = m_extGenerator.GetGlobalGenDir("RteTestExternalGenerator"); + if (!genDir.empty()) { + RteFsUtils::RemoveDir(genDir); + } + + StdStreamRedirect streamRedirect; + char* argv[5]; + const string& csolution = testinput_folder + "/ExternalGenerator/extgen.csolution.yml"; + argv[1] = (char*)csolution.c_str(); + argv[2] = (char*)"convert"; + argv[3] = (char*)"-c"; + argv[4] = (char*)"core0.Debug+MultiCore"; + EXPECT_EQ(1, RunProjMgr(5, argv, 0)); + auto errStr = streamRedirect.GetErrorString(); + EXPECT_TRUE(errStr.find("error csolution: cgen file was not found, run generator 'RteTestExternalGenerator' for context 'core0.Debug+MultiCore'") != string::npos); + + RteFsUtils::RemoveFile(dstGlobalGenerator); +} diff --git a/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp b/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp index 20f358268..4f7b0d697 100644 --- a/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp @@ -17,7 +17,8 @@ using namespace std; class ProjMgrWorkerUnitTests : public ProjMgrWorker, public ::testing::Test { protected: - ProjMgrWorkerUnitTests() {} + ProjMgrParser parser; + ProjMgrWorkerUnitTests() : ProjMgrWorker(&parser, nullptr) {} virtual ~ProjMgrWorkerUnitTests() {} void SetCsolutionPacks(CsolutionItem* csolution, std::vector packs, std::string targetType); @@ -566,8 +567,6 @@ TEST_F(ProjMgrWorkerUnitTests, LoadFilteredPack_1) { TEST_F(ProjMgrWorkerUnitTests, LoadFilteredPack_2) { CsolutionItem csolution; SetCsolutionPacks(&csolution, { "ARM" }, "Test"); - ProjMgrParser parser; - SetParser(&parser); // get list of available packs vector availablePacks; @@ -590,8 +589,6 @@ TEST_F(ProjMgrWorkerUnitTests, LoadFilteredPack_3) { TEST_F(ProjMgrWorkerUnitTests, LoadFilteredPack_4) { CsolutionItem csolution; SetCsolutionPacks(&csolution, { "ARM::*" }, "Test"); - ProjMgrParser parser; - SetParser(&parser); // get list of available packs vector availablePacks;