blob: b81fa3ddada5afe95ab3c4e0fa16a9e42a7a850e [file] [log] [blame]
# Copyright (C) 2022 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.
import("../../gn/perfetto.gni")
# Prevent that this file is accidentally included in embedder builds.
assert(enable_perfetto_site)
nodejs_bin = rebase_path("../../tools/node", root_build_dir)
# The destination directory where the website will be built. GN pollutes
# root_out_dir with all sorts of files, so we use a subdirectory.
perfetto_website_out_dir = "$root_out_dir/site"
# The directory containing all the markdown sources for the docs.
src_doc_dir = "../../docs"
group("site") {
deps = [
":all_mdfiles",
":assets",
":gen_index",
":gen_sql_stats_html",
":gen_sql_tables_html",
":gen_stdlib_docs_html",
":gen_toc",
":gen_trace_config_proto",
":gen_trace_packet_proto",
":node_assets",
":readme",
":style_scss",
]
}
# Runs a nodejs script using the hermetic node toolchain.
# Args:
# * script: The .js script to execute
# * inputs
# * outputs
# * deps
# * depfile
template("nodejs_script") {
assert(defined(invoker.script), "Need script in $target_name")
action(target_name) {
forward_variables_from(invoker,
[
"outputs",
"depfile",
])
deps = [ ":node_modules" ]
if (defined(invoker.deps)) {
deps += invoker.deps
}
script = "../../gn/standalone/build_tool_wrapper.py"
inputs = [ invoker.script ]
inputs += invoker.inputs
args = [
nodejs_bin,
rebase_path(invoker.script, root_build_dir),
]
args += invoker.args
}
}
# Installs the node modules specified in package.json
action("node_modules") {
script = "../../gn/standalone/build_tool_wrapper.py"
stamp_file = "$target_out_dir/.$target_name.stamp"
cur_dir = rebase_path(".", root_build_dir)
args = [
"--stamp",
rebase_path(stamp_file, root_build_dir),
"--chdir=$cur_dir",
rebase_path("../../tools/pnpm", root_build_dir),
"install",
"--shamefully-hoist",
"--frozen-lockfile",
]
inputs = [
"../../tools/npm",
"package.json",
"pnpm-lock.yaml",
]
outputs = [ stamp_file ]
}
# Renders a markdown file into html.
# Args:
# * markdown: Optional. The source markdown file
# * html_template: Optional. The html template to use
# * out_html: The generated html, relative to `perfetto_website_out_dir`
# * deps
template("md_to_html") {
assert(defined(invoker.out_html), "Need out_html in $target_name")
assert(defined(invoker.html_template) || defined(invoker.markdown),
"Need html_template or markdown in $target_name")
nodejs_script(target_name) {
forward_variables_from(invoker, [ "deps" ])
script = "src/markdown_render.js"
inputs = []
if (defined(invoker.markdown)) {
inputs += [ invoker.markdown ]
}
depfile = "${target_gen_dir}/$target_name.d"
if (defined(invoker.html_template)) {
inputs += [ invoker.html_template ]
}
outputs = [ "${perfetto_website_out_dir}/${invoker.out_html}" ]
args = [
"--odir",
rebase_path(perfetto_website_out_dir, root_build_dir),
"-o",
rebase_path("${perfetto_website_out_dir}/${invoker.out_html}",
root_build_dir),
"--depfile",
rebase_path(depfile, root_build_dir),
]
if (defined(invoker.markdown)) {
args += [
"-i",
rebase_path(invoker.markdown, root_build_dir),
]
}
if (defined(invoker.html_template)) {
args += [
"-t",
rebase_path(invoker.html_template, root_build_dir),
]
}
}
}
md_to_html("gen_toc") {
markdown = "${src_doc_dir}/toc.md"
out_html = "docs/_nav.html"
}
md_to_html("gen_index") {
html_template = "src/template_index.html"
deps = [ ":gen_toc" ]
out_html = "index.html"
}
nodejs_script("style_scss") {
script = "node_modules/sass/sass.js"
input = "src/assets/style.scss"
inputs = [ input ]
output = "${perfetto_website_out_dir}/assets/style.css"
outputs = [ output ]
args = [
"--quiet",
rebase_path(input, root_build_dir),
rebase_path(output, root_build_dir),
]
deps = [ ":node_modules" ]
}
sql_stats_md = "${target_gen_dir}/sql-stats.md"
nodejs_script("gen_sql_stats_md") {
script = "src/gen_stats_reference.js"
input = "../../src/trace_processor/storage/stats.h"
inputs = [ input ]
outputs = [ sql_stats_md ]
args = [
"-i",
rebase_path(input, root_build_dir),
"-o",
rebase_path(sql_stats_md, root_build_dir),
]
}
md_to_html("gen_sql_stats_html") {
markdown = sql_stats_md
html_template = "src/template_markdown.html"
deps = [
":gen_sql_stats_md",
":gen_toc",
]
out_html = "docs/analysis/sql-stats"
}
# Generates a html reference for a proto
# Args:
# * proto: The path to a .proto file
# * message_name: The proto message name
# * out_html
template("proto_reference") {
sql_stats_md = "${target_gen_dir}/${target_name}.md"
nodejs_script("${target_name}_md") {
script = "src/gen_proto_reference.js"
inputs = [ invoker.proto ]
outputs = [ sql_stats_md ]
args = [
"-i",
rebase_path(invoker.proto, root_build_dir),
"-p",
invoker.message_name,
"-o",
rebase_path(sql_stats_md, root_build_dir),
]
}
md_to_html(target_name) {
markdown = sql_stats_md
html_template = "src/template_markdown.html"
deps = [
":${target_name}_md",
":gen_toc",
]
out_html = invoker.out_html
}
}
proto_reference("gen_trace_config_proto") {
proto = "../../protos/perfetto/config/trace_config.proto"
message_name = "perfetto.protos.TraceConfig"
out_html = "docs/reference/trace-config-proto"
}
proto_reference("gen_trace_packet_proto") {
proto = "../../protos/perfetto/trace/trace_packet.proto"
message_name = "perfetto.protos.TracePacket"
out_html = "docs/reference/trace-packet-proto"
}
# WARNING: this does globbing at generation time. Incremental builds are not
# going to work properly if files are added/removed. `gn gen` needs to be
# rerun.
sql_tables =
exec_script("../../gn/standalone/glob.py",
[
"--root=" + rebase_path("../../src/trace_processor/tables",
root_build_dir),
"--filter=*.h",
],
"list lines")
src_sql_tables = []
foreach(i, sql_tables) {
src_sql_tables += [ rebase_path(i, ".", root_build_dir) ]
}
sql_tables_md = "${target_gen_dir}/sql-tables.md"
stdlib_docs_md = "${target_gen_dir}/stdlib_docs.md"
action("gen_stdlib_docs_md") {
script = "src/gen_stdlib_docs_md.py"
label_info = get_label_info(
"../../src/trace_processor/perfetto_sql/stdlib:stdlib_json_docs",
"target_gen_dir")
absolute_input_path = label_info + "/stdlib_docs.json"
deps = [
"../../python:trace_processor_stdlib_docs",
"../../src/trace_processor/perfetto_sql/stdlib:stdlib_json_docs",
]
outputs = [ stdlib_docs_md ]
args = [
"--input",
rebase_path(absolute_input_path, root_build_dir),
"--output",
rebase_path(stdlib_docs_md, root_build_dir),
]
}
md_to_html("gen_stdlib_docs_html") {
markdown = stdlib_docs_md
html_template = "src/template_markdown.html"
deps = [
":gen_stdlib_docs_md",
":gen_toc",
]
out_html = "docs/analysis/stdlib-docs"
}
nodejs_script("gen_sql_tables_md") {
python_label = "../../src/trace_processor/tables:tables_python_docs"
python_docs_json = get_label_info(python_label, "target_gen_dir") + "/" +
get_label_info(python_label, "name") + ".json"
script = "src/gen_sql_tables_reference.js"
inputs = src_sql_tables
deps = [ python_label ]
outputs = [ sql_tables_md ]
args = [
"-o",
rebase_path(sql_tables_md, root_build_dir),
]
foreach(file, src_sql_tables) {
args += [
"-i",
rebase_path(file, root_build_dir),
]
}
args += [
"-j",
rebase_path(python_docs_json, root_build_dir),
]
}
md_to_html("gen_sql_tables_html") {
markdown = sql_tables_md
html_template = "src/template_markdown.html"
deps = [
":gen_sql_tables_md",
":gen_toc",
]
out_html = "docs/analysis/sql-tables"
}
md_to_html("readme") {
markdown = "${src_doc_dir}/README.md"
html_template = "src/template_markdown.html"
out_html = "docs/index.html"
deps = [ ":gen_toc" ]
}
# WARNING: this does globbing at generation time. Incremental builds are not
# going to work properly if files are added/removed. `gn gen` needs to be
# rerun.
mdfiles = exec_script("../../gn/standalone/glob.py",
[
"--root=" + rebase_path(src_doc_dir, root_build_dir),
"--filter=*.md",
],
"list lines")
mdfiles -= [
rebase_path("../../docs/README.md", root_build_dir),
rebase_path("../../docs/toc.md", root_build_dir),
]
mdtargets = []
foreach(source, mdfiles) {
filename = rebase_path(string_replace(source, ".md", ""),
rebase_path("../../docs", root_build_dir))
md_to_html("mdfile_${source}") {
markdown = rebase_path(source, ".", root_build_dir)
html_template = "src/template_markdown.html"
out_html = "docs/${filename}"
deps = [ ":gen_toc" ]
}
mdtargets += [ ":mdfile_${source}" ]
}
# Files which have been removed/renamed/moved and now have HTTP redirections in
# src/assets/script.js
removed_renamed_moved_files = [ "analysis/common-queries.md" ]
foreach(source, removed_renamed_moved_files) {
filename = rebase_path(string_replace(source, ".md", ""),
rebase_path("../../docs", root_build_dir))
md_to_html("mdfile_${source}") {
markdown = "src/empty.md"
html_template = "src/template_markdown.html"
out_html = "docs/${filename}"
deps = [ ":gen_toc" ]
}
mdtargets += [ ":mdfile_${source}" ]
}
group("all_mdfiles") {
deps = mdtargets
}
copy("node_assets") {
sources = [
"node_modules/highlight.js/styles/tomorrow-night.css",
"node_modules/mermaid/dist/mermaid.min.js",
]
deps = [ ":node_modules" ]
outputs = [ "${perfetto_website_out_dir}/assets/{{source_file_part}}" ]
}
# WARNING: this does globbing at generation time. Incremental builds are not
# going to work properly if files are added/removed. `gn gen` needs to be
# rerun.
assets = exec_script("../../gn/standalone/glob.py",
[
"--root=" + rebase_path("src/assets", root_build_dir),
"--filter=*.png",
"--filter=*.js",
],
"list lines")
src_assets = []
foreach(i, assets) {
src_assets += [ rebase_path(i, ".", root_build_dir) ]
}
copy("assets") {
sources = src_assets
outputs = [ "${perfetto_website_out_dir}/assets/{{source_file_part}}" ]
}