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) |
+ } |
+ } |
+} |