Using CMake + Mingw to Cross-Compile Windows Apps.

As promised, here’s the second part of the tutorial on how to use cmake to build Qt4/OpenSSL Apps for Windows using mingw on Linux.

Assumptions :

1. You already followed the tutorial on how to setup Qt4/OpenSSL using mingw.
2. You have cmake installed.
3. You have a working wine setup or a way to test the executables.

Part 0 : Setup Wine

You can ignore this if you will test on windows.

  1. Run winecfg, go to Drives, add drive and set the path to your win32 dev (we will use the letter G for this).
  2. Run wine regedit, go to HKEY_LOCAL_MACHINE -> System -> Session Manager -> Enviroment -> edit PATH and append G:\qt-win-opensource-src-4.5.3\;G:\openssl-0.9.8l to the end.

Part 1 : Custom CMake Rules

We need to create a custom cmake rules file, we will name it lin-mingw.cmake for now :

if(WIN32)
	#We haven't built Qt with debug support, so no point setting debug flags.
	set(CMAKE_BUILD_TYPE "Release")
	ADD_DEFINITIONS(${QT_DEFINITIONS})
	SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG)

	#set the default pathes, should be changed to match your setup.
	set(WIN32_BASE /home/dev/win32/)
	set(QT_BASE ${WIN32_BASE}/qt-win-opensource-src-4.5.3)
	set(OSSL_BASE ${WIN32_BASE}/openssl-0.9.8l)
	set(APP_ICON_RC ${CMAKE_CURRENT_SOURCE_DIR}/win32_icon.rc)

	set(MINGW_PREFIX "i686-pc-mingw32-")

	# set "sane" default cxxflags for windows, the -mwindows so it wouldn't open a command dos window.
	set(CMAKE_CXX_FLAGS_RELEASE  "${CMAKE_CXX_FLAGS_RELEASE} -march=pentium4 -mtune=pentium4 -mwindows -O2")
	# we need -static-libgcc otherwise we'll link against libgcc_s_sjlj-1.dll.
	SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "-Wl,--no-undefined -static-libgcc -Wl,-O1 -Wl,--as-needed -Wl,--sort-common -s")

.............. etc etc ............

Download the file.

Part 2 : Summon the Devil aka Call The Custom Rules

Now we need to call our custom rules file from CMakeLists.txt :

project(Qt4OsslMingwExample)
cmake_minimum_required(VERSION 2.6)
find_package(Qt4 COMPONENTS QtCore QtGui REQUIRED)
find_package(OpenSSL REQUIRED)

include(lin-mingw.cmake)

set(SRCS     "main.cpp")
SET(UI_SRCS  "tut.ui")
SET(MOC_HDRS "ossltestapp.h")
#SET(QRC_SRC  "icons.qrc")

QT4_WRAP_UI(UI_H ${UI_SRCS})
#Qt4 wrapper for moc files, aka for files that use the Q_OBJECT macro
QT4_WRAP_CPP(MOC_H ${MOC_HDRS})
#Icon resources, we don't have any so we can skip this.
#QT4_ADD_RESOURCES(QRC_H ${QRC_SRC})

include_directories(${CMAKE_CURRENT_BINARY_DIR} ${QT_INCLUDES} ${OPENSSL_INCLUDE_DIR})
#it is safe to include ${WIN32_ICON_O}, if we're building for linux it'll be empty.
add_executable(hello-world ${UI_H} ${MOC_H} ${QRC_H} ${SRCS} ${WIN32_ICON_O})
target_link_libraries(hello-world ${QT_LIBRARIES} ${OPENSSL_LIBRARIES})

This way we don’t polute CMakeLists.txt with all code which most likely will be the same for all the projects dpeending on it.

Part 3 : Testing it all

I created an example project, you can download it here.

cd $SOMEWHERE
wget http://www.limitlessfx.com/uploads/qt4+ossl+mingw+example.zip
unzip qt4+ossl+mingw+example.zip
cd qt4+ossl+mingw+example
# Build for Win32
cd build-win32
cmake .. -DWIN32=1
make
wine hello-world.exe
# Build for Linux
cd ../build-linux
cmake ..
make
./hello-world


Conclusion : If you are willing to spend some time setting this up, you won’t need Windows to build your apps.

Wait for the next part on how to use NSIS to create Windows Installers.

Tags: , , , , , , , ,

4 Responses to “Using CMake + Mingw to Cross-Compile Windows Apps.”

  1. h4tr3d Says:

    There is more simple way:
    1. create ToolChain file, like described on Cmake Wiki: http://www.cmake.org/Wiki/CmakeMingw
    2. Before ”find_package(Qt4 REQUIRED)” add:
    if(CMAKE_CROSSCOMPILING)
    set(QT_HEADERS_DIR “/usr/i486-mingw32/include”)
    set(QT_LIBRARY_DIR “/usr/i486-mingw32/lib”)
    endif()

    Enjoy! :-)

    PS I describe it on Russian: http://hatred.homelinux.net/wiki/zhurnal/2010-05-26_16.32_cmake_qt4_i_kross-kompiljacija

  2. OneOfOne Says:

    Thank you, I’ll work that into my new tutorial.

  3. semepe Says:

    What if I want to have my binary (exe) static linked?

  4. OneOfOne Says:

    You will have to redo the wine/qt4 process with -static passed to qt4 and append -static to the LD FLAGS, however I’m not sure how to do the OpenSSL part.

Leave a Reply