mikrocontroller.net

Forum: PC-Programmierung CMake doppelte dependencies richtig managen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Vincent H. (vinci)


Bewertung
0 lesenswert
nicht lesenswert
Grüß euch

Ich dachte bis grad eben eigentlich dass ich CMake so halbwegs kapiert 
hab, nun bin ich aber dummerweise grad zum ersten Mal in ein Problem mit 
"doppelten" Abhängigkeiten gelaufen und ich hab keine Ahnung wie man das 
richtig löst.

Mein Projekt besitzt in etwa folgende Struktur:
- Hauptprogramm
  - Bibliothek
  - Modul
    - Bibliothek

Es soll sich also das Hauptprogramm und ein externes Modul die selbe 
Bibliothek teilen. CMake beschwert sich jetzt allerdings, dass der 
"add_library" Aufruf für die Bibliothek doppelt vorhanden ist und bricht 
mit einer Fehlermeldung ab.

Ich war bis jetzt immer der Auffassung dass CMake grad für solche 
Probleme entwickelt wurde...?


Hab dann auch ein Projekt auf github gefunden wo extra ein "GUARD" um 
die Bibliothek herumgewickelt wird:
https://github.com/proxict/cmake-diamond
bzw. CMakeLists hier -> 
https://github.com/proxict/cmake-diamond/blob/master/A/CMakeLists.txt

Das kann doch bitte nicht die Lösung dafür sein oder?

tia

von Sven B. (scummos)


Bewertung
-1 lesenswert
nicht lesenswert
wut

nein, definitiv nicht. Erkläre mal was du erreichen willst.

Was ist ein "Modul"? Es gibt in CMake nur Targets, die idR entweder 
Executables oder Libraries sind.

Normalerweise baut das CMakeLists.txt in einem Unterordner aus den 
Source-Files dort eine oder mehrere Libraries. Die übergeordneten Order 
linken dann gegen diese Libraries.

Du solltest nie in die Situation kommen, dass du irgendwo zweimal 
dasselbe Source File auflistest, geschweige denn zweimal dasselbe 
Target erzeugst.

: Bearbeitet durch User
von Vincent H. (vinci)


Bewertung
0 lesenswert
nicht lesenswert
Ok, nennen wir "Modul" eine "anwendungsspezifische Bibliothek" und 
"Bibliothek" eine "anwendungsagnostische Bibliothek".

Also in der einen is etwa ein std::ring_buffer, in der anderen ein 
json::parser.

Der Punkt ist, dass der json::parser auch gerne den std::ring_buffer 
nutzen würde. Ich fände es aber unlogisch deshalb die Bibliothek mit dem 
std::ring_buffer im Hauptprogramm nicht einzubinden, auch wenn das 
streng genommen natürlich nicht nötig wäre.

Meine target_link_libraries sehen auch dementsprechend aus. Also um beim 
Beispiel zu bleiben etwa
# Hauptprogramm CMakeLists.txt
target_link_libraries(Hauptprogramm PRIVATE JSON STD)

# JSON CMakeLists.txt
target_link_libraries(JSON PRIVATE STD)


/edit
Die entsprechende Fehlermeldung seitens CMake wäre dann:
add_library cannot create target "STD" because another target with the 
same name already exists

: Bearbeitet durch User
von Sven B. (scummos)


Bewertung
0 lesenswert
nicht lesenswert
Ich glaube dein Problem ist, dass du dir eine komische Mischform aus 
externen / internen Sachen überlegt hast.

Entweder du hast all diese Komponenten in einem Repository. Dann muss 
auch nur an jeweils einer Stelle add_subdirectory aufgerufen werden, 
halt in der richtigen Reihenfolge.

Oder du willst wirklich einzelne Module daraus bauen. Dann benutze 
CMake's find_package-System zusammen mit install(TARGETS ... EXPORT ...) 
um die entsprechenden .config-Files zu generieren.

