Chromium Code Reviews| Index: experimental/fiddle/fiddler.go |
| diff --git a/experimental/fiddle/fiddler.go b/experimental/fiddle/fiddler.go |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ba2ac070f0fc2d4b4fb76885a95faeca1f6e3e9b |
| --- /dev/null |
| +++ b/experimental/fiddle/fiddler.go |
| @@ -0,0 +1,156 @@ |
| +/* |
| + * 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 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" |
| + "io" |
| + "io/ioutil" |
| + "os" |
| + "os/exec" |
| + "path" |
| + "path/filepath" |
| + "strings" |
| + "syscall" |
| + |
| + "github.com/skia-dev/glog" |
| +) |
| + |
| +func setResourceLimits() { |
| + const maximumTimeInSeconds = 5 |
| + limit := syscall.Rlimit{maximumTimeInSeconds, maximumTimeInSeconds} |
| + if err := syscall.Setrlimit(syscall.RLIMIT_CPU, &limit); err != nil { |
| + glog.Fatalf("syscall.Setrlimit(RLIMIT_CPU) error: %v", err) |
|
jcgregorio
2015/12/02 15:54:34
glog.Fatal should really be restricted to being ca
hal.canary
2015/12/02 22:34:39
done
|
| + } |
| + const maximumMemoryInBytes = 1 << 28 |
| + limit = syscall.Rlimit{maximumMemoryInBytes, maximumMemoryInBytes} |
| + if err := syscall.Setrlimit(syscall.RLIMIT_AS, &limit); err != nil { |
| + glog.Fatalf("syscall.Setrlimit(RLIMIT_AS) error: %v", err) |
| + } |
| +} |
| + |
| +func trimmedBasePath(fpath string) string { |
| + basename := path.Base(fpath) |
| + return strings.TrimSuffix(basename, path.Ext(basename)) |
| +} |
| + |
| +func absPath(path string) string { |
| + abspath, err := filepath.Abs(path) |
| + if err != nil { |
| + glog.Fatalf("filepath.Abs(%s) failed: %v", path, err) |
| + } |
| + return abspath |
| +} |
| + |
| +func closeme(closer io.Closer) { |
| + err := closer.Close() |
| + if err != nil { |
| + glog.Fatalf("Close() failed: %v", err) |
| + } |
| +} |
| + |
| +// runs command and logs a fatal error if it fails. If there is no |
| +// error, all output is discarded. |
| +func execCommand(input io.Reader, dir string, name string, arg ...string) { |
| + 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 { |
| + glog.Fatalf("command failed:\n%v\n%s\n[%v]", cmd.Args, buffer.String(), err) |
| + } |
| +} |
| + |
| +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") |
| +} |
| + |
| +// Compile the input |
|
jcgregorio
2015/12/02 15:54:34
Comments begin with the name of the thing being co
hal.canary
2015/12/02 22:34:40
done
|
| +// @param skiaSrc: the base directory of the Skia repository. |
| +func fiddler(skiaSrc string, inputReader io.Reader, output io.Writer) { |
| + tempDir, err := ioutil.TempDir("", "fiddle_") |
| + if err != nil { |
| + glog.Fatalf("ioutil.TempDir() failed: %v", err) |
| + } |
| + defer func() { |
| + err = os.RemoveAll(tempDir) |
| + if err != nil { |
| + glog.Fatalf("os.RemoveAll(tempDir) failed: %v", err) |
| + } |
| + }() |
| + binarypath := path.Join(tempDir, "fiddle") |
| + fiddle_dir := path.Join(skiaSrc, "experimental", "fiddle") |
| + execCommand(inputReader, fiddle_dir, |
| + "c++", |
| + compileArgs(skiaSrc), |
| + "-I", fiddle_dir, |
| + "-o", binarypath, |
| + "-x", "c++", "-", "-x", "none", |
| + "fiddle_main.o", |
| + "-lOSMesa", |
| + linkArgs(skiaSrc)) |
| + var buffer bytes.Buffer |
| + runCmd := exec.Cmd{Path: binarypath, Stdout: output, Stderr: &buffer} |
| + if err := runCmd.Run(); err != nil { |
| + glog.Fatalf("execution failed:\n\n%s\n[%v]", buffer.String(), err) |
| + } |
| +} |
| + |
| +// Compile Skia library and fiddle_main.cpp |
| +// @param skiaSrc: the base directory of the Skia repository. |
| +func fiddlerPrerequisites(skiaSrc string) { |
| + cmakeDir := path.Join(skiaSrc, "cmake") |
| + execCommand(nil, cmakeDir, "cmake", "-G", "Ninja", ".") |
| + execCommand(nil, cmakeDir, "ninja", "skia") |
| + fiddle_dir := path.Join(skiaSrc, "experimental", "fiddle") |
| + execCommand(nil, fiddle_dir, "c++", compileArgs(skiaSrc), "fiddle_main.h") |
| + 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") |
| + fiddlerPrerequisites(skiaSrc) |
| + } else { |
| + setResourceLimits() |
| + if os.Args[2] == "-" { |
| + fiddler(skiaSrc, os.Stdin, os.Stdout) |
| + } else { |
| + inputFile, err := os.Open(os.Args[2]) |
| + if err != nil { |
| + glog.Fatalf("unable to open \"%s\": %v", os.Args[2], err) |
| + } |
| + defer closeme(inputFile) |
| + fiddler(skiaSrc, inputFile, os.Stdout) |
| + } |
| + } |
| +} |