Wednesday, 28 August 2013

How to get QMake to copy large data files only if they are updated

How to get QMake to copy large data files only if they are updated

I have some large data files that need to be copied from source folders to
build folders during our Qmake/QtCreator build. Since they are large, I
only want the copy to happen for new/changed files. And I'd really like to
avoid listing them all specifically in the project file. Here's what I've
tried:
This attempt at copying data files fails because the DemoData folder is
the target. Therefore the copy is not performed if files within the folder
are added or changed. Only if the folder does not exist.
DemoData.commands = $$COPY_CMD $${SRC_DATA_DIR}DemoData
$${BLD_DATA_DIR}DemoData
DemoData.target += $${BLD_DATA_DIR}DemoData
PRE_TARGETDEPS += $${BLD_DATA_DIR}DemoData
QMAKE_EXTRA_TARGETS += DemoData
This approach fails because the DemoData.target item is not expected to
have a list of multiple items. QMake puts the list in quotes in the
generated makefile so it becomes one target.
DemoData.commands = $$COPY_CMD $${SRC_DATA_DIR}DemoData
$${BLD_DATA_DIR}DemoData
DEMO_DATA_FILES = $$files($${SRC_DATA_DIR}DemoData/*)
for(FILE, DEMO_DATA_FILES){
DemoData.target += $${BLD_DATA_DIR}DemoData\\$$basename(FILE)
PRE_TARGETDEPS += $${BLD_DATA_DIR}DemoData\\$$basename(FILE)
}
QMAKE_EXTRA_TARGETS += DemoData
This attempt fails because (AFAICT) QMake does not support variable names
contained in other variables. It seems to be more of a one level
substitution. A makefile is generated, but the DemoDataX targets all have
no command lines. All attempts to display the contents of the 'commands'
field generate syntax errors.
DEMO_DATA_FILES = $$files($${SRC_DATA_DIR}DemoData/*)
DEMO_DATA_NAME = DemoData
for(FILE, DEMO_DATA_FILES){
$${DEMO_DATA_NAME}.target = $${FILE}
$${DEMO_DATA_NAME}.commands = $$COPY_CMD $${FILE}
$${BLD_DATA_DIR}DemoData
PRE_TARGETDEPS += $${FILE}
QMAKE_EXTRA_TARGETS += $${DEMO_DATA_NAME}
DEMO_DATA_NAME = $${DEMO_DATA_NAME}X
}
This approach works, but with two shortcomings. The minor one is that a
separate 'make install' step must be performed. The major one is that the
files are always copied unconditionally. Since our data files are large,
this is unacceptable timewise.
DemoData.path = $${BLD_DATA_DIR}DemoData
DemoData.files = $${SRC_DATA_DIR}DemoData/*
INSTALLS += DemoData
Is there a way to do this, or am I left with some sort of external script
or manually generated/maintained makefile?

No comments:

Post a Comment