In keinem Fall willst du CMake-Dateien, die zum Bauen eines externen 
Projekts benutzt werden, in dein Projekt einbinden, z.B. mit 
add_subdirectory. Das machst du aber.

von Vincent H. (vinci)


Bewertung
0 lesenswert
nicht lesenswert
Ah ok ich versteh nun so in etwa wie das gedacht ist. Bisher nutzen 
meine "FindXXX.cmake" Datein direkt add_subdirectory was wohl so nicht 
gedacht ist. Das klassische install() brauch ich so wie es überall 
dokumentiert wird allerdings auch nicht. Ich bräuchte das ganze für ein 
cross-compiliertes Embedded-Target.

Was wenn ich meine Bibliothek nicht "installieren" will (Stichwort 
GNUInstallDirs) sondern nur temporär irgendwie im Build-Ordner belassen 
damit der Rest vom Code halt dagegen linken kann?

Was ist da "best practice"? Gibts da irgendwo Beispiele oder Tutorials?


/edit
Ich hab mir jetzt nochmals folgende Talks angesehn
- Youtube-Video "CppCon 2017: Mathieu Ropert “Using Modern CMake Patterns to Enforce a Good Modular Design”"
- Youtube-Video "C++Now 2017: Daniel Pfeifer “Effective CMake""

und in beiden findet innerhalb der "FindXXX.cmake" ein add_library() 
Aufruf statt, allerdings zu einem IMPORTED target. Soweit so gut, aber 
wie das für Targets gedacht ist die ich einfach jedes mal neu bauen 
möchte und nirgends hin installiert brauche weiß ich immer noch 
nicht...?

: Bearbeitet durch User
von Sven B. (scummos)


Bewertung
0 lesenswert
nicht lesenswert
FindXXX.cmake ist legacy bzw. für Projekte die selbst kein CMake 
benutzen. Die bessere Variante, wenn du die Wahl hast, sind die 
XXX-config.cmake-Dateien. Die kannst du mit genanntem install(... 
EXPORT) fast komplett automatisch generieren.

Du kannst die Bibliothek auch aus dem Build-Ordner linken, aber dann 
indem du einfach gegen das Target linkst, das du eh schon generiert 
hast. Also, du machst add_subdirectory(A), das macht add_library(A_lib), 
dann machst du add_subdirectory(B) und das macht target_link_libraries(B 
A_lib).

Was nicht geht ist das was du versuchst hast, also da wo du gegen die 
Library linken willst nochmal das CMake-File einzubinden was die Library 
erzeugt. Das macht einfach keinen Sinn. Die wird ja dann auch nochmal 
übersetzt und alles.

