2010-10-24 17 views
12

Próbuję pobrać plik produkowanego przez add_custom_command w jednym katalogu być zależność o add_custom_command w innym katalogu.CUpewnij: zmaga się z zależnościami add_custom_command

W pierwszym katalogu (lib/rdzeń) Mam polecenie build, który wygląda tak:

add_custom_command(
    OUTPUT libcore.bc 
    COMMAND tartln -filetype=bc -link-as-library -o libcore.bc ${STDLIB_BC_FILES} 
    DEPENDS ${STDLIB_BC_FILES} tartln 
    COMMENT "Linking libcore.bc") 

W drugim katalogu, mam polecenie, które wykorzystuje moc tego polecenia:

add_custom_command(OUTPUT ${OBJ_FILE} 
    COMMAND tartln -disable-fp-elim -filetype=obj -o ${OBJ_FILE} ${BC_FILE} 
     "${PROJECT_BINARY_DIR}/lib/core/libcore.bc" 
    MAIN_DEPENDENCY "${BC_FILE}" 
    DEPENDS "${PROJECT_BINARY_DIR}/lib/core/libcore.bc" 
    COMMENT "Linking Tart bitcode file ${BC_FILE}") 

jednak gdy próbuję budować, pojawia się następujący błąd:

make[3]: *** No rule to make target `lib/core/libcore.bc', needed by `test/stdlib/ReflectionTest.o'. Stop. 

Jedna dziwna rzecz widzę, że ścieżka w komunikacie o błędzie jest względną, a nie bezwzględną ścieżką, mimo że wiem, że $ {PROJECT_BINARY_DIR} jest pełną, poprawną ścieżką. Nie wiem, czy to jest problem, czy tylko obcość marki.

Próbowałem zostały również dokonywania cel najwyższego poziomu dla biblioteki libcore w katalogu lib/rdzeń:

add_custom_target(libcore DEPENDS libcore.bc libcore.deps) 

A następnie przy użyciu, że w klauzuli zależy. Dziwne jest to, że działa po raz pierwszy, gdy robisz czystą kompilację, ale powoduje błąd podczas każdej kolejnej kompilacji. W każdym razie, moje zrozumienie jest ZWOLNIENIE ma jedynie działać dla zależności plików, więc nie wydaje się to właściwe rozwiązanie. (Jak masz polecenia niestandardowego, który zależy od docelowej najwyższego poziomu wtedy?)

Próbowałem zostały również wprowadzenie ścieżki bezwzględne wszędzie, żadnego efektu.

Odpowiedz

7

Dokumentacja CUpewnij mówi po około parametru zależy:

The DEPENDS option specifies files on which the command depends. If any dependency is an OUTPUT of another custom command in the same directory (CMakeLists.txt file) CMake automatically brings the other custom command into the target in which this command is built. If DEPENDS specifies any target (created by an ADD_* command) a target-level dependency is created to make sure the target is built before any target using this custom command.

Dlatego myślę, że trzeba będzie zdefiniować docelową korzystając add_custom_target i zależą od tego.

Dokumentacja add_custom_target mówi:

Dependencies listed with the DEPENDS argument may reference files and outputs of custom commands created with add_custom_command() in the same directory (CMakeLists.txt file).

więc trzeba będzie użyć add_custom_command i add_custom_target następująco:

  1. W pierwszym katalogu generowania pliku bc zrobić

    add_custom_command(OUTPUT libcore.bc ...) # just as in your question add_custom_target (LibCoreBC DEPENDS libcore.bc)

  2. W drugim katalogu robisz

    add_custom_command (OUT ${OBJ_FILE} DEPENDS LibCoreBC ....)

+4

Niestety, to rozwiązanie nie działa. (Zdaję sobie sprawę, że prawdopodobnie minęło już prawie zero lat). O ile mogę powiedzieć, parametr DEPENDS polecenia add_custom_command MUSI być zależnością od poziomu pliku - chociaż dokumenty mówią, że zależność poziomu celu * w tym samym katalog * będzie działał, w rzeczywistości próbowałem wielu różnych permutacji w ciągu ostatnich 11 miesięcy i żaden z nich nie działał. Oznacza to, że jeśli zdefiniuję cel niestandardowy "foo" w tym samym katalogu, a następnie wykażę ZWOLNIENIE "foo", po prostu zgłosi "brak reguł, aby uczynić cel" foo "..." – Talin

+0

@Talin Więc wydaje się to być bug, czy problem został zgłoszony w [CMake bugtracker] (http://www.cmake.org/Bug/my_view_page.php)? – lef

0

Nie sądzę add_custom_target zadziała za to, co chcę. Zgodnie z dokumentami cmake niestandardowy cel stworzony przez add_custom_target jest zawsze uważany za nieaktualny i zawsze jest budowany.

Problem polega na tym, że próbuję pobrać dane wyjściowe z jednego add_custom_command i przekazać je do wejścia innego add_custom_command w innym katalogu.Chcę tylko, aby tak się stało, jeśli oryginalny plik źródłowy jest nieaktualny - jeśli użyłbym add_custom_target, dane wyjściowe zawsze byłyby odbudowywane, nawet jeśli plik źródłowy nie został zmieniony. Biorąc pod uwagę, że istnieją setki tych plików źródłowych, spowodowałoby to bardzo powolną budowę.

Oto, co próbuję zrobić: Mam program, który generuje plik .bc (LLVM bitch) podany plik źródłowy. Istnieje wiele tych plików źródłowych, które tworzą wiele plików .bc.

Drugi program przekształca wszystkie pliki .bc w pojedynczy plik .obj (obiekt ELF). Więc etapy transformacji wyglądać następująco:

plików kod
source file -> .bc  (via add_custom_command) 
    .bc   -> .obj (via add_custom_command) 
    .obj  -> .exe (via add_executable) 

oryginalnego źródła znajdują się w różnych katalogach, ponieważ są biblioteki klas - Nie chcę, aby umieścić cały kod dla każdej klasy biblioteki w tym samym informator.

3

To nie jest odpowiedź, ale wyjaśnienie do jednego z powyższych answers.

According to the cmake documents, a custom target created by add_custom_target is always considered out of date and is always built.

IMO, dokumenty CWprowadä powinien powiedzieć zamiast:

A custom target created by add_custom_target is always considered out of date and is always built, but only when requested.

Oznacza to, że jeśli wszystkie swoje cele są oznaczone jako EXCLUDE_FROM_ALL i masz add_custom_target poleceń, które tworzą nowe cele i wpiszesz make z wiersza poleceń bez określonych celów dodano obiekty docelowe dodane do add_custom_target: nie. Ale jeśli przeliterujesz je na linii komend make jawnie, zostaną one zbudowane. Istnieje również słowo kluczowe ALL, które można określić na add_custom_target, aby zmusić je do zbudowania jako część reguły, co moim zdaniem oznacza, że ​​gdy make jest wykonywane bez argumentów.

+0

Zgadzam się. Słowa "jest zawsze zbudowany" nie są dosłownie prawdziwe. –

Powiązane problemy