Skip to content

Commit a3bb486

Browse files
committed
Initial zephyr/west integration support
1 parent b26e068 commit a3bb486

11 files changed

Lines changed: 151 additions & 19 deletions

tools/projmgr/include/ProjMgrParser.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ struct TargetSetItem {
209209
* misc compiler controls,
210210
* platform processor
211211
* context map
212+
* west defines
212213
*/
213214
struct BuildType {
214215
std::string compiler;
@@ -228,6 +229,7 @@ struct BuildType {
228229
ProcessorItem processor;
229230
std::vector<std::pair<std::string, std::string>> variables;
230231
std::vector<ContextName> contextMap;
232+
std::vector<std::string> westDefs;
231233
};
232234

233235
/**
@@ -452,6 +454,18 @@ struct GroupNode {
452454
TypeFilter type;
453455
};
454456

457+
/**
458+
* @brief west descriptor
459+
*/
460+
struct WestDesc {
461+
std::string projectId;
462+
std::string app;
463+
std::string board;
464+
std::string device;
465+
std::vector<std::string> westDefs;
466+
std::vector<std::string> westOpt;
467+
};
468+
455469
/**
456470
* @brief context descriptor containing
457471
* cproject filename,
@@ -460,6 +474,7 @@ struct GroupNode {
460474
struct ContextDesc {
461475
std::string cproject;
462476
TypeFilter type;
477+
WestDesc west;
463478
};
464479

465480
/**
@@ -506,6 +521,7 @@ typedef std::vector<std::pair<std::string, TargetType>> TargetTypes;
506521
* target types,
507522
* target properties,
508523
* list of cprojects,
524+
* list of west apps,
509525
* list of contexts descriptors,
510526
* list of packs,
511527
* cdefault enable switch,
@@ -524,6 +540,7 @@ struct CsolutionItem {
524540
TargetTypes targetTypes;
525541
TargetType target;
526542
std::vector<std::string> cprojects;
543+
std::vector<std::string> westApps;
527544
std::vector<ContextDesc> contexts;
528545
std::vector<PackItem> packs;
529546
bool enableCdefault;

tools/projmgr/include/ProjMgrUtils.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,13 @@ class ProjMgrUtils {
321321
*/
322322
static const std::string NormalizeLineEndings(const std::string& in);
323323

324+
/**
325+
* @brief convert board string to west board string
326+
* @param board string
327+
* @return output west board string
328+
*/
329+
static const std::string GetWestBoard(const std::string& board);
330+
324331
protected:
325332
/**
326333
* @brief get filtered list of contexts

tools/projmgr/include/ProjMgrWorker.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ struct DebuggerType {
429429
* load offset for generated binary
430430
* elf load mode
431431
* image only flag
432+
* west options
432433
*/
433434
struct ContextItem {
434435
CdefaultItem* cdefault = nullptr;
@@ -498,6 +499,7 @@ struct ContextItem {
498499
std::string loadOffset;
499500
std::string elfLoadMode;
500501
bool imageOnly = false;
502+
WestDesc west;
501503
};
502504

503505
/**
@@ -509,6 +511,11 @@ static constexpr const char* PLM_STATUS_UPDATE_REQUIRED = "update required";
509511
static constexpr const char* PLM_STATUS_UPDATE_RECOMMENDED = "update recommended";
510512
static constexpr const char* PLM_STATUS_UPDATE_SUGGESTED = "update suggested";
511513

514+
/**
515+
* @brief west board variable
516+
*/
517+
static constexpr const char* WEST_BOARD = "west-board";
518+
512519
/**
513520
* @brief set policy for packs loading [latest|all|required]
514521
*/

tools/projmgr/include/ProjMgrYamlParser.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ static constexpr const char* YAML_ARGUMENTS = "arguments";
2727
static constexpr const char* YAML_APID = "apid";
2828
static constexpr const char* YAML_APIS = "apis";
2929
static constexpr const char* YAML_API = "api";
30+
static constexpr const char* YAML_APP_PATH = "app-path";
3031
static constexpr const char* YAML_ATOMIC = "atomic";
3132
static constexpr const char* YAML_ATTR = "attr";
3233
static constexpr const char* YAML_AUTO = "auto";
@@ -189,6 +190,7 @@ static constexpr const char* YAML_PROCESSORS = "processors";
189190
static constexpr const char* YAML_PROCESSOR = "processor";
190191
static constexpr const char* YAML_PROGRAMMING = "programming";
191192
static constexpr const char* YAML_PROJECT = "project";
193+
static constexpr const char* YAML_PROJECT_ID = "project-id";
192194
static constexpr const char* YAML_PROJECTS = "projects";
193195
static constexpr const char* YAML_PROJECT_CONTEXT = "project-context";
194196
static constexpr const char* YAML_PROJECT_TYPE = "project-type";
@@ -243,6 +245,10 @@ static constexpr const char* YAML_VARS = "vars";
243245
static constexpr const char* YAML_VALUE = "value";
244246
static constexpr const char* YAML_VERSION = "version";
245247
static constexpr const char* YAML_WARNINGS = "warnings";
248+
static constexpr const char* YAML_WEST = "west";
249+
static constexpr const char* YAML_WEST_BOARD = "west-board";
250+
static constexpr const char* YAML_WEST_DEFS = "west-defs";
251+
static constexpr const char* YAML_WEST_OPT = "west-opt";
246252
static constexpr const char* YAML_WHILE = "while";
247253
static constexpr const char* YAML_WORKING_DIR = "working-dir";
248254

tools/projmgr/schemas/common.schema.json

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,8 @@
601601
"target-set": { "$ref": "#/definitions/TargetSetsType" },
602602
"undefine": { "$ref": "#/definitions/UndefinesType" },
603603
"variables": { "$ref": "#/definitions/VariablesType" },
604-
"warnings": { "$ref": "#/definitions/WarningsType" }
604+
"warnings": { "$ref": "#/definitions/WarningsType" },
605+
"west-defs": { "$ref": "#/definitions/WestDefsType" }
605606
},
606607
"additionalProperties": false,
607608
"required" : [ "type"]
@@ -638,7 +639,8 @@
638639
"processor": { "$ref": "#/definitions/ProcessorType" },
639640
"undefine": { "$ref": "#/definitions/UndefinesType" },
640641
"variables": { "$ref": "#/definitions/VariablesType" },
641-
"warnings": { "$ref": "#/definitions/WarningsType" }
642+
"warnings": { "$ref": "#/definitions/WarningsType" },
643+
"west-defs": { "$ref": "#/definitions/WestDefsType" }
642644
},
643645
"additionalProperties": false,
644646
"required" : [ "type"]
@@ -660,13 +662,13 @@
660662
"pattern": "^.*[/]([^.+]*\\.cproject\\.(yml|yaml))$|^([^.+]+)\\.cproject\\.(yml|yaml)$",
661663
"description": "Path to the valid project file."
662664
},
665+
"west": { "$ref": "#/definitions/WestProjectType" },
663666
"for-context": { "$ref": "#/definitions/ForContext" },
664667
"not-for-context": { "$ref": "#/definitions/NotForContext" }
665668
},
666-
"additionalProperties": false,
667-
"allOf": [
668-
{ "$ref": "#/definitions/TypeListMutualExclusion"},
669-
{ "required": [ "project" ] }
669+
"additionalProperties": true,
670+
"oneOf": [
671+
{ "$ref": "#/definitions/TypeListMutualExclusion"}
670672
]
671673
},
672674
"ProcessorTrustzone": {
@@ -1274,6 +1276,7 @@
12741276
"type": "object",
12751277
"properties": {
12761278
"cbuild": { "type": "string", "description": "Path to <context>.cbuild.yml file." },
1279+
"west": { "type": "boolean" },
12771280
"project": { "type": "string", "description": "Project name." },
12781281
"configuration": { "$ref": "#/definitions/BuildContext" },
12791282
"depends-on": {
@@ -1427,7 +1430,8 @@
14271430
"licenses": {
14281431
"type": "array",
14291432
"items": { "$ref": "#/definitions/LicenseInfoType" }
1430-
}
1433+
},
1434+
"west": { "$ref": "#/definitions/WestProjectType" }
14311435
},
14321436
"additionalProperties": false
14331437
},
@@ -2398,6 +2402,15 @@
23982402
"title": "optimize:\nDocumentation: https://open-cmsis-pack.github.io/cmsis-toolbox/YML-Input-Format/#load",
23992403
"description": "Specifies the load mode for the project output or image file.",
24002404
"enum": [ "image+symbols", "symbols", "image", "none" ]
2405+
},
2406+
"WestProjectType": {
2407+
"type": "object",
2408+
"additionalProperties": true
2409+
},
2410+
"WestDefsType": {
2411+
"type": "array",
2412+
"minItems": 1,
2413+
"items": {}
24012414
}
24022415
}
24032416
}

