2012-10-16 12 views
5

Mam projekt CMake z wieloma podprojektami. Każdy z nich może użyć funkcji I provide, aby wygenerować mały plik tekstowy z pewnymi określonymi informacjami (przez wywołanie add_custom_command). Na ostatnim etapie chciałbym połączyć wszystkie te pliki w jeden duży plik tekstowy.CMake: dodaj zależność do add_custom_command dynamicznie

Utworzono niestandardowe polecenie, które wyszukuje utworzone pliki (wszystko w jednym miejscu) i łączy je.

Problem polega na tym, że chciałbym, aby ten ostatni krok był zależny od wszystkich małych kroków wykonywanych w podprojektach, podczas gdy ja właściwie nie wiem, ile plików zostanie dostarczonych.

Moja ostatnia komenda wygląda tak:

add_custom_command(OUTPUT combination.txt 
        COMMAND create combination.txt from all files from /path/) 

i mój create-mały-text-file-for-each-podprojekcie polecenia wygląda następująco:

add_custom_command(OUTPUT /path/${sub_project_name}.txt 
        COMMAND create /path/${sub_project_name}.txt) 

i kiedy tworzę tych małych plików Chciałbym zrobić coś takiego zrobić „combination.txt” zależą /path/${sub_project_name}.txt

Tak bym chciał:

add_dependency(combination.txt /path/${sub_project_name}.txt) 

Jednak działa to tylko w przypadku celów.

Próbowałem również użyć set_source_files_properties z OBJECT_DEPENDS, ale wydaje się, że nie działa (być może jego zamiar być używane z plików cpp add_target jest?)

Ostatnim sposobem, aby to działało to widzę aby użyć zmiennej cache, które gromadzić wszystkie te małe pliki ścieżek, a następnie używać go tak:

add_custom_command(OUTPUT combination.txt 
        COMMAND create combination.txt from all files from /path/ 
        DEPENDS ${all_small_files_list}) 

ale jest to ostatnia rzecz, którą chcesz zrobić.

Odpowiedz

4

Zamiast używać add_custom_command można użyć add_custom_target z poprawną definicją zależności (tak, aby nie była budowana za każdym razem).

add_custom_target(project 
        COMMAND touch project.txt) 

add_custom_target(project2 
        COMMAND touch project2.txt) 

add_custom_target(combination 
        COMMAND cat project.txt project2.txt > combination.txt) 

add_dependencies(combination project2) 
add_dependencies(combination project) 

add_executable(t t.c) 
add_dependencies(t combination.txt) 

Znowu: upewnij się, że używasz DEPENDS argument add_custom_target stworzyć prawdziwy łańcuch zależności, tak że projekt-target, a tym samym połączenie docelowe staje się nieaktualne.

UPDATE: Byłem zbyt wcześnie. W rzeczywistości cmake (przynajmniej do 2.8.9) działa w następujący sposób dla zależności: z wywołaniem na add_dependencies nie można dodać zależności, która jest OUTPUT z polecenia niestandardowego IOW a (wygenerowany) plik. Za pomocą add_dependencies można dodać tylko target utworzony przez add_custom_target. Jednak w przypadku modelu add_custom_target można polegać na wyjściu z add_custom_command, stosując dyrektywę DEPENDS. Powiedział, że to sprawia, że ​​działa:

add_custom_command(OUTPUT project.txt 
        COMMAND uptime >> project.txt MAIN_DEPENDENCY t2.c) 
add_custom_target(project DEPENDS project.txt) 

add_custom_target(combination 
        COMMAND cat project.txt project2.txt > combination.txt) 
add_dependencies(combination project) 

To spowoduje, że cel kombinacja zawsze być regenerowane jak to ma MAIN_DEPENDENCY lub DEPENDS, ale korzystanie z add_dependencies jest dozwolone.

+0

Będzie działał, ale nie będzie dokładnie taki, jak powinien: Za każdym razem, gdy nazywam make, wszystkie cele (kombinacja, projekt i projekt2) zostaną przebudowane - pliki będą podlegać regenracji. To nie jest tak ładne, jak mogłoby być;) Spodziewanym zachowaniem jest dla mnie, aby nie odtwarzać żadnych plików, chyba że jest to konieczne. Zgodnie z dokumentami CMake - add_custom_target jest budowany za każdym razem. Chciałbym mieć rozwiązanie działające jako add_custom_command - które buduje tylko wtedy, gdy zmieni się jakakolwiek zależność. –

+0

Co używasz jako zależności do generowania pliku project.txt? Wiem, co chciałby powiedzieć docet-doc, jest to, że custom_target jest zawsze sprawdzane, czy musi zostać przebudowane, czy nie - przynajmniej wydaje się, że działa tak dla mnie. –

+0

Cóż, po odpowiednim przeczytaniu tego, jak to robimy, muszę przyznać, że byłem zbyt wcześnie. Zobacz moją aktualizację odpowiedzi. –

Powiązane problemy