How to deploy Qt application on MacOs

Missing dylib libraries

If your application using some externals dynamic libraries (called .dylib in MacOs system), you have to provide all these libraries. The simplest way is to provide these libraries into the Application.app directory.

Find out which libraries are used

Qt provide really useful tool called “otool” which serves to lots of purpose. One of them is to detect which shared libraries are required by our application. For this purpose otool has parameter -L. The usage is following:

otool -L ./Test1.app/Contents/MacOS/Test1

Output could looks like this:

./Test1:
        libboost_iostreams.dylib (compatibility version 0.0.0, current version 0.0.0)
        libboost_filesystem.dylib (compatibility version 0.0.0, current version 0.0.0)
        libboost_system.dylib (compatibility version 0.0.0, current version 0.0.0)
        libboost_thread.dylib (compatibility version 0.0.0, current version 0.0.0)
        libboost_date_time.dylib (compatibility version 0.0.0, current version 0.0.0)
        libboost_regex.dylib (compatibility version 0.0.0, current version 0.0.0)
        /Users/dev/dev/SharedLibraries/libiconv/lib/libiconv.2.dylib (compatibility version 8.0.0, current version 8.0.0)
        /Users/dev/dev/ExternalLibraries/../SharedLibraries/libxml/lib/libxml2.2.dylib (compatibility version 10.0.0, current version 10.8.0)
        /Users/dev/dev/ExternalLibraries/../SharedLibraries/libxslt/lib/libxslt.1.dylib (compatibility version 3.0.0, current version 3.26.0)
        /Users/dev/dev/ExternalLibraries/../SharedLibraries/libxslt/lib/libexslt.0.dylib (compatibility version 9.0.0, current version 9.15.0)
        /Users/dev/dev/ExternalLibraries/yaml-cpp-0.2.5/build/libyaml-cpp.0.2.dylib (compatibility version 0.2.0, current version 0.2.5)
        QtGui.framework/Versions/4/QtGui (compatibility version 4.7.0, current version 4.7.0)
        QtCore.framework/Versions/4/QtCore (compatibility version 4.7.0, current version 4.7.0)
        /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
        /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 625.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)

Output from “otool” is simmilar to linux tool “ldd”.

The Mac Deployment Tool

Because manual copying and configuring all shared libraries to our application could be difficult, Qt have deployment tool which do all work for us. Tool is called “macdeployqt” and can be found in /Developer/Tools/Qt/macdeployqt.

 /Developer/Tools/Qt/macdeployqt ./GeneratedFilesMacOs/Debug/Test1.app

Note: Every time when you call macdeployqt tool, project have to be build from scratch. But is sufficient when whole result directory is removed and linked again:

rm -rf ./GeneratedFilesMacOs/Debug/Test1.app/
make

g++ template method problem

Quick post about problem which I already solved, but think that could be handy for someone else.

I have following code:

template<class T>
struct Test
{
	T val;
	template <class T2>
	void DoSomething( T2 &obj )
	{
		obj.FindByType<int>();
	}
};

When compiling under Visual studio, everything is ok. But when try the same code snippet under g++, have following error:

test.cpp: In member function ‘void Test<T>::DoSomething(T2&)’:
test.cpp:48: error: expected primary-expression before ‘int’
test.cpp:48: error: expected ‘;’ before ‘int’

This is because compiler doesn’t known FindByType method, because T2 is templated argument. The solution which I found is in adding keyword template before FindByType method name. So updated source code will look like this:

template<class T>
struct Test
{
	T val;
	template <class T2>
	void DoSomething( T2 &obj )
	{
		obj.template FindByType<int>();
	}
};

After this update, code will be compiled correctly under both compilers.

TENG – c++ templating engine

Project site: http://teng.sourceforge.net/?page=home

External project documentation: http://teng.olmik.net/

Latest TENG source code: http://teng.cvs.sourceforge.net/teng/ (Note: Source code referenced from main site isn’t latest! )

How to compile TENG on windows

Compilation under Windows is possible only using MinGW and with few modifications in TENG code (because there is few glitch which didn’t meet c++ standards). If you want more information or updated TENG version, please let me know.

List of usefull links for Visual Studio

How to customize autoexp.dat in Visual Studio 2005

http://mariusbancila.ro/blog/?p=26
http://www.virtualdub.org/blog/pivot/entry.php?id=120

Example visualizator for XString

String::CStringSmart<String::malloc_string_trait<String::string_trait<char> > >{
  preview([$c.m_pszData,s])
  stringview([$c.m_pszData,sb])
}

