Sunday, April 7, 2013

Wine for advanced users and developers (Build and run windows apps without using Windows)

http://www.linuxuser.co.uk/tutorials/wine-for-advanced-users-and-developers


While Linux has one of the largest software catalogues on the planet, there are still many software applications which are either only available for Windows or are only possible to make on Windows. For users, it means that they will miss out on some of their favourite software (for example, Microsoft Office and a lot of games). For developers it means losing a significant market to people who are using Linux. While most of the software can be written for both the platforms if you plan ahead, it becomes painfully difficult (and sometimes impossible) when the software is already written. This is where Wine comes to rescue.
For users, Wine provides a way of running Windows applications without any modification on a Linux system. For developers, it provides a way of making their applications work with Linux with maximum compatibility.

Wine

Before we dive into the tutorial, let’s understand what Wine is. Wine is not an emulator that emulates the Windows OS to run Windows applications. It is a compatibility layer for Windows applications on POSIX-compliant operating systems such as Linux, BSD and Mac OS X. It translates Windows API calls into POSIX calls on-the-fly. Being just a compatibility layer means that Wine runs applications at native performance. That’s not all: since it doesn’t need Windows to function, you won’t need a Windows licence to run Windows applications. In addition to the Windows compatibility, Wine provides open source implementations for some of the most sought-after APIs in the industry (like DirectX, ActiveX, DDE etc).
Wine helps Windows developers to bring their software to Linux in the following ways…
Direct binary execution: This is achieved with the tool called ‘wine’ (part of the Wine distribution). In this process, application source code is compiled on the Windows platform, and then the binary file is taken to the Linux system and is run through Wine. When the application is run with binary compatibility, it can use all existing .dll files. This process is pretty straightforward, but is not able to unleash the full power of the Wine subsystem. However, this is the only way to go if you do not have the access to the source code. You can also wrap Wine with your application to create an easy-to-use way to run it on the Linux platform.
Recompiling the application with Winelib: In this method the source code file is taken to the Linux box, where it is compiled against the Winelib libraries using GCC. This way, the application will also be able to catch up with UNIX API calls in order to leverage the full power of UNIX. Winelib ships with a tool called Winemaker, which creates a GNU standard autoconf-based makefile out of a VC++ project. Winemaker is a Perl script that does all the dirty work involved in converting the source code, making it UNIX specific, clearing up case issues and a lot more.

Winelib

Winelib is a software development kit for building Windows applications for Linux (and other POSIX operating systems). It includes the Win32 API implementation providing the necessary libraries and header files. It supports C/C++ and shares 100 per cent of its code with Wine.
Winelib is capable of building GUI applications, console applications and dynamic- link libraries (DLLs).
One of the biggest benefits Winelib provides is the ability to make calls to UNIX APIs directly from your Windows source code, resulting in better integration than with the direct binary execution method.
In this tutorial we will be using Winelib to compile a Visual C++ application on the Linux platform.

Resources

Mandatory development tools: GCC, G++, Make etc
Git: It is used by the Wine project as the primary source control system
Optional: Access to Windows system with Microsoft Visual Studio 2008 installed

Step by Step

Windows on Linux
Wine Notepad running in chrooted environment

Step 01

Rules of engagement
The first step to any porting project is to make sure your code is ready for the new platform. There are a few basic rules of thumb that apply to any application which is supposed to be ported. These cover some basic Windows and Linux operating environment differences. First, differences between DOS and UNIX text files must be fixed. Otherwise you may receive errors related to carriage returns and numerous other similar errors.
Then there’s the case of filenames. As you will probably be aware, kunal.c and Kunal.c are the same in a Windows environments, but not in Linux. So, the filenames used in include statements might be different from the original files you are actually referring to.
Include statements should avoid using ‘\’ – instead they should use ‘/’. ‘/’ is recognised in both the environments, but using ‘\’ may cause errors in UNIX.
Makefiles should be changed accordingly to fit into the new environment. Makefiles are not generally cross-platform compatible.
Sprinkle your code with #ifdefs. This good old technique can be used to isolate the platform- specific code in a very efficient manner.
#ifdef _WIN32
    // Windows (x64 and x86)