von Sebastian (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Du brauchst add_library nur einmal für die Bibliothek und kannst sie 
dann zu Hauptprogramm und Modul linken.

add_library deklariert die Bibliothek, das "add" ist nur zur Verwirrung 
da.

von Sebastian (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Vincent H. schrieb:
> jedes mal neu bauen möchte

Warum? Verschiedene Flags? Dann sollten die verschieden gebauten 
Bibliotheken auch verschiedene Namen haben.

von Sven B. (scummos)


Bewertung
0 lesenswert
nicht lesenswert
Vincent H. schrieb:
> Soweit so gut, aber
> wie das für Targets gedacht ist die ich einfach jedes mal neu bauen
> möchte und nirgends hin installiert brauche weiß ich immer noch
> nicht...?

Das macht wenig Sinn als Library. Dann mach einfach nur eine Liste, 
set(mysources 1.cpp 2.cpp 3.cpp ...) und füge die jedem Target als 
Source-Liste hinzu.

Gibt auch noch diese object libraries, aber ist schon die Frage was du 
eigentlich erreichen willst.

von Vincent H. (vinci)


Bewertung
0 lesenswert
nicht lesenswert
Sven B. schrieb:
> FindXXX.cmake ist legacy bzw. für Projekte die selbst kein CMake
> benutzen. Die bessere Variante, wenn du die Wahl hast, sind die
> XXX-config.cmake-Dateien. Die kannst du mit genanntem install(...
> EXPORT) fast komplett automatisch generieren.
>
> Du kannst die Bibliothek auch aus dem Build-Ordner linken, aber dann
> indem du einfach gegen das Target linkst, das du eh schon generiert
> hast. Also, du machst add_subdirectory(A), das macht add_library(A_lib),
> dann machst du add_subdirectory(B) und das macht target_link_libraries(B
> A_lib).

Genau das möchte ich eigentlich nicht.
- es eine A_lib gibt
- jene A_lib von B_lib genutzt wird
- und C_exe sowohl B_lib als auch A_lib nutzt


Sebastian schrieb:
> Du brauchst add_library nur einmal für die Bibliothek und kannst sie
> dann zu Hauptprogramm und Modul linken.
>
> add_library deklariert die Bibliothek, das "add" ist nur zur Verwirrung
> da.

Im Prinzip die selbe Antwort?
Ich möchte eben explizit in meinem CMakeLists stehen haben dass C B und 
A nutzt. Man könnte auch einfach mal annehmen dass ich nicht weiß dass A 
bereits von B genutzt wird...


Sven B. schrieb:
> Vincent H. schrieb:
>> Soweit so gut, aber
>> wie das für Targets gedacht ist die ich einfach jedes mal neu bauen
>> möchte und nirgends hin installiert brauche weiß ich immer noch
>> nicht...?
>
> Das macht wenig Sinn als Library. Dann mach einfach nur eine Liste,
> set(mysources 1.cpp 2.cpp 3.cpp ...) und füge die jedem Target als
> Source-Liste hinzu.
>
> Gibt auch noch diese object libraries, aber ist schon die Frage was du
> eigentlich erreichen willst.

Eine Library ist ein eigenständiges Projekt. Ich möchte schon dass diese 
als Target verfügbar ist.

von Sven B. (scummos)


Bewertung
0 lesenswert
nicht lesenswert
Dann mach es wie ich beschrieben habe und generiere libA-config mit 
install(...EXPORT...). Ich würde dir aber wirklich raten auf ein 
bisschen Style zu verzichten und einfach alles als ein CMake-Projekt zu 
organisieren; die Lösung mit den Modulen ist ungleich mehr Aufwand und 
für deinen Fall over-engineered. Ich verstehe auch nicht das Problem, 
was du damit hast. Was ist an dieser Lösung schlecht?

Es macht auch keiner so, außer es gibt eine komplett andere Partei mit 
einem komplett anderen Projekt, die denselben Code benutzen will.

: Bearbeitet durch User
von Torsten R. (Firma: robitzki.de) (torstenrobitzki)


Bewertung
-1 lesenswert
nicht lesenswert
Vincent H. schrieb:
>
> # Hauptprogramm CMakeLists.txt
> target_link_libraries(Hauptprogramm PRIVATE JSON STD)
> 
> # JSON CMakeLists.txt
> target_link_libraries(JSON PRIVATE STD)
> 


Genau so, sollte es aber eigentlich funktionieren.

Main-CMakeLists.txt:
  ...
  add_executable(Hauptprogramm)
  target_link_libraries(Hauptprogramm PRIVATE JSON STD)

  add_subdirectory(json)

./json/CMakeLists.txt
  add_library(JSON STATIC ...)
  target_link_libraries(JSON PRIVATE STD)

Ich tippe mal, der Fehler liegt in dem Teil, den Du uns noch nicht 
gezeigt hast.

von Sven B. (scummos)


Bewertung
0 lesenswert
nicht lesenswert
Torsten R. schrieb:
> Ich tippe mal, der Fehler liegt in dem Teil, den Du uns noch nicht
> gezeigt hast.

Er hat doch auf ein Repo verlinkt, und warum das Unsinn ist, wurde auch 
schon drei Runden lang diskutiert.

von Vincent H. (vinci)


Bewertung
0 lesenswert
nicht lesenswert
Torsten R. schrieb:
> Genau so, sollte es aber eigentlich funktionieren.

Nein, genau so funktioniert es nicht. Aber keine Sorge falls du das 
bisher falsch gemacht hast... Um CMake richtig anzuwenden muss man nur 4 
Bücher lesen, 10 Talks schaun, 391h googlen und 7 Jungfrauen bei 
Blutmond opfern.

Srsly, die Menge an Falschinformation und wiedersprüchlichen Meinungen 
im Netz diesbezüglich is ABSOLUT FUCKING ABSURD. Selbst im offiziellen 
Repo von GTest rät Google dazu das Projekt via add_subdirectory zu 
inkludieren. Das ist ein absolutes Antipattern und darf NIE praktiziert 
werden. Den Moment wo zwei auf diese Art inkludierte Projekte die selbe 
Abhängigkeit besitzen fliegt einem alles um die Ohren.

So wie ich das sehe gibt es nur einen einzigen Grund überhaupt jemals 
add_subdirectory zu nutzen und zwar wenn man einen Sub-Teil eines 
größeren internen(!!!) Projekts inkludiert. Über diesen Teil muss man 
die absolute Kontrolle besitzen und jede Abhängigkeit muss glasklar 
bekannt sein. Am besten wäre vermutlich dass der Sub-Teil selbst 
überhaupt keine Abhängigkeiten besitzt...

Alles andere darf wie es bereits angemerkt wurde ausschließĺich über 
install(...) inkludiert werden. Ich versuche gerade von git submodulen 
auf ein Pattern umzusteigen dass mit Hilfe des FetchContent Modules 
git-repos abholt und via XXXConfig.make / find_package einbindet. Damit 
sollte es möglich sein
1.) unnötige Kopiern von Submodulen zu vermeiden
2.) bei doppelten Abhängigkeiten nicht mit Fehlern bombardiert zu werden