tools/projmgr/src/ProjMgr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ bool ProjMgr::PopulateContexts(void) {
487487
}
488488
// Check cproject separate folders and unique names
489489
const StrVec& cprojects = m_parser.GetCsolution().cprojects;
490-
if (!IsSolutionImageOnly() && cprojects.empty()) {
490+
if (!IsSolutionImageOnly() && cprojects.empty() && m_parser.GetCsolution().westApps.empty()) {
491491
ProjMgrLogger::Get().Error("projects not found", "", m_csolutionFile);
492492
return false;
493493
}

tools/projmgr/src/ProjMgrCbuild.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class ProjMgrCbuild : public ProjMgrCbuildBase {
4040
void SetBooksNode(YAML::Node node, const std::vector<BookItem>& books, const std::string& dir);
4141
void SetDebugConfigNode(YAML::Node node, const ContextItem* context);
4242
void SetPLMStatus(YAML::Node node, const ContextItem* context, const string& file);
43+
void SetWestNode(YAML::Node node, const ContextItem* context);
4344
bool m_ignoreRteFileMissing;
4445
};
4546

@@ -108,7 +109,14 @@ void ProjMgrCbuild::SetContextNode(YAML::Node contextNode, const ContextItem* co
108109
}
109110
}
110111
SetOutputDirsNode(contextNode[YAML_OUTPUTDIRS], context);
111-
SetOutputNode(contextNode[YAML_OUTPUT], context);
112+
}
113+
if (!context->west.app.empty()) {
114+
string outDir = context->directories.outdir;
115+
RteFsUtils::NormalizePath(outDir, context->directories.cprj);
116+
SetNodeValue(contextNode[YAML_OUTPUTDIRS][YAML_OUTPUT_OUTDIR], FormatPath(outDir, context->directories.cbuild));
117+
}
118+
SetOutputNode(contextNode[YAML_OUTPUT], context);
119+
if (!context->imageOnly) {
112120
SetComponentsNode(contextNode[YAML_COMPONENTS], context);
113121
SetApisNode(contextNode[YAML_APIS], context);
114122
SetGeneratorsNode(contextNode[YAML_GENERATORS], context);
@@ -117,6 +125,9 @@ void ProjMgrCbuild::SetContextNode(YAML::Node contextNode, const ContextItem* co
117125
SetConstructedFilesNode(contextNode[YAML_CONSTRUCTEDFILES], context);
118126
}
119127
SetLicenseInfoNode(contextNode[YAML_LICENSES], context);
128+
if (!context->west.app.empty()) {
129+
SetWestNode(contextNode[YAML_WEST], context);
130+
}
120131
}
121132

