Skip to content

Commit

Permalink
Merge pull request #8 from daedaleanai/jf-v0.1.3
Browse files Browse the repository at this point in the history
v0.1.3
  • Loading branch information
jfrohnhofen authored Feb 10, 2021
2 parents 1e5b66c + 2fa865a commit b8946d2
Show file tree
Hide file tree
Showing 19 changed files with 318 additions and 463 deletions.
69 changes: 35 additions & 34 deletions RULES/cc/cc.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,24 @@ type ObjectFile struct {
Toolchain Toolchain
}

// Out provides the name of the output created by ObjectFile.
func (obj ObjectFile) Out() core.OutPath {
return obj.Src.WithExt("o")
}

// BuildSteps for ObjectFile.
func (obj ObjectFile) BuildSteps() []core.BuildStep {
// Build an ObjectFile.
func (obj ObjectFile) Build(ctx core.Context) core.OutPath {
toolchain := obj.Toolchain
if toolchain == nil {
toolchain = &defaultToolchain
}

out := obj.Src.WithExt("o")
depfile := obj.Src.WithExt("d")
cmd := toolchain.ObjectFile(obj.Out(), depfile, obj.Flags, obj.Includes, obj.Src)
return []core.BuildStep{{
Out: obj.Out(),
cmd := toolchain.ObjectFile(out, depfile, obj.Flags, obj.Includes, obj.Src)
ctx.AddBuildStep(core.BuildStep{
Out: out,
Depfile: &depfile,
In: obj.Src,
Cmd: cmd,
Descr: fmt.Sprintf("CC %s", obj.Out().Relative()),
Alias: obj.Out().Relative(),
}}
Descr: fmt.Sprintf("CC %s", out.Relative()),
})
return out
}

func flattenDepsRec(deps []Dep, visited map[string]bool) []Library {
Expand All @@ -55,13 +51,12 @@ func flattenDeps(deps []Dep) []Library {
return flattenDepsRec(deps, map[string]bool{})
}

func compileSources(srcs core.Paths, flags core.Flags, deps []Library, toolchain Toolchain) ([]core.BuildStep, core.Paths) {
func compileSources(ctx core.Context, srcs core.Paths, flags core.Flags, deps []Library, toolchain Toolchain) core.Paths {
includes := core.Paths{core.NewInPath(".")}
for _, dep := range deps {
includes = append(includes, dep.Includes...)
}

steps := []core.BuildStep{}
objs := core.Paths{}

for _, src := range srcs {
Expand All @@ -71,11 +66,10 @@ func compileSources(srcs core.Paths, flags core.Flags, deps []Library, toolchain
Flags: flags,
Toolchain: toolchain,
}
objs = append(objs, obj.Out())
steps = append(steps, obj.BuildSteps()...)
objs = append(objs, obj.Build(ctx))
}

return steps, objs
return objs
}

// Dep is an interface implemented by dependencies that can be linked into a library.
Expand All @@ -91,30 +85,38 @@ type Library struct {
Includes core.Paths
CompilerFlags core.Flags
Deps []Dep
Shared bool
AlwaysLink bool
Toolchain Toolchain
}

// BuildSteps for Library.
func (lib Library) BuildSteps() []core.BuildStep {
// Build a Library.
func (lib Library) Build(ctx core.Context) core.OutPath {
toolchain := lib.Toolchain
if toolchain == nil {
toolchain = &defaultToolchain
}

steps, objs := compileSources(lib.Srcs, lib.CompilerFlags, flattenDeps([]Dep{lib}), toolchain)
objs := compileSources(ctx, lib.Srcs, lib.CompilerFlags, flattenDeps([]Dep{lib}), toolchain)
objs = append(objs, lib.Objs...)

cmd := toolchain.Library(lib.Out, objs)
arStep := core.BuildStep{
var cmd, descr string
if lib.Shared {
cmd = toolchain.SharedLibrary(lib.Out, objs)
descr = fmt.Sprintf("LD %s", lib.Out.Relative())
} else {
cmd = toolchain.StaticLibrary(lib.Out, objs)
descr = fmt.Sprintf("AR %s", lib.Out.Relative())
}

ctx.AddBuildStep(core.BuildStep{
Out: lib.Out,
Ins: objs,
Cmd: cmd,
Descr: fmt.Sprintf("AR %s", lib.Out.Relative()),
Alias: lib.Out.Relative(),
}
Descr: descr,
})

return append(steps, arStep)
return lib.Out
}

// CcLibrary for Library is just the identity.
Expand All @@ -133,15 +135,15 @@ type Binary struct {
Toolchain Toolchain
}

// BuildSteps for Binary.
func (bin Binary) BuildSteps() []core.BuildStep {
// Build a Binary.
func (bin Binary) Build(ctx core.Context) core.OutPath {
toolchain := bin.Toolchain
if toolchain == nil {
toolchain = defaultToolchain
}

deps := flattenDeps(bin.Deps)
steps, objs := compileSources(bin.Srcs, bin.CompilerFlags, deps, toolchain)
objs := compileSources(ctx, bin.Srcs, bin.CompilerFlags, deps, toolchain)

ins := objs
alwaysLinkLibs := core.Paths{}
Expand All @@ -160,13 +162,12 @@ func (bin Binary) BuildSteps() []core.BuildStep {
}

cmd := toolchain.Binary(bin.Out, objs, alwaysLinkLibs, otherLibs, bin.LinkerFlags, bin.Script)
ldStep := core.BuildStep{
ctx.AddBuildStep(core.BuildStep{
Out: bin.Out,
Ins: ins,
Cmd: cmd,
Descr: fmt.Sprintf("LD %s", bin.Out.Relative()),
Alias: bin.Out.Relative(),
}
})

return append(steps, ldStep)
return bin.Out
}
16 changes: 13 additions & 3 deletions RULES/cc/toolchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import (

type Toolchain interface {
ObjectFile(out core.OutPath, depfile core.OutPath, flags core.Flags, includes core.Paths, src core.Path) string
Library(out core.Path, objs core.Paths) string
StaticLibrary(out core.Path, objs core.Paths) string
SharedLibrary(out core.Path, objs core.Paths) string
Binary(out core.Path, objs core.Paths, alwaysLinkLibs core.Paths, libs core.Paths, flags core.Flags, script core.Path) string
EmbeddedBlob(out core.OutPath, src core.Path) string
}
Expand Down Expand Up @@ -52,15 +53,24 @@ func (gcc GccToolchain) ObjectFile(out core.OutPath, depfile core.OutPath, flags
src)
}

// Library generates the command to build a static library.
func (gcc GccToolchain) Library(out core.Path, objs core.Paths) string {
// StaticLibrary generates the command to build a static library.
func (gcc GccToolchain) StaticLibrary(out core.Path, objs core.Paths) string {
return fmt.Sprintf(
"%s rv %s %s >/dev/null 2>/dev/null",
gcc.Ar,
out,
objs)
}

// SharedLibrary generates the command to build a shared library.
func (gcc GccToolchain) SharedLibrary(out core.Path, objs core.Paths) string {
return fmt.Sprintf(
"%s -shared -o %s %s",
gcc.Cxx,
out,
objs)
}

// Binary generates the command to build an executable.
func (gcc GccToolchain) Binary(out core.Path, objs core.Paths, alwaysLinkLibs core.Paths, libs core.Paths, flags core.Flags, script core.Path) string {
flags = append(gcc.LinkerFlags, flags...)
Expand Down
83 changes: 83 additions & 0 deletions RULES/core/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package core

import (
"fmt"
"path/filepath"
"strings"
)

type Context interface {
AddTarget(name string, target interface{})
AddBuildStep(BuildStep)
}

type NinjaContext struct {
nextRuleID int
}

func ninjaEscape(s string) string {
return strings.ReplaceAll(s, " ", "$ ")
}

type buildable interface {
Build(ctx Context) OutPath
}

func (ctx *NinjaContext) AddTarget(name string, target interface{}) {
iface, ok := target.(buildable)
if !ok {
return
}

currentTarget = name
out := iface.Build(ctx)

fmt.Printf("rule r%d\n", ctx.nextRuleID)
relativePath, _ := filepath.Rel(WorkingDir(), out.Absolute())
fmt.Printf(" command = echo \"%s\"\n", relativePath)
fmt.Printf(" description = Created %s:", name)
fmt.Printf("\n")
fmt.Printf("build %s: r%d %s\n", name, ctx.nextRuleID, ninjaEscape(out.Absolute()))
fmt.Printf("\n")
fmt.Printf("\n")

ctx.nextRuleID++
}

func (ctx *NinjaContext) AddBuildStep(step BuildStep) {
ins := []string{}
for _, in := range step.Ins {
ins = append(ins, ninjaEscape(in.Absolute()))
}
if step.In != nil {
ins = append(ins, ninjaEscape(step.In.Absolute()))
}

out := ninjaEscape(step.Out.Absolute())

fmt.Printf("rule r%d\n", ctx.nextRuleID)
if step.Depfile != nil {
depfile := ninjaEscape(step.Depfile.Absolute())
fmt.Printf(" depfile = %s\n", depfile)
}
fmt.Printf(" command = %s\n", step.Cmd)
if step.Descr != "" {
fmt.Printf(" description = %s\n", step.Descr)
}
fmt.Print("\n")
fmt.Printf("build %s: r%d %s\n", out, ctx.nextRuleID, strings.Join(ins, " "))
fmt.Print("\n\n")

ctx.nextRuleID++
}

type ListTargetsContext struct{}

func (ctx *ListTargetsContext) AddTarget(name string, target interface{}) {
_, ok := target.(buildable)
if ok {
fmt.Println(name)
}
}

func (ctx *ListTargetsContext) AddBuildStep(step BuildStep) {}
10 changes: 5 additions & 5 deletions RULES/core/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ type CopyFile struct {
To OutPath
}

// BuildSteps for CopyFile.
func (copy CopyFile) BuildSteps() []BuildStep {
return []BuildStep{{
// Build for CopyFile.
func (copy CopyFile) Build(ctx Context) OutPath {
ctx.AddBuildStep(BuildStep{
Out: copy.To,
In: copy.From,
Cmd: fmt.Sprintf("cp %s %s", copy.From, copy.To),
Descr: fmt.Sprintf("CP %s", copy.To.Relative()),
Alias: copy.To.Relative(),
}}
})
return copy.To
}
45 changes: 0 additions & 45 deletions RULES/core/step.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
package core

import (
"fmt"
"strings"
)

// BuildStep represents one build step (i.e., one build command).
// Each BuildStep produces `Out` from `Ins` and `In` by running `Cmd`.
type BuildStep struct {
Expand All @@ -14,44 +9,4 @@ type BuildStep struct {
Depfile *OutPath
Cmd string
Descr string
Alias string
}

var nextRuleID = 1

func ninjaEscape(s string) string {
return strings.ReplaceAll(s, " ", "$ ")
}

// Print outputs a Ninja build rule for the BuildStep.
func (step BuildStep) Print() {
ins := []string{}
for _, in := range step.Ins {
ins = append(ins, ninjaEscape(in.Absolute()))
}
if step.In != nil {
ins = append(ins, ninjaEscape(step.In.Absolute()))
}

alias := ninjaEscape(step.Alias)
out := ninjaEscape(step.Out.Absolute())

fmt.Printf("rule r%d\n", nextRuleID)
if step.Depfile != nil {
depfile := ninjaEscape(step.Depfile.Absolute())
fmt.Printf(" depfile = %s\n", depfile)
}
fmt.Printf(" command = %s\n", step.Cmd)
if step.Descr != "" {
fmt.Printf(" description = %s\n", step.Descr)
}
fmt.Print("\n")
fmt.Printf("build %s: r%d %s\n", out, nextRuleID, strings.Join(ins, " "))
if alias != "" {
fmt.Print("\n")
fmt.Printf("build %s: phony %s\n", alias, out)
}
fmt.Print("\n\n")

nextRuleID++
}
8 changes: 4 additions & 4 deletions RULES/core/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ type ExpandTemplate struct {
}

// BuildSteps for ExpandTemplate.
func (tmpl ExpandTemplate) BuildSteps() []BuildStep {
func (tmpl ExpandTemplate) Build(ctx Context) OutPath {
substitutions := []string{}
for old, new := range tmpl.Substitutions {
substitutions = append(substitutions, fmt.Sprintf("-e 's/%s/%s/g'", old, new))
}
cmd := fmt.Sprintf("sed %s %s > %s", strings.Join(substitutions, " "), tmpl.Template, tmpl.Out)
return []BuildStep{{
ctx.AddBuildStep(BuildStep{
Out: tmpl.Out,
In: tmpl.Template,
Cmd: cmd,
Descr: fmt.Sprintf("TEMPLATE %s", tmpl.Out.Relative()),
Alias: tmpl.Out.Relative(),
}}
})
return tmpl.Out
}
Loading

0 comments on commit b8946d2

Please sign in to comment.