Chromium Chronicle #15: como restringir a visibilidade do público-alvo

Episódio 15:de Joe Mason em Montreal, PQ (novembro de 2020)
Episódios anteriores

O Chrome é um grande projeto com muitos subsistemas. É comum encontrar código criado para um componente que seria útil em outro lugar, mas que possa ter restrições ocultas. Por motivos de segurança, limite o acesso externo a recursos perigosos. Por exemplo, uma função personalizada ajustada para necessidades específicas de desempenho:

// Blazing fast for 2-char strings, O(n^3) otherwise.
std::string ConcatShortStringsFast(const std::string& a, const std::string& b);

Há várias maneiras de restringir o acesso. As regras de visibilidade de GN impedem que o código fora do seu componente dependa de um destino. Por padrão, os destinos são visíveis para todos, mas isso pode ser modificado:

# In components/restricted_component/BUILD.gn
visibility = [
  # Applies to all targets in this file.
  # Only the given targets can depend on them.
  "//components/restricted_component:*",
  "//components/authorized_other_component:a_single_target",
]
source_set("internal") {
  # This dangerous target should be locked down even more.
  visibility = [ "//components/restricted_component:privileged_target" ]
}

As declarações de visibilidade são validadas com gn check, que é executado como parte de cada build de GN.

Outro mecanismo é o DEPS include_rules, que limita o acesso aos arquivos principais. Cada diretório herda include_rules do pai e pode modificar essas regras no próprio arquivo DEPS. Todos os arquivos principais incluídos de diretórios externos precisam ser permitidos pelo include_rules.

# In //components/authorized_other_component/DEPS
include_rules = [
  # Common directories like //base are inherited from
  # //components/DEPS or //DEPS. Also allow includes from
  # restricted_component, but not restricted_component/internal.
  "+components/restricted_component",
  "-components/restricted_component/internal",
  # But do allow a single header from internal, for testing.
  "+components/restricted_component/internal/test_support.h",
]

Para garantir que essas dependências sejam adequadas, as mudanças que adicionam um diretório a include_rules precisam ser aprovadas pelo OWNERS desse diretório. Nenhuma aprovação é necessária para restringir um diretório usando include_rules. Você pode garantir que todos que mudam seu componente se lembrem de não usar determinados cabeçalhos adicionando um include_rule que proíbe esses cabeçalhos.

include_rules são verificados pelo pré-envio. Portanto, você não verá erros até tentar fazer upload de uma mudança. Para testar o include_rules sem fazer upload, execute buildtools/checkdeps/checkdeps.py <directory>.

Recursos