String::CStringSmart<String::malloc_string_trait<String::string_trait<wchar_t> > >{
  preview([$c.m_pszData,su])
  stringview([$c.m_pszData,sub])
}

How to configure STEP-INTO for Visual Studio 2005

External links:
Google group
www.cprogramming.com

http://blogs.msdn.com/b/andypennell/archive/2004/02/06/69004.aspx

Example how to setup ingoring step-into for MFC CString for VS2005

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\NativeDE\StepOver]
"\"20\""="\\scope:CString.*\\:\\:.*=NoStepInto"
"\"21\""="\\scope:CSmartObjPtr.*\\:\\:.*=NoStepInto"

Example how to setup ingoring step-into for MFC CString for VS2010 on 64bit system

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0_Config\NativeDE\StepOver]
"22"=".*CStringSmart.*=NoStepInto"

Simple iconv (libiconv) example

Here is a simple example how to use the iconv library.

#include <iostream>
#include <fstream>
#include <iconv.h>

int main(int argc, char *argv[])
{
	char src[] = "abcčde";
	char dst[100];
	size_t srclen = 6;
	size_t dstlen = 12;

	fprintf(stderr,"in: %s\n",src);

	char * pIn = src;
	char * pOut = ( char*)dst;

	iconv_t conv = iconv_open("UTF-8","CP1250");
	iconv(conv, &pIn, &srclen, &pOut, &dstlen);
	iconv_close(conv);

	fprintf(stderr,"out: %s\n",dst);
}

During my attempts with libiconv library I encountered two different problems:

Converting function returns 0, but pOut is empty

This is because iconv function modify pOut ptr during string processing. When you need to access output buffer after iconv() function finish its work, you have to access it via different pointer than one passed to this function. In my code I’m using *dst and pOut ptrs;

Conversion between different character sets returns strange results

Check if have correct order of parameters in your iconv_open() and iconv() function. Function iconv_open() has as its first parameter OUTPUT encoding, and as second parameter INPUT encoding. While iconv() function has as first parameters INPUT variables, and as second parameters OUTPUT variables. This inconsistency is really confusing.

Notes

Official libiconv site: http://www.gnu.org/software/libiconv/

Official libiconv documentation: http://www.gnu.org/software/libiconv/documentation/libiconv-1.13/

How to compile open-source libraries under Windows using MinGW

Lots of open source libraries (like libiconv, libintl, …) doesn’t have MSVC project files or makefiles. Only supported way how to compile given library under Window is using MinGW and MSYS compiler tools.

Here is step-by-step guide how to download, install and compile libraries using MinGW.

Step one download MinGW

From MinGW home web site http://www.mingw.org/ download “Automated MinGW Installer”. Current version could be downloaded here: http://sourceforge.net/projects/mingw/files_beta/Automated MinGW Installer

Step two installing

Run downloaded executable. As install directory leave C:\MinGW. It’s recommended not to change this path.  On component screen select C compiler, C++compiler, MSYS Basic System and MinGW Developer Toolkit.

After that select next,next,next, finish ;-). After that installer downloads all necessary files. This could take a few minutes.

When installation is done, as next step is necessary to setup PATH variable to c:\MinGW. Installer doesn’t modify it automatically. (more info about modifying PATH variable) .

Installing additional gcc compiler and make support

These two packages isn’t listed in available components. If you wish to install it, use mingw-get-inst. In c:\MinGW\bin directory run following commands:

mingw-get install gcc g++ mingw32-make msys-base

Step three compiling

Compiling from windows shell

Launch cmd tool, go to directory with source code and use g++.

g++ test.cpp

Compiling from MinGW console

Launching MinGW console

Laung MinGW from startmenu or msys.bat from %INSTALL_PATH%\MinGW\msys\1.0\msys.bat.

How to compile libiconv library

As first, download latest libiconv source files from http://www.gnu.org/software/libiconv. And extract whole package somewhere on your disk.

Launch MinGW console and go to the extracted directory. When you extracted directory to the path:

p:\DependentLibrariesWhole\libiconv-1.13.1

Type following command to MinGW console:

cd /p/DependentLibrariesWhole/libiconv-1.13.1

after that, run configure with required library params (in our case we want static and dynamic version of library):

configure --enable-static --enable-shared

and than run make

make

Compiled libraries are located in directory “libiconv-1.13.1\lib\.libs”. There is  additional information about building libiconv library on stackoverflow.

Additional How to guides

This list is compilation of answer to questions and informations how to solve some problems which I had during my installations.

How to get list of available parameters for configure script?

Use “configure –help” command.