122133
void ProjMgrCbuild::SetComponentsNode(YAML::Node node, const ContextItem* context) {
@@ -590,3 +601,12 @@ bool ProjMgrYamlEmitter::GenerateCbuild(ContextItem* context,
590601
context->needRebuild = NeedRebuild(filename, rootNode);
591602
return WriteFile(rootNode, filename, context->name);
592603
}
604+
605+
void ProjMgrCbuild::SetWestNode(YAML::Node node, const ContextItem* context) {
606+
SetNodeValue(node[YAML_PROJECT_ID], context->west.projectId);
607+
SetNodeValue(node[YAML_APP_PATH], FormatPath(context->west.app, context->directories.cbuild));
608+
SetNodeValue(node[YAML_BOARD], context->west.board);
609+
SetNodeValue(node[YAML_DEVICE], context->west.device);
610+
SetNodeValue(node[YAML_WEST_DEFS], context->west.westDefs);
611+
SetNodeValue(node[YAML_WEST_OPT], context->west.westOpt);
612+
}

tools/projmgr/src/ProjMgrCbuildIdx.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ ProjMgrCbuildIdx::ProjMgrCbuildIdx(YAML::Node node,
4444
SetNodeValue(node[YAML_OUTPUT_TMPDIR], FormatPath(parser->GetCsolution().directories.tmpdir, directory));
4545

4646
// Image Only flag
47-
if (!processedContexts.empty() && processedContexts.front()->imageOnly) {
47+
if (!processedContexts.empty() && processedContexts.front()->imageOnly && parser->GetCsolution().westApps.empty()) {
4848
node[YAML_IMAGE_ONLY] = true;
4949
}
5050

@@ -134,8 +134,11 @@ ProjMgrCbuildIdx::ProjMgrCbuildIdx(YAML::Node node,
134134
const string& filename = context->directories.cprj + "/" + context->name + ".cbuild.yml";
135135
const string& relativeFilename = fs::relative(filename, directory, ec).generic_string();
136136
SetNodeValue(cbuildNode[YAML_CBUILD], relativeFilename);
137+
if (!context->west.app.empty()) {
138+
cbuildNode[YAML_WEST] = true;
139+
}
137140
if (context->cproject) {
138-
if (!context->imageOnly) {
141+
if (!context->imageOnly || !context->west.app.empty()) {
139142
SetNodeValue(cbuildNode[YAML_PROJECT], context->cproject->name);
140143
}
141144
SetNodeValue(cbuildNode[YAML_CONFIGURATION],

tools/projmgr/src/ProjMgrUtils.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,3 +498,11 @@ const std::string ProjMgrUtils::NormalizeLineEndings(const std::string& in) {
498498
}
499499
return out;
500500
}
501+
502+
const std::string ProjMgrUtils::GetWestBoard(const std::string& board) {
503+
string westBoard = RteUtils::StripSuffix(RteUtils::StripPrefix(board, "::"));
504+
std::transform(westBoard.begin(), westBoard.end(), westBoard.begin(),
505+
[](unsigned char c) { return std::tolower(c); });
506+
std::replace(westBoard.begin(), westBoard.end(), '-', '_');
507+
return westBoard;
508+
}

tools/projmgr/src/ProjMgrWorker.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,26 @@ void ProjMgrWorker::AddImageOnlyContext() {
8484
}
8585

8686
bool ProjMgrWorker::AddContexts(ProjMgrParser& parser, ContextDesc& descriptor, const string& cprojectFile) {
87-
error_code ec;
8887
ContextItem context;
88+
context.cdefault = &parser.GetCdefault();
89+
context.csolution = &parser.GetCsolution();
8990
std::map<std::string, CprojectItem>& cprojects = parser.GetCprojects();
9091
if (cprojects.find(cprojectFile) == cprojects.end()) {
9192
ProjMgrLogger::Get().Error("cproject not parsed, adding context failed", "", cprojectFile);
9293
return false;
9394
}
9495
context.cproject = &cprojects.at(cprojectFile);
95-
context.cdefault = &parser.GetCdefault();
96-
context.csolution = &parser.GetCsolution();
96+
97+
// west app
98+
if (!descriptor.west.app.empty()) {
99+
context.west = descriptor.west;
100+
RteFsUtils::NormalizePath(context.west.app, context.csolution->directory);
101+
context.imageOnly = true;
102+
//context.cproject = &cprojects[westApp];
103+
context.cproject->output.baseName = "zephyr";
104+
context.cproject->name = context.west.projectId;
105+
context.cproject->output.type = { "elf", "hex" };
106+
}
97107

98108
// No build/target-types
99109
if (context.csolution->buildTypes.empty() && context.csolution->targetTypes.empty()) {
@@ -2204,7 +2214,7 @@ bool ProjMgrWorker::ProcessConfigFiles(ContextItem& context) {
22042214
}
22052215
}
22062216
// Linker script
2207-
if (context.outputTypes.elf.on) {
2217+
if (context.outputTypes.elf.on && !context.imageOnly) {
22082218
if (context.linker.autoGen) {
22092219
if (!context.linker.script.empty()) {
22102220
ProjMgrLogger::Get().Warn("conflict: automatic linker script generation overrules specified script '" + context.linker.script + "'", context.name);
@@ -2863,6 +2873,10 @@ bool ProjMgrWorker::ProcessPrecedences(ContextItem& context, BoardOrDevice proce
28632873
error |= true;
28642874
}
28652875

2876+
if (!context.west.device.empty()) {
2877+
context.cproject->target.device = context.west.device;
2878+
}
2879+
28662880
StringCollection device = {
28672881
&context.device,
28682882
{
@@ -2901,7 +2915,7 @@ bool ProjMgrWorker::ProcessPrecedences(ContextItem& context, BoardOrDevice proce
29012915
if (!ProcessCompilerPrecedence(compiler, true)) {
29022916
error |= true;
29032917
}
2904-
if (!context.imageOnly && !ProcessToolchain(context)) {
2918+
if ((!context.imageOnly || !context.west.app.empty()) && !ProcessToolchain(context)) {
29052919
error |= true;
29062920
}
29072921

@@ -2914,6 +2928,9 @@ bool ProjMgrWorker::ProcessPrecedences(ContextItem& context, BoardOrDevice proce
29142928
context.variables[RteConstants::AS_PNAME] = deviceItem.pname;
29152929
context.variables[RteConstants::AS_BNAME] = boardItem.name;
29162930
context.variables[RteConstants::AS_COMPILER] = context.toolchain.name;
2931+
context.variables.insert({ WEST_BOARD, ProjMgrUtils::GetWestBoard(boardItem.name) });
2932+
context.west.board = context.west.board.empty() ? context.variables.at(WEST_BOARD) :
2933+
RteUtils::ExpandAccessSequences(context.west.board, context.variables);
29172934

29182935
// Add cdefault misc into csolution
29192936
if (context.cdefault) {
@@ -3129,6 +3146,10 @@ bool ProjMgrWorker::ProcessPrecedences(ContextItem& context, BoardOrDevice proce
31293146
CollectionUtils::AddStringItemsUniquely(definesAsmRef, setup.definesAsm);
31303147
}
31313148

3149+
// Merge west defines
3150+
CollectionUtils::AddStringItemsUniquely(context.west.westDefs, context.controls.target.westDefs);
3151+
CollectionUtils::AddStringItemsUniquely(context.west.westDefs, context.controls.build.westDefs);
3152+
31323153
// Includes
31333154
vector<string> projectAddPaths, projectDelPaths;
31343155
CollectionUtils::AddStringItemsUniquely(projectAddPaths, context.controls.cproject.addpaths);

0 commit comments

Comments
 (0)