CONAN Abhängigkeiten und Versionen

Grundsätzlich gilt für CONAN Projekte:

Ändert man die Version, eine Einstellung oder eine Option in einer Komponente, errechnet CONAN einen neuen Hash für ein Paket und auch alle Abhängigkeiten davon bekommen neue Hashes zugeteilt.

… dachte ich.
Doch nun kenne ich eine interessante Ausnahme.


CONAN identifiziert seine Paket durch Namen und Version, wie auch durch “Settings” (Compiler, OS, Build-Toolset) und “Options” (Shared, Static, …).

So können dann aus einem Quellcode beliebig viele Pakete parallel gebaut werden, die sich durch mindestens ein Detail unterscheiden und das wird am eindeutigsten durch die Paket-Hashes signalisiert.

graph TD REPO(myLib
Repository) SRC1(myLib/1.1
Source) SRC2(myLib/1.2
Source) BIN11(myLib/1.1
Windows 32
Hash: 123) BIN12(myLib/1.1
Windows 64
Hash: 456) BIN13(myLib/1.1
Linux GCC 10
Hash: 789) BIN14(myLib/1.1
Linux GCC 11
Hash: abc) BIN21(myLib/1.2
Windows 32
Hash: def) BIN22(myLib/1.2
Windows 64
Hash: aaa) BIN23(myLib/1.2
Linux GCC 10
Hash: bbb) BIN24(myLib/1.2
Linux GCC 11
Hash: ccc) REPO --> SRC1 REPO --> SRC2 SRC1 --> BIN11 SRC1 --> BIN12 SRC1 --> BIN13 SRC1 --> BIN14 SRC2 --> BIN21 SRC2 --> BIN22 SRC2 --> BIN23 SRC2 --> BIN24

Bei Abhängigkeiten zwischen Paketen bewirkt eine Änderung der Version ebenfalls sofort eine Änderung des Paket-Hashes.

graph LR subgraph Different Versions B1(baseLib/1.1) B2(baseLib/1.2) end subgraph Same Versions L1(myLib/1.1
Hash: abc) L2(myLib/1.1
Hash: 123) P1(myProg/1.0
Hash: def) P2(myProg/1.0
Hash: 456) end B1 --required by--> L1 L1 --required by--> P1 B2 --required by--> L2 L2 --required by--> P2

Ausnahme: Nach der 3. Versionstelle wird der Rest ignoriert

CONAN erkennt gemäß “Semantic Versioning” nur 3 Stellen in einer Version an. Man kann aber noch mehr hinten anhängen, doch eben genau das wird in die Hashberechnung und damit in die Paket-Identifizierung nicht einberechnet.

Hat man also eine Bibliothek mit der Version 1.2.3.4 und wechselt zur Version 1.2.3.5, so wird das zwar von CONAN korrekt erkannt und aufgelöst, doch die davon abhängigen Projekte erfahren keine Hashänderung.

graph LR subgraph Different Versions B1(baseLib/1.4.2.1) B2(baseLib/1.4.2.2) end subgraph Same Versions L(myLib/1.1
Hash: abc) P(myProg/1.0
Hash: def) end B1 --required by--> L B2 --required by--> L L --required by--> P

Für produktive Software ist das Beispiel grundsätzlich ungeeignet, weil man in der Regel bei der Änderung der Version einer Abhängigkeit auch die eigene Version anpasst. Also aus
base/1.1 -> lib/2.3 wird dann ein base/1.2 -> lib/2.4.

Doch wenn man Softwarestände testet und zwischen unterschiedlichen Patch-Levels hin und her probiert, kommt es schon vor, dass man die “neue” Version der eigenen Komponenten mit unterschiedlichen Varianten von anderen Komponenten testet.

Kein Support für mehr als 3 Stellen in Versionen

Dass CONAN sich bei mehr als 3 Stellen anders verhält, zeigt sich auch bei Range-Angaben.
Ein conan install project/[1.2.*]@user/channel sollte die neueste Variante der 1.2 Serie herunterladen, also die mit der höchsten Versionsnummer. Existiert aber eine 4. Stelle für solche Versionen im Repository, lädt CONAN “irgendeine” herunter. Für mich sieht es so aus, als wäre es die “erste” in der Auflistung.

graph LR INSTA(CONAN INSTALL
libA/1.2.*) INSTB(CONAN INSTALL
libB/2.3.*) subgraph libA A1[[libA/1.2.1]] A2[[libA/1.2.2]] A3[[libA/1.2.3]] end subgraph libB B1[[libA/2.3.9.1]] B2[[libA/2.3.9.2]] B3[[libA/2.3.9.3]] end RESULTA(libA/1.2.3) RESULTB(libB/????) INSTA -.Match-.-> A1 INSTA -.Match-.-> A2 INSTA --Select
latest--> A3 A3 --Install
latest--> RESULTA INSTB -.Match-.-> B1 INSTB -.Match-.-> B2 INSTB -.Match-.-> B3 B1 -.Random
installation-.-> RESULTB B2 -.Random
installation-.-> RESULTB B3 -.Random
installation-.-> RESULTB

Fazit

Ich bin mir noch nicht so ganz sicher, was ich jetzt davon halten soll, denn bisher ging ich fix davon aus, dass jede Versionsänderung eine Hash-Änderung nach sich zieht.

Bei einem conan upload mit neuem Hash bleiben dann die alten Hashes im Upload-Repository liegen, sind aber über ein frisches conan install nicht mehr herunterladbar. Man kann sie jedoch immer noch direkt über den Hash z.B.: per HTTP URL beziehen.

Ändert sich der Hash jedoch nicht, dann kann eine “neue” Version einer Abhängigkeit lautlos ein bestehendes Paket überschreiben, da der gleiche Hash für zwei unterschiedliche Szenarien generiert wurde.

Wichtig ist jedenfalls, dass man dieses Detail von CONAN kennen sollte, denn gerade im Windows-Bereich sind 4-stellige Versionsnummern keine Seltenheit und führen dann womöglich mit CONAN zu unerwarteten Seiteneffekten.