Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions tools/projmgr/include/ProjMgrParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,24 @@ struct WestDesc {
std::vector<std::string> westOpt;
};

/**
* @brief CMake native project descriptor
*/
struct CmakeImage {
std::string image;
std::string type;
};

struct CmakeDesc {
std::string projectId;
std::string source;
std::string generator;
std::vector<std::string> configure;
std::string target;
std::vector<CmakeImage> images;
std::string device;
};

/**
* @brief context descriptor containing
* cproject filename,
Expand All @@ -517,6 +535,7 @@ struct ContextDesc {
std::string cproject;
TypeFilter type;
WestDesc west;
CmakeDesc cmake;
};

/**
Expand Down Expand Up @@ -649,6 +668,7 @@ struct CsolutionItem {
TargetType target;
std::vector<std::string> cprojects;
std::vector<std::string> westApps;
std::vector<std::string> cmakeApps;
std::vector<ContextDesc> contexts;
std::vector<PackItem> packs;
bool enableCdefault;
Expand Down
2 changes: 2 additions & 0 deletions tools/projmgr/include/ProjMgrWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,8 @@ struct ContextItem {
bool imageOnly = false;
WestDesc west;
bool westOn = false;
CmakeDesc cmake;
bool cmakeOn = false;
std::vector<VariablesConfiguration> variablesConfigurations;
std::set<RteComponentInstance*> unresolvedComponents;
StrMap availablePackVersions;
Expand Down
3 changes: 3 additions & 0 deletions tools/projmgr/include/ProjMgrYamlParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ static constexpr const char* YAML_BLOCKS = "blocks";
static constexpr const char* YAML_BOARD = "board";
static constexpr const char* YAML_BOARD_BOOKS = "board-books";
static constexpr const char* YAML_BOARD_PACK = "board-pack";
static constexpr const char* YAML_CONFIGURE = "configure";
static constexpr const char* YAML_BOARD_PACK_PATH = "board-pack-path";
static constexpr const char* YAML_BRANCH_PROTECTION = "branch-protection";
static constexpr const char* YAML_BUILD = "build";
Expand All @@ -54,6 +55,7 @@ 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_CMAKE = "cmake";
static constexpr const char* YAML_CBUILD_GENS = "cbuild-gens";
static constexpr const char* YAML_CBUILD_GEN = "cbuild-gen";
static constexpr const char* YAML_CBUILD_MLOPS = "cbuild-mlops";
Expand Down Expand Up @@ -255,6 +257,7 @@ static constexpr const char* YAML_SIZE = "size";
static constexpr const char* YAML_START = "start";
static constexpr const char* YAML_START_PNAME = "start-pname";
static constexpr const char* YAML_STATUS = "status";
static constexpr const char* YAML_SOURCE = "source";
static constexpr const char* YAML_SOLUTION = "solution";
static constexpr const char* YAML_SPROT = "SPROT";
static constexpr const char* YAML_SYSTEM = "system";
Expand Down
48 changes: 46 additions & 2 deletions tools/projmgr/schemas/common.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@
"ConditionIDType": {
"type": "string"
},
"ProjectIdType": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,32}$",
"description": "Project identifier used as a context name and output path component."
},
"ForType": {
"oneOf": [
{"$ref": "#/definitions/ArrayOfBuildContext" },
Expand Down Expand Up @@ -738,13 +743,18 @@
"description": "Path to the valid project file."
},
"west": { "$ref": "#/definitions/WestProjectType" },
"cmake": { "$ref": "#/definitions/CmakeProjectType" },
"for-context": { "$ref": "#/definitions/ForContext" },
"not-for-context": { "$ref": "#/definitions/NotForContext" }
},
"additionalProperties": false,
"allOf": [
{ "$ref": "#/definitions/TypeListMutualExclusion" },
{ "oneOf": [ { "required": ["project"], "not": {"required": ["west"]} }, { "required": ["west"], "not": {"required": ["project"]} } ] }
{ "oneOf": [
{ "required": ["project"], "not": {"anyOf": [{"required": ["west"]}, {"required": ["cmake"]}]} },
{ "required": ["west"], "not": {"anyOf": [{"required": ["project"]}, {"required": ["cmake"]}]} },
{ "required": ["cmake"], "not": {"anyOf": [{"required": ["project"]}, {"required": ["west"]}]} }
] }
]
},
"ProcessorTrustzone": {
Expand Down Expand Up @@ -1355,6 +1365,7 @@
"properties": {
"cbuild": { "type": "string", "description": "Path to <context>.cbuild.yml file." },
"west": { "type": "boolean" },
"cmake": { "type": "boolean" },
"project": { "type": "string", "description": "Project name." },
"configuration": { "$ref": "#/definitions/BuildContext" },
"depends-on": {
Expand Down Expand Up @@ -1510,7 +1521,8 @@
"type": "array",
"items": { "$ref": "#/definitions/LicenseInfoType" }
},
"west": { "$ref": "#/definitions/WestProjectType" }
"west": { "$ref": "#/definitions/WestProjectType" },
"cmake": { "$ref": "#/definitions/CmakeProjectType" }
},
"additionalProperties": false,
"required": ["generated-by"]
Expand Down Expand Up @@ -2650,6 +2662,38 @@
"additionalProperties": false,
"required": ["app-path"]
},
"CmakeProjectType": {
"title": "cmake:\nDocumentation: https://open-cmsis-pack.github.io/cmsis-toolbox/YML-Input-Format/#cmake",
"description": "Enable native CMake project build orchestration.",
"type": "object",
"properties": {
"source": { "type": "string", "minLength": 1, "description": "Path to the CMake source directory." },
"generator": { "type": "string", "description": "CMake generator to use for the build (default: Ninja)." },
"configure": { "type": "array", "description": "Options for the CMake configure command.", "items": { "type": "string" } },
"target": { "type": "string", "description": "CMake build target." },
"images": { "$ref": "#/definitions/CmakeImagesType" },
"device": { "$ref": "#/definitions/ProcessorNameType" },
"project-id": { "$ref": "#/definitions/ProjectIdType", "description": "Project identifier (default: last sub-dir name of source)." }
},
"additionalProperties": false,
"required": ["source"]
},
"CmakeImagesType": {
"type": "array",
"description": "List of output images produced by the CMake project.",
"uniqueItems": true,
"minItems": 1,
"items": { "$ref": "#/definitions/CmakeImageType" }
},
"CmakeImageType": {
"type": "object",
"properties": {
"image": { "type": "string", "minLength": 1, "description": "Path to the CMake build output image." },
"type": { "enum": [ "elf", "hex", "bin", "lib" ], "description": "Output image type." }
},
"additionalProperties": false,
"required": ["image", "type"]
},
"ProcessorsCapabilitiesType": {
"title": "processors:\nDocumentation: https://open-cmsis-pack.github.io/cmsis-toolbox/YML-CBuild-Format/#processors",
"description": "Capabilities of the device processors.",
Expand Down
2 changes: 1 addition & 1 deletion tools/projmgr/src/ProjMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ bool ProjMgr::PopulateContexts(void) {
}
// Check cproject separate folders and unique names
const StrVec& cprojects = m_parser.GetCsolution().cprojects;
if (!IsSolutionImageOnly() && cprojects.empty() && m_parser.GetCsolution().westApps.empty()) {
if (!IsSolutionImageOnly() && cprojects.empty() && m_parser.GetCsolution().westApps.empty() && m_parser.GetCsolution().cmakeApps.empty()) {
ProjMgrLogger::Get().Error("projects not found", "", m_csolutionFile);
return false;
}
Expand Down
24 changes: 21 additions & 3 deletions tools/projmgr/src/ProjMgrCbuild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class ProjMgrCbuild : public ProjMgrCbuildBase {
void SetDebugConfigNode(YAML::Node node, const ContextItem* context);
void SetPLMStatus(YAML::Node node, const ContextItem* context, const string& file);
void SetWestNode(YAML::Node node, const ContextItem* context);
void SetCmakeNode(YAML::Node node, const ContextItem* context);
bool m_ignoreRteFileMissing;
};

Expand Down Expand Up @@ -89,12 +90,12 @@ void ProjMgrCbuild::SetContextNode(YAML::Node contextNode, const ContextItem* co
}
SetBooksNode(contextNode[YAML_DEVICE_BOOKS], context->deviceBooks, context->directories.cbuild);
SetDebugConfigNode(contextNode[YAML_DBGCONF], context);
if (!context->imageOnly && !context->westOn) {
if (!context->imageOnly && !context->westOn && !context->cmakeOn) {
SetProcessorNode(contextNode[YAML_PROCESSOR], context->targetAttributes);
SetNpuInfoNode(contextNode[YAML_NPU_INFO], context);
}
SetPacksNode(contextNode[YAML_PACKS], context);
if (!context->imageOnly && !context->westOn) {
if (!context->imageOnly && !context->westOn && !context->cmakeOn) {
SetControlsNode(contextNode, context, context->controls.processed);
vector<string> defines;
if (context->rteActiveTarget != nullptr) {
Expand All @@ -120,7 +121,7 @@ void ProjMgrCbuild::SetContextNode(YAML::Node contextNode, const ContextItem* co
SetNodeValue(contextNode[YAML_OUTPUTDIRS][YAML_OUTPUT_OUTDIR], FormatPath(outDir, context->directories.cbuild));
}
SetOutputNode(contextNode[YAML_OUTPUT], context);
if (!context->imageOnly && !context->westOn) {
if (!context->imageOnly && !context->westOn && !context->cmakeOn) {
SetComponentsNode(contextNode[YAML_COMPONENTS], context);
SetApisNode(contextNode[YAML_APIS], context);
SetGeneratorsNode(contextNode[YAML_GENERATORS], context);
Expand All @@ -132,6 +133,9 @@ void ProjMgrCbuild::SetContextNode(YAML::Node contextNode, const ContextItem* co
if (context->westOn) {
SetWestNode(contextNode[YAML_WEST], context);
}
if (context->cmakeOn) {
SetCmakeNode(contextNode[YAML_CMAKE], context);
}
}

void ProjMgrCbuild::SetComponentsNode(YAML::Node node, const ContextItem* context) {
Expand Down Expand Up @@ -631,6 +635,20 @@ void ProjMgrCbuild::SetWestNode(YAML::Node node, const ContextItem* context) {
SetNodeValue(node[YAML_WEST_OPT], context->west.westOpt);
}

void ProjMgrCbuild::SetCmakeNode(YAML::Node node, const ContextItem* context) {
SetNodeValue(node[YAML_PROJECT_ID], context->cmake.projectId);
SetNodeValue(node[YAML_SOURCE], FormatPath(context->cmake.source, context->directories.cbuild));
SetNodeValue(node[YAML_GENERATOR], context->cmake.generator);
SetNodeValue(node[YAML_CONFIGURE], context->cmake.configure);
SetNodeValue(node[YAML_TARGET], context->cmake.target);
for (const auto& image : context->cmake.images) {
YAML::Node imageNode;
SetNodeValue(imageNode[YAML_IMAGE], image.image);
SetNodeValue(imageNode[YAML_TYPE], image.type);
node[YAML_IMAGES].push_back(imageNode);
}
}

//-- ProjMgrYamlEmitter::GenerateCbuild -----------------------------------------------------------
bool ProjMgrYamlEmitter::GenerateCbuild(ContextItem* context,
const string& generatorId, const string& generatorPack, bool ignoreRteFileMissing)
Expand Down
5 changes: 4 additions & 1 deletion tools/projmgr/src/ProjMgrCbuildIdx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ ProjMgrCbuildIdx::ProjMgrCbuildIdx(YAML::Node node,
if (!processedContexts.empty()) {
const auto& context = processedContexts.front();
SetNodeValue(node[YAML_DESCRIPTION], context->csolution->description);
if (!parser->GetCdefault().path.empty() && !context->imageOnly && !context->westOn) {
if (!parser->GetCdefault().path.empty() && !context->imageOnly && !context->westOn && !context->cmakeOn) {
SetNodeValue(node[YAML_CDEFAULT], FormatPath(parser->GetCdefault().path, directory));
}
}
Expand Down Expand Up @@ -129,6 +129,9 @@ ProjMgrCbuildIdx::ProjMgrCbuildIdx(YAML::Node node,
if (context->westOn) {
cbuildNode[YAML_WEST] = true;
}
if (context->cmakeOn) {
cbuildNode[YAML_CMAKE] = true;
}
if (context->cproject) {
if (!context->imageOnly) {
SetNodeValue(cbuildNode[YAML_PROJECT], context->cproject->name);
Expand Down
41 changes: 36 additions & 5 deletions tools/projmgr/src/ProjMgrWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,12 @@ bool ProjMgrWorker::AddContexts(ProjMgrParser& parser, ContextDesc& descriptor,
if (cprojects.find(cprojectFile) != cprojects.end()) {
context.cproject = &cprojects.at(cprojectFile);
} else {
if (descriptor.west.app.empty()) {
if (descriptor.west.app.empty() && descriptor.cmake.source.empty()) {
ProjMgrLogger::Get().Error("cproject not parsed, adding context failed", "", cprojectFile);
return false;
} else {
context.cproject = &cprojects[descriptor.west.projectId];
const string& projectId = descriptor.west.app.empty() ? descriptor.cmake.projectId : descriptor.west.projectId;
context.cproject = &cprojects[projectId];
}
}

Expand All @@ -132,6 +133,14 @@ bool ProjMgrWorker::AddContexts(ProjMgrParser& parser, ContextDesc& descriptor,
CollectionUtils::PushBackUniquely(context.west.westDefs, "CONFIG_BUILD_OUTPUT_HEX=y");
}

// CMake native project
if (!descriptor.cmake.source.empty()) {
context.cmakeOn = true;
context.cmake = descriptor.cmake;
RteFsUtils::NormalizePath(context.cmake.source, context.csolution->directory);
context.cproject->name = context.cmake.projectId;
}

// No build/target-types
if (context.csolution->buildTypes.empty() && context.csolution->targetTypes.empty()) {
AddContext(descriptor, { "" }, context);
Expand Down Expand Up @@ -2342,7 +2351,7 @@ bool ProjMgrWorker::ProcessConfigFiles(ContextItem& context) {
}
}
// Linker script
if (context.outputTypes.elf.on && !context.imageOnly && !context.westOn) {
if (context.outputTypes.elf.on && !context.imageOnly && !context.westOn && !context.cmakeOn) {
if (context.linker.autoGen) {
if (!context.linker.script.empty()) {
ProjMgrLogger::Get().Warn("conflict: automatic linker script generation overrules specified script '" + context.linker.script + "'", context.name);
Expand Down Expand Up @@ -3044,6 +3053,12 @@ bool ProjMgrWorker::ProcessPrecedences(ContextItem& context, BoardOrDevice proce
if (!context.west.device.empty()) {
context.cproject->target.device = context.west.device;
}
if (!context.cmake.device.empty()) {
DeviceItem device;
GetDeviceItem(context.cproject->target.device, device);
device.pname = RteUtils::ExtractSuffix(context.cmake.device);
context.cproject->target.device = GetDeviceInfoString(device.vendor, device.name, device.pname);
}

StringCollection device = {
&context.device,
Expand Down Expand Up @@ -5566,6 +5581,10 @@ bool ProjMgrWorker::ProcessOutputFilenames(ContextItem& context) {
baseName = context.cproject->name;
}

for (const auto& image : context.cmake.images) {
ProjMgrUtils::SetOutputType(image.type, context.outputTypes);
}

// secure project requires cmse output type
if (context.controls.processed.processor.trustzone == "secure") {
context.outputTypes.cmse.on = true;
Expand All @@ -5579,14 +5598,15 @@ bool ProjMgrWorker::ProcessOutputFilenames(ContextItem& context) {
}

// default: elf
if (!context.outputTypes.lib.on && !context.outputTypes.elf.on && !context.imageOnly) {
if (!context.outputTypes.lib.on && !context.outputTypes.elf.on && !context.imageOnly &&
!(context.cmakeOn && !context.cmake.images.empty())) {
context.outputTypes.elf.on = true;
}

// set output filename for each required output type
const string toolchain = affixesMap.find(context.toolchain.name) != affixesMap.end() ? context.toolchain.name : "";
if (context.outputTypes.elf.on) {
context.outputTypes.elf.filename = baseName + (context.westOn ? ".elf" : get<0>(affixesMap.at(toolchain)));
context.outputTypes.elf.filename = baseName + ((context.westOn || context.cmakeOn) ? ".elf" : get<0>(affixesMap.at(toolchain)));
}
if (context.outputTypes.lib.on) {
context.outputTypes.lib.filename = get<1>(affixesMap.at(toolchain)) + baseName + get<2>(affixesMap.at(toolchain));
Expand All @@ -5597,6 +5617,17 @@ bool ProjMgrWorker::ProcessOutputFilenames(ContextItem& context) {
if (context.outputTypes.bin.on) {
context.outputTypes.bin.filename = baseName + ".bin";
}
for (const auto& image : context.cmake.images) {
if (image.type == RteConstants::OUTPUT_TYPE_ELF) {
context.outputTypes.elf.filename = image.image;
} else if (image.type == RteConstants::OUTPUT_TYPE_HEX) {
context.outputTypes.hex.filename = image.image;
} else if (image.type == RteConstants::OUTPUT_TYPE_BIN) {
context.outputTypes.bin.filename = image.image;
} else if (image.type == RteConstants::OUTPUT_TYPE_LIB) {
context.outputTypes.lib.filename = image.image;
}
}
if (context.outputTypes.map.on) {
context.outputTypes.map.filename = baseName + get<0>(affixesMap.at(toolchain)) + ".map";
}
Expand Down
Loading
Loading