2011-12-13 20 views
9

Od pewnego czasu borykam się z tym problemem, a moje przygody z cmake doprowadziły tylko do hackowych rozwiązań, które jestem prawie pewien, że nie są poprawne.Właściwy sposób na skonstruowanie mojego projektu C++ za pomocą cmake?

stworzyłem bibliotekę, która składa się z kilku plików, co następuje:

-libfolder 
    -codepart1folder 
    -CMakeLists.txt 
    -codepart1.cpp 
    -codepart1.hpp 
    -codepart2folder 
    -codepart3folder 
    -lib.cpp 
    -lib.hpp 
    -CMakeLists.txt 

pisałem plik CMakeLists skompilować bibliotekę (po pewnym eksperymentów) i mogę wygenerować plik lib.a. Teraz chciałbym włączyć ten kod jako bibliotekę w innych projektach i uzyskać do niej dostęp poprzez interfejs w lib.hpp. Jaki jest najlepszy sposób, aby to zrobić, jeśli chodzi o strukturę katalogów i co muszę umieścić w CMakeLists.txt w moim głównym projekcie?

Moja obecna próba została dodać -libfolder jako podfolder do mojego obecnego projektu i dodać komendy:

include_directories(${PROJECT_SOURCE_DIR}/libfolder) 
link_directories(${PROJECT_BINARY_DIR}/libfolder) 
add_subdirectory(libfolder) 
target_link_libraries(project lib) 

Kiedy biegnę zrobić, biblioteka kompiluje grzywny, ale gdy project.cpp kompiluje, narzeka, że ​​nie może znaleźć codepart1.hpp (który jest zawarty w lib.hpp, dołączony z project.cpp).

Podejrzewam, że jest to niewłaściwy sposób, ale nie mogę przejrzeć dokumentacji CMake i znaleźć dobrego samouczka na temat tworzenia takich projektów. Proszę o pomoc, guru CMake!

+0

Być może niezbyt pomocna dla cmake per-see, ale radziłbym ci spojrzeć na premake. Zbliża się dojrzałość i ma wiele zalet dla cmake (jednym z nich jest to, że jest o wiele szybszy, aby przyspieszyć, zwłaszcza jeśli już znasz Lua). Możesz to sprawdzić na stronie http://industriousone.com/what-premake. – Ylisar

+1

, więc czy chcesz włączyć nowy projekt, aby użyć poprzednio zbudowanej biblioteki, czy chcesz zbudować go z meta-projektu sortof? – moooeeeep

Odpowiedz

2

Ok, więc po konsultacji współpracownika kopalni, który jest guru CUpewnij wydaje CMake nie ma wsparcia, co próbuję zrobić, pozostawiając jedną z 3 opcji:

  1. Dodaj wszystko zależności do nadrzędnych projektów CMakeLists.txt - niezbyt czyste, ale to sprawi, że wszystko będzie działać. Będziesz musiał to zrobić dla każdego projektu, do którego dodasz kod, i wrócić i naprawić rzeczy, jeśli zmieni się twoja biblioteka.

  2. posprzątać nagłówki biblioteki. Odbywa się to za pomocą jakiegoś hackery kompilatora. Chodzi o to, aby forwardować - deklarować każdą klasę i używać tylko wskaźników lub boost :: shared_ptr, a następnie włączać zależności tylko w pliku cpp. W ten sposób możesz zbudować plik cpp przy użyciu wszystkich rzeczy pakietu findpackage, a otrzymasz premię z możliwości korzystania z biblioteki, włączając tylko nagłówek i link do biblioteki.

  3. Zajrzyj do systemów kompilacji. Posiadanie przenośnego kodu i szybka kompilacja kodu ze złożonymi zależnościami nie rozwiązuje problemu! Z moich badań okazało się dość skomplikowane. Skończyłem na przyjęciu mojego systemu budowania współpracowników, który sam stworzył w cmake, wykorzystując rzeczy, które wziął od Google.

+0

+1, ponieważ czyszczenie interfejsu w taki sposób, że nie wymaga3 rdparty include-dirs jest jeszcze lepsze. –

5

Oczywistym sposobem importowania jednego projektu CMake do innego jest wykonanie polecenia find_package. Deklarację pakietu wykonuje się przy użyciu polecenia export. Zaletą korzystania z find_package jest to, że eliminuje potrzebę stosowania ścieżek o twardym kodowaniu do plików pakietu.

Jeśli chodzi o brakujący plik hpp, nie uwzględniono pliku kodepartu1, więc nie ma go na ścieżce dołączania.

+0

Ok ...z tej odpowiedzi nie jest dla mnie jasne, czy find_package i export są właściwymi rzeczami do użycia w tym przypadku, lub w jaki sposób bym to zrobił. Czy mógłbyś to rozwinąć? – dlants

+0

użyj include_directories ($ {PROJECT_SOURCE_DIR}/libfolder/codepart1folder) – LeDYoM

