Official website for Linux User & Developer
FOLLOW US ON:
Mar
30

Wine for advanced users and developers

by Kunal Deo

Build and run windows apps without using Windows

Step 03

Porting Hello World Win32 application

In this step we will see what it takes to build a simple Hello World application in Linux using Wine.

The following example shows a message box with the text ‘Hello from Windows World!’.

hello.c
#include 
int WINAPI WinMain(HINSTANCE
hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShowCmd )
{
   MessageBox(NULL,TEXT(“Hello
from Windows
World!”),TEXT(“HelloMsg”),0);
   return 0;
}

Winelib ships with nice GCC wrappers which are compatible with the MinGW compiler. These wrappers are called winegcc and wineg++. This way if you have an application that uses the MinGW compiler on Windows, you can simply replace the gcc/g++/windres with winegcc/ wineg++/wrc .

To compile the application, we use the winegcc command:

# winegcc hello.c -o hello

Upon successful compilation, you will notice that it produces two files instead of just one. In this case…

hello.exe.so: This is the main binary of the application. But you cannot execute this directly. It is a shared object file that must be run using Wine. It is directly linked to the Wine library.

# ldd hello.exe.so
   linux-gate.so.1 =>  (0xf771d000)
   libwine.so.1 => /usr/local/lib/
libwine.so.1 (0xf75b9000)
   libc.so.6 => /lib/i386-linux-gnu/
libc.so.6 (0xf740f000)
   libdl.so.2 => /lib/i386-linux-
gnu/libdl.so.2 (0xf7409000)
   /lib/ld-linux.so.2 (0xf771e000)

hello.exe: Although it looks like the main output of the source, it is merely a script to launch the main application. You can modify hello.exe to customise the launch parameters. You can even specify a different version of Wine for use with the executable.

