Копирование файлов с помощью qmake
Иногда бывает нужно скопировать определенные файлы из каталога с исходниками в каталог сборки с бинарными файлами разрабатываемого приложения. И инструмент qmake в Qt способен выполнять такие операции.
Некоторые гении, возможно, и захотят использовать для этого скрипты, но лучше этого не делать, потому что речь идет о кроссплатформенной разработке, а ваш xcopy
из Windows работает только на Windows, так что лучше найти какой-то универсальный метод. И в qmake
есть такая штука, хотя она и не документирована должным образом.
QMAKE_COPY
– выполняет копирование файла, а на разных платформах трансформируется в xcopy
, или в cp
, или во что-то еще.
QMAKE_COPY_DIR
– то же самое, но для каталогов. Например, в Linux/Mac он добавляет опцию -r
к cp
.
Итак, возьмем следующую структуру каталога с исходниками:
smith_chart/
├── main.cpp
├── прочие файлы и каталоги с исходниками
├── translations
│ ├── smith_chart_en.qm
│ └── smith_chart_ru.qm
├── config.ini
├── smith_chart.pro
└── smith_chart.pro.user
Мы хотим скопировать каталог translations с файлами переводов и файл config.ini с конфигурацией по умолчанию в каталог сборки, чтобы он был рядом с исполняемым файлом приложения (чтобы мы могли использовать относительные пути к файлам переводов и файлу конфигурации).
Вот как это сделать в файле .pro:
CONFIG(debug, debug|release) {
VARIANT = debug
} else {
VARIANT = release
}
# копирует заданные файлы в каталог назначения
defineTest(copyToDestDir) {
files = $$1
dir = $$2
# заменить слеши в пути назначения для Windows
win32:dir ~= s,/,\\,g
for(file, files) {
# заменить слеши в исходном пути для Windows
win32:file ~= s,/,\\,g
QMAKE_POST_LINK += $$QMAKE_COPY_DIR $$shell_quote($$file) $$shell_quote($$dir) $$escape_expand(\\n\\t)
}
export(QMAKE_POST_LINK)
}
copyToDestDir($$PWD/config.ini, $$OUT_PWD/$${VARIANT}/)
copyToDestDir($$PWD/translations, $$OUT_PWD/$${VARIANT}/translations/)
Обратите внимание на завершающий /
и его отсутствие в путях к источнику и месту назначения. Оказалось, Windows весьма чувствительна к таким вещам.
Итак, файлы скопированы, проблема решена.
Однако, поскольку я упомянул кроссплатформенную разработку, вы должны знать, что на разных платформах каталог сборки организован по-разному.
Linux – всё в одном каталоге. Поэтому при вызове copyToDestDir
необходимо убрать $${VARIANT}
из пути каталога назначения.
Windows – в каталоге сборки есть папки debug и release. Поэтому, чтобы выполнить копирование в нужный из этих двух подкаталогов, необходимо использовать $${VARIANT}
в пути каталога назначения.