Skip to content

Commit 386f4f3

Browse files
authored
Handle zephyr module generation (#457)
* Handle zephyr module generation * Address review suggestions * Fix lint issue
1 parent f92f316 commit 386f4f3

9 files changed

Lines changed: 726 additions & 7 deletions

File tree

cmd/cbuild2cmake/commands/root.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024 Arm Limited. All rights reserved.
2+
* Copyright (c) 2024-2026 Arm Limited. All rights reserved.
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -94,12 +94,14 @@ func NewRootCmd() *cobra.Command {
9494
debug, _ := cmd.Flags().GetBool("debug")
9595
verbose, _ := cmd.Flags().GetBool("verbose")
9696
useContextSet, _ := cmd.Flags().GetBool("context-set")
97+
zephyr, _ := cmd.Flags().GetBool("zephyr")
9798

9899
options := maker.Options{
99100
Quiet: quiet,
100101
Debug: debug,
101102
Verbose: verbose,
102103
UseContextSet: useContextSet,
104+
Zephyr: zephyr,
103105
}
104106

105107
configs, _ := utils.GetInstallConfigs()
@@ -134,6 +136,7 @@ func NewRootCmd() *cobra.Command {
134136
rootCmd.Flags().BoolP("debug", "d", false, "Enable debug messages")
135137
rootCmd.Flags().BoolP("verbose", "v", false, "Enable verbose messages from toolchain builds")
136138
rootCmd.Flags().BoolP("context-set", "S", false, "Select the context names from cbuild-set.yml")
139+
rootCmd.Flags().BoolP("zephyr", "z", false, "Generate Zephyr modules for clayer.yml files")
137140

138141
rootCmd.SetFlagErrorFunc(FlagErrorFunc)
139142
return rootCmd

pkg/maker/buildcontent.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,17 @@ func GetScope(file Files) string {
8888
}
8989

9090
func ReplaceDelimiters(identifier string) string {
91+
// replace component delimiters
9192
pattern := regexp.MustCompile(`::|:|&|@>=|@|\.|/|\(|\)| `)
9293
return pattern.ReplaceAllString(identifier, "_")
9394
}
9495

96+
func ReplaceSpecialChars(identifier string) string {
97+
// replace component delimiters and dash '-'
98+
pattern := regexp.MustCompile(`::|:|&|@>=|@|\.|/|\(|\)|-| `)
99+
return pattern.ReplaceAllString(identifier, "_")
100+
}
101+
95102
func MergeLanguageCommonIncludes(languages LanguageMap) LanguageMap {
96103
intersection := utils.Intersection(languages["C"], languages["CXX"])
97104
if len(intersection) > 0 {

pkg/maker/buildcontent_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,19 @@ func TestReplaceDelimiters(t *testing.T) {
2626
})
2727
}
2828

29+
func TestReplaceSpecialChars(t *testing.T) {
30+
assert := assert.New(t)
31+
32+
t.Run("test replace special chars", func(t *testing.T) {
33+
assert.Equal("Cvendor_Cbundle_Cclass_Cgroup_Cvariant_Cversion", maker.ReplaceSpecialChars("Cvendor&Cbundle::Cclass:Cgroup&Cvariant@Cversion"))
34+
assert.Equal("ARM_CMSIS_CORE_A", maker.ReplaceSpecialChars("ARM::CMSIS.CORE A"))
35+
assert.Equal("AC6_6_16_0", maker.ReplaceSpecialChars("AC6@>=6.16.0"))
36+
assert.Equal("path_with_spaces", maker.ReplaceSpecialChars("path/with spaces"))
37+
assert.Equal("Handlers__GCC_", maker.ReplaceSpecialChars("Handlers (GCC)"))
38+
assert.Equal("name_with_dash", maker.ReplaceSpecialChars("name-with-dash"))
39+
})
40+
}
41+
2942
func TestBuildContent(t *testing.T) {
3043
assert := assert.New(t)
3144

pkg/maker/maker.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024-2025 Arm Limited. All rights reserved.
2+
* Copyright (c) 2024-2026 Arm Limited. All rights reserved.
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -26,12 +26,14 @@ type Options struct {
2626
Debug bool
2727
Verbose bool
2828
UseContextSet bool
29+
Zephyr bool
2930
}
3031

3132
type Vars struct {
3233
CbuildIndex CbuildIndex
3334
CbuildSet CbuildSet
3435
Cbuilds []Cbuild
36+
Clayers []Clayer
3537
Contexts []string
3638
EnvVars utils.EnvVars
3739
GeneratedFiles []string
@@ -42,6 +44,7 @@ type Vars struct {
4244
SolutionTmpDir string
4345
SolutionRoot string
4446
SolutionName string
47+
ZephyrMaker ZephyrMaker
4548
}
4649

4750
type Maker struct {
@@ -69,6 +72,11 @@ func (m *Maker) GenerateCMakeLists() error {
6972
}
7073
m.SolutionTmpDir = path.Join(m.CbuildIndex.BaseDir, m.CbuildIndex.BuildIdx.TmpDir)
7174

75+
// Create Zephyr modules
76+
if m.Options.Zephyr {
77+
return m.GenerateZephyrModules()
78+
}
79+
7280
// Create roots.cmake
7381
err = m.CMakeCreateRoots(m.SolutionRoot)
7482
if err != nil {

pkg/maker/parser.go

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"path/filepath"
1313
"regexp"
1414
"slices"
15+
"strings"
1516

1617
"gopkg.in/yaml.v3"
1718

@@ -92,12 +93,27 @@ type Cbuild struct {
9293
LinkerLto bool
9394
}
9495

96+
type Clayer struct {
97+
Layer struct {
98+
Description string `yaml:"description"`
99+
Packs []Packs `yaml:"packs"`
100+
Define []interface{} `yaml:"define"`
101+
Components []struct {
102+
Component string `yaml:"component"`
103+
} `yaml:"components"`
104+
} `yaml:"layer"`
105+
Name string
106+
File string
107+
BaseDir string
108+
}
109+
95110
type Cbuilds struct {
96-
Cbuild string `yaml:"cbuild"`
97-
Project string `yaml:"project"`
98-
Configuration string `yaml:"configuration"`
99-
DependsOn []string `yaml:"depends-on"`
100-
West bool `yaml:"west"`
111+
Cbuild string `yaml:"cbuild"`
112+
Project string `yaml:"project"`
113+
Configuration string `yaml:"configuration"`
114+
DependsOn []string `yaml:"depends-on"`
115+
Clayers []Clayers `yaml:"clayers"`
116+
West bool `yaml:"west"`
101117
}
102118

103119
type Clayers struct {
@@ -338,3 +354,36 @@ func (m *Maker) ParseCbuildFiles() error {
338354
}
339355
return err
340356
}
357+
358+
func (m *Maker) ParseClayerFile(clayerFile string) (data Clayer, err error) {
359+
yfile, err := os.ReadFile(clayerFile)
360+
if err != nil {
361+
return
362+
}
363+
err = yaml.Unmarshal(yfile, &data)
364+
return
365+
}
366+
367+
func (m *Maker) ParseClayerFiles() error {
368+
// Parse clayer files
369+
if len(m.CbuildIndex.BuildIdx.Cbuilds) > 0 {
370+
m.Clayers = make([]Clayer, 0, len(m.CbuildIndex.BuildIdx.Cbuilds[0].Clayers))
371+
for _, clayerRef := range m.CbuildIndex.BuildIdx.Cbuilds[0].Clayers {
372+
clayerFile := path.Join(m.CbuildIndex.BaseDir, clayerRef.Clayer)
373+
if _, err := os.Stat(clayerFile); os.IsNotExist(err) {
374+
log.Warn("file " + clayerFile + " was not found")
375+
continue
376+
}
377+
clayer, err := m.ParseClayerFile(clayerFile)
378+
if err != nil {
379+
return err
380+
}
381+
clayer.File = filepath.ToSlash(clayerFile)
382+
clayer.BaseDir, _ = filepath.Abs(path.Dir(clayerFile))
383+
clayer.BaseDir = filepath.ToSlash(clayer.BaseDir)
384+
clayer.Name = strings.TrimSuffix(filepath.Base(clayerFile), ".clayer.yml")
385+
m.Clayers = append(m.Clayers, clayer)
386+
}
387+
}
388+
return nil
389+
}

0 commit comments

Comments
 (0)