Search code examples
c++qtqmake

QMAKE_EXTRA_COMPILERS output directory, msvc


In a Qt project using msvc2013, I have one .cpp which has to be built with the custom option /arch:IA32 and the preprocessor command _CRT_SECURE_NO_WARNINGS.

Here is the interesting part a my .pro file:

CONFIG(release, debug|release){
    DESTDIR = RELEASE
    OBJECTS_DIR = RELEASE/.obj
    MOC_DIR = RELEASE/.moc
    RCC_DIR = RELEASE/.rcc
    UI_DIR = RELEASE/.ui
}
CONFIG(debug, debug|release){
    DESTDIR = DEBUG
    OBJECTS_DIR = DEBUG/.obj
    MOC_DIR = DEBUG/.moc
    RCC_DIR = DEBUG/.rcc
    UI_DIR = DEBUG/.ui
}

(...)

SPECIAL_SOURCE = extractor.cpp
ExtraCompiler.input = SPECIAL_SOURCE
ExtraCompiler.variable_out = OBJECTS
ExtraCompiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_IN_BASE}$${QMAKE_EXT_OBJ}
ExtraCompiler.commands = $${QMAKE_CXX} $(CXXFLAGS) /arch:IA32 /D_CRT_SECURE_NO_WARNINGS $(INCPATH) -c ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}

QMAKE_EXTRA_COMPILERS += ExtraCompiler

The problem I got is that the object created - which is "extractor.obj" - is not placed in the same directory than the others. The directory can either be RELEASE/.obj or DEBUG/.obj. Instead of this, "extractor.obj" is created in the root directory, just next my .pro file.

This system worked with other compilers such as MinGW, Clang or GCC. I don't know what is wrong here. Has anyone encountered the same problem? Thanks a lot.


Edit: two solutions found

Solution 1: change ExtraCompiler.output for windows build (release and debug)

SPECIAL_SOURCE = extractor.cpp
ExtraCompiler.input = SPECIAL_SOURCE
ExtraCompiler.variable_out = OBJECTS
win32:CONFIG(release, debug|release):    ExtraCompiler.output = ${QMAKE_VAR_OBJECTS_DIR}release/${QMAKE_FILE_IN_BASE}$${QMAKE_EXT_OBJ}
else:win32:CONFIG(debug, debug|release): ExtraCompiler.output = ${QMAKE_VAR_OBJECTS_DIR}debug/${QMAKE_FILE_IN_BASE}$${QMAKE_EXT_OBJ}
else:                                    ExtraCompiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_IN_BASE}$${QMAKE_EXT_OBJ}
ExtraCompiler.commands = $${QMAKE_CXX} $(CXXFLAGS) -arch:IA32 -D_CRT_SECURE_NO_WARNINGS $(INCPATH) -c ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}

Solution 2: specify the output folder with -Fo instead of -o (https://msdn.microsoft.com/en-us/library/yb8e9b8y.aspx)

SPECIAL_SOURCE = extractor.cpp
ExtraCompiler.input = SPECIAL_SOURCE
ExtraCompiler.variable_out = OBJECTS
ExtraCompiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_IN_BASE}$${QMAKE_EXT_OBJ}
ExtraCompiler.commands = $${QMAKE_CXX} $(CXXFLAGS) -arch:IA32 -D_CRT_SECURE_NO_WARNINGS $(INCPATH) -c ${QMAKE_FILE_IN} -Fo${QMAKE_FILE_OUT}

Solution

  • Idea 1

    MSVC places object files usually into a release/debug sub-directory of the build dir. The other compilers don't.

    Thus you just have to add release/ or debug/ between ${QMAKE_VAR_OBJECTS_DIR} and ${QMAKE_FILE_IN_BASE}, e.g.

    win32:CONFIG(release, debug|release):    ExtraCompiler.output = ${QMAKE_VAR_OBJECTS_DIR}release/${QMAKE_FILE_IN_BASE}$${QMAKE_EXT_OBJ}
    else:win32:CONFIG(debug, debug|release): ExtraCompiler.output = ${QMAKE_VAR_OBJECTS_DIR}debug/${QMAKE_FILE_IN_BASE}$${QMAKE_EXT_OBJ}
    else:                                    ExtraCompiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_IN_BASE}$${QMAKE_EXT_OBJ}
    

    Idea 2

    Your ExtraCompiler.input is empty because when you use custom-defined qmake variables, you need to add $$ when you use them. Try

    SPECIAL_SOURCE = extractor.cpp
    ExtraCompiler.input = $$SPECIAL_SOURCE
    

    Now check whether there is something between / and .obj in your error message.