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 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 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.
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
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.
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
current distribution
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
Set up the Apt sources
To make the GUI applications work from within the chrooted environment, you will need to set up the X-server:
On the system shell
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!’.
To compile the application, we use the winegcc command:
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.
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
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
Compile the project by issuing Make
The ‘make’ command will produce ludwin32project.exe.so and ludwin32project.exe. Run the ludwin32project.exe file to start the ported application.
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.
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 etcGit: 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
Step 01
Rules of engagementThe 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 WineThere 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.
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 debootstrapCreate a directory which will hold the root of the chroot environment
$ sudo mkdir /var/chrootCreate 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=rootYou’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 gitInstall additional dependencies
# apt-get install libosmesa-dev ocl- icd-opencl-dev libhal-dev libxml- perlCloning the Wine Git
$ git clone git://source.winehq.org/ git/wine.gitBuild and install Wine
We are now all set up to build Wine. # cd wine* # ./configure # make # make installSetting 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.0You can now test the setup by running the following command
# wine notepadNow you can use the chrooted environment for all your Wine-related activities.
Step 03
Porting Hello World Win32 applicationIn 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 #includeWinelib 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 .int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) { MessageBox(NULL,TEXT(“Hello from Windows World!”),TEXT(“HelloMsg”),0); return 0; }
To compile the application, we use the winegcc command:
# winegcc hello.c -o helloUpon 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” “$@”
Step 04
Porting a bigger project using WinemakerWinegcc 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.
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 GougetThe 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.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... .
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 = arThis 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 -luuidAs 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.
Step 05
ConclusionWine 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.
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.
ReplyDeleteI wonder could you help with compiling mfc and creating mfc90u.dll.so winelib dlls.Or post article about it. Thanks !!!
Send me files and steps u followed with their output
ReplyDelete