| Index: experimental/fiddle/fiddler.go
|
| diff --git a/experimental/fiddle/fiddler.go b/experimental/fiddle/fiddler.go
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d3056c95d3f0cecbbcff9a1aa41a75972a1346be
|
| --- /dev/null
|
| +++ b/experimental/fiddle/fiddler.go
|
| @@ -0,0 +1,159 @@
|
| +/*
|
| + * Copyright 2015 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +package main
|
| +
|
| +// Example use:
|
| +// git clone https://skia.googlesource.com/skia.git
|
| +// cd skia
|
| +// SKIA=$PWD
|
| +// cd experimental/fiddle
|
| +// go get github.com/skia-dev/glog
|
| +// go get go.skia.org/infra/go/util
|
| +// go build fiddler.go
|
| +// # compile prerequisites
|
| +// ./fiddler "$SKIA"
|
| +// # compile and run a fiddle
|
| +// ./fiddler "$SKIA" draw.cpp | ./parse-fiddle-output
|
| +// # compile and run a different fiddle
|
| +// ./fiddler "$SKIA" ANOTHER_FIDDLE.cpp | ./parse-fiddle-output
|
| +
|
| +import (
|
| + "bytes"
|
| + "fmt"
|
| + "io"
|
| + "io/ioutil"
|
| + "os"
|
| + "os/exec"
|
| + "path"
|
| + "syscall"
|
| +
|
| + "github.com/skia-dev/glog"
|
| + "go.skia.org/infra/go/util"
|
| +)
|
| +
|
| +func setResourceLimits() error {
|
| + const maximumTimeInSeconds = 5
|
| + limit := syscall.Rlimit{maximumTimeInSeconds, maximumTimeInSeconds}
|
| + if err := syscall.Setrlimit(syscall.RLIMIT_CPU, &limit); err != nil {
|
| + return err
|
| + }
|
| + const maximumMemoryInBytes = 1 << 28
|
| + limit = syscall.Rlimit{maximumMemoryInBytes, maximumMemoryInBytes}
|
| + return syscall.Setrlimit(syscall.RLIMIT_AS, &limit)
|
| +}
|
| +
|
| +// execCommand runs command and returns an error if it fails. If there is no
|
| +// error, all output is discarded.
|
| +func execCommand(input io.Reader, dir string, name string, arg ...string) error {
|
| + var buffer bytes.Buffer
|
| + cmd := exec.Command(name, arg...)
|
| + cmd.Dir = dir
|
| + cmd.Stdout = &buffer
|
| + cmd.Stderr = &buffer
|
| + cmd.Stdin = input
|
| + if err := cmd.Run(); err != nil {
|
| + return fmt.Errorf("execution failed:\n\n%s\n[%v]", buffer.String(), err)
|
| + }
|
| + return nil
|
| +}
|
| +
|
| +func compileArgs(skiaSrc string) string {
|
| + return "@" + path.Join(skiaSrc, "cmake", "skia_compile_arguments.txt")
|
| +}
|
| +
|
| +func linkArgs(skiaSrc string) string {
|
| + return "@" + path.Join(skiaSrc, "cmake", "skia_link_arguments.txt")
|
| +}
|
| +
|
| +// fiddler compiles the input, links against skia, and runs the executable.
|
| +// @param skiaSrc: the base directory of the Skia repository
|
| +// @param inputReader: C++ fiddle source
|
| +// @param output: stdout of executable sent here
|
| +// @param tempDir: where to place the compiled executable
|
| +func fiddler(skiaSrc string, inputReader io.Reader, output io.Writer, tempDir string) error {
|
| + binarypath := path.Join(tempDir, "fiddle")
|
| + fiddle_dir := path.Join(skiaSrc, "experimental", "fiddle")
|
| + if err := execCommand(inputReader, fiddle_dir,
|
| + "c++",
|
| + compileArgs(skiaSrc),
|
| + "-I", fiddle_dir,
|
| + "-o", binarypath,
|
| + "-x", "c++", "-", "-x", "none",
|
| + "fiddle_main.o",
|
| + "-lOSMesa",
|
| + linkArgs(skiaSrc),
|
| + ); err != nil {
|
| + return err
|
| + }
|
| + var buffer bytes.Buffer
|
| + runCmd := exec.Cmd{Path: binarypath, Stdout: output, Stderr: &buffer}
|
| + if err := runCmd.Run(); err != nil {
|
| + return fmt.Errorf("execution failed:\n\n%s\n[%v]", buffer.String(), err)
|
| + }
|
| + return nil
|
| +}
|
| +
|
| +// Compile Skia library and fiddle_main.cpp
|
| +// @param skiaSrc: the base directory of the Skia repository.
|
| +func fiddlerPrerequisites(skiaSrc string) error {
|
| + cmakeDir := path.Join(skiaSrc, "cmake")
|
| + if err := execCommand(nil, cmakeDir, "cmake", "-G", "Ninja", "."); err != nil {
|
| + return err
|
| + }
|
| + if err := execCommand(nil, cmakeDir, "ninja", "skia"); err != nil {
|
| + return err
|
| + }
|
| + fiddle_dir := path.Join(skiaSrc, "experimental", "fiddle")
|
| + if err := execCommand(nil, fiddle_dir, "c++", compileArgs(skiaSrc),
|
| + "fiddle_main.h"); err != nil {
|
| + return err
|
| + }
|
| + return execCommand(nil, fiddle_dir, "c++", compileArgs(skiaSrc),
|
| + "-c", "-o", "fiddle_main.o", "fiddle_main.cpp")
|
| +}
|
| +
|
| +func main() {
|
| + if len(os.Args) < 2 {
|
| + glog.Fatalf("usage: %s SKIA_SRC_PATH [PATH_TO_DRAW.CPP]", os.Args[0])
|
| + }
|
| + skiaSrc := os.Args[1]
|
| + if len(os.Args) < 3 {
|
| + // execCommand(nil, skiaSrc, "git", "fetch")
|
| + // execCommand(nil, skiaSrc, "git", "checkout", "origin/master")
|
| + if err := fiddlerPrerequisites(skiaSrc); err != nil {
|
| + glog.Fatal(err)
|
| + }
|
| + } else {
|
| + if err := setResourceLimits(); err != nil {
|
| + glog.Fatal(err)
|
| + }
|
| + tempDir, err := ioutil.TempDir("", "fiddle_")
|
| + if err != nil {
|
| + glog.Fatal(err)
|
| + }
|
| + defer func() {
|
| + err = os.RemoveAll(tempDir)
|
| + if err != nil {
|
| + glog.Fatalf("os.RemoveAll(tempDir) failed: %v", err)
|
| + }
|
| + }()
|
| + if os.Args[2] == "-" {
|
| + if err := fiddler(skiaSrc, os.Stdin, os.Stdout, tempDir); err != nil {
|
| + glog.Fatal(err)
|
| + }
|
| + } else {
|
| + inputFile, err := os.Open(os.Args[2])
|
| + if err != nil {
|
| + glog.Fatalf("unable to open \"%s\": %v", os.Args[2], err)
|
| + }
|
| + util.Close(inputFile)
|
| + if err = fiddler(skiaSrc, inputFile, os.Stdout, tempDir); err != nil {
|
| + glog.Fatal(err)
|
| + }
|
| + }
|
| + }
|
| +}
|
|
|