Active Qt is  a convenient cross compiler module reuse technology. In contrast 
to building a general application, building the ActiveX control has more than 
one extra step after completing the link step. Currently, the MSYS2 environment 
needs some additional fixes for ActiveQt support, and here's a list of them.

#1 Fix g++ library search sequence determined by the specified order
In gcc manu, it is said that " It makes a difference where in the command you 
write this option; the linker searches and processes libraries and object files 
in the order they are specified. Thus, `foo.o -lz bar.o' searches library `z' 
after file foo.o but before bar.o. If bar.o refers to functions in `z', those 
functions may not be loaded."
It means that if a wrong -l order is specified, link error will occur, that is 
exactly happened in MSYS2::Qt::ActiveQt.
To slove this problem, now we explicitly specify order and dependency in pro 
file. 
##1.1 For projects using an active control, use:
win32-g++{  
    CONFIG += no_lflags_merge  
    LIBS += -lQt5AxServer -lQt5AxBase -lole32 -loleaut32 -luser32 -lgdi32 
-ladvapi32 -luuid  
}
##1.2 For projects that produce an active ctrl for others, use:
win32-g++{  
    CONFIG += no_lflags_merge  
    LIBS += -lQt5AxServer -lQt5AxBase -lole32 -loleaut32 -luser32 -lgdi32 
-ladvapi32 -luuid  
}  
Flag "no_lflags_merge" avoid qmake sorting the raw libraries order. The sorting 
process removes redundant libraries and disrupts the given order. Through this 
step, the project can be properly compiled and linked.

#2 Patch idcidl.prf for correct command line escape character
In windows, command line arguments normally started by character '/', which is 
different in linux. Linux and MSYS2 using '-' instead of '/'. In msys2, '/' is 
treated same as '\'.
The problem is located in idcidl.prf, a command line parameter will be 
interpreted as a file path using '/'.
Raw file:
...  
!qaxserver_no_postlink {  
    !isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK += $ $quote($ $ACTIVEQT_NEWLINE)  
    QMAKE_POST_LINK += $ $quote($ $ACTIVEQT_IDC $ ${ACTIVEQT_TARGET} /idl $ 
${ACTIVEQT_OUTPUT}.idl -version $ ${ACTIVEQT_VERSION}$ ${ACTIVEQT_NEWLINE})  
    !isEmpty(RC_FILE) {  
        QMAKE_POST_LINK += $ $quote($ $ACTIVEQT_IDL "$ ${ACTIVEQT_OUTPUT}.idl" 
/nologo /tlb "$ ${ACTIVEQT_OUTPUT}.tlb"$ $ACTIVEQT_NEWLINE)  
        QMAKE_POST_LINK += $ $quote($ $ACTIVEQT_IDC $ ${ACTIVEQT_TARGET} -tlb $ 
${ACTIVEQT_OUTPUT}.tlb$ $ACTIVEQT_NEWLINE)  
    } else {  
        QMAKE_POST_LINK += $ $quote($ $ACTIVEQT_IDL "$ ${ACTIVEQT_OUTPUT}.idl" 
/nologo /tlb "$ ${ACTIVEQT_TLBOUT}"$ $ACTIVEQT_NEWLINE)  
        message("No rc-file linked into project; type library will be a 
separate file.")  
    }  
    !qaxserver_no_register: \  
        QMAKE_POST_LINK += $ $quote($ $ACTIVEQT_IDC $ ${ACTIVEQT_TARGET} 
/regserver)  
    QMAKE_CLEAN += $ ${ACTIVEQT_OUTPUT}.idl $ ${ACTIVEQT_OUTPUT}.tlb  
}  
We patch it like :
!qaxserver_no_postlink {  
    !isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK += $ $quote($ $ACTIVEQT_NEWLINE)  
    QMAKE_POST_LINK += $ $quote($ $ACTIVEQT_IDC $ ${ACTIVEQT_TARGET} -idl $ 
${ACTIVEQT_OUTPUT}.idl -version $ ${ACTIVEQT_VERSION}$ ${ACTIVEQT_NEWLINE})  
    !isEmpty(RC_FILE) {  
        QMAKE_POST_LINK += $ $quote($ $ACTIVEQT_IDL "$ ${ACTIVEQT_OUTPUT}.idl" 
-nologo -tlb "$ ${ACTIVEQT_OUTPUT}.tlb"$ $ACTIVEQT_NEWLINE)  
        QMAKE_POST_LINK += $ $quote($ $ACTIVEQT_IDC $ ${ACTIVEQT_TARGET} -tlb $ 
${ACTIVEQT_OUTPUT}.tlb$ $ACTIVEQT_NEWLINE)  
    } else {  
        QMAKE_POST_LINK += $ $quote($ $ACTIVEQT_IDL "$ ${ACTIVEQT_OUTPUT}.idl" 
-nologo -tlb "$ ${ACTIVEQT_TLBOUT}"$ $ACTIVEQT_NEWLINE)  
        message("No rc-file linked into project; type library will be a 
separate file.")  
    }  
    !qaxserver_no_register: \  
        QMAKE_POST_LINK += $ $quote($ $ACTIVEQT_IDC $ ${ACTIVEQT_TARGET} 
-regserver)  
    QMAKE_CLEAN += $ ${ACTIVEQT_OUTPUT}.idl $ ${ACTIVEQT_OUTPUT}.tlb  
}  
Through this step, the "post-build step" is nearly OK, except for next approach.
#3 Create a proxy "midl.exe" program to properly introduce midl.exe
The  IDL compiler in windows is a part of Windows SDK, which has a deep 
connection with Visual C++ enviroment. We could not simply add path to raw 
midl.exe for mingw32, this is not enough. midl.exe needs  env paras set by 
VCVARS32.BAT . We can build a simple proxy app called "midl.exe", put it in 
msys2 bin folder. This tiny proxy will call real "midl.exe" when post-build 
step is called.
##3.1 The pro file for midl.exe proxy
QT += core  
QT -= gui  
  
CONFIG += c++11  
  
TARGET = midl  
CONFIG += console  
CONFIG -= app_bundle  
  
TEMPLATE = app  
  
SOURCES += main.cpp  
##3.2 The cpp file for midl.exe proxy
#include <QCoreApplication>  
#include <QString>  
#include <QSettings>  
#include <QDir>  
#include <QProcess>  
#include <QStringList>  
#include <QDebug>  
#include <stdlib.h>  
int main(int argc, char *argv[])  
{  
    QCoreApplication a(argc, argv);  
    QString exeName = a.applicationName();  
    //0. the exe name and ini filename should be  stored together.  
    QString iniFile = a.applicationFilePath() + ".ini";  
    QSettings settings(iniFile,QSettings::IniFormat);  
    //1.get the current directory  
    QString strCurrentDir = QDir::current().absolutePath();  
    //2.get the visual studio vcvars32 path and raw EXE path  
    QString vcvarsPath = settings.value("SETTINGS/VCVARS","D:\\Microsoft Visual 
Studio 10.0\\VC\\bin\\vcvars32.bat")  
            .toString();  
    QString exeDir = settings.value("SETTINGS/EXEDIR","C:\\Program Files 
(x86)\\Windows Kits\\8.1\\bin\\x86")  
            .toString();  
    //3.Make the cmd target  
    QString cmd ;  
    //3.1. call vc vars to  
    //  cmd += " && ";  
    cmd += "CALL ";  
    cmd += "\"" + vcvarsPath + "\"";  
    //3.2. chdir back to current  
    cmd += " && ";  
    cmd += "CD /D \"" + strCurrentDir.replace("/","\\") + "\"";  
    //3.3. call exeName with args  
    cmd += " && ";  
    cmd += "\"" + exeDir + "\\" + exeName + "\" ";  
  
    for(int i=1;i<argc;++i)  
        cmd += argv[i] + QString(" ");  
  
    settings.setValue("SETTINGS/VCVARS",vcvarsPath);  
    settings.setValue("SETTINGS/EXEDIR",exeDir);  
  
    //4. display and exe the cmd  
    puts(cmd.toStdString().c_str());  
    int ret = system(cmd.toStdString().c_str());  
    a.exit(0);  
    return ret;  
}
##3.3 midl.exe.Ini file to specify path to VC and SDK
[SETTINGS]  
VCVARS=C:\\Microsoft Visual Studio 10.0\\VC\\bin\\vcvars32.bat  
EXEDIR=C:\\Program Files (x86)\\Windows Kits\\8.1\\bin\\x86  
Put midl.exe and midl.exe.ini to mingw32/bin or mingw64/bin, all problems is 
finished.
OK! We can build ActiveX project in MSYS2 Now!

Attachment: midl.cpp
Description: Binary data

Attachment: midl.exe.ini
Description: Binary data

Attachment: midl.pro
Description: Binary data

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Msys2-users mailing list
Msys2-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/msys2-users

Reply via email to