von Sven B. (scummos)


Bewertung
0 lesenswert
nicht lesenswert
Vincent H. schrieb:
> Srsly, die Menge an Falschinformation und wiedersprüchlichen Meinungen
> im Netz diesbezüglich is ABSOLUT FUCKING ABSURD.

Ja, das ist leider eines der großen Probleme von CMake, es hat sich in 
den letzten 10 Jahren sehr viel verändert. Dazu haben viele Leute keine 
Lust, sich hinreichend mit den Problemstellungen auseinanderzusetzen und 
pfuschen einfach irgendwas hin. Man muss sich dessen bewusst sein und 
die Seriösität der Quelle mit bewerten. Ist aber eigentlich immer so. ;)

Schöne CMake-Dateien haben z.B. die KDE Frameworks 5-Projekte sowie 
einige der Applications. Im Zweifel z.B. da mal nach Anregungen suchen.

> Selbst im offiziellen
> Repo von GTest rät Google dazu das Projekt via add_subdirectory zu
> inkludieren. Das ist ein absolutes Antipattern und darf NIE praktiziert
> werden.

Naja, aber das Projekt wird doch dann auch von deinem Build-System 
gebaut, oder? Deshalb macht es an der Stelle schon Sinn. Ob es schön 
ist, ist sicher diskutierbar.

> So wie ich das sehe gibt es nur einen einzigen Grund überhaupt jemals
> add_subdirectory zu nutzen und zwar wenn man einen Sub-Teil eines
> größeren internen(!!!) Projekts inkludiert.

Hm? Nein, der Anwendungszweck für add_subdirectory ist, Teile des 
eigenen Projekts, die in Unterordnern sind, in separaten 
CMakeLists.txt-Dateien zu verwalten. In diesem Sinne ist GTest auch Teil 
des eigenen Projekts, weil du ja alle Source-Files in deinem Repo hast.

> Alles andere darf wie es bereits angemerkt wurde ausschließĺich über
> install(...) inkludiert werden.

