cmake: борется с зависимостями add_custom_command - PullRequest
13 голосов
/ 25 октября 2010

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

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

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 / core:

add_custom_target(libcore DEPENDS libcore.bc libcore.deps)

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

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

Ответы [ 4 ]

7 голосов
/ 25 октября 2010

В документации по cmake сказано следующее о параметре DEPENDS:

Параметр DEPENDS указывает файлы, от которых зависит команда. Если любая зависимость - это ВЫХОД другой пользовательской команды в той же каталог (файл CMakeLists.txt) CMake автоматически выводит другой Пользовательская команда в цель, в которой эта команда построена. Если DEPENDS указывает любую цель (созданную командой ADD_ *) зависимость уровня цели создается, чтобы убедиться, что цель построена перед любой целью, используя эту пользовательскую команду.

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

Документация для add_custom_target гласит:

Зависимости, перечисленные с аргументом DEPENDS может ссылаться на файлы и результаты пользовательских команд, созданных с add_custom_command () в том же каталоге (файл CMakeLists.txt).

Так что вам придется использовать add_custom_command и add_custom_target следующим образом:

  1. В первом каталоге, создающем файл bc, который вы делаете

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

3 голосов
/ 20 декабря 2010

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

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

IMO, документы cmake должны сказать вместо этого:

Пользовательская цель, созданная add_custom_target, всегда считается устаревшей и являетсявсегда строится, , но только по запросу .

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

0 голосов
/ 27 сентября 2018

попробуйте добавить следующую команду во второй каталог: set_source_files_properties ($ {PROJECT_BINARY_DIR} /lib/core/libcore.bc PROPERTIES GENERATED TRUE)

Я решил мою проблему с этой командой.ссылка: https://cmake.org/cmake/help/latest/prop_sf/GENERATED.html

0 голосов
/ 26 октября 2010

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...