Автоматически перестраивать зависимости в Qt Creator - PullRequest
0 голосов
/ 12 июня 2018

Qt Creator (4.6.1) сводит меня с ума.Мое приложение разделено на 3 части:

  • приложение
  • библиотека
  • приложение модульных тестов

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

Кроме того, когда я изменяю библиотеку, перекомпилирую ее и затем компилирую приложение, без компиляциипроисходит, потому что он использует кэшированное приложение.

Есть ли параметр, чтобы изменить это?Вот мой файл проекта:

TEMPLATE = subdirs

SUBDIRS += \
    app \
    lib_mylib \
    tests

app.depends = lib_mylib
tests.depends = lib_mylib

Библиотека построена как статическая библиотека:

TEMPLATE = lib
TARGET = mylib
CONFIG += staticlib

Ответы [ 2 ]

0 голосов
/ 23 июня 2018

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

Рабочим решением будет: вы используете либо b.depends += a как вы делали раньше или CONFIG += ordered и добавьте PRE_TARGETDEPS += ... к b.(Примечание: заказывать не рекомендуется, так как это может значительно замедлить ваши сборки и обычно считается плохой практикой)

TL; DR: Причина, по которой необходима эта специальная комбинация:app.depends = lib_mylib в проекте subdirs гарантирует, что библиотека всегда собирается перед запуском сборки приложения, а PRE_TARGETDEPS гарантирует, что приложение фактически перестраивается при каждом изменении библиотеки.


Длинное объяснение:

Чтобы понять, почему это работает, нам нужно понять, как qmake обрабатывает подкаталоги.qmake является генератором Makefile, что означает, что он будет создавать только make-файлы.Таким образом, все упорядочение зависимостей должно выполняться с использованием методов make prodives.Чтобы понять, что происходит, мы должны сначала понять, как работает make.

В make зависимости относительно просты:

some_target: dep1 dep2 dep3
    some_command

означает, что если вы хотите создать some_target, make будетсначала создайте dep1, dep2 и dep3 в неопределенном порядке .После того как все 3 будут выполнены, будет выполнено some_command.

Тем не менее, make оптимизирует это для файлов.Учитывая следующее:

hello.txt:
    echo "creating hello"
    echo "hello" > hello.txt

hello2.txt: hello.txt
    echo "creating hello2"
    echo "hello2" > hello2.txt

Запуск make создаст оба файла и напечатает оба сообщения.Запуск его во второй раз ничего не даст.Причина в том, что make отслеживает уже созданные файлы и их изменения.Поскольку hello.txt уже существует, он не создается снова.И поскольку hello.txt не изменился, нет необходимости создавать hello2.txt снова.Если вы теперь внешне измените содержимое hello.txt и запустите make снова, hello2.txt будет создан заново, и вы увидите сообщение.

Теперь с проектами subdirs это становится немного сложнее, так как мытеперь нужны зависимости между несколькими разными make-файлами!Обычно это решается с помощью рекурсивных вызовов.Для вашего примера qmake создает следующий код (упрощенно):

lib_mylib: FORCE
    $(MAKE) lib_mylib/Makefile

app: lib_mylib FORCE
    $(MAKE) app/Makefile

Этот код, как и ожидалось, сначала создаст lib_mylib (блокировка, т.е. lib_mylib завершится только после того, как вся библиотекабыл построен) и после этого создать app.Зависимость FORCE гарантирует, что эта команда всегда выполняется, даже если цель уже существует.


С учетом этих основ мы можем теперь восстановить то, что происходит с qmake.Использование b.depends += a сгенерирует код, как указано выше - это гарантирует, что все зависимости построены в правильном порядке, но не более того!Использование упорядоченного конфига просто автоматически создает эти зависимые правила, поэтому нет логической разницы в том, как они работают.

Однако этого недостаточно для фактического перестроения app при изменении lib_mylib.Это только гарантирует, что lib_mylib будет собран до того, как make начнет сборку app.

. Чтобы перестроить app, мы используем PRE_TARGETDEPS - это добавляет зависимость, как показано ранее, к цели make вmake-файл приложения

app.exe: mylib.lib:
    #linker code

Это означает, что при каждом изменении lib_mylib app теперь также перестраивается.Однако использование этого без упорядоченного конфига может привести к сбою, так как возможно, что make сначала попытается собрать app (который либо ничего не делает, так как lib не изменился, либо завершится ошибкой, если lib еще не существует) и после этого перестроитьlib_mylib.Выполнение make во второй раз также приведет к перестройке app, но это довольно неудобно.

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

0 голосов
/ 12 июня 2018

Я использовал CONFIG + = order, DEPENDPATH и PRE_TARGETDEPS, чтобы избавиться от тех же проблем.У меня это работает на Linux и на Win с MSVC.Попробуйте.

в вашем проекте pro file добавьте:

CONFIG += ordered

PS: ваша библиотека должна быть указана первой.Например:

SUBDIRS += \
    lib \
    app \
    tests

в вашем exe .pro файле добавьте это с правильными путями:

DEPENDPATH += $$PWD/../lib
PRE_TARGETDEPS += $$OUT_PWD/../lib/liblib.a

Дополнительные параметры и флаги можно найти здесь

...