Ich vermute du meinst über find_package, mit dem install() kann man 
höchstens die für find_package nötigen Dateien erzeugen.

> Ich versuche gerade von git submodulen
> auf ein Pattern umzusteigen dass mit Hilfe des FetchContent Modules
> git-repos abholt und via XXXConfig.make / find_package einbindet.

Stelle dir die Frage, ob der Mehrwert getrennter Repos und Build-Systeme 
den Aufwand wert ist, oder ob du nicht lieber alles in ein Repo legst. 
Der Mehraufwand ist auf Dauer ziemlich erheblich und der Nutzen 
abgesehen von "sieht cooler aus" nicht unbedingt gegeben.

Auch dann ist die Frage, ob die Repos mit CMake klonen so die Lösung 
ist. Vielleicht doch lieber ein "bootstrap.sh"-Skript und das 
Build-System kümmert sich nur um's Bauen? Die typische Linux-Distro oder 
der typische CI-Admin werden jedenfalls mit letzterem besser klar 
kommen.

von Vincent H. (vinci)


Bewertung
0 lesenswert
nicht lesenswert
Sven B. schrieb:
>> So wie ich das sehe gibt es nur einen einzigen Grund überhaupt jemals
>> add_subdirectory zu nutzen und zwar wenn man einen Sub-Teil eines
>> größeren internen(!!!) Projekts inkludiert.
>
> Hm? Nein, der Anwendungszweck für add_subdirectory ist, Teile des
> eigenen Projekts, die in Unterordnern sind, in separaten
> CMakeLists.txt-Dateien zu verwalten. In diesem Sinne ist GTest auch Teil
> des eigenen Projekts, weil du ja alle Source-Files in deinem Repo hast.

Ja das mein ich ja. Auf der offiziellen Seite könnte man trotzdem darauf 
hinweisen dass dies maximal für Test-Frameworks Sinn macht.

>> Alles andere darf wie es bereits angemerkt wurde ausschließĺich über
>> install(...) inkludiert werden.
>
> Ich vermute du meinst über find_package, mit dem install() kann man
> höchstens die für find_package nötigen Dateien erzeugen.

Exakt. Halt die Kombination install() + export() + find_package().


>> Ich versuche gerade von git submodulen
>> auf ein Pattern umzusteigen dass mit Hilfe des FetchContent Modules
>> git-repos abholt und via XXXConfig.make / find_package einbindet.
>
> Stelle dir die Frage, ob der Mehrwert getrennter Repos und Build-Systeme
> den Aufwand wert ist, oder ob du nicht lieber alles in ein Repo legst.
> Der Mehraufwand ist auf Dauer ziemlich erheblich und der Nutzen
> abgesehen von "sieht cooler aus" nicht unbedingt gegeben.


Nachdem wir manche Sachen auch extern sharen müssen würd ich diese Frage 
für mich mit ja beantworten.

: Bearbeitet durch User
von Sven B. (scummos)


Bewertung
0 lesenswert
nicht lesenswert
Vincent H. schrieb:
> Ja das mein ich ja. Auf der offiziellen Seite könnte man trotzdem darauf
> hinweisen dass dies maximal für Test-Frameworks Sinn macht.

Verstehe ich nicht. Nochmal: Der Sinn von add_subdirectory ist, Teile 
eines Projekts -- das können Plugins, Libraries, oder einfach nur 
logische Gruppen von Quelldateien sein -- in getrennten 
CMakeLists.txt-Dateien in einer Ordnerstruktur zu verwalten, anstatt 
eine Top-Level CMakeLists.txt-Datei mit 12.000 Zeilen zu haben. Daraus 
folgt nicht, dass jeder Unterordner ein eigenständig kompilierbares 
Projekt darstellt.

Siehe z.B.
https://invent.kde.org/kde/kdevelop/-/blob/master/plugins/CMakeLists.txt
oder
https://invent.kde.org/kde/kdevelop/-/blob/master/kdevplatform/CMakeLists.txt
wo add_subdirectory extensiv und m.E. sinnvoll verwendet wird.