#!/bin/sh
appname=”hello.exe.so”
# determine the application
directory
appdir=''
case “$0” in
  */*)
    # $0 contains a path, use it
    appdir=`dirname “$0”`
    ;;
  *)
    # no directory in $0, search in
PATH
    saved_ifs=$IFS
    IFS=:
    for d in $PATH
    do
      IFS=$saved_ifs
      if [ -x “$d/$appname” ]; then appdir=”$d”; break; fi
    done
    ;;
esac
# figure out the full app path
if [ -n “$appdir” ]; then
    apppath=”$appdir/$appname”
    WINEDLLPATH=”$appdir:$WINEDLLPATH”
    export WINEDLLPATH
else
    apppath=”$appname”
fi
# determine the WINELOADER
if [ ! -x “$WINELOADER” ]; then
WINELOADER=”wine”; fi
# and try to start the app
exec “$WINELOADER” “$apppath” “$@”
Windows on Linux
Visual Studio 2008 New Project dialog

Step 04

Porting a bigger project using Winemaker

Winegcc is helpful if your application consists of only one file, but that isn’t usually the case. In most cases a Windows application consists of multiple source files as well as resource files. Winelib ships with a tool called Winemaker. It is capable of generating UNIX-compatible makefiles from Windows project source code. Winemaker is a very important tool in getting your first step (also the most difficult one) ready. It does all the dirty work for you, from fixing up files to creating a UNIX-compatible makefile. It is capable of fixing most of the issues mentioned in step 1 ‘Rules of engagement’.

Winemaker provides the following options to help you out with porting your code. These options customise the resultant makefile to suit your needs.

–lower-uppercase: This option deals with the cases of filenames and puts them in order.

–dll: This option instructs Winelib to build a DLL (dynamic-link library) project instead of a GUI project.

–console: This option directs Winelib to build a console application.

–mfc: This directs Winelib to build an MFC (Microsoft Foundation Class) library application. Please note that Wine does not ship with the MFC library; you will have to build it on your own with Winelib.

–nobackup: Winelib keeps a backup of files which it changes. If you already have this source code present somewhere else, you can use this option to save a lot of time and disk space.

-Idir: Specifies to include file directories. This option accepts paths to files in absolute format.

-Ldir: Specifies library file directories.

-idll: Directs Winelib to import a library file through the spec file mechanism.

-llibrary: Instructs Winelib to import UNIX library files

In this step we will take the default application built by Microsoft Visual Studio and try to compile it with Winemaker on Linux.

Creating the Win32 Application:

Open Microsoft Visual Studio 2008. Click File> New>Project…

From the New Project dialog box, select Visual C++>Win32. Then select Win32 Project. Give an appropriate Name for the project, Location and Solution Name. Then click OK. The Win32 Application Wizard will open.

Click Next to continue. On the Application Settings page, select the Application type as a Windows application. Leave the rest of the settings as is. Click Finish to create the project.

The finished project will now open in Visual Studio. Solution Explorer will show all the files created for the project.

As you can see, this is a fully featured project with multiple header files, source files and resource files. For this tutorial we need to modify the project itself. We would rather focus on porting part of this application.

Let’s run this application to see if everything is working perfectly. Click Build>Build Solution to build the project, then click Debug>Start Without Debugging.

Copy the LUDWin32Project directory to the chrooted folder, ie /var/chroot/. Then perform the following steps to create a UNIX makefile project using Winemaker:

cd into main project directory

# cd LUDWin32Project/ LUDWin32Project/

Run Winemaker to fix the source files and create UNIX makefiles:

# winemaker --lower-uppercase --nomfc .
Winemaker 0.8.3
Copyright 2000-2004 Francois Gouget  for CodeWeavers
Copyright 2004 Dimitrie O. Paun
Copyright 2009-2012 Andr Hentschel Scanning the source directories... Projectfile found! You might want to try using it directly.
Fixing the source files...
  LUDWin32Project.cpp
  LUDWin32Project.rc
  LUDWin32Project.h
  Resource.h
  stdafx.cpp
  stdafx.h
  targetver.h
Generating project files...
  .

The above command fixes the case-related issues with the source code. ‘-nomfc’ indicates that we do not want to use the MFC library with this project. As you can see in the out put above, it has located a project file (vcproj), but we will skip it for this tutorial as Visual Studio project files are not fully compatible with Winemaker.

Winemaker will fix the files and create .bak files for the modified files. It will also create the makefile which we can run against the standard GNU Make utility to build the application.

Makefile structure of a Winelib project:
Most of the time, the makefile generated with Winemaker will be a good fit for your project. However, for some advanced and complex applications, you might need to customise the makefile yourself. The following explains the very basic structure of a Winelib project.

Makefile generated by Winemaker

SRCDIR                = .
SUBDIRS               =
DLLS                  =
LIBS                  =
EXES                  =
ludwin32project
### Common settings
CEXTRA                = -mno-cygwin
CXXEXTRA              = -mno-cygwin
### Global source lists
C_SRCS                =
$(ludwin32project_C_SRCS)
CXX_SRCS              =
$(ludwin32project_CXX_SRCS)
RC_SRCS               =
$(ludwin32project_RC_SRCS)
### Tools
CC = winegcc
CXX = wineg++
RC = wrc
AR = ar

This is not a complete makefile, but the main options you should take a look at. However, most of the options will be filled by Winemaker itself.

Compile the project by issuing Make

# make
wineg++ -c  -mno-cygwin -I.   -o
LUDWin32Project.o LUDWin32Project.cpp
wineg++ -c  -mno-cygwin -I.   -o
stdafx.o stdafx.cpp
wrc   -I.   -foLUDWin32Project.res
LUDWin32Project.rc
wineg++ -mwindows -mno-cygwin -o
ludwin32project  LUDWin32Project.o
stdafx.o LUDWin32Project.res
-lodbc32 -lole32 -loleaut32
-lwinspool -lodbccp32 -luuid

As you can see, the correct compilers are used for respective files. For example, wineg++ is used for .cpp files, wrc (Wine Resource Compiler) is used for .rc files.

The ‘make’ command will produce ludwin32project.exe.so and ludwin32project.exe. Run the ludwin32project.exe file to start the ported application.

Windows on Linux
Solution Explorer with LUDWin32Project open

Step 05

Conclusion

Wine is one of the key technologies which can help you go Windows free. There are an enormous number of Windows applications that just work on Wine without developer support – see the full list at the Wine HQ. If your application is not on that list, you can use Winelib to port your application natively to Linux. It will have the same performance as any other native application. Winelib is very easy to use, especially with a tool like winemaker which takes care of much of the standard porting issues by itself. So, if you are a Windows developer avoiding the Linux platform because you thought it was too much work, it’s time to give Wine a try.

This tutorial was originally published in Linux User & Developer 123. You can get our latest issue, and subscriptions, from our online shop.

Pages: 1 2
  • Tell a Friend
  • Follow our Twitter to find out about all the latest Linux news, reviews, previews, interviews, features and a whole more.