#elif __unix__ // all unix
    // Unix
#elif __posix__
    // POSIX
#elif __linux__
    // linux
#elif __APPLE__
    // Mac OSX code
#endif

Step 02

Building Wine
There is a very good chance that the Wine shipping with your favourite Linux distribution is outdated. That’s why we will build Wine directly from the source. This will allow us to build Wine to our liking.
NOTE: We are using Ubuntu 12.10 64-bit for this tutorial. If you are using any other 64-bit distribution you will need the respective package management command. If you are using Ubuntu 12.10 32-bit or any other 32-bit distribution, skip this – go directly to installing build dependencies.
Creating chroot for Wine: Since Wine depends upon a lot of 32-bit libraries, it is a good idea to build it in a chroot environment. A chroot is a way of isolating applications from the rest of your computer, by putting them in a jail. In this case we will set up a chroot with the 32-bit binaries and libraries.
Install the chroot packages
$ sudo apt-get install dchroot debootstrap
Create a directory which will hold the root of the chroot environment
$ sudo mkdir /var/chroot
Create chroot configuration for the
current distribution
@config file: /etc/schroot/schroot. conf
[quantal]
description=Quantal Quetzal directory=/var/chroot
users=kunal
groups=sbuild
root-groups=root
You’ll need to replace ‘Quantal’ with the name of the distro you are using. You will also need to replace ‘kunal’ with the correct username.
NOTE: The distribution name should be a valid distribution, else chroot environment will not be created. To find valid and supported distribution names, look in the directory /usr/share/debootstrap/scripts/.
Install the base system for your chroot
$ sudo debootstrap --variant=buildd --arch i386 quantal /var/chroot/ http://mirrors.us.kernel.org/ubuntu/
NOTE: You can replace the mirror with one of your liking, preferably nearby. A list of mirrors is located at https://launchpad.net/ubuntu/+archivemirrors. You will need to make sure that the mirror you are selecting contains the distribution you are chrooting.
Set up the Apt sources
$ sudo cp /etc/apt/sources.list / var/chroot/etc/apt/
Enter chroot and install the build dependencies
$ sudo chroot /var/chroot
# apt-get update
# apt-get build-dep wine
# apt-get install git
Install additional dependencies
# apt-get install libosmesa-dev ocl- icd-opencl-dev libhal-dev libxml- perl
Cloning the Wine Git
$ git clone git://source.winehq.org/ git/wine.git
Build and install Wine
We are now all set up to build Wine. # cd wine*
# ./configure
# make
# make install
Setting up the X-server
To make the GUI applications work from within the chrooted environment, you will need to set up the X-server:
On the system shell
$ xhost +
On the chrooted shell
# export DISPLAY=:0.0
You can now test the setup by running the following command
# wine notepad
Now you can use the chrooted environment for all your Wine-related activities.


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.

2 comments:

  1. Hello Sameh, how are you?! Very nice and informative article. I am pretty new to using winelib and have been trying to build my MFC GUI source with winelib, but because they didn't ship mfc90u.dll.so files I couldn't do that. I understand b-se of mfc licence issue (microsoft huh :( ) There is very little info on 'winehq' about creating your own winedlls using .spec file and function prototypes, but mfc library is so huge with many functions. I tried to use winedump & winebuild to create .spec file but it come empty. Tried convert mfc.def to mfc.spec but no success. I have my purchased copy of licensed MSVS2008 so have mfc90 source code.
    I wonder could you help with compiling mfc and creating mfc90u.dll.so winelib dlls.Or post article about it. Thanks !!!

    ReplyDelete
  2. Send me files and steps u followed with their output

    ReplyDelete