> Nachdem wir manche Sachen auch extern sharen müssen würd ich diese Frage
> für mich mit ja beantworten.

Ok, das weißt nur du. Das allein finde ich aber nicht hinreichend -- du 
kannst auch aus einem großen Repository mit install() verschiedene 
Komponenten exportieren.

: Bearbeitet durch User
von Vincent H. (vinci)


Bewertung
0 lesenswert
nicht lesenswert
Sven B. schrieb:
> Vincent H. schrieb:
>> Ja das mein ich ja. Auf der offiziellen Seite könnte man trotzdem darauf
>> hinweisen dass dies maximal für Test-Frameworks Sinn macht.
>
> Verstehe ich nicht. Nochmal: Der Sinn von add_subdirectory ist, *Teile*
> eines Projekts -- das können Plugins, Libraries, oder einfach nur
> logische Gruppen von Quelldateien sein -- in getrennten
> CMakeLists.txt-Dateien in einer Ordnerstruktur zu verwalten, anstatt
> eine Top-Level CMakeLists.txt-Datei mit 12.000 Zeilen zu haben. Daraus
> folgt nicht, dass jeder Unterordner ein eigenständig kompilierbares
> Projekt darstellt.

Genau deshalb find ich es nicht sinnvoll dass z.b. GTest dazu rät via 
add_subdirectory eingebunden zu werden. Das Testframework ist in meinen 
Augen nicht mehr Teil eines Projekts.

von Sven B. (scummos)


Bewertung
0 lesenswert
nicht lesenswert
Vincent H. schrieb:
> Genau deshalb find ich es nicht sinnvoll dass z.b. GTest dazu rät via
> add_subdirectory eingebunden zu werden. Das Testframework ist in meinen
> Augen nicht mehr Teil eines Projekts.

Der Grund an der Stelle ist die ungewöhnliche Distributionsstrategie, 
dass alle Sources in das Projekt kopiert und nochmal kompiliert werden. 
In der Regel würde man eher eine Shared Library zur Verfügung stellen 
und Header exportieren (und dann eben auch find_package etc verwenden). 
Ich bin nur sehr tangential mit GTest vertraut und weiß nicht, warum es 
da so gemacht ist.

von Torsten R. (Firma: robitzki.de) (torstenrobitzki)


Bewertung
0 lesenswert
nicht lesenswert
Vincent H. schrieb:

> Ja das mein ich ja. Auf der offiziellen Seite könnte man trotzdem darauf
> hinweisen dass dies maximal für Test-Frameworks Sinn macht.

Das ist nicht so, bzw. muss nicht so sein. CMakeLists.txt können sowohl 
eigenständig stehen, als auch mit add_subdirectory() in ein bestehendes 
Projekt eingebunden werden, wo sie dann dem einbindenden Projekt targets 
zur verfügung stellen.

Ich denke auch nicht, dass man 10 Bücher gelesen haben muss, um CMake zu 
verstehen. Es gibt aber erstaunlich wenig, gute Quellen. Die Referenz 
ist natürlich vollständig, erklärt aber immer nur die Details, wenn man 
eh schon weiß was man braucht. Meiner Meinung nach gibt es im Moment nur 
ein einziges, brauchbares Buch: https://crascit.com/professional-cmake/

von Vincent H. (vinci)


Bewertung
0 lesenswert
nicht lesenswert
Torsten R. schrieb:
> Vincent H. schrieb:
>
>> Ja das mein ich ja. Auf der offiziellen Seite könnte man trotzdem darauf
>> hinweisen dass dies maximal für Test-Frameworks Sinn macht.
>
> Das ist nicht so, bzw. muss nicht so sein. CMakeLists.txt können sowohl
> eigenständig stehen, als auch mit add_subdirectory() in ein bestehendes
> Projekt eingebunden werden, wo sie dann dem einbindenden Projekt targets
> zur verfügung stellen.

