Hallo Zusammen, auf der Arbeit sind wir dabei eine SW-Library zu schreiben. Diese Library besteht aus mehreren SW-Komponenten. Einige dieser SW-Komponenten sind komplett unabhängig von den anderen SW-Komponenten. Einige habe allerdings auch starke Abhängigeiten voneinander, seien es gemeinsam genutzte Schnittstellen, Funktionen oder aber zeitliche Abläufe. Ich habe gelesen das man in der Softwareentwicklung von Kopplung spricht. - Wie löst ihr solche Abhängikeiten in euren SW-Projekten? - Benutzt ihr dafür Versionsnummern an den SW-Komponenten, ala Major, Minor und Patch? - Gibt es eine möglich automatisch zu ermitteln, dass wenn man z.B. SWC_A v1.0.2 integrieren man zwangsläufig SWC_B v1.0.5 auch integrieren muss? - Kann man diese Abhängigkeiten überhaupt "automatisch" aufzeigen? Ich bin auf eure Vorschläge / Erfahrungen gespannt. Gerne auch Literaturhinweise :-) Grüße Patrick
:
Verschoben durch Moderator
Patrick L. schrieb: > auf der Arbeit sind wir dabei eine SW-Library zu schreiben. Diese > Library besteht aus mehreren SW-Komponenten. Quelltexte? Libraries? für µC? Was konkret heißt "integrieren"? Wenn es z.B. normale C-Libs sind, brauchst Du nichts zu tun. Software-Versionierung ist ein anderes Ding. Ein Teil davon sollte auf jeden Fall die Revisionsnummer der Versionskontrolle sein, alles andere ist Schall und Rauch und wird doch nicht gepflegt.
A. S. schrieb: > Quelltexte? Libraries? für µC? Was konkret heißt "integrieren"? Quelltext also C-Code der wiederum auf Mikrocontrollern läuft.
Wir erstellen für die Softwarekomponenten weak Funktionen. Bsp. Wir haben einen Sensor der eine Kommunikationsschnittstelle benötigt. Die Softwarekomponente, welche den Sensor abbildet, besitzt eine Übertragungsfuntion (z.B: Transmit(in, out), welche mit dem weak attribute erstellt wurde. Somit lässt sich diese Komponente komplett testen, ohne das wir irgendeine Abhängigkeit haben. Um die Softwarekomponente mit dem Sensor reden zu lassen, wird an einer anderen stelle der Software, diese Funktion "richtig" implementiert, bspw.
1 | Transmit(in, out) |
2 | {
|
3 | Spi(in, out); |
4 | }
|
Maulwurfmann schrieb: > Wir erstellen für die Softwarekomponenten weak Funktionen. Das sagt mir gar nichts. Also eigentlich eine zusätzliche Abstraktionsebende? Ihr verbindet SW-Komponenten nicht direkt untereinander sondern habt immer eine SW-Komponente dazwischen die die Abstraktion vornimmt?
Patrick L. schrieb: > Maulwurfmann schrieb: >> Wir erstellen für die Softwarekomponenten weak Funktionen. > > Das sagt mir gar nichts. Weak bedeutet: es gibt da schon eine Funktion, aber die kann problemlos durch eine andere irgendwo anders deklarierte ersetzt werden, solange diese andere dieselbe Signatur hat. > Also eigentlich eine zusätzliche > Abstraktionsebende? Nein. Das ist einfach nur ein Platzhalter für eine optionale Nutzfunktion. Die Platzhalterfunktion existiert halt nur dann, wenn keine echte Nutzfunktion sie überschreibt. Aber immer existiert eine entsprechende Funktion. (auch wenn sie typisch nix tut und damit letztlich samt allen ihren Aufrufen rausoptimiert wird).
c-hater schrieb: > Nein. Das ist einfach nur ein Platzhalter für eine optionale > Nutzfunktion. Die Platzhalterfunktion existiert halt nur dann, wenn > keine echte Nutzfunktion sie überschreibt. Aber immer existiert eine > entsprechende Funktion. (auch wenn sie typisch nix tut und damit > letztlich samt allen ihren Aufrufen rausoptimiert wird). Achso, dann also wie eine Art "Abwärtskompatibilität". Die alte Schnittstelle bleibt vorhanden wird aber nicht weiter benutzt, wenn ich das jetzt richtig verstanden habe? Aber nicht immer sind ja Abhängigkeiten auf Schnittstellenänderungen zurück zu führen. Manchmal ändert sich auch das Verhalten hinter einer Komponente. Wie geht ihr mit sowas um?
Patrick L. schrieb: > Aber nicht immer sind ja Abhängigkeiten auf Schnittstellenänderungen > zurück zu führen. Manchmal ändert sich auch das Verhalten hinter einer > Komponente. Wie geht ihr mit sowas um? Durchs ausgraben von Artefakten... ^^ Artifactory, Nuget, solches Zeug halt, z.B. in Verbindung mit nem make-System wie CMake o.ä.
Patrick L. schrieb: > Quelltext also C-Code der wiederum auf Mikrocontrollern läuft. Dann solltest Du Dein Vorhaben und Deine Fragen erläutern. Quelltexte in einem repository, z.b. 20 Themen in je einem Unterverzeichnis mit 2 bis 20 Sourcen? Einbindung als externals? Oder gar als Kopie? Warum nicht als Lib? Dann sammelt der linker nur das ein, was er braucht. Erfordert natürlich ein Buildlauf für jede Plattform. Das alles und richtig eingebunden ist, übernehme compiletime-asserts und ggf. entsprechende dummy-token. Also wie wollt ihr das benutzen? Was soll Programmierer A tun, wenn er z.b eine CRC oder eine ADC-Ansteuerung verwenden will?
A. S. schrieb: > Quelltexte in einem repository, z.b. 20 Themen in je einem > Unterverzeichnis mit 2 bis 20 Sourcen? Ungefähr 100 SW-Komponenten die jeweils einen eigenen Ordner im SVN-Repository haben. Für jede SW-Komponente gibt es eigene Releases. Versions-Nummern weerden an Anlehnung an https://semver.org/lang/de/ vergeben. Es gibt pro SW-Komponente trunk, tag und branch als Unterordner. > Einbindung als externals? Oder gar als Kopie? In die Projekte werden die SW-Komponenten als external eingebunden. > Warum nicht als Lib? Dann sammelt der linker nur das ein, was er > braucht. Erfordert natürlich ein Buildlauf für jede Plattform. Sehen wir aktuell keinen nutzen von und erschwert auch die Fehlersuche in den Projekten die die SW-Komponenten einsetzen.
Patrick L. schrieb: > Wie geht ihr mit sowas um? Grundsätzlich sagen wir, dass die SW-Komponente 1 mit der Version 1.0.0 von SW-Komponente 2 läuft. Ändert sich die Version von 2, dann müssen wir eben bewerten. Zusätzlich führen wir unsere Integrationstests, .... durch.
Patrick L. schrieb: > Wie löst ihr solche Abhängikeiten in euren SW-Projekten? Durch möglichst logische Funktionsgruppierung > Benutzt ihr dafür Versionsnummern an den SW-Komponenten, ala Major, > Minor und Patch? Ja. > Gibt es eine möglich automatisch zu ermitteln, dass wenn man z.B. SWC_A > v1.0.2 integrieren man zwangsläufig SWC_B v1.0.5 auch integrieren muss? SWC_A kam halt bis Version x mit SWC_B Major-Version v aus, muss aber seit Version y mit SWB_B Major-Version w arbeiten sonst scheitert schon beim linken/laden. d.h. die Komponente überprüft selbst ob die Version der Subkomponente ausreicht. Die Minor bzw. Patch Version sollte immer die höchste verfügbare sein, denn wenn sich das Interface ändert, wird Major erhöht. > Kann man diese Abhängigkeiten überhaupt "automatisch" aufzeigen? die Komponente überprüft selbst ob die Version der verbundenen Subkomponente ausreicht, durch Benutzung vorher nicht verfügbarer exportierter Funktionen.
Wenn man erst mal gelernt hat, dass diese ganze Versionsnummern in den unzähligen Sub-Komponenten nur einen gigantischen Verwaltungsaufwand produziert, lässt man es bleiben.
Patrick L. schrieb: > Ungefähr 100 SW-Komponenten die jeweils einen eigenen Ordner im > SVN-Repository haben. Für jede SW-Komponente gibt es eigene Releases. Man kann es sich auch schwer machen. Darf ich raten, in dem Projekt gibt es mindestens einen der sich in die Idee mit den 100 Verionsnummern verliebt hat und das als den geilen Scheiß verkauft? Den Typen solltet ihr loswerden, der hat keine Ahnung. Na gut: Vorbereitung: 1. Abhängigkeiten gerade ziehen (auf Neuenglisch Refactoring). Keine zyklischen Abhängigkeiten. 2. Eigentlich alles was Lakos als "physical design" für C++ durchgespielt hat gilt auch für C. Einfach C++-spezifische Dinge wie seinen Aussagen zu Klassen entsprechend für C interpretieren. Dann: 3. Management-System drüber stricken. Versionsnummer-Abhängigkeiten lassen sich in svn (oder git) nicht direkt verwalten. Das Managementsystem muss dann halt alle Versionsnummer einsammeln und eine Liste (Listen) gültiger Kombinationen der Komponenten erstellen. Dazu am besten noch die Kommandos um genau so eine gültige Kombination auszuchecken. > Sehen wir aktuell keinen nutzen von und erschwert auch die Fehlersuche > in den Projekten die die SW-Komponenten einsetzen. Verwegene Behauptung.
Maulwurfmann schrieb: > Grundsätzlich sagen wir, dass die SW-Komponente 1 mit der Version 1.0.0 > von SW-Komponente 2 läuft. Ändert sich die Version von 2, dann müssen > wir eben bewerten. Zusätzlich führen wir unsere Integrationstests, .... > durch. Ok, das heißt ihr habt einen "Dependency-Tree" für eure SW-Komponenten gemalt und wenn ihr eine SW-Komponente A ändert schaut ihr euch am besten alle SW-Komponenten B bis n an die davon abhängig sind. Ich höre da raus das man um den mnuellen Schritt des überprüfens nicht herum kommt :-)
MaWin schrieb: > die Komponente überprüft selbst ob die Version der verbundenen > Subkomponente ausreicht, durch Benutzung vorher nicht verfügbarer > exportierter Funktionen. Ok, das setzt aber voraus, dass man sich sehr genau gedanken macht wo etwas noch kompatibel ist und wo nicht mehr. Oder macht das eine "externe" SW-Komponente? Also holt die die ganzen Versionen der SWC zusammen und prüft dann?
Hannes J. schrieb: > Man kann es sich auch schwer machen. Darf ich raten, in dem Projekt gibt > es mindestens einen der sich in die Idee mit den 100 Verionsnummern > verliebt hat und das als den geilen Scheiß verkauft? Den Typen solltet > ihr loswerden, der hat keine Ahnung. Ist leider Automobil-Industrie und wir sind an AUTOSAR gebunden... Das schränkt unserer Lösungsraum leider ein wenig ein.
Hannes J. schrieb: > Das Managementsystem muss dann halt alle Versionsnummer einsammeln und > eine Liste (Listen) gültiger Kombinationen der Komponenten erstellen. > Dazu am besten noch die Kommandos um genau so eine gültige Kombination > auszuchecken. Wir haben zumindest schon mal eine möglichkeit bei der wir die Versionen der SW-Komponenten zusammen klauben. Wir wollen auch mehrere SW-Versionen in "Logischen Funktionen" bündeln um diese dann in einer Funktionsfreigabe freizugeben.
Patrick L. schrieb: > Ok, das setzt aber voraus, dass man sich sehr genau gedanken macht wo > etwas noch kompatibel ist und wo nicht mehr. Nein. Man sorgt nur dafür, dass neue Features auch neue Funktionsnamen/Methoden/Eintrittspunkte haben. Dann guckt der Linker (bzw..DLL Loader) ob's passt. Alte Funktionen bleiben entsprechend ihrer Dokumentation und bekommen nur Änderungen innerhalb ihrer Spezifikation, Bugfixes, Performancebeschleunigungen .. Natürlich ist die Methode doof für Scrum Programmierer die ohne Plan loslegen, keine Dokumentation haben sondern der Meinung sind ihr Programm reift mit jeder Zahlung vom Kunden, in dem überall noch ein wenig rumgepfuscht wird.
Patrick L. schrieb: > Ok, das heißt ihr habt einen "Dependency-Tree" für eure SW-Komponenten > gemalt und wenn ihr eine SW-Komponente A ändert schaut ihr euch am > besten alle SW-Komponenten B bis n an die davon abhängig sind. Ich höre > da raus das man um den mnuellen Schritt des überprüfens nicht herum > kommt :-) Wir haben ein ReuireManagement Tool. Wir haben zu jeder Komponente eine Spezifikation und wenn sich die Komponente ändert, dann wird die Version hochgezählt und das Tool sagt allen Units, welche diese Verwenden, dass die sich geändert hat und man neu bewerten muss. Wie tief die Bewertung ausfällt, hängt davon ab, ob es eine Minor oder Major Änderung ist.
Maulwurfmann schrieb: > Wir haben zu jeder Komponente eine > Spezifikation und wenn sich die Komponente ändert, dann wird die Version > hochgezählt und das Tool sagt allen Units, welche diese Verwenden, dass > die sich geändert hat und man neu bewerten muss. Hat aber eig. den Nachteil das ihr erst hinterum die Änderungen bewertet. Eig. würde es ja Sinn machen erstmal alle Leute an einen Tisch zusammen zu bringen um gemeinsam zu diskutieren was eine Sinnvollae Änderung ist, oder nicht?
Patrick L. schrieb: > In die Projekte werden die SW-Komponenten als external eingebunden. Also habt ihr nach ein paar Monaten 100 Trunks mit jeweils 5 Tags, die jeweils 10 andere Modultags brauchen. Und wenn ihr einen Fehler feststellt in Modul7-Tag4, dann macht ihr daraus einen Branch und schaut Euch an, welche Module-Tags/-Trunks und -Branches auf diesen Branch umgestellt werden müssen oder welche besser auf eine neueres Tag umgestellt werden. Und wo habt ihr dazu die Header- und Konfigurationsdateien?
A. S. schrieb: > Also habt ihr nach ein paar Monaten 100 Trunks mit jeweils 5 Tags, die > jeweils 10 andere Modultags brauchen. Und wenn ihr einen Fehler > feststellt in Modul7-Tag4, dann macht ihr daraus einen Branch und schaut > Euch an, welche Module-Tags/-Trunks und -Branches auf diesen Branch > umgestellt werden müssen oder welche besser auf eine neueres Tag > umgestellt werden. Hmm, so Recht verstehe ich glaube ich nicht was du meinst. Die einzelnen SW-Komponenten sind frei geschnitten. Abhängigkeiten zu anderen SW-Komponenten sind gestubbt. In den jeweiligen "Zielprojekten" werden diese erst miteinander "verbunden".
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.