Skip to content

Commit 21f62ef

Browse files
authored
[projmgr] Add support for image-only solutions
1 parent d8089a3 commit 21f62ef

14 files changed

+338
-60
lines changed

tools/projmgr/include/ProjMgrWorker.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ struct DebuggerType {
362362
* selected target-set
363363
* load offset for generated binary
364364
* load modes
365+
* image only flag
365366
*/
366367
struct ContextItem {
367368
CdefaultItem* cdefault = nullptr;
@@ -430,6 +431,7 @@ struct ContextItem {
430431
std::string targetSet;
431432
std::string loadOffset;
432433
StrMap loadMode;
434+
bool imageOnly = false;
433435
};
434436

435437
/**
@@ -748,13 +750,11 @@ class ProjMgrWorker {
748750
* @brief parse context selection
749751
* @param contexts pattern (wildcards are allowed)
750752
* @param check cbuildset flag (default false)
751-
* @param active target-set (default empty)
752753
* @return true if executed successfully
753754
*/
754755
bool ParseContextSelection(
755756
const std::vector<std::string>& contextSelection,
756-
const bool checkCbuildSet = false,
757-
const std::string activeTargetSet = std::string());
757+
const bool checkCbuildSet = false);
758758

759759
/**
760760
* @brief get the list of selected contexts
@@ -910,6 +910,18 @@ class ProjMgrWorker {
910910
*/
911911
bool ValidateContext(ContextItem& context);
912912

913+
/**
914+
* @brief populate active target set
915+
* @param active target set command line option
916+
* @return true if there is no error
917+
*/
918+
bool PopulateActiveTargetSet(const std::string& activeTargetSet);
919+
920+
/**
921+
* @brief add image-only context
922+
*/
923+
void AddImageOnlyContext();
924+
913925
/**
914926
* @brief clear worker members for reloading a solution
915927
* @return true if there is no error
@@ -978,6 +990,7 @@ class ProjMgrWorker {
978990
std::map<std::string, FileNode> m_missingFiles;
979991
std::string m_activeTargetType;
980992
TargetSetItem m_activeTargetSet;
993+
CprojectItem m_imageOnly;
981994

982995
bool CheckMissingPackRequirements(const std::string& contextName);
983996
void CheckMissingLinkerScript(ContextItem& context);
@@ -1084,8 +1097,7 @@ class ProjMgrWorker {
10841097
void ProcessTmpDir(std::string& tmpdir, const std::string& base);
10851098
bool IsCreatedByExecute(const std::string file, const std::string dir);
10861099
bool CollectAllRequiredPdscFiles();
1087-
bool ParseTargetSetContextSelection(const std::string& activeTargetSet);
1088-
bool GetActiveTargetSet(const std::string& activeTargetSet);
1100+
bool ParseTargetSetContextSelection();
10891101
};
10901102

10911103
#endif // PROJMGRWORKER_H

tools/projmgr/include/ProjMgrYamlParser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ static constexpr const char* YAML_ID = "id";
128128
static constexpr const char* YAML_IF = "if";
129129
static constexpr const char* YAML_IMAGES = "images";
130130
static constexpr const char* YAML_IMAGE = "image";
131+
static constexpr const char* YAML_IMAGE_ONLY = "image-only";
131132
static constexpr const char* YAML_IMPLEMENTED_BY = "implemented-by";
132133
static constexpr const char* YAML_IMPLEMENTS = "implements";
133134
static constexpr const char* YAML_INDEX = "index";

tools/projmgr/schemas/common.schema.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,7 +1152,7 @@
11521152
"warnings": { "$ref": "#/definitions/WarningsType" }
11531153
},
11541154
"additionalProperties": false,
1155-
"required": [ "target-types", "projects" ]
1155+
"required": [ "target-types" ]
11561156
},
11571157
"ProjectDescType": {
11581158
"title": "project:\nDocumentation: https://open-cmsis-pack.github.io/cmsis-toolbox/YML-Input-Format/#project",
@@ -1208,6 +1208,7 @@
12081208
"csolution": { "type": "string", "description": "Path to csolution.yml file." },
12091209
"cbuild-run": { "type": "string", "description": "Path to cbuild-run.yml file." },
12101210
"tmpdir": { "type": "string", "description": "Specifies the directory for the interim temporary files." },
1211+
"image-only": { "type": "boolean", "description": "Indicates image only solution." },
12111212
"cprojects": { "$ref": "#/definitions/BuildProjectsType" },
12121213
"cbuilds": { "$ref": "#/definitions/BuildContextsType" },
12131214
"configurations": { "$ref": "#/definitions/BuildConfigurationsType" },
@@ -1219,7 +1220,7 @@
12191220
"rebuild": { "type": "boolean", "description": "Flag indicating intermediate files need to be cleaned before the next build." }
12201221
},
12211222
"additionalProperties": false,
1222-
"required": ["generated-by", "csolution", "cprojects"]
1223+
"required": ["generated-by", "csolution"]
12231224
},
12241225
"BuildProjectsType": {
12251226
"title": "cprojects:\nDocumentation: https://open-cmsis-pack.github.io/cmsis-toolbox/YML-CBuild-Format/#cprojects",
@@ -1279,7 +1280,7 @@
12791280
"messages": { "$ref": "#/definitions/MessagesType" }
12801281
},
12811282
"additionalProperties": false,
1282-
"required": ["cbuild", "project", "configuration"]
1283+
"required": ["cbuild", "configuration"]
12831284
},
12841285
"BuildConfigurationsType": {
12851286
"type": "array",

tools/projmgr/src/ProjMgr.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,10 @@ bool ProjMgr::PopulateContexts(void) {
470470
}
471471
// Check cproject separate folders and unique names
472472
const StrVec& cprojects = m_parser.GetCsolution().cprojects;
473+
if (m_activeTargetSet.empty() && cprojects.empty()) {
474+
ProjMgrLogger::Get().Error("projects not found", "", m_csolutionFile);
475+
return false;
476+
}
473477
if (cprojects.size() > 1) {
474478
multiset<string> dirs;
475479
multiset<string> names;
@@ -526,6 +530,14 @@ bool ProjMgr::PopulateContexts(void) {
526530
}
527531
}
528532

533+
// Populate active target-set
534+
if (!m_activeTargetSet.empty() && !m_worker.PopulateActiveTargetSet(m_activeTargetSet)) {
535+
return false;
536+
}
537+
538+
// Add image only context
539+
m_worker.AddImageOnlyContext();
540+
529541
// Retrieve all context types
530542
m_worker.RetrieveAllContextTypes();
531543

@@ -580,7 +592,7 @@ bool ProjMgr::GenerateYMLConfigurationFiles(bool previousResult) {
580592

581593
bool ProjMgr::ParseAndValidateContexts() {
582594
// Parse context selection
583-
if (!m_worker.ParseContextSelection(m_context, m_contextSet, m_activeTargetSet)) {
595+
if (!m_worker.ParseContextSelection(m_context, m_contextSet)) {
584596
return false;
585597
}
586598

@@ -1026,7 +1038,7 @@ bool ProjMgr::RunCodeGenerator(void) {
10261038
return false;
10271039
}
10281040
// Parse context selection
1029-
if (!m_worker.ParseContextSelection(m_context, (m_context.size() == 0) && m_contextSet, m_activeTargetSet)) {
1041+
if (!m_worker.ParseContextSelection(m_context, (m_context.size() == 0) && m_contextSet)) {
10301042
return false;
10311043
}
10321044
if (m_extGenerator.IsGlobalGenerator(m_codeGenerator)) {

tools/projmgr/src/ProjMgrCbuild.cpp

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ void ProjMgrCbuild::SetContextNode(YAML::Node contextNode, const ContextItem* co
6060
SetNodeValue(generatorNode[YAML_FROM_PACK], generatorPack);
6161
}
6262
SetNodeValue(contextNode[YAML_SOLUTION], FormatPath(context->csolution->path, context->directories.cbuild));
63-
SetNodeValue(contextNode[YAML_PROJECT], FormatPath(context->cproject->path, context->directories.cbuild));
63+
if (!context->cproject->path.empty()) {
64+
SetNodeValue(contextNode[YAML_PROJECT], FormatPath(context->cproject->path, context->directories.cbuild));
65+
}
6466
SetNodeValue(contextNode[YAML_CONTEXT], context->name);
6567
SetNodeValue(contextNode[YAML_COMPILER], context->toolchain.name +
6668
(context->toolchain.required.empty() || context->toolchain.required == ">=0.0.0" ? "" : '@' + context->toolchain.required));
@@ -83,33 +85,37 @@ void ProjMgrCbuild::SetContextNode(YAML::Node contextNode, const ContextItem* co
8385
}
8486
SetBooksNode(contextNode[YAML_DEVICE_BOOKS], context->deviceBooks, context->directories.cbuild);
8587
SetDebugConfigNode(contextNode[YAML_DBGCONF], context);
86-
SetProcessorNode(contextNode[YAML_PROCESSOR], context->targetAttributes);
88+
if (!context->imageOnly) {
89+
SetProcessorNode(contextNode[YAML_PROCESSOR], context->targetAttributes);
90+
}
8791
SetPacksNode(contextNode[YAML_PACKS], context);
88-
SetControlsNode(contextNode, context, context->controls.processed);
89-
vector<string> defines;
90-
if (context->rteActiveTarget != nullptr) {
91-
for (const auto& define : context->rteActiveTarget->GetDefines()) {
92-
CollectionUtils::PushBackUniquely(defines, define);
92+
if (!context->imageOnly) {
93+
SetControlsNode(contextNode, context, context->controls.processed);
94+
vector<string> defines;
95+
if (context->rteActiveTarget != nullptr) {
96+
for (const auto& define : context->rteActiveTarget->GetDefines()) {
97+
CollectionUtils::PushBackUniquely(defines, define);
98+
}
9399
}
94-
}
95-
SetDefineNode(contextNode[YAML_DEFINE], defines);
96-
SetDefineNode(contextNode[YAML_DEFINE_ASM], defines);
97-
if (context->rteActiveTarget != nullptr) {
98-
for (auto include : context->rteActiveTarget->GetIncludePaths(RteFile::Language::LANGUAGE_NONE)) {
99-
RteFsUtils::NormalizePath(include, context->cproject->directory);
100-
include = FormatPath(include, context->directories.cbuild);
101-
SetNodeValueUniquely(contextNode[YAML_ADDPATH], include);
102-
SetNodeValueUniquely(contextNode[YAML_ADDPATH_ASM], include);
100+
SetDefineNode(contextNode[YAML_DEFINE], defines);
101+
SetDefineNode(contextNode[YAML_DEFINE_ASM], defines);
102+
if (context->rteActiveTarget != nullptr) {
103+
for (auto include : context->rteActiveTarget->GetIncludePaths(RteFile::Language::LANGUAGE_NONE)) {
104+
RteFsUtils::NormalizePath(include, context->cproject->directory);
105+
include = FormatPath(include, context->directories.cbuild);
106+
SetNodeValueUniquely(contextNode[YAML_ADDPATH], include);
107+
SetNodeValueUniquely(contextNode[YAML_ADDPATH_ASM], include);
108+
}
103109
}
110+
SetOutputDirsNode(contextNode[YAML_OUTPUTDIRS], context);
111+
SetOutputNode(contextNode[YAML_OUTPUT], context);
112+
SetComponentsNode(contextNode[YAML_COMPONENTS], context);
113+
SetApisNode(contextNode[YAML_APIS], context);
114+
SetGeneratorsNode(contextNode[YAML_GENERATORS], context);
115+
SetLinkerNode(contextNode[YAML_LINKER], context);
116+
SetGroupsNode(contextNode[YAML_GROUPS], context, context->groups);
117+
SetConstructedFilesNode(contextNode[YAML_CONSTRUCTEDFILES], context);
104118
}
105-
SetOutputDirsNode(contextNode[YAML_OUTPUTDIRS], context);
106-
SetOutputNode(contextNode[YAML_OUTPUT], context);
107-
SetComponentsNode(contextNode[YAML_COMPONENTS], context);
108-
SetApisNode(contextNode[YAML_APIS], context);
109-
SetGeneratorsNode(contextNode[YAML_GENERATORS], context);
110-
SetLinkerNode(contextNode[YAML_LINKER], context);
111-
SetGroupsNode(contextNode[YAML_GROUPS], context, context->groups);
112-
SetConstructedFilesNode(contextNode[YAML_CONSTRUCTEDFILES], context);
113119
SetLicenseInfoNode(contextNode[YAML_LICENSES], context);
114120
}
115121

tools/projmgr/src/ProjMgrCbuildIdx.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,24 @@ ProjMgrCbuildIdx::ProjMgrCbuildIdx(YAML::Node node,
3030
const set<string>& failedContexts, const map<string, ExecutesItem>& executes) : ProjMgrCbuildBase(false) {
3131
error_code ec;
3232
SetNodeValue(node[YAML_GENERATED_BY], ORIGINAL_FILENAME + string(" version ") + VERSION_STRING);
33-
if (processedContexts.size() > 0) {
34-
SetNodeValue(node[YAML_DESCRIPTION], processedContexts[0]->csolution->description);
35-
}
36-
if (!parser->GetCdefault().path.empty()) {
37-
SetNodeValue(node[YAML_CDEFAULT], FormatPath(parser->GetCdefault().path, directory));
33+
if (!processedContexts.empty()) {
34+
const auto& context = processedContexts.front();
35+
SetNodeValue(node[YAML_DESCRIPTION], context->csolution->description);
36+
if (!parser->GetCdefault().path.empty() && !context->imageOnly) {
37+
SetNodeValue(node[YAML_CDEFAULT], FormatPath(parser->GetCdefault().path, directory));
38+
}
3839
}
3940
SetNodeValue(node[YAML_CSOLUTION], FormatPath(parser->GetCsolution().path, directory));
4041
if (!cbuildRun.empty()) {
4142
SetNodeValue(node[YAML_CBUILD_RUN], FormatPath(cbuildRun, directory));
4243
}
4344
SetNodeValue(node[YAML_OUTPUT_TMPDIR], FormatPath(parser->GetCsolution().directories.tmpdir, directory));
4445

46+
// Image Only flag
47+
if (!processedContexts.empty() && processedContexts.front()->imageOnly) {
48+
node[YAML_IMAGE_ONLY] = true;
49+
}
50+
4551
// Generate layer info for each target
4652
vector<string> configTargets;
4753
for (const auto& context : processedContexts) {
@@ -129,7 +135,9 @@ ProjMgrCbuildIdx::ProjMgrCbuildIdx(YAML::Node node,
129135
const string& relativeFilename = fs::relative(filename, directory, ec).generic_string();
130136
SetNodeValue(cbuildNode[YAML_CBUILD], relativeFilename);
131137
if (context->cproject) {
132-
SetNodeValue(cbuildNode[YAML_PROJECT], context->cproject->name);
138+
if (!context->imageOnly) {
139+
SetNodeValue(cbuildNode[YAML_PROJECT], context->cproject->name);
140+
}
133141
SetNodeValue(cbuildNode[YAML_CONFIGURATION],
134142
(context->type.build.empty() ? "" : ("." + context->type.build)) +
135143
"+" + context->type.target);

tools/projmgr/src/ProjMgrWorker.cpp

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,25 @@ ProjMgrWorker::~ProjMgrWorker(void) {
6464
}
6565
}
6666

67+
void ProjMgrWorker::AddImageOnlyContext() {
68+
if (!m_activeTargetSet.images.empty()) {
69+
for (const auto& item : m_activeTargetSet.images) {
70+
if (!item.context.empty()) {
71+
return;
72+
}
73+
}
74+
ContextDesc descriptor;
75+
ContextItem context;
76+
context.imageOnly = true;
77+
context.csolution = &m_parser->GetCsolution();
78+
const string name = context.csolution->name;
79+
context.cproject = &m_imageOnly;
80+
context.cproject->name = name;
81+
context.cproject->directory = context.csolution->directory;
82+
AddContext(descriptor, { "", m_activeTargetType }, context);
83+
}
84+
}
85+
6786
bool ProjMgrWorker::AddContexts(ProjMgrParser& parser, ContextDesc& descriptor, const string& cprojectFile) {
6887
error_code ec;
6988
ContextItem context;
@@ -2134,7 +2153,7 @@ bool ProjMgrWorker::ProcessConfigFiles(ContextItem& context) {
21342153
}
21352154
}
21362155
// Linker script
2137-
if (!context.outputTypes.lib.on) {
2156+
if (context.outputTypes.elf.on) {
21382157
if (context.linker.autoGen) {
21392158
if (!context.linker.script.empty()) {
21402159
ProjMgrLogger::Get().Warn("conflict: automatic linker script generation overrules specified script '" + context.linker.script + "'", context.name);
@@ -2816,7 +2835,7 @@ bool ProjMgrWorker::ProcessPrecedences(ContextItem& context, BoardOrDevice proce
28162835
if (!ProcessCompilerPrecedence(compiler, true)) {
28172836
error |= true;
28182837
}
2819-
if (!ProcessToolchain(context)) {
2838+
if (!context.imageOnly && !ProcessToolchain(context)) {
28202839
error |= true;
28212840
}
28222841

@@ -4540,17 +4559,17 @@ bool ProjMgrWorker::ProcessSequencesRelatives(ContextItem& context, BuildType& b
45404559
}
45414560

45424561
bool ProjMgrWorker::ParseContextSelection(
4543-
const vector<string>& contextSelection, const bool checkCbuildSet, const string activeTargetSet)
4562+
const vector<string>& contextSelection, const bool checkCbuildSet)
45444563
{
45454564
vector<string> ymlOrderedContexts;
45464565
ListContexts(ymlOrderedContexts, RteUtils::EMPTY_STRING, true);
45474566

4548-
if (checkCbuildSet && !activeTargetSet.empty()) {
4567+
if (checkCbuildSet && !m_activeTargetType.empty()) {
45494568
ProjMgrLogger::Get().Error("invalid arguments: '-a' option cannot be used in combination with '-S'");
45504569
return false;
45514570
}
4552-
else if (!activeTargetSet.empty()) {
4553-
if (!ParseTargetSetContextSelection(activeTargetSet)) {
4571+
else if (!m_activeTargetType.empty()) {
4572+
if (!ParseTargetSetContextSelection()) {
45544573
return false;
45554574
}
45564575
}
@@ -4917,7 +4936,7 @@ bool ProjMgrWorker::ProcessOutputFilenames(ContextItem& context) {
49174936
}
49184937

49194938
// default: elf
4920-
if (!context.outputTypes.lib.on && !context.outputTypes.elf.on) {
4939+
if (!context.outputTypes.lib.on && !context.outputTypes.elf.on && !context.imageOnly) {
49214940
context.outputTypes.elf.on = true;
49224941
}
49234942

@@ -5421,11 +5440,8 @@ void ProjMgrWorker::CollectUnusedPacks() {
54215440
}
54225441
}
54235442

5424-
bool ProjMgrWorker::ParseTargetSetContextSelection(const string& activeTargetSet) {
5443+
bool ProjMgrWorker::ParseTargetSetContextSelection() {
54255444
// get project-contexts from active target-set
5426-
if (!GetActiveTargetSet(activeTargetSet)) {
5427-
return false;
5428-
}
54295445
m_selectedContexts.clear();
54305446
const auto& targetType = '+' + m_activeTargetType;
54315447
for (const auto& item : m_activeTargetSet.images) {
@@ -5435,9 +5451,11 @@ bool ProjMgrWorker::ParseTargetSetContextSelection(const string& activeTargetSet
54355451
}
54365452
if (m_selectedContexts.empty()) {
54375453
// when target-set is missing under target-types the default value is the first project with first build-type
5454+
// when the solution is image-only the processing is carried over a single context (+<target-type>)
54385455
vector<string> contexts;
5439-
ListContexts(contexts, targetType, true);
5440-
m_selectedContexts.push_back(contexts.front());
5456+
if (ListContexts(contexts, targetType, true)) {
5457+
m_selectedContexts.push_back(contexts.front());
5458+
}
54415459
} else {
54425460
// validate context selection
54435461
if (!ValidateContexts(m_selectedContexts, false)) {
@@ -5447,7 +5465,7 @@ bool ProjMgrWorker::ParseTargetSetContextSelection(const string& activeTargetSet
54475465
return true;
54485466
}
54495467

5450-
bool ProjMgrWorker::GetActiveTargetSet(const string& activeTargetSet) {
5468+
bool ProjMgrWorker::PopulateActiveTargetSet(const string& activeTargetSet) {
54515469
const auto& targetType = RteUtils::GetPrefix(activeTargetSet, '@');
54525470
const auto& targetSet = RteUtils::GetSuffix(activeTargetSet, '@');
54535471
bool targetSetFound = false;

tools/projmgr/src/ProjMgrYamlParser.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,6 @@ bool ProjMgrYamlParser::ParseCsolution(const string& input,
9090
return false;
9191
}
9292

93-
if (csolution.cprojects.size() == 0) {
94-
ProjMgrLogger::Get().Error("projects not found", "", input);
95-
return false;
96-
}
97-
9893
if (!ParseTargetTypes(solutionNode, csolution.path, csolution.targetTypes)) {
9994
ProjMgrLogger::Get().Error("target-types not found", "", input);
10095
return false;

0 commit comments

Comments
 (0)