Important: Please read the Qt Code of Conduct -

Why does qmake fail to remove (rm) files correctly during rebuild with a custom compiler?

  • I am trying to get the thrift framework test samples to build in a Qt qmake environment and I'm seeing a problem when I rebuild my project.
    My question is

    • What am I doing wrong that causes the makefile to concatenate all all the .out files together with no spaces in the rm call?'

    I'll show the output first, then go into the specifics.

    Error: - see the first 'rm' command rm -fthrifttest.... (every filename is run together??? Why?)

    06:09:37: Running steps for project thrifttest...
    06:09:37: Starting: "/usr/bin/make" clean
    /opt/Qt/5.4/gcc/bin/qmake -spec linux-g++ CONFIG+=debug -o Makefile ../../thrifttest/idl/
    rm -fthrifttest/idl/tutorial.outthrifttest/idl/shared.out
    rm -f Calculator.o shared_constants.o shared_types.o SharedService.o tutorial_constants.o tutorial_types.o
    rm -f *~ core *.core
    rm: invalid option -- 't'
    Try 'rm --help' for more information.
    make: [compiler_idl_clean] Error 1 (ignored)
    06:09:37: The process "/usr/bin/make" exited normally.
    06:09:37: Starting: "/opt/Qt/5.4/gcc/bin/qmake" /home/developer/dev/thrifttest/idl/ -r -spec linux-g++ CONFIG+=debug
    06:09:37: The process "/opt/Qt/5.4/gcc/bin/qmake" exited normally.
    06:09:37: Starting: "/usr/bin/make" 
    g++ -c -pipe -g -Wall -W -D_REENTRANT -fPIC  -I../../thrifttest/idl -I. -I/opt/Qt/5.4/gcc/mkspecs/linux-g++ -o Calculator.o ../../thrifttest/idl/gen-cpp/Calculator.cpp

    .pro file design - Qt version is 5.4

    QT        -= core
    QT        -= gui
    TEMPLATE  = lib
    # the IDL files I am interested in.
        tutorial.thrift \
    # a special tool (compiler) that generates the appropriate .cpp and .h files from the IDL generator
    # called 'thrift'. There is a ton of undocumented nuggets in here
    #  IN_PWD — the base directory of the source tree
    #  QMAKE_FILE_BASE - the current processing filename without extension or path. Changes for each call to .commands
    #  QMAKE_FILE_IN - the current processing filename including its path and extension. Changes for each call to .commands
    #  $$escape_expand(\\n\\t) - a way to output more than one command (could have added '&&' as well)
    #  idl.output -  sets the output file name that the step will generate. In this case I am creating
    #                a touched .out file to match against the .thrift file processed. This file is matched by
    #                timestamp against the current input file to determine if it needs building.
    #  idl.input - The tool will iterate through the specified files.
    #  idl.commands - this is the guts of the compiler tool. The commands listed here act upon files found
    #                 in the .input list that need to be updated.
    # - this appears to just be an internal name used in qmake;
    #             just ensure you use a different value for each custom compiler.
    #  idl.variable_out - the generated target files outputted from the build step will be added to this variable
    #  idl.CONFIG - target_predeps — I *think* this makes sure that the custom compiler
    #                                is run as the first thing in the project...
    #               no_link -  the files that are created should not be added to OBJECTS —
    #                          i.e., they are not compiled code which should be linked
    idl.output   = $${IN_PWD}/${QMAKE_FILE_BASE}.out
    idl.input    = THRIFTSOURCES
    idl.commands = thrift -r -o "$${IN_PWD}" --gen cpp ${QMAKE_FILE_IN}$$escape_expand(\\n\\t) \
                   touch $${IN_PWD}/${QMAKE_FILE_BASE}.out$$escape_expand(\\n\\t)     = thrift-compiler 
    idl.variable_out = JUNK
    idl.CONFIG = no_link target_predeps # guarantee this is called before the regular compiler actions.
    QMAKE_EXTRA_COMPILERS += idl        # add to the compiler action list.
    # We have no idea how many .cpp files will be generated by the IDL compiler. This
    # set of lines finds all the .cpp files and then eliminates all the *.skeleton.cpp files
    # (which are just sample applications and not needed by our library code).
    # Once a good list is defined, then make it the SOURCES list to use as the build
    # structure. The $$files(glob) is an UNDOCUMENTED function to handle wildcard searches.
    TESTS = $$files($${IN_PWD}/gen-cpp/*.cpp)
    SKELS = $$files($${IN_PWD}/gen-cpp/*.skeleton.cpp)
    TESTS -= $$SKELS
    HEADERS = $$files($${IN_PWD}/gen-cpp/*.h)

    Source file directory structure

    ├── idl
    │   ├── gen-cpp  <--- generated files go in here
    │   │   ├── Calculator.cpp
    │   │   ├── Calculator.h
    │   │   ├── Calculator_server.skeleton.cpp
    │   │   ├── shared_constants.cpp
    │   │   ├── shared_constants.h
    │   │   ├── SharedService.cpp
    │   │   ├── SharedService.h
    │   │   ├── SharedService_server.skeleton.cpp
    │   │   ├── shared_types.cpp
    │   │   ├── shared_types.h
    │   │   ├── tutorial_constants.cpp
    │   │   ├── tutorial_constants.h
    │   │   ├── tutorial_types.cpp
    │   │   └── tutorial_types.h
    │   ├──
    │   ├── shared.out
    │   ├── shared.thrift
    │   ├── tutorial.out
    │   └── tutorial.thrift