Search code examples
qtqmake

Qt qmake: removing entries from a variable


As part of the deployment process for a Qt project, I need to copy several files to the deployment folder. My problem is that I can't get the -= operator to work. I also want to filter out specific files based on file names.

To reproduce my problem, I have created a simple Qt project whose .pro file is shown below (see "portion of interest"):

TEMPLATE = app
QT = core
CONFIG += console
CONFIG -= app_bundle
CONFIG += c++11

SOURCES += main.cpp \
myfile1.cpp \
myfile1d.cpp

SOURCES += myfile1.cpp
SOURCES += myfile1d.cpp

#portion of interest - start
FOLDER_PATH = $$_PRO_FILE_PWD_/../files/

#add all files present in 'files' folder
FILES_TO_COPY = $$FOLDER_PATH/*

#exclude a specific file
win32:CONFIG(release, debug|release): {
FILES_TO_COPY -= $$FOLDER_PATH/filecd.txt
}

filesToCopy.files = $$FILES_TO_COPY
filesToCopy.path = $$_PRO_FILE_PWD_/../deploy

INSTALLS += filesToCopy
#portion of interest - finish

I have added a "make install" step to the build process in Qt Creator project settings. This step should look into the INSTALLS variable in the .pro file and copy the specified files from 'files' to 'deploy' folder.

Now, the folder 'files' contains the following files:

  • fileb.txt
  • filec.txt
  • filecd.txt
  • filed.txt
  • filedd.txt

Here's what I want to do:

1) Initially, I want all files except 'filecd.txt' to be copied from 'files' to 'deploy'. I am trying to use '-=' to exclude 'filecd.txt' but I am still getting all files copied across.

2) I would also like to filter out specific files based on their names. For example, if we are in release mode, then the debug versions of files should not be copied. This should exclude filecd.txt and filedd.txt, which are simulated to be the debug versions of filec.txt and filed.txt.

Thanks for any help.

{ version info: Qt Creator 4.2.1, based on Qt 5.8.0 (MSVC 2015, 32-bit)

kit info: Desktop Qt 5.8.0 MSVC2015 32bit) }

UPDATE: For others trying to do something similar (and for review by experienced ones), here's what I ended up doing:

#add all files present in 'files' folder
FILES_TO_COPY = $$files($$FOLDER_PATH/*)

#From these files: fileb.txt filec.txt filecd.txt filed.txt filedd.txt
#we only want to copy the following files to the deployment folder
#fileb.txt filec.txt filed.txt

#i.e., we wish to exclude these files from deployment folder: 
#filecd.txt filedd.txt
win32:CONFIG(release, debug|release): {
    #FILES_TO_COPY -= $$FOLDER_PATH/filecd.txt

    for(iter, FILES_TO_COPY): {
        #name of one file
        FNAME = $$iter #/path/to/filecd.txt        

        SEARCH_TOKEN = 'd.txt'
        SECTIONS = $$split(FNAME, $$SEARCH_TOKEN)#filec d.txt

        FNAME1 = $$first(SECTIONS) #filec        

        #if 'd.txt' is not part of the filename then split returns
        #the filename untouched (i.e. FNAME1 would be equal to FNAME,
        #and should be found in FILES_TO_COPY)
        #NOTE: If we are unlucky enough to have another file called                   
        #'filec' (without any extension) then the search for filecd.txt  
        #will be abandoned.        
        !contains(FILES_TO_COPY, $$FNAME1) : {
            FILE_EXT = '.txt'
            FNAME1D = $$join(FNAME1, , , $$FILE_EXT) #filec.txt                
            contains(FILES_TO_COPY, $$FNAME1D): {
                REDUNDANT_FILES += $$FNAME                    
            }
        }

    }
}

FILES_TO_COPY -= $$REDUNDANT_FILES
filesToCopy.files = $$FILES_TO_COPY
filesToCopy.path = $$_PRO_FILE_PWD_/../deploy
INSTALLS += filesToCopy

Solution

  • qmake performs glob expansion after the file has been parsed, so when the FILES_TO_COPY -= ... line is parsed, the variable still has the unexpanded glob value.

    Instead, use the $$files built-in test function to assemble a list of files that you can then remove from:

    FILES_TO_COPY = $$files($$FOLDER_PATH/*)
    
    win32:CONFIG(release, debug|release): {
      FILES_TO_COPY -= $$FOLDER_PATH/filecd.txt
    }