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!
midl.cpp
Description: Binary data
midl.exe.ini
Description: Binary data
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 [email protected] https://lists.sourceforge.net/lists/listinfo/msys2-users
