Saturday 29 August 2015

Building icu statically for linkage to Qt

It's bad enough having to link to all the Qt dll's without having to distribute its various dependencies as well - OpenSSL and  ICU chiefly among them. Then if you write a dll that plugs into someone else's exe you need to watch out that you could be trying to load a different version of a dependency dll that's used elsewhere in the exe.

So using static libs of the dependencies to link when you build Qt should help a lot. OpenSSL has some nice well-maintained static windows binaries (https://www.openssl.org/related/binaries.html), but icu does not.

There is this: http://www.npcglib.org/~stathis/blog/precompiled-icu/

But it uses static runtimes. So if you want a static build with dynamic (MD) runtimes, you're out of luck.

Building with Visual Studio

The Visual Studio solution all_in_one.sln that comes with ICU only builds dynamic libs. So you can modify the projects in the solution to link statically. Make sure that the output debug libraries have a suffix 'd' to their filenames, because they'll be built in the same directory as the release libraries.

Building with make

The recipe to build static ICU with MSVC is:

cd "%WORKSPACE%\source\"
set PATH=C:\cygwin\bin;%PATH%
call "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" x86
dos2unix -f *
dos2unix -f configure
dos2unix -f mkinstalldirs

bash runConfigureICU Cygwin/MSVC -prefix=/cygdrive/d/Jarvis/icu_static/dist -enable-static -disable-shared
dos2unix -f install-sh

make && make install


Dos2unix prevents errors of the form '\r unknown command' in the make script.

Path order is crucial. If you call vcvarsall.bat before adding cygwin\bin to the path, you'll get something like:

icupkg: unable to open input file
/cygdrive/d/icu/win32-x86/data/out/build/icudt55l\coll\root.res"

But if you add cygwin/bin after %PATH%, you'll get something like:

link.exe is not a valid executable.

So only the above order works.

Output

You'll get these files in lib (for Win32) or lib64 (for x64):

icudt.lib icuin.lib
icuio.lib
icule.lib
iculx.lib
icutest.lib
icutu.lib
icuuc.lib
testplug.lib

and for debug:
icudtd.lib icuind.lib
icuiod.lib
iculed.lib
iculxd.lib icutestd.lib
icutud.lib
icuucd.lib testplugd.lib

When you come to build Qt, set an ICU environment variable to the parent icu directory, and in the Qt make command add the options:

-icu -I "%ICU%\include" -L "%ICU%\%LIB_OR_LIB64%"

where LIB_OR_LIB64 is "lib" or "lib64" depending on the platform.

Thursday 20 August 2015

Help Qt Designer to find plugins

Qt Designer can't find plugins without QT_PLUGIN_PATH being set. You should also set QT_QPA_PLATFORM_PLUGIN_PATH for the Qt gui applications. If you're writing your own Qt exe, you can set these paths internally.
set QTDIR=C:/Qt/qt5_msvc2012_x64_build/qtbase
set QT_PLUGIN_PATH=%QTDIR%/plugins
set QT_QPA_PLATFORM_PLUGIN_PATH=%QTDIR%/plugins/platforms
Note also that Qt Designer will only load plugins built with the same libraries. And when you do a debug build of Qt, although it appends "d.dll" to its dll's, it does not append "d" to its executables. So a debug build of Qt Designer, in the same Qt distribution as release, will overwrite the release build, thus preventing your plugins from loading! So always build debug first, then release.

Cygwin connecting by ssh to remote Linux

If ssh can't add your server to its list of known hosts, you may need to create a "passwd" file in C:\cygwin\etc. Use:

mkpasswd -l -p "$(cygpath -H)" > /etc/passwd

Thursday 6 August 2015

Using Sublime Text Search+Replace to clean Visual Studio Projects

The find-in-files functionality of Sublime Text can be used to find end remove bad settings from Visual Studio project files - handy if you have a lot of projects.

Search for: <ShowProgress>LinkVerboseLib</ShowProgress>\n
and replace it with nothing. That hides a lot of unneeded output.

Replace:

<LinkLibraryDependencies>true</LinkLibraryDependencies>

with
<LinkLibraryDependencies>false</LinkLibraryDependencies>

To stop MSBuild from linking stuff you don't want lunk.