1

Patrząc na swój wpis, nie wydaje się dodawać "codepart1folder" do załączników w dowolnym miejscu. Jak się pan tym codepart1.hpp jak:

#include <codepart1.hpp> 
#include "codepart1folder/codepart1.hpp" 

nie sądzę jest standardem przyjętym sposobem strukturyzacji projektów CUpewnij. Spojrzałem na kilka repo CMU i mają tendencję do różnic. Osobiście wykonać następujące czynności:

-project 
    CMakeLists.txt 
    -build 
    -cmake 
     OptionalCmakeModule.cmake 
    -src 
     -Main 
      Main.cpp 
      Main.hpp 
     -DataStructs 
      SomeTree.hpp 
      SomeObject.hpp 
     -Debug 
      Debug.hpp 
     -UI 
      Window.hpp 
      Window.cpp 

Zasadniczo że wysypisk cały kod źródłowy do 1 katalogu, a następnie wykonują z źródła zbudować z: "mkdir budować & & cd budować & & cmake .. & & markę "w folderze głównym projektów.

Jeśli masz oddzielne biblioteki jako część swojego projektu, możesz potrzebować oddzielnego katalogu libs z innym podfolderem dla konkretnej biblioteki.

Mam kilka moich repozytoriów: https://github.com/dcbishop/, jeśli chcesz przejrzeć pliki CMakeLists.txt.

Główne problemy z moim struktury projektu jest to, że używam FILE_GLOB który jest pozornie „niewłaściwy” sposób zrobić rzeczy (jeśli dodać pliki po uruchomieniu „cmake ..” wtedy nie będzie podniósł do zrobienia "make").Nie doszedłem do wniosku, że "właściwy" sposób to zrobić (z tego co widzę wymaga oddzielnej listy plików) Używam tylko 1 pliku CMakeLists.txt.

Niektóre projekty również wybierają oddzielenie swoich plików cpp i hpp w oddzielne katalogi. Więc będziesz miał foldery include i src (przynajmniej dla plików hpp, które mają być używane zewnętrznie). Myślę, że dotyczyłoby to głównie projektów, które są głównie dużymi bibliotekami. Czyni też znacznie łatwiejsze instalowanie plików nagłówkowych.

+0

codepart1folder jest zawarty w pliku CMakeLists.txt wewnątrz libfolder. Błędne wydaje mi się dodanie wszystkich podfolderów, włączeń i linków w folderze CmakeLists.txt w folderze projektu, ponieważ projekt.cpp nie zależy od żadnego z nich - działa tylko lib.hpp. W twoim drzewie wyobraź sobie, że istnieje projekt2, który definiuje bibliotekę i chcę użyć projektu2 jako części projektu. – dlants

+0

@JohnSavage. Ale to jest właściwa droga ... Stworzyłbym zmienną LIB_INCLUDE_DIRS w projekcie lib, który jest "eksportowany" do CMakeCache'a zawierającego wszystkie niezbędne zależne katalogi-include. Następnie przyjmijmy, że zmienna będzie obecna podczas Projektu Wymiany. –

+0

+1 za linki do github – hAcKnRoCk

0

Prawdopodobnie brakuje

include_directories(${PROJECT_SOURCE_DIR}/libfolder/codepart1folder) 

W takim przypadku warto set(CMAKE_INCLUDE_CURRENT_DIR on) dodać wszystkie foldery do zmiennej zawierać ścieżkę katalogu.

Sprawdź dane wyjściowe cmake w wierszu poleceń, czy ustawione są właściwe foldery dołączania. Dodatkowo zawsze możesz użyć message() jako "debugowania drukowania" dla zmiennych cmake. W przypadku katalogów dołączania należy jednak przeczytać właściwość katalogu, aby zobaczyć, co faktycznie znajduje się w katalogach uwzględniania.

get_property(inc_dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES) 
message("inc_dirs = ${inc_dirs}") 

Mam nadzieję, że pomoże to w ustaleniu, czego brakuje.

Edit

Właśnie widziałem komentarz o dodanej codepart1folder w libfolder. Jest dostępny tylko w ścieżce include_directory folderu libfolder i nie jest propagowany do folderu głównego. Ponieważ plik include codepart1.hpp znajduje się w bibliotece lib.hpp, ale musisz mieć go również dostępny w ścieżce projektu, w przeciwnym razie podczas tworzenia projektu otrzymasz błąd braku deklaracji.

+0

Ok, więc to jest mój problem. Czuję, że nie powinienem iść i ponownie uwzględnić wszystkie moje podfoldery w projekcie nadrzędnym. lib jest samodzielnym kawałkiem kodu z własnym CMakeLists.txt i kompiluje dobrze do lib.a. Nie chcę podłączać wszystkiego do każdego projektu, w którym chcę go użyć. – dlants

+1

Następnie powinieneś poprawnie interfejsować swoją bibliotekę. – Bort

Powiązane problemy