blob: bd2ae586d4211c6ae0ecbcf147cb5c7729b7ef4a [file] [log] [blame]
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"fmt"
"strings"
"android.googlesource.com/platform/tools/gpu/cc"
"android.googlesource.com/platform/tools/gpu/framework/file"
"android.googlesource.com/platform/tools/gpu/framework/log"
"android.googlesource.com/platform/tools/gpu/tools/maker/config"
"android.googlesource.com/platform/tools/gpu/tools/maker/do"
"android.googlesource.com/platform/tools/gpu/tools/maker/graph"
"android.googlesource.com/platform/tools/gpu/tools/maker/run"
)
func main() { run.Run() }
const (
GPURoot = "android.googlesource.com/platform/tools/gpu"
)
var (
gpusrc = do.GoSrcPath(GPURoot)
gapidsrc = gpusrc.Join("gapid")
gapirpath = gpusrc.Join("cc/gapir")
gapiipath = gpusrc.Join("cc/gapii")
gapiiwinpath = gpusrc.Join("cc/gapii/windows")
gapiiosxpath = gpusrc.Join("cc/gapii/osx")
cppcoder = gpusrc.Join("cc/gapic/coder")
interceptorpath = gpusrc.Join("cc/third_party/prebuilts/interceptor")
pkginfobase = gpusrc.Join("cmd/pkginfo")
gfxtracerbase = gpusrc.Join("cmd/gfxtracer")
Tools struct {
Apic file.Path
Annotate file.Path
CleanGenerated file.Path
Codergen file.Path
Copyright file.Path
Embed file.Path
PullAPK file.Path
Stringgen file.Path
VerifyGLESAPI file.Path
}
Apps struct {
Gapis file.Path
Gapir file.Path
Gapit file.Path
}
code = graph.Virtual("code")
codergen = graph.Virtual("codergen")
embed = graph.Virtual("embed")
messages = graph.Virtual("messages")
apic = graph.Virtual("apic")
annotate = graph.Virtual("annotate")
ccSpy = graph.Virtual("cc:spy")
ccGapii = graph.Virtual("cc:gapii")
tools = graph.Virtual("tools")
runtime = graph.Virtual("runtime")
test = graph.Virtual("test")
apps = graph.Virtual("apps")
pkginfo = graph.Virtual("pkginfo")
gfxtracer = graph.Virtual("gfxtracer")
interceptor = graph.Virtual("interceptor")
goTest = graph.Virtual("go_test")
ccTest = graph.Virtual("cc_test")
)
func init() {
run.Register(func(ctx log.Context) {
// Install rules for the build tools
Tools.Apic = do.GoInstall(ctx, GPURoot, "cmd/apic")
Tools.Annotate = do.GoInstall(ctx, GPURoot, "cmd/annotate")
Tools.CleanGenerated = do.GoInstall(ctx, GPURoot, "cmd/clean_generated")
Tools.Codergen = do.GoInstall(ctx, GPURoot, "cmd/codergen")
Tools.Copyright = do.GoInstall(ctx, GPURoot, "cmd/copyright")
Tools.Embed = do.GoInstall(ctx, GPURoot, "cmd/embed")
Tools.PullAPK = do.GoInstall(ctx, GPURoot, "cmd/pullapk")
Tools.Stringgen = do.GoInstall(ctx, GPURoot, "cmd/stringgen")
Tools.VerifyGLESAPI = do.GoInstall(ctx, GPURoot, "cmd/verify_gles_api")
graph.List(ctx, tools).DependsStruct(Tools)
// All the embed rules
embedCopyright := Embed(ctx, gpusrc.Join("tools/copyright"), "")
embedCodergen := Embed(ctx, gpusrc.Join("tools/codergen/template"), "")
embedStringgen := Embed(ctx, gpusrc.Join("cmd/stringgen"), "main")
graph.Creator(Tools.Apic).DependsOn(embedCopyright)
graph.Creator(Tools.Codergen).DependsOn(embedCopyright, embedCodergen)
graph.Creator(Tools.Stringgen).DependsOn(embedStringgen)
// The stringgen rule
Messages(ctx, gpusrc.Join("gapid/messages/en-us.stb.md"))
// All the apic rules
GfxApi(ctx, "test", "gfxapi_test.api")
GfxApi(ctx, "gles", "gles.api")
GlApi(ctx, "gles", "gles.api")
VkApi(ctx, "vulkan", "vulkan.api")
// The codergen rule
Codergen(ctx, codergen,
"--signatures", gpusrc.Join("signatures.txt").System(),
"--go",
"-cpp", cppcoder.System(),
GPURoot+"/...")
graph.Creator(Tools.Annotate).DependsOn(codergen)
graph.List(ctx, code).DependsOn(
embed, messages, apic, codergen, annotate)
// The native code rules
cc.Graph()
Apps.Gapir = graph.Virtual("cc:gapir")
graph.Creator(ccSpy).DependsOn(code)
graph.Creator(ccGapii).DependsOn(code)
// The testing rules
gotest := do.GoTest(ctx, GPURoot+"/...", "integration")
// Runtime dependencies
graph.List(ctx, runtime).DependsOn(Apps.Gapir, ccSpy, ccGapii)
graph.Creator(gotest).DependsOn(code, runtime)
if config.TargetOS == config.HostOS {
graph.List(ctx, test).DependsOn(goTest, ccTest)
} else {
graph.List(ctx, test).DependsOn(goTest)
}
// The main binary rules
Apps.Gapis = do.GoInstall(ctx, GPURoot, "cmd/gapis")
graph.Creator(Apps.Gapis).DependsOn(code)
Apps.Gapit = do.GoInstall(ctx, GPURoot, "cmd/gapit")
graph.Creator(Apps.Gapit).DependsOn(code)
graph.List(ctx, apps).DependsStruct(Apps)
// Application launchers
do.Exec(Apps.Gapis).Creates(ctx, graph.Virtual("gapis")).DependsOn(Apps.Gapir)
// Utilties
do.GoRun(ctx, gpusrc.Join("cmd/clean_generated/main.go"), gpusrc).Creates(ctx, graph.Virtual("clean_gpu"))
do.GoRun(ctx, gpusrc.Join("cmd/copyright/main.go"), "-o", gpusrc).Creates(ctx, graph.Virtual("copyright")).DependsOn(embedCopyright)
// pkginfo helper APK
PkgInfo(ctx)
// Tracer Android Library AAR
GfxTracer(ctx)
// Interceptor library
Interceptor(ctx)
// The default rules
graph.List(ctx, graph.Default).DependsOn(tools, apps, test, interceptor)
})
}
func Embed(ctx log.Context, path file.Path, pkg string) file.Path {
out := path.Join("embed.go")
args := []string{"--out", out.System()}
if pkg != "" {
args = append(args, "-package", pkg)
}
files := path.Files().NotMatching("*.go", "*.gradle")
for _, f := range files {
args = append(args, f.System())
}
s := do.Exec(Tools.Embed, args...).Creates(ctx, out)
for _, f := range files {
s.DependsOn(f)
}
graph.List(ctx, embed).DependsOn(out)
return out
}
func Messages(ctx log.Context, files ...file.Path) file.Path {
out := gapidsrc.Join("messages/messages.go")
args := []string{
"--def", out.System(),
"--pkg", config.Paths.Bin.Join("strings").System(),
}
for _, f := range files {
args = append(args, f.System())
}
s := do.Exec(Tools.Stringgen, args...).Creates(ctx, out)
for _, f := range files {
s.DependsOn(f)
}
graph.List(ctx, messages).DependsOn(out)
return out
}
func Annotate(ctx log.Context, dst file.Path, api file.Path) {
// Generate the text file for understandability.
snippetsText := dst.Join("snippets.text")
globalsSnippetsText := dst.Join("globals_snippets.text")
snippetsBase64 := dst.Join("snippets.base64")
globalsSnippetsBase64 := dst.Join("globals_snippets.base64")
snippetsEmbed := dst.Join("snippets_embed.go")
do.Exec(Tools.Annotate,
"--base64", snippetsBase64.System(),
"--text", snippetsText.System(),
"--globals_base64", globalsSnippetsBase64.System(),
"--globals_text", globalsSnippetsText.System(),
api.System()).DependsOn(api).
Creates(ctx, snippetsBase64, snippetsText, globalsSnippetsBase64, globalsSnippetsText)
// Embed the base64 file into gapis
do.Exec(Tools.Embed,
"--out", snippetsEmbed.System(),
snippetsBase64.System(), globalsSnippetsBase64.System()).
Creates(ctx, snippetsEmbed).DependsOn(snippetsBase64, globalsSnippetsBase64)
graph.List(ctx, annotate).DependsOn(snippetsEmbed)
}
func Apic(ctx log.Context, dst file.Path, api file.Path, template file.Path) {
deps := config.Paths.Deps.Join(fmt.Sprintf("%v_%v.deps", api.Basename(), template.Basename()))
s := do.Exec(Tools.Apic,
"template",
"--dir", dst.System(),
"--deps", deps.System(),
api.System(), template.System()).DependsOn(api, template, dst, config.Paths.Deps)
s.UseDepsFile(ctx, deps)
graph.List(ctx, apic).DependsOn(deps)
}
func Codergen(ctx log.Context, name file.Path, args ...string) {
do.Exec(Tools.Codergen, args...).Creates(ctx, name).DependsOn(apic).Access(do.GoPkgResource)
}
func PkgInfo(ctx log.Context) {
gradleAPK := pkginfobase.Join("app/build/outputs/apk/app-debug.apk")
binAPK := config.Paths.Bin.Join("pkginfo.apk")
graph.NewStep(func(ctx log.Context, step *graph.Step) error {
return do.ExecAt(ctx, pkginfobase, pkginfobase.Join("gradlew"), "build")
}).Creates(ctx, gradleAPK)
do.CopyFile(ctx, binAPK, gradleAPK)
graph.List(ctx, pkginfo).DependsOn(binAPK)
}
func GfxTracer(ctx log.Context) {
gradleAAR := gfxtracerbase.Join("lib/build/outputs/aar/lib-debug.aar")
binAAR := config.Paths.Bin.Join("gfxtracer.aar")
s := graph.NewStep(func(ctx log.Context, step *graph.Step) error {
return do.ExecAt(ctx, gfxtracerbase, gfxtracerbase.Join("gradlew"), "build")
}).Creates(ctx, gradleAAR)
jniLibs := gfxtracerbase.Join("lib/src/main/jniLibs")
do.CopyFile(ctx, jniLibs.Join("armeabi-v7a/libgapii.so"), config.Paths.Bin.Join("android-armv7a/libgapii.so"))
s.DependsOn(jniLibs.Join("armeabi-v7a/libgapii.so"))
do.CopyFile(ctx, jniLibs.Join("arm64-v8a/libgapii.so"), config.Paths.Bin.Join("android-armv8a/libgapii.so"))
s.DependsOn(jniLibs.Join("/arm64-v8a/libgapii.so"))
do.CopyFile(ctx, binAAR, gradleAAR)
graph.List(ctx, gfxtracer).DependsOn(binAAR)
}
// Interceptor copies the prebuilt files in interceptorpath to the bin directory
// as the virtual list 'interceptor'.
func Interceptor(ctx log.Context) {
graph.List(ctx, interceptor)
for _, file := range interceptorpath.Glob("*/*") {
rel, _ := file.RelativeTo(interceptorpath)
dst := config.Paths.Bin.Join(rel)
do.CopyFile(ctx, dst, file)
graph.List(ctx, interceptor).DependsOn(dst)
}
}
func VkApi(ctx log.Context, pkg string, api string) {
out := gapidsrc.Join("gfxapi", pkg)
in := out.Join(api)
templates := gapidsrc.Join("gfxapi", "vulkan", "templates")
root_templates := gapidsrc.Join("gfxapi", "templates")
// gapiiv code
istest := strings.HasSuffix(pkg, "test")
Apic(ctx, out, in, gapidsrc.Join("gfxapi", "templates", "api.go.tmpl"))
Apic(ctx, out, in, gapidsrc.Join("gfxapi", "templates", "mutate.go.tmpl"))
Annotate(ctx, out, in)
if istest {
return
}
Apic(ctx, gapiipath, in, templates.Join("api_spy.cpp.tmpl"))
Apic(ctx, gapiipath, in, templates.Join("api_exports.cpp.tmpl"))
Apic(ctx, gapiipath, in, templates.Join("api_imports.cpp.tmpl"))
Apic(ctx, gapiipath, in, templates.Join("api_imports.h.tmpl"))
Apic(ctx, gapiipath, in, templates.Join("vk_spy_helpers.cpp.tmpl"))
Apic(ctx, gapiipath, in, root_templates.Join("api_spy.h.tmpl"))
Apic(ctx, gapiipath, in, root_templates.Join("api_types.h.tmpl"))
}
func GlApi(ctx log.Context, pkg string, api string) {
out := gapidsrc.Join("gfxapi", pkg)
in := out.Join(api)
templates := gapidsrc.Join("gfxapi", "gles", "templates")
istest := strings.HasSuffix(pkg, "test")
if istest {
return
}
Apic(ctx, gapiipath, in, templates.Join("api_spy.cpp.tmpl"))
Apic(ctx, gapiipath, in, templates.Join("api_exports.cpp.tmpl"))
Apic(ctx, gapiipath, in, templates.Join("api_imports.cpp.tmpl"))
Apic(ctx, gapiipath, in, templates.Join("api_imports.h.tmpl"))
}
func GfxApi(ctx log.Context, pkg string, api string) {
out := gapidsrc.Join("gfxapi", pkg)
in := out.Join(api)
templates := gapidsrc.Join("gfxapi", "templates")
istest := strings.HasSuffix(pkg, "test")
// go code
Apic(ctx, out, in, templates.Join("api.go.tmpl"))
Apic(ctx, out, in, templates.Join("mutate.go.tmpl"))
Annotate(ctx, out, in)
if istest {
return
}
// gapir code
Apic(ctx, gapirpath, in, templates.Join("gfx_api.cpp.tmpl"))
Apic(ctx, gapirpath, in, templates.Join("gfx_api.h.tmpl"))
// gapii code
Apic(ctx, gapiipath, in, templates.Join("api_spy.h.tmpl"))
Apic(ctx, gapiipath, in, templates.Join("api_types.h.tmpl"))
Apic(ctx, gapiiwinpath, in, templates.Join("opengl32_exports.def.tmpl"))
Apic(ctx, gapiiwinpath, in, templates.Join("opengl32_resolve.cpp.tmpl"))
Apic(ctx, gapiiwinpath, in, templates.Join("opengl32_x64.asm.tmpl"))
Apic(ctx, gapiiosxpath, in, templates.Join("opengl_framework_exports.cpp.tmpl"))
}