W jakiś sposób jestem całkowicie zdezorientowany tym, jak działa CMake. Za każdym razem, gdy myślę, że zbliżam się do zrozumienia, jak powinno być napisane CMake, znika to w następnym przeczytanym przykładzie. Chcę tylko wiedzieć, jak powinienem ustrukturyzować mój projekt, aby mój CMake wymagał jak najmniejszej konserwacji w przyszłości. Na przykład nie chcę aktualizować mojego CMakeList.txt podczas dodawania nowego folderu w moim drzewie src, który działa dokładnie tak samo, jak wszystkie inne foldery src.
Tak wyobrażam sobie strukturę mojego projektu, ale proszę, to tylko przykład. Jeśli zalecany sposób różni się, proszę, powiedz mi i powiedz, jak to zrobić.
myProject
src/
module1/
module1.h
module1.cpp
module2/
[...]
main.cpp
test/
test1.cpp
resources/
file.png
bin
[execute cmake ..]
Nawiasem mówiąc, ważne jest, aby mój program wiedział, gdzie są zasoby. Chciałbym poznać zalecany sposób zarządzania zasobami. Nie chcę uzyskiwać dostępu do moich zasobów za pomocą „../resources/file.png”
źródło
For example I don't want to update my CMakeList.txt when I am adding a new folder in my src tree
czy możesz podać przykład IDE, które automatycznie zbiera źródła?Odpowiedzi:
po kilku badaniach mam teraz własną wersję najprostszego, ale kompletnego przykładu cmake. Oto ona i stara się omówić większość podstaw, w tym zasoby i opakowania.
jedną z niestandardowych rzeczy jest obsługa zasobów. Domyślnie cmake chce umieścić je w / usr / share /, / usr / local / share / i czymś równoważnym w systemie Windows. Chciałem mieć prosty plik zip / tar.gz, który można wypakować w dowolnym miejscu i uruchomić. Dlatego zasoby są ładowane względem pliku wykonywalnego.
Podstawową zasadą zrozumienia poleceń cmake jest następująca składnia:
<function-name>(<arg1> [<arg2> ...])
bez przecinka lub półkoloru. Każdy argument jest łańcuchem.foobar(3.0)
ifoobar("3.0")
jest taki sam. możesz ustawić listy / zmienne za pomocąset(args arg1 arg2)
. Z tym zestawem zmiennychfoobar(${args})
ifoobar(arg1 arg2)
faktycznie są takie same. Nieistniejąca zmienna jest równoważna pustej liście. Lista jest wewnętrznie tylko ciągiem znaków ze średnikami oddzielającymi elementy. Dlatego lista zawierająca tylko jeden element jest z definicji tylko tym elementem, nie ma miejsca na boksowanie. Zmienne mają charakter globalny. Funkcje wbudowane oferują pewną formę nazwanych argumentów przez fakt, że oczekują pewnych identyfikatorów, takich jakPUBLIC
lubDESTINATION
na swojej liście argumentów, aby pogrupować argumenty. Ale to nie jest cecha języka, te identyfikatory są również po prostu łańcuchami i analizowane przez implementację funkcji.możesz sklonować wszystko z github
źródło
set(sources src/main.cpp)
.CMakeLists.txt
, normalna marka (lub ninja) spowoduje ponowne wywołanie cmake, więc nie możesz o tym zapomnieć. Jest też trochę bardziej przyjazny dla zespołu, ponieważ wtedy członkowie zespołu również nie mogą zapomnieć o wykonaniu cmake. Ale myślę, że nie trzeba dotykać pliku makefile, tylko dlatego, że ktoś dodał plik. Napisz to raz, a nikt nie powinien już o tym myśleć.Najbardziej podstawowy, ale kompletny przykład można znaleźć w samouczku dotyczącym CMake :
Na przykład swojego projektu możesz mieć:
Jeśli chodzi o dodatkowe pytanie, jedną z możliwości jest ponowne skorzystanie z samouczka: utwórz konfigurowalny plik nagłówkowy, który umieścisz w kodzie. W tym celu utwórz plik
configuration.h.in
o następującej zawartości:Następnie w Twoim
CMakeLists.txt
dodatku:Wreszcie, gdy potrzebujesz ścieżki w swoim kodzie, możesz zrobić:
źródło
string resourcePath = string(RESOURCE_PATH) + "file.png"
IMHO złym pomysłem jest zakodowanie bezwzględnej ścieżki do katalogu źródłowego. Co jeśli musisz zainstalować swój projekt?Tutaj piszę najprostszy, ale kompletny przykład plików CMakeLists.txt.
Kod źródłowy
Następnie zaoferowałem dokument ze szczegółami.
Jeśli masz jakieś pytania, skontaktuj się ze mną, a ja wyjaśnię.
źródło