isEmpty(COPIES): return() contains(TEMPLATE, .*subdirs): error("COPIES does not work with TEMPLATE=subdirs") build_pass:build_all:!isEqual(BUILD_PASS, $$first(BUILDS)) { # Avoid that multiple build passes race with each other. # This will fail to copy anything if the user explicitly invokes # only the non-primary build. This is unfixable, as at qmake time # we cannot possibly know how make will be invoked, yet we must # predict it here. return() } defineReplace(qtStripProPwd) { return($$relative_path($$1, $$_PRO_FILE_PWD_)) } for (cp, COPIES) { isEmpty($${cp}.files): next() pfx = copy_$${cp} notdir = false dir = false for (f, $${cp}.files) { fil = $$absolute_path($$f, $$_PRO_FILE_PWD_) tfiles = $$files($$fil/*) isEmpty(tfiles): \ notdir = true else: \ dir = true $${pfx}.files += $$fil } $$dir:$$notdir: \ error("COPIES entry $$cp lists both files and directories.") path = $$eval($${cp}.path) isEmpty(path): error("COPIES entry $$cp defines no .path") base = $$eval($${cp}.base) isEmpty(base) { $${pfx}.output = $$path/${QMAKE_FILE_IN_NAME} } else: isEqual(base, $$_PRO_FILE_PWD_) { $${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripProPwd} } else { eval(defineReplace(qtStripSrcDir_$$cp) { \ return(\$\$relative_path(\$\$1, $$val_escape(base))) \ }) $${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripSrcDir_$$cp} } $${pfx}.input = $${pfx}.files $${pfx}.commands = $(QINSTALL) ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} $${pfx}.name = COPY ${QMAKE_FILE_IN} $${pfx}.CONFIG = no_link no_clean target_predeps QMAKE_EXTRA_COMPILERS += $${pfx} }