2021-08-16 19:00:15 +00:00
|
|
|
#!/usr/bin/env python3
|
2013-01-17 12:55:34 +00:00
|
|
|
# Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
|
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
|
|
# found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
|
|
"""Top-level presubmit script for Skia.
|
|
|
|
|
|
|
|
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
|
|
|
|
for more details about the presubmit API built into gcl.
|
|
|
|
"""
|
|
|
|
|
2014-02-03 14:18:32 +00:00
|
|
|
import fnmatch
|
2013-03-29 17:26:00 +00:00
|
|
|
import os
|
2014-01-31 17:33:04 +00:00
|
|
|
import re
|
2015-02-26 18:16:13 +00:00
|
|
|
import subprocess
|
2013-03-29 17:26:00 +00:00
|
|
|
import sys
|
2014-02-03 14:18:32 +00:00
|
|
|
import traceback
|
2013-03-29 17:26:00 +00:00
|
|
|
|
2013-01-23 14:35:58 +00:00
|
|
|
|
2019-07-25 17:45:15 +00:00
|
|
|
RELEASE_NOTES_FILE_NAME = 'RELEASE_NOTES.txt'
|
2014-02-03 14:18:32 +00:00
|
|
|
|
2016-05-20 10:50:01 +00:00
|
|
|
GOLD_TRYBOT_URL = 'https://gold.skia.org/search?issue='
|
2015-02-26 18:16:13 +00:00
|
|
|
|
2018-04-26 17:09:48 +00:00
|
|
|
SERVICE_ACCOUNT_SUFFIX = [
|
2018-04-26 18:02:43 +00:00
|
|
|
'@%s.iam.gserviceaccount.com' % project for project in [
|
2018-09-07 18:22:16 +00:00
|
|
|
'skia-buildbots.google.com', 'skia-swarming-bots', 'skia-public',
|
2019-03-12 12:51:42 +00:00
|
|
|
'skia-corp.google.com', 'chops-service-accounts']]
|
2018-01-02 18:29:21 +00:00
|
|
|
|
2022-05-06 12:30:28 +00:00
|
|
|
USE_PYTHON3 = True
|
|
|
|
|
2013-04-12 19:45:46 +00:00
|
|
|
|
2013-01-25 18:27:34 +00:00
|
|
|
def _CheckChangeHasEol(input_api, output_api, source_file_filter=None):
|
2020-01-17 23:48:13 +00:00
|
|
|
"""Checks that files end with at least one \n (LF)."""
|
2013-01-25 18:27:34 +00:00
|
|
|
eof_files = []
|
|
|
|
for f in input_api.AffectedSourceFiles(source_file_filter):
|
|
|
|
contents = input_api.ReadFile(f, 'rb')
|
2020-01-17 23:48:13 +00:00
|
|
|
# Check that the file ends in at least one newline character.
|
2013-01-25 18:27:34 +00:00
|
|
|
if len(contents) > 1 and contents[-1:] != '\n':
|
|
|
|
eof_files.append(f.LocalPath())
|
|
|
|
|
|
|
|
if eof_files:
|
|
|
|
return [output_api.PresubmitPromptWarning(
|
|
|
|
'These files should end in a newline character:',
|
|
|
|
items=eof_files)]
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
2018-02-09 22:41:20 +00:00
|
|
|
def _JsonChecks(input_api, output_api):
|
|
|
|
"""Run checks on any modified json files."""
|
|
|
|
failing_files = []
|
|
|
|
for affected_file in input_api.AffectedFiles(None):
|
|
|
|
affected_file_path = affected_file.LocalPath()
|
|
|
|
is_json = affected_file_path.endswith('.json')
|
|
|
|
is_metadata = (affected_file_path.startswith('site/') and
|
|
|
|
affected_file_path.endswith('/METADATA'))
|
|
|
|
if is_json or is_metadata:
|
|
|
|
try:
|
|
|
|
input_api.json.load(open(affected_file_path, 'r'))
|
|
|
|
except ValueError:
|
|
|
|
failing_files.append(affected_file_path)
|
|
|
|
|
|
|
|
results = []
|
|
|
|
if failing_files:
|
|
|
|
results.append(
|
|
|
|
output_api.PresubmitError(
|
|
|
|
'The following files contain invalid json:\n%s\n\n' %
|
|
|
|
'\n'.join(failing_files)))
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
2015-03-12 14:48:40 +00:00
|
|
|
def _IfDefChecks(input_api, output_api):
|
|
|
|
"""Ensures if/ifdef are not before includes. See skbug/3362 for details."""
|
|
|
|
comment_block_start_pattern = re.compile('^\s*\/\*.*$')
|
|
|
|
comment_block_middle_pattern = re.compile('^\s+\*.*')
|
|
|
|
comment_block_end_pattern = re.compile('^\s+\*\/.*$')
|
|
|
|
single_line_comment_pattern = re.compile('^\s*//.*$')
|
|
|
|
def is_comment(line):
|
|
|
|
return (comment_block_start_pattern.match(line) or
|
|
|
|
comment_block_middle_pattern.match(line) or
|
|
|
|
comment_block_end_pattern.match(line) or
|
|
|
|
single_line_comment_pattern.match(line))
|
|
|
|
|
|
|
|
empty_line_pattern = re.compile('^\s*$')
|
|
|
|
def is_empty_line(line):
|
|
|
|
return empty_line_pattern.match(line)
|
|
|
|
|
|
|
|
failing_files = []
|
|
|
|
for affected_file in input_api.AffectedSourceFiles(None):
|
|
|
|
affected_file_path = affected_file.LocalPath()
|
|
|
|
if affected_file_path.endswith('.cpp') or affected_file_path.endswith('.h'):
|
|
|
|
f = open(affected_file_path)
|
2022-05-06 18:06:40 +00:00
|
|
|
for line in f:
|
2015-03-12 14:48:40 +00:00
|
|
|
if is_comment(line) or is_empty_line(line):
|
|
|
|
continue
|
|
|
|
# The below will be the first real line after comments and newlines.
|
|
|
|
if line.startswith('#if 0 '):
|
|
|
|
pass
|
|
|
|
elif line.startswith('#if ') or line.startswith('#ifdef '):
|
|
|
|
failing_files.append(affected_file_path)
|
|
|
|
break
|
|
|
|
|
|
|
|
results = []
|
|
|
|
if failing_files:
|
|
|
|
results.append(
|
|
|
|
output_api.PresubmitError(
|
|
|
|
'The following files have #if or #ifdef before includes:\n%s\n\n'
|
2015-11-07 13:29:00 +00:00
|
|
|
'See https://bug.skia.org/3362 for why this should be fixed.' %
|
2015-03-12 14:48:40 +00:00
|
|
|
'\n'.join(failing_files)))
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
2015-03-25 11:47:02 +00:00
|
|
|
def _CopyrightChecks(input_api, output_api, source_file_filter=None):
|
|
|
|
results = []
|
|
|
|
year_pattern = r'\d{4}'
|
|
|
|
year_range_pattern = r'%s(-%s)?' % (year_pattern, year_pattern)
|
|
|
|
years_pattern = r'%s(,%s)*,?' % (year_range_pattern, year_range_pattern)
|
|
|
|
copyright_pattern = (
|
|
|
|
r'Copyright (\([cC]\) )?%s \w+' % years_pattern)
|
|
|
|
|
|
|
|
for affected_file in input_api.AffectedSourceFiles(source_file_filter):
|
2020-09-14 14:21:44 +00:00
|
|
|
if ('third_party/' in affected_file.LocalPath() or
|
2022-03-25 18:59:33 +00:00
|
|
|
'tests/sksl/' in affected_file.LocalPath() or
|
|
|
|
'bazel/rbe/' in affected_file.LocalPath()):
|
2015-03-25 11:47:02 +00:00
|
|
|
continue
|
|
|
|
contents = input_api.ReadFile(affected_file, 'rb')
|
|
|
|
if not re.search(copyright_pattern, contents):
|
|
|
|
results.append(output_api.PresubmitError(
|
|
|
|
'%s is missing a correct copyright header.' % affected_file))
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
2016-10-14 13:32:09 +00:00
|
|
|
def _InfraTests(input_api, output_api):
|
|
|
|
"""Run the infra tests."""
|
2016-07-26 18:52:17 +00:00
|
|
|
results = []
|
2016-07-27 11:14:07 +00:00
|
|
|
if not any(f.LocalPath().startswith('infra')
|
|
|
|
for f in input_api.AffectedFiles()):
|
|
|
|
return results
|
|
|
|
|
2022-05-06 18:06:40 +00:00
|
|
|
cmd = ['python3', os.path.join('infra', 'bots', 'infra_tests.py')]
|
2016-10-04 19:45:41 +00:00
|
|
|
try:
|
|
|
|
subprocess.check_output(cmd)
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
|
|
results.append(output_api.PresubmitError(
|
|
|
|
'`%s` failed:\n%s' % (' '.join(cmd), e.output)))
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
2016-08-03 21:18:22 +00:00
|
|
|
def _CheckGNFormatted(input_api, output_api):
|
|
|
|
"""Make sure any .gn files we're changing have been formatted."""
|
2020-02-14 19:28:33 +00:00
|
|
|
files = []
|
2020-04-08 08:24:04 +00:00
|
|
|
for f in input_api.AffectedFiles(include_deletes=False):
|
2020-02-14 19:28:33 +00:00
|
|
|
if (f.LocalPath().endswith('.gn') or
|
|
|
|
f.LocalPath().endswith('.gni')):
|
|
|
|
files.append(f)
|
|
|
|
if not files:
|
|
|
|
return []
|
2016-08-03 21:18:22 +00:00
|
|
|
|
2022-05-06 18:06:40 +00:00
|
|
|
cmd = ['python3', os.path.join('bin', 'fetch-gn')]
|
2020-02-14 19:28:33 +00:00
|
|
|
try:
|
|
|
|
subprocess.check_output(cmd)
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
|
|
return [output_api.PresubmitError(
|
|
|
|
'`%s` failed:\n%s' % (' '.join(cmd), e.output))]
|
|
|
|
|
|
|
|
results = []
|
|
|
|
for f in files:
|
2020-02-18 20:08:27 +00:00
|
|
|
gn = 'gn.exe' if 'win32' in sys.platform else 'gn'
|
2020-02-14 00:02:46 +00:00
|
|
|
gn = os.path.join(input_api.PresubmitLocalPath(), 'bin', gn)
|
2016-10-11 18:03:06 +00:00
|
|
|
cmd = [gn, 'format', '--dry-run', f.LocalPath()]
|
2016-08-03 21:18:22 +00:00
|
|
|
try:
|
|
|
|
subprocess.check_output(cmd)
|
|
|
|
except subprocess.CalledProcessError:
|
2020-02-14 00:02:46 +00:00
|
|
|
fix = 'bin/gn format ' + f.LocalPath()
|
2016-08-03 21:18:22 +00:00
|
|
|
results.append(output_api.PresubmitError(
|
2016-08-10 14:30:58 +00:00
|
|
|
'`%s` failed, try\n\t%s' % (' '.join(cmd), fix)))
|
2016-08-03 21:18:22 +00:00
|
|
|
return results
|
|
|
|
|
2020-12-16 16:42:29 +00:00
|
|
|
|
|
|
|
def _CheckGitConflictMarkers(input_api, output_api):
|
|
|
|
pattern = input_api.re.compile('^(?:<<<<<<<|>>>>>>>) |^=======$')
|
|
|
|
results = []
|
|
|
|
for f in input_api.AffectedFiles():
|
|
|
|
for line_num, line in f.ChangedContents():
|
|
|
|
if f.LocalPath().endswith('.md'):
|
|
|
|
# First-level headers in markdown look a lot like version control
|
|
|
|
# conflict markers. http://daringfireball.net/projects/markdown/basics
|
|
|
|
continue
|
|
|
|
if pattern.match(line):
|
|
|
|
results.append(
|
|
|
|
output_api.PresubmitError(
|
|
|
|
'Git conflict markers found in %s:%d %s' % (
|
|
|
|
f.LocalPath(), line_num, line)))
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
2019-07-26 16:55:40 +00:00
|
|
|
def _CheckIncludesFormatted(input_api, output_api):
|
|
|
|
"""Make sure #includes in files we're changing have been formatted."""
|
2019-07-29 17:34:39 +00:00
|
|
|
files = [str(f) for f in input_api.AffectedFiles() if f.Action() != 'D']
|
2022-05-06 18:06:40 +00:00
|
|
|
cmd = ['python3',
|
2019-07-26 16:55:40 +00:00
|
|
|
'tools/rewrite_includes.py',
|
2019-07-29 17:34:39 +00:00
|
|
|
'--dry-run'] + files
|
2019-07-30 17:49:45 +00:00
|
|
|
if 0 != subprocess.call(cmd):
|
2019-07-26 16:55:40 +00:00
|
|
|
return [output_api.PresubmitError('`%s` failed' % ' '.join(cmd))]
|
|
|
|
return []
|
2016-07-26 18:52:17 +00:00
|
|
|
|
2019-07-19 12:07:44 +00:00
|
|
|
|
2017-10-12 21:55:19 +00:00
|
|
|
class _WarningsAsErrors():
|
|
|
|
def __init__(self, output_api):
|
|
|
|
self.output_api = output_api
|
|
|
|
self.old_warning = None
|
|
|
|
def __enter__(self):
|
|
|
|
self.old_warning = self.output_api.PresubmitPromptWarning
|
|
|
|
self.output_api.PresubmitPromptWarning = self.output_api.PresubmitError
|
|
|
|
return self.output_api
|
|
|
|
def __exit__(self, ex_type, ex_value, ex_traceback):
|
|
|
|
self.output_api.PresubmitPromptWarning = self.old_warning
|
|
|
|
|
|
|
|
|
2019-07-24 19:15:43 +00:00
|
|
|
def _CheckDEPSValid(input_api, output_api):
|
|
|
|
"""Ensure that DEPS contains valid entries."""
|
|
|
|
results = []
|
|
|
|
script = os.path.join('infra', 'bots', 'check_deps.py')
|
|
|
|
relevant_files = ('DEPS', script)
|
|
|
|
for f in input_api.AffectedFiles():
|
|
|
|
if f.LocalPath() in relevant_files:
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
return results
|
2022-05-06 18:06:40 +00:00
|
|
|
cmd = ['python3', script]
|
2019-07-24 19:15:43 +00:00
|
|
|
try:
|
|
|
|
subprocess.check_output(cmd, stderr=subprocess.STDOUT)
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
|
|
results.append(output_api.PresubmitError(e.output))
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
2021-07-01 15:03:36 +00:00
|
|
|
def _RegenerateAllExamplesCPP(input_api, output_api):
|
|
|
|
"""Regenerates all_examples.cpp if an example was added or deleted."""
|
|
|
|
if not any(f.LocalPath().startswith('docs/examples/')
|
|
|
|
for f in input_api.AffectedFiles()):
|
|
|
|
return []
|
|
|
|
command_str = 'tools/fiddle/make_all_examples_cpp.py'
|
2022-05-06 18:06:40 +00:00
|
|
|
cmd = ['python3', command_str]
|
2021-07-01 15:03:36 +00:00
|
|
|
if 0 != subprocess.call(cmd):
|
|
|
|
return [output_api.PresubmitError('`%s` failed' % ' '.join(cmd))]
|
|
|
|
|
|
|
|
results = []
|
|
|
|
git_diff_output = input_api.subprocess.check_output(
|
|
|
|
['git', 'diff', '--no-ext-diff'])
|
|
|
|
if git_diff_output:
|
|
|
|
results += [output_api.PresubmitError(
|
|
|
|
'Diffs found after running "%s":\n\n%s\n'
|
|
|
|
'Please commit or discard the above changes.' % (
|
|
|
|
command_str,
|
|
|
|
git_diff_output,
|
|
|
|
)
|
|
|
|
)]
|
|
|
|
return results
|
|
|
|
|
2022-05-04 13:59:13 +00:00
|
|
|
def _CheckBazelBUILDFiles(input_api, output_api):
|
|
|
|
"""Makes sure our BUILD.bazel files are compatible with G3."""
|
|
|
|
results = []
|
2022-05-04 15:06:10 +00:00
|
|
|
for affected_file in input_api.AffectedFiles(include_deletes=False):
|
2022-05-04 13:59:13 +00:00
|
|
|
affected_file_path = affected_file.LocalPath()
|
|
|
|
is_bazel = affected_file_path.endswith('BUILD.bazel')
|
[infra] Add BazelBuild task to build CanvasKit on the CI with Bazel
For additional context, see "Codifying Certain Build Options"
and "Building on the CI" in the design doc go/skia-bazel
Suggested review order:
- builder_name_schema.json to see the three required and
one optional part of BazelBuild jobs.
- jobs.json to see one new BazelBuild job added. In an
ideal world, this job would have been named
BazelBuild-//modules/canvaskit:canvaskit_wasm-debug-linux_x64
but Buildbucket (?) requires jobs match the regex
^[a-zA-Z0-9\\-_.\\(\\) ]{1,128}$
so we use spaces instead of slashes or colons.
- gen_tasks_logic.go; noting the makeBazelLabel function
expands most of the spaces to / and the last one to a
colon to make a single-target label. If there are three
dots, then it is a multi-target label, and we do not
need to add a colon.
- bazel_build.go; This is a very simple task driver, and
I do not anticipate getting too much more complex.
The place where we decide which args to augment
a build with depend on the host platform and thus
should be set in gen_tasks_logic.go.
- bazel/buildrc to see some initial configurations set,
one of which, "debug", is used by the new job.
The "release" version of CanvasKit probably works on
3.1.10 which had a bugfix, but we are still on
3.1.9
- .bazelrc to see a rename of the linux-rbe config to
linux_rbe (our configs should have no dashes if
we want to specify them verbatim in our Job names).
It also imports the Skia-specified build configs
from //bazel/buildrc and supports the user-specified
//bazel/user/buildrc file if it exists.
- All other files in any order.
Change-Id: Ib954dd6045100eadcbbf4ffee0888f6fbce65fa7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/537797
Reviewed-by: Eric Boren <borenet@google.com>
Reviewed-by: Jorge Betancourt <jmbetancourt@google.com>
2022-05-06 17:20:12 +00:00
|
|
|
# This list lines up with the one in autoroller_lib.py (see G3).
|
2022-05-27 19:12:31 +00:00
|
|
|
excluded_paths = ["infra/", "bazel/rbe/", "bazel/external/", "bazel/common_config_settings/",
|
[bazel] Add support for Macs to make Linux RBE builds
The big change here is having the C++ toolchain use
Bazel platforms instead of the C++ specific flags/setup.
In Bazel, platforms are a general purpose way to define
things like os, cpu architecture, etc. We were not using
platforms previously, because the best documentation at
the time focused on the old ways.
However, the old ways were clumsy/difficult when trying
to manage cross-compilation, specifically when trying
to have a Mac host trigger a build on our Linux RBE
system targeting a Linux x64 system. Thus, rather than
keep investing in the legacy system, this CL migrates
us to using platforms where possible.
Suggested background reading to better understand this CL:
- https://bazel.build/concepts/platforms-intro
- https://bazel.build/docs/platforms
- https://bazel.build/docs/toolchains#registering-building-toolchains
The hermetic toolchain itself is not changing in this CL
(and likely does not need to), only how we tell Bazel
about it (i.e. registering it) and how Bazel decides
to use it (i.e. resolving toolchains).
Here is my understanding of how platforms and toolchains
interact (supported by some evidence from [1][2])
- Bazel needs to resolve platforms for the Host, Execution,
and Target.
- If not specified via flags, these are the machine from
which Bazel is invoked, aka "@local_config_platform//:host".
- With this CL, the Host could be a Mac laptop, the Execution
platform is our Linux RBE pool, and the Target is "a Linux
system with a x64 CPU"
- To specify the Host, that is, describe to Bazel the
capabilities of the system it is running on, one can
set --host_platform [3] with a label pointing to a platform()
containing the appropriate settings. Tip: have this
platform inherit from @local_config_platform//:host
so it can add to any of the constraint_settings and
constraint_values that Bazel deduces automatically.
- To specify the Target platform(s), that is, the system
on which a final output resides and can execute, one
can set the --platforms flag with a label referencing
a platform().
- Bazel will then choose an execution platform to fulfill
that request. Bazel will look through a list of available
platforms, which can be augmented* with the
--extra_execution_platforms. Platforms specified by this
flag will be considered higher than the default platforms!
- Having selected the appropriate platforms, Bazel now
needs to select a toolchain to actually run the actions
of the appropriate type.
- Bazel looks through the list of available toolchains
and finds one that "matches" the Execution and the Target
platform. This means, the toolchain's exec_compatible_with
is a strict subset of the Execution platform and
the toolchain's target_compatible_with is a strict subset
of the Target platform. To register toolchains* (i.e. add
them to the resolution list), we use --extra_toolchains.
Once Bazel finds a match, it stops looking.
Using --toolchain_resolution_debug=".*" makes Bazel log
how it is resolving these toolchains and what execution
platform it picked.
* We can also register execution platforms and toolchains in
WORKSPACE.bazel [4], but the flags come with higher priority
and that made resolution a bit tricky. Also, when we want
to conditionally add them (e.g. --config=linux_rbe), we
cannot remove them conditionally in the WORKSPACE.bazel file.
The above resolution flow directly necessitated the changes
in this CL.
Example usage of the new configs and platforms:
# Can be run on a x64 Linux host and uses the hermetic toolchain.
bazel build //:skia_public
# Can be run on Mac or Linux and uses the Linux RBE system along
# with the hermetic toolchain to compile a binary for Linux x64.
bazel build //:skia_public --config=linux_rbe --config=for_linux_x64
# Shorthand for above
bazel build //:skia_public --config=for_linux_x64_with_rbe
Notice we don't have to type out --config=clang_linux anymore!
That was due to me reading the Bazel docs more carefully and
realizing we can set options for *all* Bazel build commands.
Current Limitations:
- Targets which require a py_binary (e.g. Dawn's genrules)
will not work on RBE when cross compiling because the
python runtime we download is for the host machine, not
the executor. This means //example:hello_world_dawn does
not work on Mac when cross-compiling via linux_rbe.
- Mac M1 linking not quite working with SkOpts settings.
Probably need to set -target [5]
Suggested Review order:
- toolchain/BUILD.bazel Notice how we do away with
cc_toolchain_suite for toolchain. These have the same
role: giving Bazel the information about where a toolchain
can run. The platforms one is more expressive (IMO), allowing
us to say both where to run the toolchain and what it can
make. In order to more easily force the use of our hermetic
toolchain, but also allow the hermetic toolchain to be used
on RBE, we specify "use_hermetic_toolchain" only on the target,
because the RBE image does not have the hermetic toolchain
on it by default (but can certainly run it).
- bazel/platform/BUILD.bazel to see the custom constraint_setting
and corresponding constraint_value. The names for both of these
are completely arbitrary - they do not need to have any deeper
meaning or relation to any file or Docker image or system or
any other constraints. Think of the constraint_setting as
an Enum and the constraint_value being the one and only member.
We need to pass around a constant value, not a type, so we
need to provide the constraint_value (e.g. in toolchain/BUILD.bazel)
but not a constraint_setting. However we need a
constraint_setting declared so we can make a constraint_value
of that "type".
Notice the platform declared here - it allows us to force
Bazel to use the hermetic toolchain because of the extra
constraint_value.
- .bazelrc I set a few flags that will be on for all
bazel build commands. Importantly, this causes the C++
build logic to use platforms and not the old, bespoke way.
I also found a way to avoid using the local toolchain on
the host, which will hopefully lead to clearer errors
if platforms are mis-specified instead of odd compile
errors because the host toolchain is too old or something.
There are also a few RBE settings tweaked to be a bit
more modern, as well the new shorthands for specifying
target platforms (e.g. for_linux_x64).
- bazel/buildrc where we have to turn off the platforms
logic for emscripten https://github.com/emscripten-core/emsdk/issues/984
- bazel/rbe/BUILD.bazel for a fix in the platform description
that makes it work on Mac.
- Notice that _m1 has been removed from the mac-related toolchain
files because the same toolchain should work on both
architectures.
- All other changes in any order.
[1] https://bazel.build/docs/toolchains#debugging-toolchains
[2] https://bazel.build/docs/toolchains#toolchain-resolution
[3] https://bazel.build/reference/command-line-reference
[4] https://bazel.build/docs/toolchains#registering-building-toolchains
[5] https://github.com/google/skia/blob/17dc3f16fc78477503ba1ef484c3b47bc3aab893/gn/skia/BUILD.gn#L258-L271
Change-Id: I515c114099d659639a808f74e47d489a68b7af62
Bug: skia:12541
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/549737
Reviewed-by: Erik Rose <erikrose@google.com>
Reviewed-by: Jorge Betancourt <jmbetancourt@google.com>
2022-06-22 19:28:10 +00:00
|
|
|
"modules/canvaskit/go/", "experimental/", "bazel/platform"]
|
[infra] Add BazelBuild task to build CanvasKit on the CI with Bazel
For additional context, see "Codifying Certain Build Options"
and "Building on the CI" in the design doc go/skia-bazel
Suggested review order:
- builder_name_schema.json to see the three required and
one optional part of BazelBuild jobs.
- jobs.json to see one new BazelBuild job added. In an
ideal world, this job would have been named
BazelBuild-//modules/canvaskit:canvaskit_wasm-debug-linux_x64
but Buildbucket (?) requires jobs match the regex
^[a-zA-Z0-9\\-_.\\(\\) ]{1,128}$
so we use spaces instead of slashes or colons.
- gen_tasks_logic.go; noting the makeBazelLabel function
expands most of the spaces to / and the last one to a
colon to make a single-target label. If there are three
dots, then it is a multi-target label, and we do not
need to add a colon.
- bazel_build.go; This is a very simple task driver, and
I do not anticipate getting too much more complex.
The place where we decide which args to augment
a build with depend on the host platform and thus
should be set in gen_tasks_logic.go.
- bazel/buildrc to see some initial configurations set,
one of which, "debug", is used by the new job.
The "release" version of CanvasKit probably works on
3.1.10 which had a bugfix, but we are still on
3.1.9
- .bazelrc to see a rename of the linux-rbe config to
linux_rbe (our configs should have no dashes if
we want to specify them verbatim in our Job names).
It also imports the Skia-specified build configs
from //bazel/buildrc and supports the user-specified
//bazel/user/buildrc file if it exists.
- All other files in any order.
Change-Id: Ib954dd6045100eadcbbf4ffee0888f6fbce65fa7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/537797
Reviewed-by: Eric Boren <borenet@google.com>
Reviewed-by: Jorge Betancourt <jmbetancourt@google.com>
2022-05-06 17:20:12 +00:00
|
|
|
is_excluded = any(affected_file_path.startswith(n) for n in excluded_paths)
|
|
|
|
if is_bazel and not is_excluded:
|
2022-05-04 13:59:13 +00:00
|
|
|
with open(affected_file_path, 'r') as file:
|
|
|
|
contents = file.read()
|
2022-06-01 18:45:46 +00:00
|
|
|
if 'exports_files_legacy(' not in contents:
|
2022-05-04 13:59:13 +00:00
|
|
|
results.append(output_api.PresubmitError(
|
|
|
|
('%s needs to call exports_files_legacy() to support legacy G3 ' +
|
|
|
|
'rules.\nPut this near the top of the file, beneath ' +
|
|
|
|
'licenses(["notice"]).') % affected_file_path
|
|
|
|
))
|
|
|
|
if 'licenses(["notice"])' not in contents:
|
|
|
|
results.append(output_api.PresubmitError(
|
|
|
|
('%s needs to have\nlicenses(["notice"])\nimmediately after ' +
|
|
|
|
'the load() calls to comply with G3 policies.') % affected_file_path
|
|
|
|
))
|
|
|
|
if 'cc_library(' in contents and '"cc_library"' not in contents:
|
|
|
|
results.append(output_api.PresubmitError(
|
|
|
|
('%s needs load cc_library from macros.bzl instead of using the ' +
|
|
|
|
'native one. This allows us to build differently for G3.\n' +
|
|
|
|
'Add "cc_library" to load("//bazel:macros.bzl", ...)')
|
|
|
|
% affected_file_path
|
|
|
|
))
|
|
|
|
return results
|
|
|
|
|
2022-05-17 17:43:52 +00:00
|
|
|
|
|
|
|
def _CheckPublicBzl(input_api, output_api):
|
|
|
|
"""Reminds devs to add/remove files from public.bzl."""
|
|
|
|
results = []
|
|
|
|
public_bzl = ''
|
|
|
|
with open('public.bzl', 'r', encoding='utf-8') as f:
|
|
|
|
public_bzl = f.read().strip()
|
|
|
|
for affected_file in input_api.AffectedFiles(include_deletes=True):
|
|
|
|
# action is A for newly added, D for newly deleted, M for modified
|
|
|
|
action = affected_file.Action()
|
|
|
|
affected_file_path = affected_file.LocalPath()
|
|
|
|
if ((affected_file_path.startswith("include") or affected_file_path.startswith("src")) and
|
|
|
|
(affected_file_path.endswith(".cpp") or affected_file_path.endswith(".h"))):
|
|
|
|
affected_file_path = '"' + affected_file_path + '"'
|
|
|
|
if action == "D" and affected_file_path in public_bzl:
|
|
|
|
results.append(output_api.PresubmitError(
|
|
|
|
"Need to delete %s from public.bzl (or rename it)" % affected_file_path))
|
|
|
|
elif action == "A" and affected_file_path not in public_bzl:
|
|
|
|
results.append(output_api.PresubmitPromptWarning(
|
|
|
|
"You may need to add %s to public.bzl" % affected_file_path))
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
[bazel] Add in hierarchical filegroup Bazel rules.
The primary goal of this organization structure is to keep
our top level BUILD.bazel file short, with as little logic
as feasible. The logic required to control which files to
include, which third_party deps are needed, what system libraries
should be linked again, etc, should be in the BUILD.bazel
file best should be as close to the affected files as feasible.
In essence, we use filegroup() rules to bubble up the files
needed to build Skia (all as one big cc_library call) and
cc_library rules to bubble up the other components needed to build.
For example, //src/ports/SkFontHost_FreeType.cpp needs FreeType,
but only if we are compiling Skia with that type of font
support. With the new organization structure in this CL,
//src/ports/BUILD.bazel should have the logic that determines
if the cpp file should be included in the build of Skia and
if it is, that the Skia build should depend on //third_party:freetype2
Another example is //src/gpu/ganesh/BUILD.bazel, which
chooses which of the dawn, gl, vulkan, etc backend sources,
and the associated dependencies to include in the build.
It does not specify what those are, but delegates to the
BUILD.bazel files in the subdirectories housing the
backend-specific code.
The structure guidelines for BUILD.bazel files are as follows:
- Have a filegroup() called "hdrs" (for public headers) or
"srcs" (for private headers and all .cpp files) that is
visible to the parent directory. This should list the
files from the containing directory to include in the
build.
See //include/core/BUILD.bazel and //src/effects/BUILD.bazel
as examples.
- filegroup() rules can list a child directory's "hdrs"
or "srcs" in their "srcs" attributes, but should not contain
select statements pertaining to child directory files.
See //include/gpu/BUILD.bazel and //src/gpu/ganesh/BUILD.bazel
as examples.
- May have a cc_library() called "deps". This can specify
dependencies, cc_opts, and linkopts, but not srcs or hdrs. [1]
See //src/codec/BUILD.bazel as an example. These should
be visible to the parent directory.
- "hdrs", "srcs", and "deps" for the primary Skia build
(currently called "skia_core") should bubble up through
//include/BUILD.bazel and //src/BUILD.bazel, one directory
at a time.
This CL demonstrates a very basic build of Skia with many features
turned off (CPU only, no fonts, no codecs). Follow-on CLs will
add to these rules as more targets are supported. See bazel/Makefile
for the builds that work with just this CL.
Suggested Review Order:
- //BUILD.bazel to see the very small skia_core rule which
delegates all the logic down stack. Note that it has a
dependency on //bazel:defines_from_flags which will set
all the defines listed there when compiling all the
.cpp and .h files in skia_core *and* anything that depends
on skia_core, but *not* //src:deps.
- //include/BUILD.bazel and other BUILD.bazel files in the
subdirectories of that folder. Note that the filegroups in
//include/private/... are called "srcs" to be similar to
how Bazel wants "private headers" to be in the "srcs" of
cc_library, cc_binary, etc. and only public headers are
to be in "hdrs" [2].
- //src/BUILD.bazel and other BUILD.bazel files in the
subdirectories of that folder. //src/gpu/ganesh/...
will be filled in for dawn, vulkan, and GL in the next CL.
- //PRESUBMIT.py, which adds a check that runs buildifier [3]
on modified BUILD.bazel files to make sure they stay
consistently formatted.
- //bazel/... to see the new option I added to make sksl
opt-in or opt-out, so one could build Skia with sksl,
but not with a gpu backend.
- Misc .h and .cpp files, whose includes were removed if
unnecessary or #ifdef'd out to make the minimal build
work without GPU or SkSL includes.
- //bazel/Makefile to see the builds that work with this CL.
[1] Setting srcs or hdrs is error-prone at best, because those
files will be compiled with a different set of defines than
the rest of skia_core, because they wouldn't depend on
//bazel:defines_from_flags.
[2] https://bazel.build/reference/be/c-cpp#cc_library.hdrs
[3] https://github.com/bazelbuild/buildtools/releases
Change-Id: I5e0e3ae01ad42d672506d5aad1239f2512188191
Bug: skia:12541
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/543977
Reviewed-by: Leandro Lovisolo <lovisolo@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
2022-05-27 17:56:03 +00:00
|
|
|
def _RunCommandAndCheckGitDiff(output_api, command):
|
|
|
|
"""Run an arbitrary command. Fail if it produces any diffs."""
|
|
|
|
command_str = ' '.join(command)
|
|
|
|
results = []
|
|
|
|
|
|
|
|
try:
|
|
|
|
output = subprocess.check_output(
|
|
|
|
command,
|
|
|
|
stderr=subprocess.STDOUT, encoding='utf-8')
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
|
|
results += [output_api.PresubmitError(
|
|
|
|
'Command "%s" returned non-zero exit code %d. Output: \n\n%s' % (
|
|
|
|
command_str,
|
|
|
|
e.returncode,
|
|
|
|
e.output,
|
|
|
|
)
|
|
|
|
)]
|
|
|
|
|
|
|
|
git_diff_output = subprocess.check_output(
|
|
|
|
['git', 'diff', '--no-ext-diff'], encoding='utf-8')
|
|
|
|
if git_diff_output:
|
|
|
|
results += [output_api.PresubmitError(
|
|
|
|
'Diffs found after running "%s":\n\n%s\n'
|
|
|
|
'Please commit or discard the above changes.' % (
|
|
|
|
command_str,
|
|
|
|
git_diff_output,
|
|
|
|
)
|
|
|
|
)]
|
|
|
|
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
|
|
|
def _CheckBuildifier(input_api, output_api):
|
|
|
|
"""Runs Buildifier and fails on linting errors, or if it produces any diffs.
|
|
|
|
|
|
|
|
This check only runs if the affected files include any WORKSPACE, BUILD,
|
|
|
|
BUILD.bazel or *.bzl files.
|
|
|
|
"""
|
|
|
|
files = []
|
|
|
|
for affected_file in input_api.AffectedFiles(include_deletes=False):
|
|
|
|
affected_file_path = affected_file.LocalPath()
|
|
|
|
if affected_file_path.endswith('BUILD.bazel') or affected_file_path.endswith('.bzl'):
|
2022-07-15 12:32:45 +00:00
|
|
|
if not affected_file_path.endswith('public.bzl') and not affected_file_path.endswith('go_repositories.bzl'):
|
2022-06-02 19:42:58 +00:00
|
|
|
files.append(affected_file_path)
|
[bazel] Add in hierarchical filegroup Bazel rules.
The primary goal of this organization structure is to keep
our top level BUILD.bazel file short, with as little logic
as feasible. The logic required to control which files to
include, which third_party deps are needed, what system libraries
should be linked again, etc, should be in the BUILD.bazel
file best should be as close to the affected files as feasible.
In essence, we use filegroup() rules to bubble up the files
needed to build Skia (all as one big cc_library call) and
cc_library rules to bubble up the other components needed to build.
For example, //src/ports/SkFontHost_FreeType.cpp needs FreeType,
but only if we are compiling Skia with that type of font
support. With the new organization structure in this CL,
//src/ports/BUILD.bazel should have the logic that determines
if the cpp file should be included in the build of Skia and
if it is, that the Skia build should depend on //third_party:freetype2
Another example is //src/gpu/ganesh/BUILD.bazel, which
chooses which of the dawn, gl, vulkan, etc backend sources,
and the associated dependencies to include in the build.
It does not specify what those are, but delegates to the
BUILD.bazel files in the subdirectories housing the
backend-specific code.
The structure guidelines for BUILD.bazel files are as follows:
- Have a filegroup() called "hdrs" (for public headers) or
"srcs" (for private headers and all .cpp files) that is
visible to the parent directory. This should list the
files from the containing directory to include in the
build.
See //include/core/BUILD.bazel and //src/effects/BUILD.bazel
as examples.
- filegroup() rules can list a child directory's "hdrs"
or "srcs" in their "srcs" attributes, but should not contain
select statements pertaining to child directory files.
See //include/gpu/BUILD.bazel and //src/gpu/ganesh/BUILD.bazel
as examples.
- May have a cc_library() called "deps". This can specify
dependencies, cc_opts, and linkopts, but not srcs or hdrs. [1]
See //src/codec/BUILD.bazel as an example. These should
be visible to the parent directory.
- "hdrs", "srcs", and "deps" for the primary Skia build
(currently called "skia_core") should bubble up through
//include/BUILD.bazel and //src/BUILD.bazel, one directory
at a time.
This CL demonstrates a very basic build of Skia with many features
turned off (CPU only, no fonts, no codecs). Follow-on CLs will
add to these rules as more targets are supported. See bazel/Makefile
for the builds that work with just this CL.
Suggested Review Order:
- //BUILD.bazel to see the very small skia_core rule which
delegates all the logic down stack. Note that it has a
dependency on //bazel:defines_from_flags which will set
all the defines listed there when compiling all the
.cpp and .h files in skia_core *and* anything that depends
on skia_core, but *not* //src:deps.
- //include/BUILD.bazel and other BUILD.bazel files in the
subdirectories of that folder. Note that the filegroups in
//include/private/... are called "srcs" to be similar to
how Bazel wants "private headers" to be in the "srcs" of
cc_library, cc_binary, etc. and only public headers are
to be in "hdrs" [2].
- //src/BUILD.bazel and other BUILD.bazel files in the
subdirectories of that folder. //src/gpu/ganesh/...
will be filled in for dawn, vulkan, and GL in the next CL.
- //PRESUBMIT.py, which adds a check that runs buildifier [3]
on modified BUILD.bazel files to make sure they stay
consistently formatted.
- //bazel/... to see the new option I added to make sksl
opt-in or opt-out, so one could build Skia with sksl,
but not with a gpu backend.
- Misc .h and .cpp files, whose includes were removed if
unnecessary or #ifdef'd out to make the minimal build
work without GPU or SkSL includes.
- //bazel/Makefile to see the builds that work with this CL.
[1] Setting srcs or hdrs is error-prone at best, because those
files will be compiled with a different set of defines than
the rest of skia_core, because they wouldn't depend on
//bazel:defines_from_flags.
[2] https://bazel.build/reference/be/c-cpp#cc_library.hdrs
[3] https://github.com/bazelbuild/buildtools/releases
Change-Id: I5e0e3ae01ad42d672506d5aad1239f2512188191
Bug: skia:12541
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/543977
Reviewed-by: Leandro Lovisolo <lovisolo@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
2022-05-27 17:56:03 +00:00
|
|
|
if not files:
|
|
|
|
return []
|
|
|
|
try:
|
|
|
|
subprocess.check_output(
|
|
|
|
['buildifier', '--version'],
|
|
|
|
stderr=subprocess.STDOUT)
|
2022-06-02 19:22:29 +00:00
|
|
|
except:
|
|
|
|
return [output_api.PresubmitNotifyResult(
|
[bazel] Add in hierarchical filegroup Bazel rules.
The primary goal of this organization structure is to keep
our top level BUILD.bazel file short, with as little logic
as feasible. The logic required to control which files to
include, which third_party deps are needed, what system libraries
should be linked again, etc, should be in the BUILD.bazel
file best should be as close to the affected files as feasible.
In essence, we use filegroup() rules to bubble up the files
needed to build Skia (all as one big cc_library call) and
cc_library rules to bubble up the other components needed to build.
For example, //src/ports/SkFontHost_FreeType.cpp needs FreeType,
but only if we are compiling Skia with that type of font
support. With the new organization structure in this CL,
//src/ports/BUILD.bazel should have the logic that determines
if the cpp file should be included in the build of Skia and
if it is, that the Skia build should depend on //third_party:freetype2
Another example is //src/gpu/ganesh/BUILD.bazel, which
chooses which of the dawn, gl, vulkan, etc backend sources,
and the associated dependencies to include in the build.
It does not specify what those are, but delegates to the
BUILD.bazel files in the subdirectories housing the
backend-specific code.
The structure guidelines for BUILD.bazel files are as follows:
- Have a filegroup() called "hdrs" (for public headers) or
"srcs" (for private headers and all .cpp files) that is
visible to the parent directory. This should list the
files from the containing directory to include in the
build.
See //include/core/BUILD.bazel and //src/effects/BUILD.bazel
as examples.
- filegroup() rules can list a child directory's "hdrs"
or "srcs" in their "srcs" attributes, but should not contain
select statements pertaining to child directory files.
See //include/gpu/BUILD.bazel and //src/gpu/ganesh/BUILD.bazel
as examples.
- May have a cc_library() called "deps". This can specify
dependencies, cc_opts, and linkopts, but not srcs or hdrs. [1]
See //src/codec/BUILD.bazel as an example. These should
be visible to the parent directory.
- "hdrs", "srcs", and "deps" for the primary Skia build
(currently called "skia_core") should bubble up through
//include/BUILD.bazel and //src/BUILD.bazel, one directory
at a time.
This CL demonstrates a very basic build of Skia with many features
turned off (CPU only, no fonts, no codecs). Follow-on CLs will
add to these rules as more targets are supported. See bazel/Makefile
for the builds that work with just this CL.
Suggested Review Order:
- //BUILD.bazel to see the very small skia_core rule which
delegates all the logic down stack. Note that it has a
dependency on //bazel:defines_from_flags which will set
all the defines listed there when compiling all the
.cpp and .h files in skia_core *and* anything that depends
on skia_core, but *not* //src:deps.
- //include/BUILD.bazel and other BUILD.bazel files in the
subdirectories of that folder. Note that the filegroups in
//include/private/... are called "srcs" to be similar to
how Bazel wants "private headers" to be in the "srcs" of
cc_library, cc_binary, etc. and only public headers are
to be in "hdrs" [2].
- //src/BUILD.bazel and other BUILD.bazel files in the
subdirectories of that folder. //src/gpu/ganesh/...
will be filled in for dawn, vulkan, and GL in the next CL.
- //PRESUBMIT.py, which adds a check that runs buildifier [3]
on modified BUILD.bazel files to make sure they stay
consistently formatted.
- //bazel/... to see the new option I added to make sksl
opt-in or opt-out, so one could build Skia with sksl,
but not with a gpu backend.
- Misc .h and .cpp files, whose includes were removed if
unnecessary or #ifdef'd out to make the minimal build
work without GPU or SkSL includes.
- //bazel/Makefile to see the builds that work with this CL.
[1] Setting srcs or hdrs is error-prone at best, because those
files will be compiled with a different set of defines than
the rest of skia_core, because they wouldn't depend on
//bazel:defines_from_flags.
[2] https://bazel.build/reference/be/c-cpp#cc_library.hdrs
[3] https://github.com/bazelbuild/buildtools/releases
Change-Id: I5e0e3ae01ad42d672506d5aad1239f2512188191
Bug: skia:12541
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/543977
Reviewed-by: Leandro Lovisolo <lovisolo@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
2022-05-27 17:56:03 +00:00
|
|
|
'Skipping buildifier check because it is not on PATH. \n' +
|
2022-06-02 19:22:29 +00:00
|
|
|
'You can download it from https://github.com/bazelbuild/buildtools/releases')]
|
[bazel] Add in hierarchical filegroup Bazel rules.
The primary goal of this organization structure is to keep
our top level BUILD.bazel file short, with as little logic
as feasible. The logic required to control which files to
include, which third_party deps are needed, what system libraries
should be linked again, etc, should be in the BUILD.bazel
file best should be as close to the affected files as feasible.
In essence, we use filegroup() rules to bubble up the files
needed to build Skia (all as one big cc_library call) and
cc_library rules to bubble up the other components needed to build.
For example, //src/ports/SkFontHost_FreeType.cpp needs FreeType,
but only if we are compiling Skia with that type of font
support. With the new organization structure in this CL,
//src/ports/BUILD.bazel should have the logic that determines
if the cpp file should be included in the build of Skia and
if it is, that the Skia build should depend on //third_party:freetype2
Another example is //src/gpu/ganesh/BUILD.bazel, which
chooses which of the dawn, gl, vulkan, etc backend sources,
and the associated dependencies to include in the build.
It does not specify what those are, but delegates to the
BUILD.bazel files in the subdirectories housing the
backend-specific code.
The structure guidelines for BUILD.bazel files are as follows:
- Have a filegroup() called "hdrs" (for public headers) or
"srcs" (for private headers and all .cpp files) that is
visible to the parent directory. This should list the
files from the containing directory to include in the
build.
See //include/core/BUILD.bazel and //src/effects/BUILD.bazel
as examples.
- filegroup() rules can list a child directory's "hdrs"
or "srcs" in their "srcs" attributes, but should not contain
select statements pertaining to child directory files.
See //include/gpu/BUILD.bazel and //src/gpu/ganesh/BUILD.bazel
as examples.
- May have a cc_library() called "deps". This can specify
dependencies, cc_opts, and linkopts, but not srcs or hdrs. [1]
See //src/codec/BUILD.bazel as an example. These should
be visible to the parent directory.
- "hdrs", "srcs", and "deps" for the primary Skia build
(currently called "skia_core") should bubble up through
//include/BUILD.bazel and //src/BUILD.bazel, one directory
at a time.
This CL demonstrates a very basic build of Skia with many features
turned off (CPU only, no fonts, no codecs). Follow-on CLs will
add to these rules as more targets are supported. See bazel/Makefile
for the builds that work with just this CL.
Suggested Review Order:
- //BUILD.bazel to see the very small skia_core rule which
delegates all the logic down stack. Note that it has a
dependency on //bazel:defines_from_flags which will set
all the defines listed there when compiling all the
.cpp and .h files in skia_core *and* anything that depends
on skia_core, but *not* //src:deps.
- //include/BUILD.bazel and other BUILD.bazel files in the
subdirectories of that folder. Note that the filegroups in
//include/private/... are called "srcs" to be similar to
how Bazel wants "private headers" to be in the "srcs" of
cc_library, cc_binary, etc. and only public headers are
to be in "hdrs" [2].
- //src/BUILD.bazel and other BUILD.bazel files in the
subdirectories of that folder. //src/gpu/ganesh/...
will be filled in for dawn, vulkan, and GL in the next CL.
- //PRESUBMIT.py, which adds a check that runs buildifier [3]
on modified BUILD.bazel files to make sure they stay
consistently formatted.
- //bazel/... to see the new option I added to make sksl
opt-in or opt-out, so one could build Skia with sksl,
but not with a gpu backend.
- Misc .h and .cpp files, whose includes were removed if
unnecessary or #ifdef'd out to make the minimal build
work without GPU or SkSL includes.
- //bazel/Makefile to see the builds that work with this CL.
[1] Setting srcs or hdrs is error-prone at best, because those
files will be compiled with a different set of defines than
the rest of skia_core, because they wouldn't depend on
//bazel:defines_from_flags.
[2] https://bazel.build/reference/be/c-cpp#cc_library.hdrs
[3] https://github.com/bazelbuild/buildtools/releases
Change-Id: I5e0e3ae01ad42d672506d5aad1239f2512188191
Bug: skia:12541
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/543977
Reviewed-by: Leandro Lovisolo <lovisolo@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
2022-05-27 17:56:03 +00:00
|
|
|
|
|
|
|
return _RunCommandAndCheckGitDiff(
|
|
|
|
# One can change --lint=warn to --lint=fix to have things automatically fixed where possible.
|
|
|
|
# However, --lint=fix will not cause a presubmit error if there are things that require
|
|
|
|
# manual intervention, so we leave --lint=warn on by default.
|
|
|
|
output_api, ['buildifier', '--mode=fix', '--lint=warn'] + files)
|
|
|
|
|
|
|
|
|
2013-01-17 14:50:59 +00:00
|
|
|
def _CommonChecks(input_api, output_api):
|
|
|
|
"""Presubmit checks common to upload and commit."""
|
|
|
|
results = []
|
|
|
|
sources = lambda x: (x.LocalPath().endswith('.h') or
|
|
|
|
x.LocalPath().endswith('.py') or
|
|
|
|
x.LocalPath().endswith('.sh') or
|
2015-03-25 14:21:20 +00:00
|
|
|
x.LocalPath().endswith('.m') or
|
|
|
|
x.LocalPath().endswith('.mm') or
|
|
|
|
x.LocalPath().endswith('.go') or
|
|
|
|
x.LocalPath().endswith('.c') or
|
|
|
|
x.LocalPath().endswith('.cc') or
|
2013-01-17 14:50:59 +00:00
|
|
|
x.LocalPath().endswith('.cpp'))
|
2017-10-12 21:55:19 +00:00
|
|
|
results.extend(_CheckChangeHasEol(
|
|
|
|
input_api, output_api, source_file_filter=sources))
|
|
|
|
with _WarningsAsErrors(output_api):
|
|
|
|
results.extend(input_api.canned_checks.CheckChangeHasNoCR(
|
|
|
|
input_api, output_api, source_file_filter=sources))
|
|
|
|
results.extend(input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
|
|
|
|
input_api, output_api, source_file_filter=sources))
|
2018-02-09 22:41:20 +00:00
|
|
|
results.extend(_JsonChecks(input_api, output_api))
|
2015-03-12 14:48:40 +00:00
|
|
|
results.extend(_IfDefChecks(input_api, output_api))
|
2015-03-25 11:47:02 +00:00
|
|
|
results.extend(_CopyrightChecks(input_api, output_api,
|
|
|
|
source_file_filter=sources))
|
2019-07-24 19:15:43 +00:00
|
|
|
results.extend(_CheckDEPSValid(input_api, output_api))
|
2019-07-26 16:55:40 +00:00
|
|
|
results.extend(_CheckIncludesFormatted(input_api, output_api))
|
2020-04-03 15:59:37 +00:00
|
|
|
results.extend(_CheckGNFormatted(input_api, output_api))
|
2020-12-16 16:42:29 +00:00
|
|
|
results.extend(_CheckGitConflictMarkers(input_api, output_api))
|
2021-07-01 15:03:36 +00:00
|
|
|
results.extend(_RegenerateAllExamplesCPP(input_api, output_api))
|
2022-05-04 13:59:13 +00:00
|
|
|
results.extend(_CheckBazelBUILDFiles(input_api, output_api))
|
2013-01-17 14:50:59 +00:00
|
|
|
return results
|
|
|
|
|
2013-01-17 12:55:34 +00:00
|
|
|
|
|
|
|
def CheckChangeOnUpload(input_api, output_api):
|
2020-03-02 18:19:02 +00:00
|
|
|
"""Presubmit checks for the change on upload."""
|
2013-01-17 14:50:59 +00:00
|
|
|
results = []
|
|
|
|
results.extend(_CommonChecks(input_api, output_api))
|
2016-07-26 18:52:17 +00:00
|
|
|
# Run on upload, not commit, since the presubmit bot apparently doesn't have
|
2016-10-04 19:45:41 +00:00
|
|
|
# coverage or Go installed.
|
2016-10-14 13:32:09 +00:00
|
|
|
results.extend(_InfraTests(input_api, output_api))
|
2019-07-25 17:45:15 +00:00
|
|
|
results.extend(_CheckReleaseNotesForPublicAPI(input_api, output_api))
|
2022-05-17 17:43:52 +00:00
|
|
|
# Only check public.bzl on upload because new files are likely to be a source
|
|
|
|
# of false positives and we don't want to unnecessarily block commits.
|
|
|
|
results.extend(_CheckPublicBzl(input_api, output_api))
|
[bazel] Add in hierarchical filegroup Bazel rules.
The primary goal of this organization structure is to keep
our top level BUILD.bazel file short, with as little logic
as feasible. The logic required to control which files to
include, which third_party deps are needed, what system libraries
should be linked again, etc, should be in the BUILD.bazel
file best should be as close to the affected files as feasible.
In essence, we use filegroup() rules to bubble up the files
needed to build Skia (all as one big cc_library call) and
cc_library rules to bubble up the other components needed to build.
For example, //src/ports/SkFontHost_FreeType.cpp needs FreeType,
but only if we are compiling Skia with that type of font
support. With the new organization structure in this CL,
//src/ports/BUILD.bazel should have the logic that determines
if the cpp file should be included in the build of Skia and
if it is, that the Skia build should depend on //third_party:freetype2
Another example is //src/gpu/ganesh/BUILD.bazel, which
chooses which of the dawn, gl, vulkan, etc backend sources,
and the associated dependencies to include in the build.
It does not specify what those are, but delegates to the
BUILD.bazel files in the subdirectories housing the
backend-specific code.
The structure guidelines for BUILD.bazel files are as follows:
- Have a filegroup() called "hdrs" (for public headers) or
"srcs" (for private headers and all .cpp files) that is
visible to the parent directory. This should list the
files from the containing directory to include in the
build.
See //include/core/BUILD.bazel and //src/effects/BUILD.bazel
as examples.
- filegroup() rules can list a child directory's "hdrs"
or "srcs" in their "srcs" attributes, but should not contain
select statements pertaining to child directory files.
See //include/gpu/BUILD.bazel and //src/gpu/ganesh/BUILD.bazel
as examples.
- May have a cc_library() called "deps". This can specify
dependencies, cc_opts, and linkopts, but not srcs or hdrs. [1]
See //src/codec/BUILD.bazel as an example. These should
be visible to the parent directory.
- "hdrs", "srcs", and "deps" for the primary Skia build
(currently called "skia_core") should bubble up through
//include/BUILD.bazel and //src/BUILD.bazel, one directory
at a time.
This CL demonstrates a very basic build of Skia with many features
turned off (CPU only, no fonts, no codecs). Follow-on CLs will
add to these rules as more targets are supported. See bazel/Makefile
for the builds that work with just this CL.
Suggested Review Order:
- //BUILD.bazel to see the very small skia_core rule which
delegates all the logic down stack. Note that it has a
dependency on //bazel:defines_from_flags which will set
all the defines listed there when compiling all the
.cpp and .h files in skia_core *and* anything that depends
on skia_core, but *not* //src:deps.
- //include/BUILD.bazel and other BUILD.bazel files in the
subdirectories of that folder. Note that the filegroups in
//include/private/... are called "srcs" to be similar to
how Bazel wants "private headers" to be in the "srcs" of
cc_library, cc_binary, etc. and only public headers are
to be in "hdrs" [2].
- //src/BUILD.bazel and other BUILD.bazel files in the
subdirectories of that folder. //src/gpu/ganesh/...
will be filled in for dawn, vulkan, and GL in the next CL.
- //PRESUBMIT.py, which adds a check that runs buildifier [3]
on modified BUILD.bazel files to make sure they stay
consistently formatted.
- //bazel/... to see the new option I added to make sksl
opt-in or opt-out, so one could build Skia with sksl,
but not with a gpu backend.
- Misc .h and .cpp files, whose includes were removed if
unnecessary or #ifdef'd out to make the minimal build
work without GPU or SkSL includes.
- //bazel/Makefile to see the builds that work with this CL.
[1] Setting srcs or hdrs is error-prone at best, because those
files will be compiled with a different set of defines than
the rest of skia_core, because they wouldn't depend on
//bazel:defines_from_flags.
[2] https://bazel.build/reference/be/c-cpp#cc_library.hdrs
[3] https://github.com/bazelbuild/buildtools/releases
Change-Id: I5e0e3ae01ad42d672506d5aad1239f2512188191
Bug: skia:12541
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/543977
Reviewed-by: Leandro Lovisolo <lovisolo@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
2022-05-27 17:56:03 +00:00
|
|
|
# Buildifier might not be on the CI machines.
|
|
|
|
results.extend(_CheckBuildifier(input_api, output_api))
|
2013-01-17 14:50:59 +00:00
|
|
|
return results
|
2013-01-17 12:55:34 +00:00
|
|
|
|
|
|
|
|
2016-08-29 15:13:29 +00:00
|
|
|
class CodeReview(object):
|
|
|
|
"""Abstracts which codereview tool is used for the specified issue."""
|
|
|
|
|
|
|
|
def __init__(self, input_api):
|
|
|
|
self._issue = input_api.change.issue
|
|
|
|
self._gerrit = input_api.gerrit
|
|
|
|
|
|
|
|
def GetOwnerEmail(self):
|
2017-10-09 19:50:52 +00:00
|
|
|
return self._gerrit.GetChangeOwner(self._issue)
|
2016-08-29 15:13:29 +00:00
|
|
|
|
|
|
|
def GetSubject(self):
|
2017-10-09 19:50:52 +00:00
|
|
|
return self._gerrit.GetChangeInfo(self._issue)['subject']
|
2016-08-29 15:13:29 +00:00
|
|
|
|
|
|
|
def GetDescription(self):
|
2017-10-09 19:50:52 +00:00
|
|
|
return self._gerrit.GetChangeDescription(self._issue)
|
2016-08-29 15:13:29 +00:00
|
|
|
|
2016-10-05 12:41:12 +00:00
|
|
|
def GetReviewers(self):
|
2017-10-09 19:50:52 +00:00
|
|
|
code_review_label = (
|
|
|
|
self._gerrit.GetChangeInfo(self._issue)['labels']['Code-Review'])
|
|
|
|
return [r['email'] for r in code_review_label.get('all', [])]
|
2016-10-05 12:41:12 +00:00
|
|
|
|
2016-08-29 15:13:29 +00:00
|
|
|
def GetApprovers(self):
|
|
|
|
approvers = []
|
2017-10-09 19:50:52 +00:00
|
|
|
code_review_label = (
|
|
|
|
self._gerrit.GetChangeInfo(self._issue)['labels']['Code-Review'])
|
|
|
|
for m in code_review_label.get('all', []):
|
|
|
|
if m.get("value") == 1:
|
|
|
|
approvers.append(m["email"])
|
2016-08-29 15:13:29 +00:00
|
|
|
return approvers
|
|
|
|
|
|
|
|
|
2019-07-25 17:45:15 +00:00
|
|
|
def _CheckReleaseNotesForPublicAPI(input_api, output_api):
|
|
|
|
"""Checks to see if release notes file is updated with public API changes."""
|
|
|
|
results = []
|
|
|
|
public_api_changed = False
|
|
|
|
release_file_changed = False
|
|
|
|
for affected_file in input_api.AffectedFiles():
|
|
|
|
affected_file_path = affected_file.LocalPath()
|
|
|
|
file_path, file_ext = os.path.splitext(affected_file_path)
|
|
|
|
# We only care about files that end in .h and are under the top-level
|
|
|
|
# include dir, but not include/private.
|
|
|
|
if (file_ext == '.h' and
|
|
|
|
file_path.split(os.path.sep)[0] == 'include' and
|
|
|
|
'private' not in file_path):
|
|
|
|
public_api_changed = True
|
|
|
|
elif affected_file_path == RELEASE_NOTES_FILE_NAME:
|
|
|
|
release_file_changed = True
|
|
|
|
|
|
|
|
if public_api_changed and not release_file_changed:
|
|
|
|
results.append(output_api.PresubmitPromptWarning(
|
|
|
|
'If this change affects a client API, please add a summary line '
|
|
|
|
'to the %s file.' % RELEASE_NOTES_FILE_NAME))
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
2020-01-17 23:48:13 +00:00
|
|
|
def PostUploadHook(gerrit, change, output_api):
|
2015-02-26 18:16:13 +00:00
|
|
|
"""git cl upload will call this hook after the issue is created/modified.
|
|
|
|
|
|
|
|
This hook does the following:
|
|
|
|
* Adds a link to preview docs changes if there are any docs changes in the CL.
|
2017-05-23 18:24:08 +00:00
|
|
|
* Adds 'No-Try: true' if the CL contains only docs changes.
|
2015-02-26 18:16:13 +00:00
|
|
|
"""
|
2020-01-17 23:48:13 +00:00
|
|
|
if not change.issue:
|
|
|
|
return []
|
|
|
|
|
|
|
|
# Skip PostUploadHooks for all auto-commit service account bots. New
|
|
|
|
# patchsets (caused due to PostUploadHooks) invalidates the CQ+2 vote from
|
|
|
|
# the "--use-commit-queue" flag to "git cl upload".
|
|
|
|
for suffix in SERVICE_ACCOUNT_SUFFIX:
|
|
|
|
if change.author_email.endswith(suffix):
|
|
|
|
return []
|
2015-02-26 18:16:13 +00:00
|
|
|
|
|
|
|
results = []
|
2021-04-22 12:51:49 +00:00
|
|
|
at_least_one_docs_change = False
|
2015-02-26 18:16:13 +00:00
|
|
|
all_docs_changes = True
|
|
|
|
for affected_file in change.AffectedFiles():
|
|
|
|
affected_file_path = affected_file.LocalPath()
|
|
|
|
file_path, _ = os.path.splitext(affected_file_path)
|
2021-04-22 12:51:49 +00:00
|
|
|
if 'site' == file_path.split(os.path.sep)[0]:
|
|
|
|
at_least_one_docs_change = True
|
2015-02-26 18:16:13 +00:00
|
|
|
else:
|
|
|
|
all_docs_changes = False
|
2021-04-22 12:51:49 +00:00
|
|
|
if at_least_one_docs_change and not all_docs_changes:
|
|
|
|
break
|
2015-02-26 18:16:13 +00:00
|
|
|
|
2020-01-17 23:48:13 +00:00
|
|
|
footers = change.GitFootersFromDescription()
|
|
|
|
description_changed = False
|
2017-12-07 16:10:11 +00:00
|
|
|
|
2020-01-17 23:48:13 +00:00
|
|
|
# If the change includes only doc changes then add No-Try: true in the
|
|
|
|
# CL's description if it does not exist yet.
|
|
|
|
if all_docs_changes and 'true' not in footers.get('No-Try', []):
|
|
|
|
description_changed = True
|
2020-02-04 20:30:18 +00:00
|
|
|
change.AddDescriptionFooter('No-Try', 'true')
|
2020-01-17 23:48:13 +00:00
|
|
|
results.append(
|
|
|
|
output_api.PresubmitNotifyResult(
|
|
|
|
'This change has only doc changes. Automatically added '
|
|
|
|
'\'No-Try: true\' to the CL\'s description'))
|
|
|
|
|
|
|
|
# If the description has changed update it.
|
|
|
|
if description_changed:
|
|
|
|
gerrit.UpdateDescription(
|
|
|
|
change.FullDescriptionText(), change.issue)
|
|
|
|
|
|
|
|
return results
|
2015-02-26 18:16:13 +00:00
|
|
|
|
|
|
|
|
2013-01-17 12:55:34 +00:00
|
|
|
def CheckChangeOnCommit(input_api, output_api):
|
2020-03-02 18:19:02 +00:00
|
|
|
"""Presubmit checks for the change on commit."""
|
2013-01-17 12:55:34 +00:00
|
|
|
results = []
|
2013-01-17 14:50:59 +00:00
|
|
|
results.extend(_CommonChecks(input_api, output_api))
|
2017-09-12 17:52:05 +00:00
|
|
|
# Checks for the presence of 'DO NOT''SUBMIT' in CL description and in
|
|
|
|
# content of files.
|
|
|
|
results.extend(
|
|
|
|
input_api.canned_checks.CheckDoNotSubmit(input_api, output_api))
|
2013-01-17 12:55:34 +00:00
|
|
|
return results
|