2012-12-01 11 views
7

C++ - projekt, powiedzmy, foo jest utrzymywany przez cmake. Jeden chce utworzyć jedną bibliotekę libfoo.a (ze wszystkimi klasami/metodami/funkcjami utworzonymi w całym drzewie źródłowym), aby umożliwić tworzenie programów, które mogłyby być połączone z biblioteką za pomocą -lfoo.utworzyć jedną bibliotekę statyczną z całego projektu za pomocą cmake

ok, rozważmy teraz przykład zabawki, a prolbem będzie jasne. Katalog foo (katalog główny projektu) zawiera katalogi a i b. Dwa CmakeLists.txt tworzone są:

# a/CMakeLists.txt 
add_library(A <a_sources>) 
# b/CMakeLists.txt 
add_library(B <b_sources>) 

And jedną CMakeLists.txt do katalogu:

add_subdirectory(a) 
add_subdirectory(b) 
add_library(foo <foo_sources> 
target_link_libraries(foo A B) 

To było zaskoczenie dla mnie: po libfoo.a budynku zawiera tylko metody z foo_sources i a_sources, b_sources Są wykluczone. Jest to ok w przypadku, gdy pliki wykonywalne są budowane z tym samym projektem: podczas tworzenia plików wykonywalnych cmake "zgaduje", że muszą być połączone a i b, jeśli jest połączony z foo. Ale w przypadku, gdy plik wykonywalny jest tworzony w projekcie "na zewnątrz" do korzystania z biblioteki foo należy połączyć z -lfoo -la -lb, teraz wyobraź sobie projekt z dużą ilością podkatalogów - jak sobie z nim radzić? więc pytanie brzmi "jak stworzyć jedną bibliotekę, agregując metody z całego projektu za pomocą cmake?"

Googling doprowadził mnie do stosunkowo niedawno osadzonego (pojawił się w 2.8.8) OBJECT library okazji. Dobry przykład korzystania z niego pokazano here. Teraz powyższy problem można rozwiązać:

# a/CMakeLists.txt 
add_library(A OBJECT <a_sources>) 
# b/CMakeLists.txt 
add_library(B OBJECT <b_sources>) 
# foo/CMakeLists.txt 
add_subdirectory(a) 
add_subdirectory(b) 
add_library(foo <foo_sources> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>) 

problem wydaje się być rozwiązany, niestety, niezupełnie.

jeśli łańcuch zależności jest dłuższy niż 2, na przykład foo zależy od A, który zależy od B, problem nadal pozostaje. To dlatego, że,

Biblioteki obiektów mogą zawierać tylko źródła (i nagłówki), które kompilują się do plików obiektów.

i

bibliotek obiektów nie można importować, eksportować zainstalowany lub połączone.

(cytaty pochodzą z tego samego link)

Próbowałem kilka kombinacji target_link_library(), add_library(), add_library(... OBJECT ..) próbuje połączyć A i B do foo bez powodzenia (błąd podczas cmake-procesie.)

Muszę tracić coś prostego, proszę o pomoc, dziękuję! Nie jestem pewien czy to ważne: projekt jest utrzymywany na Linuksie.

Odpowiedz

3

Myślę, że jesteś zaplątany w termin "zależy od".Jeśli budujesz bibliotekę o nazwie foo i ma ona dwie części, A i B, nie ma znaczenia, czy A zależy od B; biblioteka powinna zawierać oba. Przedstawiony kod CMake prawidłowo zbuduje foo.

0

Tak, popieram odpowiedź @Pete Becker @. Ale należy również powiedzieć, że biblioteki te w rzeczywistości nie są bibliotekami, a raczej zawierają wewnętrzną listę modułów obiektów. Nie ma zależności między kompilacją modułów obiektowych (z wyjątkiem źródeł generowanych automatycznie), więc można to zrobić w dowolnej kolejności i równolegle.

Podejrzewam, że bardziej prawidłowym terminem dla twojej intencji jest zebranie kilku TARGET_OBJECTS w bibliotece pojedynczego obiektu. To naprawdę źle, że nie można pisać add_library(B OBJECT b.cpp $<TARGET_OBJECTS:A>). Ale zawsze można realizować ten sam:

add_library(A OBJECT a.cpp) 
set(A_OBJECTS $<TARGET_OBJECTS:A>) 

add_library(B OBJECT b.cpp) 
set(B_OBJECTS $<TARGET_OBJECTS:B> ${A_OBJECTS}) 

add_library(foo ${B_OBJECTS}) 

tj prostu stworzyć specjalne zmienne _OBJECTS z nich korzystać kiedy chcesz zawierać tych bibliotek obiektów w bibliotece, wykonywalnego lub jako część innej biblioteki obiektów z tej _OBJECTS smaku.

Powiązane problemy