Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Ueberfluessige *.o- und sonstige Dateien

2 views
Skip to first unread message

Stefan Reuther

unread,
Aug 22, 2020, 4:08:48 AM8/22/20
to
Hallo,

ich baue diverse Programme, wie man das halt so macht: *.c/*.cpp nach
*.o compilieren, in *.a einpacken, Binaries draus machen.

Nun passiert es gelegentlich, dass beim Refactoring ein *.cpp und damit
ein *.o entfällt. *.a wird ohne dieses neu gebaut, soweit alles fein.

Allerdings liegt dann noch das alte *.o rum. Das an sich wäre kein
Problem. Beim Bauen mit Coverage-Analyse stürzt sich dann allerdings
lcov auf die dazugehörigen *.gcno/*.gcda Dateien und mault (a) dass es
dazu keinen Quelltext mehr findet und (b) dass dafür keine Testabdeckung
besteht.

Kennt da jemand best practices wie man mit sowas umgeht - außer
gelegentlich eben alles plattmachen und neu bauen?


Stefan

Dietrich Clauss

unread,
Aug 22, 2020, 12:08:04 PM8/22/20
to
Stefan Reuther wrote:
> ich baue diverse Programme, wie man das halt so macht: *.c/*.cpp nach
> *.o compilieren, in *.a einpacken, Binaries draus machen.

Welches Buildsystem? Ich nehme mal an, `make`.

> Nun passiert es gelegentlich, dass beim Refactoring ein *.cpp und damit
> ein *.o entfällt. *.a wird ohne dieses neu gebaut, soweit alles fein.

Nicht ganz, s.u.

> Allerdings liegt dann noch das alte *.o rum. Das an sich wäre kein
> Problem. Beim Bauen mit Coverage-Analyse stürzt sich dann allerdings
> lcov auf die dazugehörigen *.gcno/*.gcda Dateien und mault (a) dass es
> dazu keinen Quelltext mehr findet und (b) dass dafür keine Testabdeckung
> besteht.
>
> Kennt da jemand best practices wie man mit sowas umgeht - außer
> gelegentlich eben alles plattmachen und neu bauen?

Best practice ist da vmtl. wirklich ein `make clean`. Bei ordentlich
aufgebauten Makefiles reicht ein `make clean` im entsprechenden
Verzeichnis.

Alternativ kann man im Zuge des Refactoring das betreffende *.o einfach
mit löschen. Das reicht aber noch nicht. Man muß auch alle
Folgeprodukte löschen. Das *.a wird sonst gar nicht neu gebaut, denn
keines der benötigten *.o ist jünger als dieses.

- Dietrich

Bastian Blank

unread,
Aug 22, 2020, 12:17:35 PM8/22/20
to
Stefan Reuther wrote:
> Kennt da jemand best practices wie man mit sowas umgeht - außer
> gelegentlich eben alles plattmachen und neu bauen?

Man nimmt ein Buildsystem das weiß welche Dateien da sind und was daraus
gebaut wird. Dem ist es vollkommen egal, das dort noch ein foobar.o
rumliegt.

Bastian

Stefan Reuther

unread,
Aug 23, 2020, 3:37:23 AM8/23/20
to
Welches Buildsystem zum Beispiel?

Dass dort ein foobar.o rumliegt, ist CMake/Make/Ninja auch vollkommen
egal. Dem lcov ist aber nicht egal, dass dort noch ein foobar.gcno
rumliegt, und das wird auch in keinerlei Buildskript erwähnt.


Stefan

Stefan Reuther

unread,
Aug 23, 2020, 3:37:23 AM8/23/20
to
Am 22.08.2020 um 17:34 schrieb Dietrich Clauss:
> Stefan Reuther wrote:
>> ich baue diverse Programme, wie man das halt so macht: *.c/*.cpp nach
>> *.o compilieren, in *.a einpacken, Binaries draus machen.
>
> Welches Buildsystem? Ich nehme mal an, `make`.

Das tritt mit den verschiedensten Buildsystemen auf. In der Firma mit
CMake, das Makefiles macht. Daheim hab ich mir versehentlich einen
Generator gefrickelt, der Makefiles oder ninja ausspuckt.

>> Kennt da jemand best practices wie man mit sowas umgeht - außer
>> gelegentlich eben alles plattmachen und neu bauen?
>
> Best practice ist da vmtl. wirklich ein `make clean`. Bei ordentlich
> aufgebauten Makefiles reicht ein `make clean` im entsprechenden
> Verzeichnis.
>
> Alternativ kann man im Zuge des Refactoring das betreffende *.o einfach
> mit löschen. Das reicht aber noch nicht. Man muß auch alle
> Folgeprodukte löschen. Das *.a wird sonst gar nicht neu gebaut, denn
> keines der benötigten *.o ist jünger als dieses.

Das Problem mit dem *.a ist gelöst: Kommandozeile zum Bauen des *.a
geändert -> Bauprodukt wird gelöscht und neu erstellt. Ninja macht sowas
intern, in Makefiles geht das mit etwas Gebastel auch.

Das betreffende *.o zu löschen ist nicht so einfach, weil es das
mehrfach gibt: mehrere Build-Workspaces für verschiedene
Konfigurationen, teilweise auch unbeaufsichtigt (CI).


Stefan

Dietrich Clauss

unread,
Aug 23, 2020, 3:08:04 PM8/23/20
to
Stefan Reuther wrote:
> Am 22.08.2020 um 17:34 schrieb Dietrich Clauss:
>> Stefan Reuther wrote:

[überflüssige *.o-Files]
>>> Kennt da jemand best practices wie man mit sowas umgeht - außer
>>> gelegentlich eben alles plattmachen und neu bauen?
>>
>> Best practice ist da vmtl. wirklich ein `make clean`. Bei ordentlich
>> aufgebauten Makefiles reicht ein `make clean` im entsprechenden
>> Verzeichnis.
>>
>> Alternativ kann man im Zuge des Refactoring das betreffende *.o einfach
>> mit löschen. Das reicht aber noch nicht. Man muß auch alle
>> Folgeprodukte löschen. Das *.a wird sonst gar nicht neu gebaut, denn
>> keines der benötigten *.o ist jünger als dieses.
>
> Das Problem mit dem *.a ist gelöst: Kommandozeile zum Bauen des *.a
> geändert -> Bauprodukt wird gelöscht und neu erstellt. Ninja macht sowas
> intern, in Makefiles geht das mit etwas Gebastel auch.
>
> Das betreffende *.o zu löschen ist nicht so einfach, weil es das
> mehrfach gibt: mehrere Build-Workspaces für verschiedene
> Konfigurationen, teilweise auch unbeaufsichtigt (CI).

OK, Problem erkannt, aber eine wirklich saubere Lösung fällt mir dafür
auch nicht ein. Das Buildsystem kann zwar überflüssige *.o ermitteln,
aber es kann nicht wissen, zu welchen (Zwischen-)zielen sie gehört
haben.

Vmtl. würde ich hier in das CI-Buildscript eine Logik einbauen, die
entsprechende `gcov`-Warnungen erkennt und in dem Fall ein `make clean`
probiert, gefolgt von einem neuen Build-Lauf.

- Dietrich

Stefan Reuther

unread,
Aug 24, 2020, 3:58:00 AM8/24/20
to
Am 23.08.2020 um 20:18 schrieb Dietrich Clauss:
> Vmtl. würde ich hier in das CI-Buildscript eine Logik einbauen, die
> entsprechende `gcov`-Warnungen erkennt und in dem Fall ein `make clean`
> probiert, gefolgt von einem neuen Build-Lauf.

Das ist vermutlich gar keine so dumme Idee.

Statt dem `make clean` allerdings eher "den Build-Workspace komplett
wegwerfen"; das Problem ist ja gerade, dass die "*.gcno"-Dateien dem
Buildsystem und somit dem `make clean` gar nicht bekannt sind. Die
Relation *.o -> *.gcno/*.gcda hartzucodieren halte ich auch für gewagt,
es gibt ja auch andere Dateien, die da parallel anfallen könnten. Ich
hatte schon Toolchains in der Hand, die haben zu jedem *.o ein *.dbo
erzeugt.


Danke,
Stefan

Sven Hartge

unread,
Aug 24, 2020, 9:19:22 AM8/24/20
to
Stefan Reuther <stefa...@arcor.de> wrote:

> Allerdings liegt dann noch das alte *.o rum. Das an sich wäre kein
> Problem. Beim Bauen mit Coverage-Analyse stürzt sich dann allerdings
> lcov auf die dazugehörigen *.gcno/*.gcda Dateien und mault (a) dass es
> dazu keinen Quelltext mehr findet und (b) dass dafür keine
> Testabdeckung besteht.

> Kennt da jemand best practices wie man mit sowas umgeht - außer
> gelegentlich eben alles plattmachen und neu bauen?

"Gelegentlich"?

Die CI sollte doch immer eine saubere Umgebung aus z.B. dem GIT erzeugen
und gar keinen alten Müll beinhalten.

Alles andere ist doch nix Halbes, nix Ganzes.

S!

--
Sigmentation fault. Core dumped.

Rainer Weikusat

unread,
Aug 24, 2020, 5:45:52 PM8/24/20
to
Dietrich Clauss <diet...@clauss-it.com> writes:
> Stefan Reuther wrote:

[...]

> Vmtl. würde ich hier in das CI-Buildscript eine Logik einbauen, die
> entsprechende `gcov`-Warnungen erkennt und in dem Fall ein `make clean`
> probiert, gefolgt von einem neuen Build-Lauf.

Eventuell koennte man auch die .o-Datei, wegen der gewarnt wird, loeschen
(lassen) und dann das ganze nochmal versuchen (dh alles andere, was
bereits uebersetzt wurde, weiterbenutzen).

Stefan Reuther

unread,
Aug 26, 2020, 6:05:05 AM8/26/20
to
Hi,

Am 24.08.2020 um 15:19 schrieb Sven Hartge:
> Stefan Reuther <stefa...@arcor.de> wrote:
>> Allerdings liegt dann noch das alte *.o rum. Das an sich wäre kein
>> Problem. Beim Bauen mit Coverage-Analyse stürzt sich dann allerdings
>> lcov auf die dazugehörigen *.gcno/*.gcda Dateien und mault (a) dass es
>> dazu keinen Quelltext mehr findet und (b) dass dafür keine
>> Testabdeckung besteht.
>
>> Kennt da jemand best practices wie man mit sowas umgeht - außer
>> gelegentlich eben alles plattmachen und neu bauen?
>
> "Gelegentlich"?
>
> Die CI sollte doch immer eine saubere Umgebung aus z.B. dem GIT erzeugen
> und gar keinen alten Müll beinhalten.

Naja, warum denn die "saubere Umgebung"? Doch nur, weil 100%
zuverlässige inkrementelle Builds immer noch schwierig sind.

Bis auf das Problem mit den *.gcno/*.gcda meine ich, das Problem für
meine Software eigentlich gelöst zu haben und würde gerne die gewonnene
Zeit nutzen, stattdessen mehr Varianten (clang vs g++, x86 vs x64 vs ARM
usw.) zu bauen, ohne mir dafür einen dicken Serverschrank mit drölfzig
CPUs hinstellen zu müssen.


Stefan

Sven Hartge

unread,
Aug 26, 2020, 7:07:20 AM8/26/20
to
Warum dröflzig CPUs? Für soetwas wurden Container oder mindestens
chroots erfunden.

Stefan Reuther

unread,
Aug 26, 2020, 4:15:45 PM8/26/20
to
Das soll halt auch irgendwann mal fertig werden.

Ich baue in der Tat in einer Sandbox (konkret: unter Zuhilfenahme von
<https://github.com/BobBuildTool/bob>, was mit User Namespaces im
Wesentlichen sowas wie Container macht).

Gerade bei dem Privatkram bin ich nicht die QA-Abteilung, die den
hunderten Entwicklern auf die Finger klopft, sondern der neugierige
Entwickler, der wissen will, in welcher Konfiguration das jetzt wieder
nicht klappt.

Und beim Dienstkram hab ich schon entgegnet bekommen "dein
Codereview-Fund ist absolut berechtigt, aber die (nicht inkrementell
bauende) Pipeline braucht aktuell 6 Stunden, das änder ich jetzt nicht
mehr".

Also inkrementell Bauen für mehr Geschwindigkeit ist schon schön.


Stefan
0 new messages