⑂ Open source

Compatibilità tra licenze open source: combinare codice diverso

Quando si può unire codice MIT, Apache, GPL e MPL nello stesso progetto, come si ragiona sulla direzione della compatibilità e quali casi evitare.

Quasi nessun software moderno è scritto da zero: si compone di decine o centinaia di librerie, ciascuna con la propria licenza. Finché si usano componenti separati, le licenze convivono senza problemi. Le difficoltà nascono quando si combina codice con licenze diverse in un'unica opera e la si distribuisce. A quel punto bisogna chiedersi se esiste un modo di rispettare contemporaneamente tutti gli obblighi. Se esiste, le licenze sono compatibili; se due licenze pretendono cose opposte, non lo sono.

Il principio di fondo

Una licenza A è compatibile con una licenza B, in una certa direzione, quando il codice sotto A può essere incluso in un'opera distribuita sotto B rispettando entrambe. La compatibilità quindi ha una direzione. Il codice MIT può entrare in un progetto GPL, perché la MIT chiede solo di conservare l'avviso, e questo non contrasta con la GPL. Il codice GPL non può entrare in un progetto che si vuole distribuire sotto MIT, perché la GPL richiede che l'insieme resti GPL.

Un modo semplice per ragionare: le licenze più permissive possono «scorrere» verso quelle più restrittive, non il contrario.

Una mappa pratica

Codice incluso in progetto MIT in progetto Apache 2.0 in progetto GPLv2 solo in progetto GPLv3
MIT / BSD sì sì sì sì
Apache 2.0 sì, con obblighi Apache sì no sì
LGPLv2.1 come libreria separata come libreria separata sì sì
MPL 2.0 sì, a livello di file sì, a livello di file sì, con licenze secondarie sì, con licenze secondarie
GPLv2 solo no no sì no
GPLv3 no no no sì

Note importanti sulla tabella:

  • «Sì» non significa «nessun obbligo»: gli avvisi e i testi delle licenze vanno sempre conservati.
  • Le voci LGPL presuppongono che la libreria resti un componente distinto e sostituibile.
  • Per la MPL, la combinazione con le GPL vale salvo che il codice sia marcato come incompatibile con le licenze secondarie.

Distinguere aggregazione e combinazione

Molti dubbi si sciolgono distinguendo due situazioni.

Aggregazione: programmi separati distribuiti insieme, ad esempio sullo stesso disco o nella stessa immagine di sistema, che comunicano attraverso meccanismi standard come file, pipe, socket o riga di comando. La GPL stessa prevede che l'aggregazione non estenda la licenza agli altri programmi.

Combinazione in un'unica opera: codice compilato insieme, collegato in uno stesso eseguibile, oppure moduli che condividono strutture dati interne in modo stretto. Qui le licenze devono essere compatibili.

Il confine non è sempre netto. Plugin caricati nello stesso processo, linguaggi interpretati, estensioni di un editor: in questi casi bisogna valutare come i componenti interagiscono davvero.

Esempi concreti

Un'applicazione web in Python

Un progetto sotto licenza MIT usa un framework BSD, una libreria per PDF sotto AGPL e un client per database sotto Apache 2.0. Se l'applicazione viene offerta come servizio e la libreria AGPL è importata direttamente nel codice, l'insieme è soggetto agli obblighi dell'AGPL. Il progetto non può più essere presentato come «MIT» nel suo complesso: si possono mantenere i propri file sotto MIT, ma l'opera combinata va trattata come AGPL. In alternativa si sceglie un'altra libreria per i PDF.

Uno strumento a riga di comando

Uno script proprietario invoca un programma GPL come processo separato, passandogli file e leggendone l'output. È aggregazione: lo script non diventa GPL. Se invece lo stesso script importasse il codice GPL come libreria, la situazione cambierebbe.

Un firmware

Un produttore vuole includere nel firmware un componente «solo GPLv2» e una libreria Apache 2.0, collegati nello stesso binario. Le due licenze sono incompatibili: serve sostituire uno dei due componenti o tenerli in processi distinti.

Come impostare un controllo

  1. Censire le dipendenze, comprese quelle indirette, con nome, versione e licenza.
  2. Verificare la licenza effettiva nei file del progetto, non solo nei metadati del gestore di pacchetti.
  3. Stabilire la licenza dell'opera finale e come viene distribuita (binario, servizio, codice).
  4. Controllare la direzione di ogni combinazione rispetto alla licenza finale.
  5. Documentare le eccezioni e le scelte architetturali, come processi separati o librerie dinamiche.

Nel mio lavoro questo controllo si fa all'inizio, non a prodotto finito: sostituire una dipendenza a progetto avviato costa molto più che sceglierla bene.

Le doppie licenze

Alcuni progetti offrono il codice sotto due licenze alternative, ad esempio «MIT oppure Apache 2.0». Chi riceve sceglie quella che preferisce, e questo risolve molti problemi di compatibilità. Con gli identificatori standard si scrive MIT OR Apache-2.0.

In sintesi

  • La compatibilità tra licenze ha una direzione: il codice permissivo può confluire in progetti copyleft, non il contrario.
  • Apache 2.0 e GPLv2 da sola non sono compatibili; Apache 2.0 e GPLv3 sì.
  • Aggregare programmi separati è diverso dal combinarli in un'unica opera.
  • Il controllo va fatto all'inizio, censendo anche le dipendenze indirette.
  • Le doppie licenze semplificano l'integrazione lasciando la scelta a chi riceve il codice.
MM
Marco Marzaduri

Marco Marzaduri si occupa di cybersecurity, informatica forense e sviluppo web. Laureato in informatica, unisce il rigore dell'analisi tecnica all'attenzione per le persone che usano la tecnologia.

Leggi anche