2010-10-24 2 views
12

Я пытаюсь получить файл, созданный командой add_custom_command в одном каталоге, в зависимости от add_custom_command в другом каталоге.cmake: борется с зависимостями add_custom_command

В первом каталоге (Библиотека/ядро) у меня есть команда сборки, которая выглядит следующим образом:

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") 

Во втором каталоге, у меня есть команда, которая использует вывод этой команды:

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}") 

Однако, когда я пытаюсь построить, я получаю следующее сообщение об ошибке:

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

Одна странная вещь что я вижу, что путь в сообщении об ошибке является относительным, а не абсолютным путем, несмотря на то, что я знаю, что $ {PROJECT_BINARY_DIR} - полный, правильный путь. Я не знаю, является ли это проблемой или просто странностью make.

Я также попытался сделать цель верхнего уровня для библиотеки libcore, в директории Lib/ядра:

add_custom_target(libcore DEPENDS libcore.bc libcore.deps) 

И затем, используя, что в пункте ЗАВИСИТ. Странная вещь в том, что это работает в первый раз, когда вы делаете чистую сборку, но выдает ошибку при любой последующей сборке. В любом случае, я понимаю, что DEPENDS должен работать только для зависимостей файлов, поэтому это не похоже на правильное решение. (Как у вас есть пользовательская команда, которая зависит от целевого уровня верхнего уровня?)

Я также попытался установить абсолютные пути везде, без эффекта.

ответ

7

документация CMake говорит следующее о параметре ЗАВИСИТ:

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.

Поэтому я думаю, вы должны определить цели, используя add_custom_target и зависит от этого.

Документация add_custom_target говорит:

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).

Таким образом, вы должны будете использовать add_custom_command и add_custom_target следующим образом:

  1. В первом каталоге создания файла Ьс вы

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

  2. Во втором каталоге вы

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

+4

К сожалению, это решение не работает. (Я понимаю, что это, вероятно, безнадежный ответ после того, как прошло почти год.) Насколько я могу судить, параметр DEPENDS add_custom_command ДОЛЖЕН быть зависимым от файлового уровня - хотя документы говорят, что зависимость уровня на уровне * в том же каталог * будет работать, на самом деле я пробовал много разных перестановок за последние 11 месяцев, и никто из них не работает. То есть, если я определяю пользовательскую целевую «foo» в том же каталоге, а затем скажу DEPENDS «foo», она просто сообщит «нет правил, чтобы сделать цель» foo »... – Talin

+0

@Talin Итак, это похоже на ошибка, есть ли проблема, указанная для этого в [CMake bugtracker] (http://www.cmake.org/Bug/my_view_page.php)? – lef

0

Я не думаю, что add_custom_target будет работать на то, что я хочу. Согласно документам cmake, пользовательская цель, созданная add_custom_target, всегда считается устаревшей и всегда строится.

Проблема заключается в том, что я пытаюсь вывести результат из одного add_custom_command и подавать его на вход другого add_custom_command в другом каталоге.Я хочу, чтобы это произошло только в том случае, если исходный исходный файл устарел - если я использовал add_custom_target, тогда вывод всегда будет перестроен, даже если исходный файл не изменился. Учитывая, что есть сотни этих исходных файлов, это сделало бы сборку очень медленной.

Вот что я пытаюсь сделать: у меня есть программа, которая генерирует файл .bc (LLVM bitcode) с исходным файлом. Есть много этих исходных файлов, которые создают много .bc-файлов.

Вторая программа преобразует все файлы .bc в один файл .obj (объект ELF). Таким образом, этапы трансформации выглядеть следующим образом:

source file -> .bc  (via add_custom_command) 
    .bc   -> .obj (via add_custom_command) 
    .obj  -> .exe (via add_executable) 

исходных файлы код находятся в разных каталогах, поскольку они являются библиотеками классов - Я не хочу, чтобы поместить весь код для каждой библиотеки классов в том же каталог.

3

Это не ответ, но пояснение к одному из ваших answers выше.

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

ИМО, CMake документы должны сказать вместо этого:

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

Это означает, что, если все ваши цели отмечены как EXCLUDE_FROM_ALL, и у вас есть add_custom_target команды, которые создают новые цели, и вы наберете make из командной строки без заданных целей, цели, добавленные add_custom_target, - не. Но если вы явно укажете их в командной строке make, они будут построены. Кроме того, есть ключевое слово ALL, которое вы можете указать add_custom_target, чтобы заставить те, которые должны быть построены, как часть всего правила, что, я считаю, означает, когда make выполняется без аргументов.

+0

Согласен. Слова «всегда построены» буквально не верны. –

Смежные вопросы