Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

CMake - jeden projekt korzystający z drugiego (biblioteka), automatyczne dostosowywanie

Ostatnio zmodyfikowano 2018-12-04 19:29
Autor Wiadomość
RazzorFlame
Temat założony przez niniejszego użytkownika
CMake - jeden projekt korzystający z drugiego (biblioteka), automatyczne dostosowywanie
» 2018-12-04 16:45:25
Cześć, średnio znam się na CMake a w zasadzie dopiero zaczynam przenosić projekt z Visual Studio.
Mam dwa projekty:
- Engine (biblioteka)
- Game (apka korzystająca z Engine)
Obydwa to dwa osobne CMake-owe projekty.
Engine dodatkowo korzysta np. z jakiejś biblioteki o nazwie QuickMaffs (tak, moja autorska do matematyki). Żeby Game poprawnie działało, to również musi poprawnie korzystać z QuickMaffs (dodane ścieżki include itd). Z tego powodu postanowiłem, że w Engine dam:

target_include_directories(EngineLib PUBLIC /path/to/QuickMaffs/include)

Specjalnie PUBLIC, no bo gdy inne projekty/targety będą chciały korzystać z Engine, to fajnie by było, gdyby same sobie tą ścieżkę dodały.

No i teraz jest problem: jak poprawnie podłączyć do Game bibliotekę Engine? Jeśli dodam same:

target_link_libraries

I wskażę same pliki .dll/.so/.lib/.a to ręcznie znów będę musiał dodawać np. te includesy do QuickMaffs. Fajnie by było, gdybym mógł po prostu wskazać w CMakeLists od projektu Game:
"Patrz, tu jest sobie taki inny CMakeLists i on ma w sobie projekt Engine, tam masz ustawienia, sam sobie to ustaw".

No i założmy, że:
- Projekt: "Engine", Target: "EngineLib"
- Projekt: "Game", Target: "GameApp"

Szukałem sporo na internetach ale jest tam dużo starych technik, często słabo wytłumaczone i nic z tego nie rozumiem. Ktoś mógłby mi to jakoś elegancko wyjaśnić?
Dzięki z góry.
P-173098
garlonicon
» 2018-12-04 19:29:58
"Patrz, tu jest sobie taki inny CMakeLists i on ma w sobie projekt Engine, tam masz ustawienia, sam sobie to ustaw".
Użyj add_subdirectory(nazwa_podfolderu).

Dopisano:
No i założmy, że:
- Projekt: "Engine", Target: "EngineLib"
- Projekt: "Game", Target: "GameApp"
Nic nie stoi na przeszkodzie, aby target nazywał się inaczej niż projekt. Przykład:
CMake
project(nazwa_projektu)
add_executable(nazwa_targetu ...)
target_include_directories(nazwa_targetu ...)
target_link_libraries(nazwa_targetu ...)

target_include_directories(EngineLib PUBLIC /path/to/QuickMaffs/include)
Nie tu! Nie dawaj w EngineLib ścieżki do QuickMaffs! Daj ją w QuickMaffs, a w EngineLib użyj add_subdirectory(QuickMaffs). Podobnie w GameApp nie dawaj ścieżek do EngineLib. Każdy projekt ma podpinać w target_include_directories swoje pliki nagłówkowe oraz w add_executable/add_library swoje pliki źródłowe. Inaczej skończy się to na kopiuj-wklej i przy każdej zmianie w QuickMaffs zaczniesz latać po wszystkich projektach i odpowiednio zmieniać sposób dołączania plików. A to PUBLIC/PRIVATE jest właśnie w tym celu, aby ustalić, jakie foldery zaciągną projekty nadrzędne, a jakich nie.

Dopisano:
target_link_libraries

I wskażę same pliki .dll/.so/.lib/.a
Nie! Jeśli używasz target_link_libraries, to nie wstawiasz tam biblioteka.dll! Pisz przenośnie! Czyli:
1. Jeśli budujesz wszystko od zera (czyli na przykład EngineLib korzystający z QuickMaffs buduje najpierw QuickMaffs), to dajesz nazwę targetu, jakoś tak:
CMake
target_link_libraries(EngineLib QuickMaffs)
2. Jeśli natomiast nie budujesz danej biblioteki, ale masz już ją gdzieś zainstalowaną w systemie, to używasz find_library() do jej znalezienia, a później jej nazwę bierzesz ze zmiennej CMake-a. Czyli jakoś tak:
CMake
find_library(LIB_QUICK_MAFFS QuickMaffs)
target_link_libraries(EngineLib ${LIB_QUICK_MAFFS})
3. Jeśli biblioteki nie ma w samym systemie, ale masz gdzieś folder dependencies/libs z biblioteką oraz dependencies/headers z jej nagłówkami, to robisz to nieco inaczej:
CMake
find_library(LIB_QUICK_MAFFS QuickMaffs HINTS "${Engine_SOURCE_DIR}/dependencies/libs")
target_include_directories(EngineLib PUBLIC "${Engine_SOURCE_DIR}/dependencies/headers")
target_link_libraries(EngineLib ${LIB_QUICK_MAFFS})
W tym szczególnym przypadku możesz złamać regułę, że target_include_directories nie dołącza nieswoich ścieżek, bo siłą rzeczy biblioteka już jest zbudowana, więc nie można tego oddelegować niżej przez add_subdirectory.

Dopisano:
Aha, jeszcze miałem napisać odnośnie ścieżek: samo polecenie(ścieżka) może czasem nie wystarczyć, dlatego najlepiej używać polecenie("${nazwa_projektu_SOURCE_DIR}/ścieżka"). Natomiast jeśli z jakiegoś powodu chcesz się odwoływać nie do katalogu ze źródłami, ale do folderu, gdzie są budowane binarki, to zamiast SOURCE_DIR wstawiasz BINARY_DIR. Chodzi o to, że zwykle najlepiej używać ścieżek względnych zamiast bezwzględnych, a siłą rzeczy z punktu widzenia projektu nadrzędnego takie ścieżki względne prowadzą w inne miejsca. Dlatego taki przedrostek umożliwia jawne określenie względem którego projektu ma być ustawiana ścieżka.
P-173100
« 1 »
  Strona 1 z 1