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..15944b20966e034851b4d77301fc935004e76f44 |
| --- /dev/null |
| +++ b/experimental/fiddle/fiddler.go |
| @@ -0,0 +1,194 @@ |
| +/* |
| + * 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" |
| + "fmt" |
| + "io" |
| + "io/ioutil" |
| + "os" |
| + "os/exec" |
| + "path" |
| + "path/filepath" |
| + "sort" |
| + "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) |
| + } |
| + 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 failed %v", err) |
| + } |
| + return abspath |
| +} |
| + |
| +// 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 compileSkia(inputReader io.Reader, skiaSrc string, arguments []string) { |
| + compileArguments := []string{ |
| + "--std=c++11", |
| + "-DSK_RELEASE", |
| + "-DSK_MESA", |
| + fmt.Sprintf("-I%s", path.Join(skiaSrc, "include/core")), |
| + fmt.Sprintf("-I%s", path.Join(skiaSrc, "include/gpu")), |
| + fmt.Sprintf("-I%s", path.Join(skiaSrc, "include/effects")), |
| + fmt.Sprintf("-I%s", path.Join(skiaSrc, "include/pathops")), |
| + fmt.Sprintf("-I%s", path.Join(skiaSrc, "include/c")), |
| + fmt.Sprintf("-I%s", path.Join(skiaSrc, "include/utils")), |
| + fmt.Sprintf("-I%s", path.Join(skiaSrc, "include/config")), |
| + } |
| + compileArguments = append(compileArguments, arguments...) |
| + execCommand(inputReader, "", "c++", compileArguments...) |
| +} |
| + |
| +func closeme(closer io.Closer) { |
| + err := closer.Close() |
| + if err != nil { |
| + glog.Fatalf("Close() failed: %v", err) |
| + } |
| +} |
| + |
| +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") |
| + libskia_dir := absPath(path.Join(skiaSrc, "cmake")) |
| + |
| + compileSkia(inputReader, skiaSrc, []string{ |
| + "-o", binarypath, |
| + "-x", "c++", "-", "-x", "none", |
| + path.Join(fiddle_dir, "fiddle_main.o"), |
| + path.Join(libskia_dir, "libskia.so"), |
| + "-lOSMesa", |
| + fmt.Sprintf("-Wl,-rpath,%s", libskia_dir), |
| + }) |
| + glog.Infof("Successfully compiled %s", binarypath) |
| + var buffer bytes.Buffer |
| + runCmd := exec.Command(binarypath) |
| + runCmd.Stdout = output |
| + runCmd.Stderr = &buffer |
| + if err := runCmd.Run(); err != nil { |
| + glog.Fatalf("execution failed:\n\n%s\n[%v]", buffer.String(), err) |
| + } |
| +} |
| + |
| +func fiddlerPrerequisites(skiaSrc string) { |
| + execCommand(nil, path.Join(skiaSrc, "cmake"), "cmake", "-G", "Ninja") |
| + execCommand(nil, path.Join(skiaSrc, "cmake"), "ninja", "skia") |
| + |
| + fiddle_dir := path.Join(skiaSrc, "experimental", "fiddle") |
| + out, err := os.Create(path.Join(fiddle_dir, "skia.h")) |
|
jcgregorio
2015/11/24 20:21:35
Generating skia.h should be part of cmake, that wa
|
| + if err != nil { |
| + glog.Fatalf("os.Create('experimental/fiddle/skia.h') failed: %v", err) |
| + } |
| + defer closeme(out) |
| + |
| + fmt.Fprintf(out, "#ifndef skia_headers_DEFINED\n") |
| + fmt.Fprintf(out, "#define skia_headers_DEFINED\n\n") |
| + |
| + for _, dir := range []string{"c", "core", "effects", "pathops", "gpu"} { |
| + fmt.Fprintf(out, "// %s\n", dir) |
| + matches, err := filepath.Glob(path.Join(skiaSrc, "include", dir, "*.h")) |
| + if err != nil { |
| + glog.Fatalf("glob failed: %v", err) |
| + } |
| + sortedMatches := sort.StringSlice(matches) |
| + sortedMatches.Sort() |
| + for _, match := range sortedMatches { |
| + fmt.Fprintf(out, "#include \"%s\"\n", filepath.Base(match)) |
| + } |
| + fmt.Fprintf(out, "\n") |
| + } |
| + fmt.Fprintf(out, "#include \"gl/GrGLInterface.h\"\n") |
| + fmt.Fprintf(out, "\n#endif // skia_headers_DEFINED\n") |
| + |
| + compileSkia(nil, skiaSrc, []string{path.Join(fiddle_dir, "fiddle_main.h")}) |
| + compileSkia(nil, skiaSrc, []string{ |
| + "-c", "-o", path.Join(fiddle_dir, "fiddle_main.o"), |
| + path.Join(fiddle_dir, "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) |
| + } |
| + } |
| +} |