2014-11-18 11 views
5

Próbuję uzyskać lokalizację statycznej biblioteki innego projektu. PróbowałemCMAKE Jak uzyskać docelową lokalizację pliku

get_property (TARGET_NAME TARGET testowania właściwości location), ale CUpewnij daje następujący błąd

CMake Error at project.cmake:6 (get_property): 
The LOCATION property may not be read from target "A". 
Use the target name directly with add_custom_command, or use the generator 
expression $<TARGET_FILE>, as appropriate. 

próbowałem użyć wyrażenia generatora wymieniony w komunikacie o błędzie bez powodzenia.

MESSAGE($<TARGET_FILE:A>) 

prostu wyjść dokładnie ten sam ciąg, więc wyrażenie generator nie wydaje się być oceniana w ogóle:

$<TARGET_FILE:A> 

czytam Documentation. W pierwszych liniach wspomina: wyrażenia

Generator ocenia podczas generacji systemu budowania produkować informacje specyficzne dla każdej konfiguracji kompilacji.

Jeśli rozumiem to poprawnie, to w czasie, gdy funkcja wiadomości jest oceniana, wyrażeń generatora nie są już oceniane? Więc co mam robić w tym przypadku?

popełniłem minimalny przykład tego problemu na GitHub

EDIT:

Przepraszam, że zadał pytanie w taki okrężną drogą bez jasnego wyjaśnienia moich intencjach:

Moim celem jest przekonanie CMake'a do zbudowania biblioteki statycznej pojedynczej (!) Dla mojego projektu, z której może korzystać inna osoba (która nie używa CMake). Nadal korzystałbym z "normalnej" rozdzielczości zależności dla mojego projektu, ale druga osoba - która nie używa CMake - musiałaby ręcznie łączyć wiele bibliotek z jego projektem, co jest dość niewygodne. Pojedyncza biblioteka rozwiązałaby to.

Na mojej drodze próbowania uzyskania CMake'a do statycznego połączenia dwóch statycznych bibliotek, czytałem gdzieś (przepraszam, nie zapisałem linku), że przynajmniej przy użyciu Visual Studio jako kompilatora można uzyskać wynik, który chcę jeśli dołączę pełną ścieżkę do biblioteki statycznej, która zostanie powiązana z flagami statycznego linkera:

set_target_properties(B PROPERTIES STATIC_LIBRARY_FLAGS >>>INSERT_PATH_HERE<<<) 

która faktycznie działa. Ale teraz będę musiał recznie wstawić pełną ścieżkę do zmiennej tam

set_target_properties(B PROPERTIES STATIC_LIBRARY_FLAGS "/path/to/library.lib") 

co nie wydaje się być „dobry” sposób to zrobić ze mną. Więc eksperymentowałem z wyrażeń generatora i wymyśliłem następujący:

set_target_properties(B PROPERTIES STATIC_LIBRARY_FLAGS $<TARGET_FILE:A>) 

który nie działa, z przyczyn, których nie w pełni rozumiem. Domyślam się, że set_target_properties po prostu nie obsługuje wyrażeń generatora.Starając się uzyskać mojego projektu do pracy Próbowałem

MESSAGE($<TARGET_FILE:A>) 

(jak wskazano powyżej tej explenation) i myślę, że gdybym się, że oświadczenie do pracy mogę rozwiązać mój prawdziwy problem. Tak właśnie zadałem pytanie zamieszczone powyżej. Nie zdawałem sobie sprawy, że może to doprowadzić do zamieszania dla osób próbujących mi odpowiedzieć.

+1

Wiadomość nie może podjąć wyrażeń generatora. Ponieważ są generowane dla każdej konfiguracji kompilacji, zachowują się bardzo dziwnie w porównaniu do normalnych zmiennych. Tak naprawdę to pytanie brzmi: gdzie próbujesz użyć docelowej lokalizacji właściwości? – IdeaHat

+0

Chcę, aby wygenerować flagę łącznik do łączenia biblioteka statyczna A do innej biblioteki statycznej B tak: set_target_properties (B PROPERTIES STATIC_LIBRARY_FLAGS $ ) to nie działa. Powoduje to wygenerowanie pliku w pliku projektu zamiast jego wyniku. Używanie message() było dla mnie środkiem do debugowania problemu. Przypuszczam, że gdy uruchomię go do pracy z message(), powinien również działać z set_target_properties(). – Dirk

Odpowiedz

2

Jeśli chcesz korzystać z biblioteki w innym należy użyć target_link_libraries funkcję:

target_link_libraries(B A) 

Podpis target_link_libraries automatycznie rozchodzi A do wszystkich non-statycznych bibliotek i plików wykonywalnych, które używają B (zarówno bezpośrednio, jak i pośrednio).

Statyczne biblioteki korzystające z są świadome swojej zależności od A, ale nie będą w nich miały kopii plików obiektów z A. Informacje o zależnościach są przenoszone w docelowych właściwościach bibliotek.

Zgodnie z projektem biblioteka statyczna jest po prostu archiwum plików obiektowych. Nie ma potrzeby ręcznego mieszania plików obiektów z różnych bibliotek, jeśli chcesz korzystać tylko z bibliotek w projekcie CMake. CMake poleci twojemu linkerowi listę bibliotek, do której ma być podłączona, i właściwą kolejność bibliotek (która rzeczywiście jest tworzona na podstawie wykresu zależności). Łącznik z kolei rozwiąże wszystkie symbole z plików obiektowych przenoszonych w dostarczonych bibliotekach statycznych.

Jeśli nadal trzeba mieć precyzyjną kontrolę mieszania obiektów plików, można rozważyć użycie OBJECT library type:

# Create plain objects library which essentially is a set of object files 
add_library(zipobj OBJECT zip.cpp) 
# Archive all objects from zipobj. Recompilation of zip.cpp won't take place. 
add_library(zip STATIC $<TARGET_OBJECTS:zipobj>) 

add_library(lzmaobj OBJECT lzma.zpp) 
add_library(lzma STATIC $<TARGET_OBJECTS:lzmaobj>) 

# Create a library which contains object files from both zipobj and lzmaobj 
add_library(archive STATIC $<TARGET_OBJECTS:zipobj> $<TARGET_OBJECTS:lzmaobj>) 

EDIT: Również można spróbować merge_libraries funkcję: http://www.mail-archive.com/[email protected]/msg28670.html

+0

Dzięki za odpowiedź roolebo, ale afaik to tylko oznacza cmake "Jeśli ktoś łączy się z B automatycznie łączy A także". Chcę, żeby A było zawarte w B naprawdę, więc jeśli wezmę bibliotekę i użyję jej gdzie indziej, wszystko jest w niej zawarte. – Dirk

+0

@Dirk, wyjaśniłem odpowiedź. Prawdopodobnie typ biblioteki OBJECT jest tym, czego szukasz. – roolebo

+0

Jeszcze raz dziękuję za odpowiedź. Wygląda na to, że nie wyraziłem wystarczająco jasno swoich intencji. Wyjaśniłem moje pytanie powyżej. Chcę tylko jednego CMake'a do zbudowania biblioteki statycznej, która zawiera wszystkie symbole bez zakłócania mojej struktury biblioteki. – Dirk

Powiązane problemy