> 18 февр. 2017 г., в 10:23, goldenhawk...@163.com написал(а):
>
>
> 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!
Instead of wrapping MSVC midl you need use WIDL from mingw-w64
Your solution is not good for us. We don’t use any MSVC programs.
> <midl.cpp><midl.exe.ini><midl.pro>------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, SlashDot.org <http://slashdot.org/>!
> http://sdm.link/slashdot_______________________________________________
> <http://sdm.link/slashdot_______________________________________________>
> Msys2-users mailing list
> Msys2-users@lists.sourceforge.net <mailto:Msys2-users@lists.sourceforge.net>
> https://lists.sourceforge.net/lists/listinfo/msys2-users
> <https://lists.sourceforge.net/lists/listinfo/msys2-users>
------------------------------------------------------------------------------
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