Skip to content

Commit 8085398

Browse files
committed
[cbuild2cmake] Add link-time-optimize handling
1 parent 763826b commit 8085398

11 files changed

Lines changed: 68 additions & 18 deletions

File tree

pkg/maker/buildcontent.go

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ func (c *Cbuild) CMakeTargetCompileOptionsGlobal(name string, scope string) stri
345345
}
346346
}
347347
// add global misc options
348-
c.GetCompileOptionsLanguageMap(c.BuildDescType.Misc, &optionsMap)
348+
c.GetCompileOptionsLanguageMap((c.BuildDescType.Lto), c.BuildDescType.Misc, &optionsMap)
349349

350350
// pre-includes global
351351
for _, preInclude := range c.PreIncludeGlobal {
@@ -370,11 +370,11 @@ func (c *Cbuild) CMakeTargetLinkLibraries(name string, scope string, libraries .
370370
return content
371371
}
372372

373-
func (c *Cbuild) CMakeTargetCompileOptions(name string, scope string, misc Misc, preIncludes []string, parent string) string {
373+
func (c *Cbuild) CMakeTargetCompileOptions(name string, scope string, lto bool, misc Misc, preIncludes []string, parent string) string {
374374
content := "\ntarget_compile_options(" + name + " " + scope
375375
content += "\n $<TARGET_PROPERTY:" + parent + ",INTERFACE_COMPILE_OPTIONS>"
376376
optionsMap := make(map[string][]string)
377-
c.GetCompileOptionsLanguageMap(misc, &optionsMap)
377+
c.GetCompileOptionsLanguageMap(lto, misc, &optionsMap)
378378
for _, preInclude := range preIncludes {
379379
optionsMap["C,CXX"] = append(optionsMap["C,CXX"], "${_PI}\""+preInclude+"\"")
380380
}
@@ -406,19 +406,31 @@ func (c *Cbuild) CMakeTargetCompileOptionsAbstractions(name string, abstractions
406406
return content
407407
}
408408

409-
func (c *Cbuild) GetCompileOptionsLanguageMap(misc Misc, optionsMap *map[string][]string) {
409+
func (c *Cbuild) GetCompileOptionsLanguageMap(lto bool, misc Misc, optionsMap *map[string][]string) {
410410
for _, language := range c.Languages {
411411
switch language {
412412
case "ASM":
413413
if len(misc.ASM) > 0 {
414414
(*optionsMap)[language] = append((*optionsMap)[language], misc.ASM...)
415415
}
416416
case "C", "CXX":
417-
if language == "C" && len(misc.C) > 0 {
418-
(*optionsMap)[language] = append((*optionsMap)[language], misc.C...)
417+
if language == "C" {
418+
if lto {
419+
c.LinkerLto = true
420+
(*optionsMap)[language] = append((*optionsMap)[language], "${CC_LTO}")
421+
}
422+
if len(misc.C) > 0 {
423+
(*optionsMap)[language] = append((*optionsMap)[language], misc.C...)
424+
}
419425
}
420-
if language == "CXX" && len(misc.CPP) > 0 {
421-
(*optionsMap)[language] = append((*optionsMap)[language], misc.CPP...)
426+
if language == "CXX" {
427+
if lto {
428+
c.LinkerLto = true
429+
(*optionsMap)[language] = append((*optionsMap)[language], "${CXX_LTO}")
430+
}
431+
if len(misc.CPP) > 0 {
432+
(*optionsMap)[language] = append((*optionsMap)[language], misc.CPP...)
433+
}
422434
}
423435
if len(misc.CCPP) > 0 {
424436
(*optionsMap)[language] = append((*optionsMap)[language], misc.CCPP...)
@@ -460,6 +472,9 @@ func GetFileOptions(file Files, hasAbstractions bool, delimiter string) string {
460472
case "CXX":
461473
options = append(file.Misc.CPP, file.Misc.CCPP...)
462474
}
475+
if file.Lto {
476+
options = append(options, "${"+prefix+"_LTO}")
477+
}
463478
if hasAbstractions {
464479
options = append(options, "${"+prefix+"_OPTIONS_FLAGS}")
465480
}
@@ -759,6 +774,7 @@ func (c *Cbuild) CMakeSetFileProperties(file Files, abstractions CompilerAbstrac
759774
// file build options
760775
language := GetLanguage(file)
761776
hasMisc := !IsCompileMiscEmpty(file.Misc)
777+
c.LinkerLto = c.LinkerLto || file.Lto
762778
// file compiler abstractions
763779
hasAbstractions := !AreAbstractionsEmpty(abstractions, []string{language})
764780
if hasAbstractions {
@@ -768,9 +784,9 @@ func (c *Cbuild) CMakeSetFileProperties(file Files, abstractions CompilerAbstrac
768784
filename := c.AddRootPrefix(c.ContextRoot, file.File)
769785
isGenerated := slices.Contains(c.GeneratedFiles, filename)
770786
// set file properties
771-
if hasMisc || hasAbstractions || isGenerated {
787+
if hasMisc || file.Lto || hasAbstractions || isGenerated {
772788
content += "\nset_source_files_properties(\"" + filename + "\" PROPERTIES"
773-
if hasMisc || hasAbstractions {
789+
if hasMisc || file.Lto || hasAbstractions {
774790
content += "\n COMPILE_OPTIONS \"" + GetFileOptions(file, hasAbstractions, ";") + "\""
775791
}
776792
if isGenerated {
@@ -834,6 +850,9 @@ func (c *Cbuild) LinkerOptions() (linkerVars string, linkerOptions string) {
834850
if len(c.BuildDescType.Processor.Trustzone) > 0 {
835851
linkerOptions += "\n " + AddShellPrefix("${LD_SECURE}")
836852
}
853+
if c.LinkerLto {
854+
linkerOptions += "\n " + AddShellPrefix("${LD_LTO}")
855+
}
837856
options := c.BuildDescType.Misc.Link
838857
for _, language := range c.Languages {
839858
if language == "C" {

pkg/maker/buildcontent_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,14 @@ func TestBuildContent(t *testing.T) {
152152
CPP: []string{"-cpp-flag"},
153153
CCPP: []string{"-c-cpp-flag"},
154154
}
155+
lto := true
155156
var cbuild maker.Cbuild
156157
cbuild.Languages = []string{"ASM", "C", "CXX"}
157158
preIncludes := []string{"${SOLUTION_ROOT}/project/RTE/class/pre-include.h"}
158-
content := cbuild.CMakeTargetCompileOptions("TARGET", "PUBLIC", misc, preIncludes, "${CONTEXT}")
159+
content := cbuild.CMakeTargetCompileOptions("TARGET", "PUBLIC", lto, misc, preIncludes, "${CONTEXT}")
159160
assert.Contains(content, "$<$<COMPILE_LANGUAGE:ASM>:\n \"SHELL:-asm-flag\"")
160-
assert.Contains(content, "$<$<COMPILE_LANGUAGE:C>:\n \"SHELL:-c-flag\"\n \"SHELL:-c-cpp-flag\"")
161-
assert.Contains(content, "$<$<COMPILE_LANGUAGE:CXX>:\n \"SHELL:-cpp-flag\"\n \"SHELL:-c-cpp-flag\"")
161+
assert.Contains(content, "$<$<COMPILE_LANGUAGE:C>:\n \"SHELL:${CC_LTO}\"\n \"SHELL:-c-flag\"\n \"SHELL:-c-cpp-flag\"")
162+
assert.Contains(content, "$<$<COMPILE_LANGUAGE:CXX>:\n \"SHELL:${CXX_LTO}\"\n \"SHELL:-cpp-flag\"\n \"SHELL:-c-cpp-flag\"")
162163
assert.Contains(content, "\"SHELL:${_PI}\\\"${SOLUTION_ROOT}/project/RTE/class/pre-include.h\\\"\"")
163164
})
164165

pkg/maker/contextlists.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ func (c *Cbuild) CMakeCreateGroupRecursively(parent string, groups []Groups,
244244
}
245245
// target_compile_options
246246
if hasChildren || len(buildFiles.Source) > 0 || len(buildFiles.Custom) > 0 {
247-
content += c.CMakeTargetCompileOptions(name, scope, group.Misc, buildFiles.PreIncludeLocal, parentName)
247+
content += c.CMakeTargetCompileOptions(name, scope, group.Lto, group.Misc, buildFiles.PreIncludeLocal, parentName)
248248
}
249249
// target_link_libraries
250250
libraries = append(libraries, buildFiles.Library...)
@@ -269,7 +269,7 @@ func (c *Cbuild) CMakeCreateGroupRecursively(parent string, groups []Groups,
269269
content += CMakeTargetCompileDefinitions(fileTargetName, name, "PUBLIC", file.Define, file.Undefine)
270270
}
271271
// target_compile_options
272-
content += c.CMakeTargetCompileOptions(fileTargetName, "PUBLIC", Misc{}, []string{}, name)
272+
content += c.CMakeTargetCompileOptions(fileTargetName, "PUBLIC", false, Misc{}, []string{}, name)
273273
}
274274
// asm defines are set in file properties
275275
if GetLanguage(file) == "ASM" {
@@ -331,7 +331,7 @@ func (c *Cbuild) CMakeCreateComponents(contextDir string) error {
331331
}
332332
// target_compile_options
333333
if len(buildFiles.Source) > 0 || len(buildFiles.Custom) > 0 {
334-
content += c.CMakeTargetCompileOptions(name, scope, component.Misc, buildFiles.PreIncludeLocal, "${CONTEXT}")
334+
content += c.CMakeTargetCompileOptions(name, scope, component.Lto, component.Misc, buildFiles.PreIncludeLocal, "${CONTEXT}")
335335
}
336336
// target_link_libraries
337337
libraries = append(libraries, buildFiles.Library...)

pkg/maker/parser.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ type Cbuild struct {
5757
Warnings string `yaml:"warnings"`
5858
LanguageC string `yaml:"language-C"`
5959
LanguageCpp string `yaml:"language-CPP"`
60+
Lto bool `yaml:"link-time-optimize"`
6061
Misc Misc `yaml:"misc"`
6162
Define []interface{} `yaml:"define"`
6263
DefineAsm []interface{} `yaml:"define-asm"`
@@ -83,6 +84,7 @@ type Cbuild struct {
8384
BuildGroups []string
8485
Toolchain string
8586
GeneratedFiles []string
87+
LinkerLto bool
8688
}
8789

8890
type Cbuilds struct {
@@ -122,6 +124,7 @@ type Components struct {
122124
Warnings string `yaml:"warnings"`
123125
LanguageC string `yaml:"language-C"`
124126
LanguageCpp string `yaml:"language-CPP"`
127+
Lto bool `yaml:"link-time-optimize"`
125128
Define []interface{} `yaml:"define"`
126129
DefineAsm []interface{} `yaml:"define-asm"`
127130
Undefine []string `yaml:"undefine"`
@@ -155,6 +158,7 @@ type Files struct {
155158
Warnings string `yaml:"warnings"`
156159
LanguageC string `yaml:"language-C"`
157160
LanguageCpp string `yaml:"language-CPP"`
161+
Lto bool `yaml:"link-time-optimize"`
158162
Define []interface{} `yaml:"define"`
159163
DefineAsm []interface{} `yaml:"define-asm"`
160164
Undefine []string `yaml:"undefine"`
@@ -180,6 +184,7 @@ type Groups struct {
180184
Warnings string `yaml:"warnings"`
181185
LanguageC string `yaml:"language-C"`
182186
LanguageCpp string `yaml:"language-CPP"`
187+
Lto bool `yaml:"link-time-optimize"`
183188
Define []interface{} `yaml:"define"`
184189
DefineAsm []interface{} `yaml:"define-asm"`
185190
Undefine []string `yaml:"undefine"`

pkg/maker/parser_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ func TestParser(t *testing.T) {
5151
assert.Equal("bti-signret", data.BuildDescType.Processor.BranchProtection)
5252
assert.Equal("non-secure", data.BuildDescType.Processor.Trustzone)
5353
assert.Equal("Cortex-M0", data.BuildDescType.Processor.Core)
54+
assert.True(data.BuildDescType.Lto)
5455

5556
assert.Equal("vendorName::DFP@8.8.8", data.BuildDescType.Packs[0].Pack)
5657
assert.Equal("${CMSIS_PACK_ROOT}/vendorName/DFP/8.8.8", data.BuildDescType.Packs[0].Path)
@@ -83,13 +84,15 @@ func TestParser(t *testing.T) {
8384
assert.Equal("vendorName::DFP@8.8.8", data.BuildDescType.Components[0].FromPack)
8485
assert.Equal("DFP:CORE@1.1.1", data.BuildDescType.Components[0].Implements)
8586
assert.Equal("CORE", data.BuildDescType.Components[0].SelectedBy)
87+
assert.True(data.BuildDescType.Components[0].Lto)
8688

8789
assert.Equal("DFP:CORE@1.1.1", data.BuildDescType.Apis[0].API)
8890
assert.Equal("vendorName::DFP@8.8.8", data.BuildDescType.Apis[0].FromPack)
8991

9092
assert.Equal("Source", data.BuildDescType.Groups[0].Group)
9193
assert.Equal("./TestSource.c", data.BuildDescType.Groups[0].Files[0].File)
9294
assert.Equal("sourceC", data.BuildDescType.Groups[0].Files[0].Category)
95+
assert.True(data.BuildDescType.Groups[0].Files[0].Lto)
9396

9497
assert.Equal("Subgroup", data.BuildDescType.Groups[0].Groups[0].Group)
9598
assert.Equal("./TestSubgroup.c", data.BuildDescType.Groups[0].Groups[0].Files[0].File)

test/data/generic/contextName0.cbuild.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ build:
3636
from-pack: vendorName::DFP@8.8.8
3737
implements: DFP:CORE@1.1.1
3838
selected-by: CORE
39+
link-time-optimize: true
3940
apis:
4041
- api: DFP:CORE@1.1.1
4142
from-pack: vendorName::DFP@8.8.8
@@ -44,6 +45,7 @@ build:
4445
regions: regions_deviceName.h
4546
define:
4647
- LD_PP_DEF0
48+
link-time-optimize: true
4749
groups:
4850
- group: Source
4951
files:
@@ -56,6 +58,7 @@ build:
5658
warnings: all
5759
language-C: c90
5860
language-CPP: c++20
61+
link-time-optimize: true
5962
define:
6063
- DEF_FILE
6164
undefine:

test/data/solutions/abstractions/project/project.GCC+ARMCM0.cbuild.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
build:
2-
generated-by: csolution version 2.6.0
2+
generated-by: csolution version 0.0.0+gd100d305
33
solution: ../solution.csolution.yml
44
project: project.cproject.yml
55
context: project.GCC+ARMCM0
66
compiler: GCC
7-
device: ARMCM0
7+
device: ARM::ARMCM0
88
device-pack: ARM::Cortex_DFP@1.1.0
9+
device-books:
10+
- name: https://developer.arm.com/documentation/dui0497
11+
title: Cortex-M0 Processor Devices Generic Users Guide
912
processor:
1013
fpu: off
1114
core: Cortex-M0
@@ -84,6 +87,7 @@ build:
8487
from-pack: ARM::Cortex_DFP@1.1.0
8588
selected-by: ARM::Device:Startup&C Startup
8689
optimize: none
90+
link-time-optimize: true
8791
files:
8892
- file: ${CMSIS_PACK_ROOT}/ARM/Cortex_DFP/1.1.0/Device/ARMCM0/Include/ARMCM0.h
8993
category: header
@@ -104,6 +108,7 @@ build:
104108
script: RTE/Device/ARMCM0/ARMCM0_gcc.ld
105109
groups:
106110
- group: Group1
111+
link-time-optimize: true
107112
files:
108113
- file: main.c
109114
category: sourceC
@@ -134,6 +139,7 @@ build:
134139
category: sourceC
135140
- file: optimize_size2.c
136141
category: sourceC
142+
link-time-optimize: true
137143
constructed-files:
138144
- file: RTE/_GCC_ARMCM0/RTE_Components.h
139145
category: header

test/data/solutions/abstractions/project/project.cproject.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ project:
66
- component: ARM::CMSIS:CORE
77
- component: ARM::Device:Startup&C Startup
88
optimize: none
9+
link-time-optimize:
910

1011
#inherited from build-type: optimize: size
1112

1213
groups:
1314
- group: Group1
15+
link-time-optimize:
1416
files:
1517
- file: ./main.c
1618
- group: Group2
@@ -34,3 +36,4 @@ project:
3436
files:
3537
- file: ./optimize_size1.c
3638
- file: ./optimize_size2.c
39+
link-time-optimize:

test/data/solutions/abstractions/ref/project.GCC+ARMCM0/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ target_link_libraries(${CONTEXT} PUBLIC
8989
target_link_options(${CONTEXT} PUBLIC
9090
"SHELL:${LD_CPU}"
9191
"SHELL:${_LS}\"${LD_SCRIPT_PP}\""
92+
"SHELL:${LD_LTO}"
9293
"SHELL:--specs=nano.specs"
9394
"SHELL:--specs=nosys.specs"
9495
"SHELL:-Wl,--gc-sections"

test/data/solutions/abstractions/ref/project.GCC+ARMCM0/components.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ target_compile_options(ARM_Device_Startup_C_Startup_2_2_0_ABSTRACTIONS INTERFACE
3434
)
3535
target_compile_options(ARM_Device_Startup_C_Startup_2_2_0 PUBLIC
3636
$<TARGET_PROPERTY:${CONTEXT},INTERFACE_COMPILE_OPTIONS>
37+
$<$<COMPILE_LANGUAGE:C>:
38+
"SHELL:${CC_LTO}"
39+
>
3740
)
3841
target_link_libraries(ARM_Device_Startup_C_Startup_2_2_0 PUBLIC
3942
ARM_Device_Startup_C_Startup_2_2_0_ABSTRACTIONS

0 commit comments

Comments
 (0)