All checks were successful
build-dsl-smoke / Discover matrix (push) Successful in 8s
build-dsl-smoke / Build judge (push) Successful in 11s
build-dsl-smoke / ${{ matrix.cell.build }} / ${{ matrix.cell.toolchain }} / ${{ matrix.cell.platform }} (push) Successful in 5s
memory-limit / Build judge (pull_request) Successful in 10s
build-dsl-smoke / SUMMARY (push) Successful in 3s
memory-limit / Linux / gcc (pull_request) Successful in 9s
memory-limit / Linux / clang (pull_request) Successful in 13s
memory-limit / Windows / clang (pull_request) Successful in 16s
memory-limit / Windows / msvc (pull_request) Successful in 17s
188 lines
4.9 KiB
Go
188 lines
4.9 KiB
Go
package dsl
|
|
|
|
// BuildProfile is a named compilation profile. The translator maps it into
|
|
// compiler-specific flag sets at execution time (e.g. ProfileRelease → "-O2"
|
|
// on gnu-like compilers, "/O2" on msvc).
|
|
type BuildProfile int
|
|
|
|
const (
|
|
ProfileUnset BuildProfile = iota
|
|
ProfileRelease
|
|
ProfileDebug
|
|
ProfileSanitized
|
|
)
|
|
|
|
func (p BuildProfile) String() string {
|
|
switch p {
|
|
case ProfileRelease:
|
|
return "release"
|
|
case ProfileDebug:
|
|
return "debug"
|
|
case ProfileSanitized:
|
|
return "sanitized"
|
|
default:
|
|
return "unset"
|
|
}
|
|
}
|
|
|
|
// WarningLevel describes how strict the compiler should be about warnings.
|
|
type WarningLevel int
|
|
|
|
const (
|
|
WarningsUnset WarningLevel = iota
|
|
WarningsDefault
|
|
WarningsStrict
|
|
WarningsPedantic
|
|
)
|
|
|
|
func (w WarningLevel) String() string {
|
|
switch w {
|
|
case WarningsDefault:
|
|
return "default"
|
|
case WarningsStrict:
|
|
return "strict"
|
|
case WarningsPedantic:
|
|
return "pedantic"
|
|
default:
|
|
return "unset"
|
|
}
|
|
}
|
|
|
|
// BuildConfig describes one structured build variant. It is the new-style
|
|
// replacement for the free-form `build "shell-string"` field.
|
|
//
|
|
// A top-level `build_defaults { ... }` in the suite file produces a
|
|
// BuildConfig stored on File.BuildDefaults. Each `build "name" { ... }`
|
|
// block produces an entry in File.Builds; the effective configuration used
|
|
// by the runner is BuildDefaults merged with the named block, then merged
|
|
// with the OS-specific override (Linux / Windows / Darwin) when present.
|
|
//
|
|
// Zero-valued fields inherit from the parent during merge. Slice and map
|
|
// fields accumulate rather than replace.
|
|
type BuildConfig struct {
|
|
// Name of the variant. Empty on BuildDefaults and on OS-override sub-blocks.
|
|
Name string
|
|
|
|
Language string // e.g. "c", "c++"
|
|
Standard string // e.g. "c11", "c++17"
|
|
Sources []string // globs, relative to work dir
|
|
Includes []string // include search paths
|
|
Output string // binary name (OS-specific extension added automatically)
|
|
|
|
Profile BuildProfile
|
|
Warnings WarningLevel
|
|
Sanitize []string
|
|
Wrapper string // e.g. "address", "undefined", "thread"
|
|
|
|
Defines map[string]string
|
|
Link []string // libraries to link against (e.g. "pthread", "m")
|
|
Extra []string // raw passthrough flags
|
|
|
|
// Filters — empty means "applies to any". A build is skipped at runtime
|
|
// if the current OS or compiler is not in the list.
|
|
Platforms []string // "linux", "windows", "darwin"
|
|
Compilers []string // "gcc", "clang", "msvc"
|
|
|
|
// OS-specific overrides. Only one level of nesting is allowed: these
|
|
// sub-configs must not themselves contain Linux/Windows/Darwin blocks.
|
|
Linux *BuildConfig
|
|
Windows *BuildConfig
|
|
Darwin *BuildConfig
|
|
}
|
|
|
|
// MergeFrom layers src on top of dst in place. Non-zero scalar fields in src
|
|
// overwrite dst; slices and maps accumulate. The Name and OS override fields
|
|
// on src are intentionally ignored — merging never copies the hierarchy,
|
|
// only the leaves.
|
|
func (dst *BuildConfig) MergeFrom(src *BuildConfig) {
|
|
if src == nil {
|
|
return
|
|
}
|
|
if src.Language != "" {
|
|
dst.Language = src.Language
|
|
}
|
|
if src.Standard != "" {
|
|
dst.Standard = src.Standard
|
|
}
|
|
if src.Output != "" {
|
|
dst.Output = src.Output
|
|
}
|
|
if src.Profile != ProfileUnset {
|
|
dst.Profile = src.Profile
|
|
}
|
|
if src.Warnings != WarningsUnset {
|
|
dst.Warnings = src.Warnings
|
|
}
|
|
if src.Wrapper != "" {
|
|
dst.Wrapper = src.Wrapper
|
|
}
|
|
|
|
dst.Sources = append(dst.Sources, src.Sources...)
|
|
dst.Includes = append(dst.Includes, src.Includes...)
|
|
dst.Sanitize = append(dst.Sanitize, src.Sanitize...)
|
|
dst.Link = append(dst.Link, src.Link...)
|
|
dst.Extra = append(dst.Extra, src.Extra...)
|
|
dst.Platforms = append(dst.Platforms, src.Platforms...)
|
|
dst.Compilers = append(dst.Compilers, src.Compilers...)
|
|
|
|
if len(src.Defines) > 0 {
|
|
if dst.Defines == nil {
|
|
dst.Defines = map[string]string{}
|
|
}
|
|
for k, v := range src.Defines {
|
|
dst.Defines[k] = v
|
|
}
|
|
}
|
|
}
|
|
|
|
// Resolve returns the effective BuildConfig for the given OS by merging
|
|
// BuildDefaults → this block → the matching OS override. The result is a
|
|
// fresh value; the receiver is not mutated.
|
|
func (b *BuildConfig) Resolve(defaults *BuildConfig, os string) BuildConfig {
|
|
var out BuildConfig
|
|
out.MergeFrom(defaults)
|
|
out.MergeFrom(b)
|
|
out.Name = b.Name
|
|
|
|
var osOverride *BuildConfig
|
|
switch os {
|
|
case "linux":
|
|
osOverride = b.Linux
|
|
case "windows":
|
|
osOverride = b.Windows
|
|
case "darwin":
|
|
osOverride = b.Darwin
|
|
}
|
|
out.MergeFrom(osOverride)
|
|
|
|
return out
|
|
}
|
|
|
|
// AppliesTo reports whether this build should run on (os, compiler).
|
|
// An empty Platforms/Compilers list means no filter on that axis.
|
|
func (b *BuildConfig) AppliesTo(os, compiler string) bool {
|
|
if len(b.Platforms) > 0 && !contains(b.Platforms, os) {
|
|
return false
|
|
}
|
|
if len(b.Compilers) > 0 && !contains(b.Compilers, compiler) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func contains(xs []string, x string) bool {
|
|
for _, v := range xs {
|
|
if v == x {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
type ToolchainSpec struct {
|
|
Name string
|
|
Platforms []string
|
|
Binary string
|
|
Class string
|
|
}
|