| # 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}}" ] |
| } |