Chromium Chronicle n. 15: limitazione della visibilità dei target

Episodio 15: di Joe Mason a Montreal, PQ (novembre 2020)
Puntate precedenti

Chrome è un grande progetto con molti sottosistemi. È comune trovare codice scritto per un componente che sarebbe utile altrove, ma che potrebbe avere limitazioni nascoste. Per motivi di sicurezza, limita l'accesso esterno a funzionalità pericolose. Ad esempio, una funzione personalizzata ottimizzata per specifiche esigenze di prestazioni:

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

Esistono diversi modi per limitare l'accesso. Le regole di visibilità GN interrompono il codice esterno al componente in base a una destinazione. Per impostazione predefinita, i target sono visibili a tutti, ma puoi modificare questa impostazione:

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

Le dichiarazioni della visibilità vengono convalidate con gn check, che viene eseguito come parte di ogni build GN.

Un altro meccanismo è il DEPS include_rules, che limita l'accesso ai file di intestazione. Ogni directory eredita include_rules dalla directory padre e può modificare queste regole nel proprio file DEPS. Tutti i file di intestazione inclusi da directory esterne devono essere consentiti dal criterio 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",
]

Per garantire che queste dipendenze siano appropriate, le modifiche che aggiungono una directory a include_rules devono essere approvate dal OWNERS di tale directory. Non è necessaria alcuna approvazione per limitare una directory che utilizza include_rules. Per fare in modo che tutte le persone che modificano il componente si ricordino di non utilizzare determinate intestazioni, aggiungi un include_rule che le impedisce.

include_rules vengono controllati tramite il pre-invio, pertanto non verrà visualizzato alcun errore finché non proverai a caricare una modifica. Per testare include_rules senza caricare, esegui buildtools/checkdeps/checkdeps.py <directory>.

Risorse