Clone mal das oben von mir verlinkte Repo:
https://github.com/proxict/cmake-diamond

Entferne den GUARD aus der CMakeLists.txt im Ordner /A.
Sprich so ->
cmake_minimum_required(VERSION 3.0)

project(libA VERSION 1.0.0 LANGUAGES C CXX)

add_library(alib STATIC
    src/a.cpp
)

target_include_directories(alib
    PUBLIC include
)

Und dann probier das ganze zu Builden.

: Bearbeitet durch User
von Torsten R. (Firma: robitzki.de) (torstenrobitzki)


Bewertung
0 lesenswert
nicht lesenswert
Vincent H. schrieb:

> Und dann probier das ganze zu Builden.

Wenn Du die Targets mehrfach definierst, dann bekommst Du natürlich 
Probleme. Wenn Du aber einfach im Top-Level ein CMakeLists.txt anlegst 
(geh' bitte mal auf eine neuere Version in letzter Zeit hat sich bei 
Cmake sehr viel getan):
cmake_minimum_required(VERSION 3.15)

project(diamond VERSION 1.0.0 LANGUAGES C CXX)

add_subdirectory(A)
add_subdirectory(B_dependingOnA)
add_subdirectory(C_dependingOnA)
add_subdirectory(D_dependingOnBC)

und die ganzen add_subdirectory() entfernst, die den Symbolischen Links 
folgen, dann hat CMake da kein Problem.

Wenn A kein Teil von B ist, dann sollte B auch nicht so tun, als wäre A 
ein Teil von B (sprich kein add_subdirectory). An der Stelle sollte B 
dann einfach davon ausgehen, dass der Top-Level dafür sorgen wird, dass 
A definiert wird.

Guck Dir mal 
https://github.com/TorstenRobitzki/bluetoe/blob/master/CMakeLists.txt 
an. Das Projekt kannst Du so z.B. einfach über Git submodules in Dein 
Projekt einbinden und das Projekt mit add_subdirectory() hinzufügen. Die 
Beispiele des Projekts nutzen das z.B. und binden die Bibliothek über 
add_subdirectory() ein: 
https://github.com/TorstenRobitzki/bluetoe/blob/master/examples/CMakeLists.txt

von Vincent H. (vinci)


Bewertung
0 lesenswert
nicht lesenswert
Torsten R. schrieb:
> Wenn A kein Teil von B ist, dann sollte B auch nicht so tun, als wäre A
> ein Teil von B (sprich kein add_subdirectory). An der Stelle sollte B
> dann einfach davon ausgehen, dass der Top-Level dafür sorgen wird, dass
> A definiert wird.

Das wurde doch mittlerweile ein paar mal wiederholt. Ja, das geht gut 
solange man selbst Herr all seiner Abhängigkeiten ist. Bindet man 
externe Projekte ein, dann ist das eine sehr fragile Angelegenheit.

Das verlinkte Projekt ist übrigens nicht von mir. Ich bin momentan auf 
3.16.5.


/edit
Eine Frage hätte ich noch. CMake findet meine XXXConfig.cmake Datei 
immer erst beim 2. Anlauf. Den Pfad der Config füge ich folgendermaßen 
hinzu:
set(MYLIB_DIR "/path/to/folder")
find_package(MYLIB)

Beim 1.mal Laufen beschwer sich CMake immer dass die Config Datei nicht 
gefunden werden kann? Beim 2.mal funktionierts dann? Kann das irgendwie 
am FetchContent Modul liegen?

: Bearbeitet durch User
von Vincent H. (vinci)


Bewertung
0 lesenswert
nicht lesenswert
Hab ein reproduzierbares Minimalbeispiel in ein Repo gepackt:
https://gitlab.com/higaski/CMakeError

Und hier die Stackoverflow-Frage dazu:
https://stackoverflow.com/questions/60719333/package-configuration-only-found-when-running-cmake-twice

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.