Building my first Windows application in Wine [Draft]
Why am I doing this? To determine if Windows’ HTML Help API function HtmlHelp() allows an incorrect pzrURL parameter where backslashes rather than forward slashes are used after the ::
delimiter, e.g.:
C:\Program Files\My App\Helpfile.chm::\Html\Overview\Topic.htm
(incorrect) vsC:\Program Files\My App\Helpfile.chm::/Html/Overview/Topic.htm
(correct)
(TODO: write a separate blog article about it.)
Basic steps
(Note: I did not have Wine installed to system paths…)
- Save the sample Windows application source code, e.g., as
hello.cpp
- Make sure wineg++ and winemaker are in the path.
- Use
winemaker .
to generate a Makefile - Edit Makefile: Add appropriate compiler flags, include paths and library paths, etc.
- Run
make
. Fix problems as they arise. - Test by running
hello_world.exe
(sh wrapper) directly, or by running~/wine-dirs/wine-build/wine hello_world.exe.so
.
Actually doing it
Fetch the source code
Scroll down to “Example > Code”, copy and paste the code listing, and save it as hello.cpp
(original name: GT_HelloWorldWin32.cpp
).
Prepare Makefile
First, generate an initial Makefile with the command winemaker .
Then, edit Makefile and modify the variables under ### Common settings
:
Set
DEFINES
to-D_UNICODE -DUNICODE -DWIN32 -D_WINDOWS
(per instruction in the header ofGT_HelloWorldWin32.cpp
)Set
INCLUDE_PATH
to-I$(HOME)/wine-dirs/wine-source/include -I$(HOME)/wine-dirs/wine-build/include
(Some Wine include files are generated during build time. Also, note that tilde expansion does not work here, so$(HOME)
rather than~
.)Set
DLL_PATH
to-L$(HOME)/wine-dirs/wine-build/dlls
Set
LIBRARY_PATH
to-L$(HOME)/wine-dirs/wine-build/libs/wine
Deal with compilation errors
In file included from hello.cpp:7:0:
../wine-source/include/tchar.h:27:2: error: #error You must use msvcrt when building in Unicode/MBCS mode
#error You must use msvcrt when building in Unicode/MBCS mode
^
But how do I use “use msvcrt”?
- Searching the error message yields this post: https://www.winehq.org/pipermail/wine-devel/2012-July/096607.html
- -mno-cygwin
- Use Wine implementation of MSVCRT, instead of linking against the host system libc. This is necessary for the vast majority of Win32 applications, as they typically depend on various features of MSVCRT. This switch is also used by the MinGW compiler to link against MSVCRT on Windows, instead of linking against Cygwin libc. Sharing the syntax with MinGW makes it very easy to write Makefiles that work under Wine, MinGW+MSYS, or MinGW+Cygwin.
https://www.winehq.org/docs/winegcc
-mno-cygwin
… the-mno-cygwin
flag did not work for me… not sure what I was doing wrong… incomplete build environment so it cannot find an alternativetchar.h
? Or-mno-cygwin
does not come into effect during the compilation stage?After reading this: http://forums.miranda-im.org/showthread.php?4624-Miranda-on-Linux&s=eccf29c4b45a41ab7d8a444ae60202fb&p=71372#post71372 (from http://forums.miranda-im.org/showthread.php?4624-Miranda-on-Linux&s=eccf29c4b45a41ab7d8a444ae60202fb&p=71372#post71372), I decided to simply make a local copy of
tchar.h
and remove the offending lines therein.After reading https://www.winehq.org/pipermail/wine-devel/2012-July/096607.html and https://www.winehq.org/pipermail/wine-devel/2004-October/030349.html again, I finally realized that the correct solution is to do the following:
Patch ~/wine-dirs/wine-source/include/tchar.h:
diff –git a/include/tchar.h b/include/tchar.h index 38885d4..13c8ee6 100644 — a/include/tchar.h +++ b/include/tchar.h @@ -23,8 +23,8 @@ #error Wine should not include tchar.h internally #endif
-#if defined(_UNICODE) || defined(_MBCS) -#error You must use msvcrt when building in Unicode/MBCS mode +#if !defined(MSVCRT) && (defined(_UNICODE) || defined(_MBCS)) +#error You must use msvcrt when building in Unicode/MBCS mode [-mno-cygwin] #endif
#ifdef __cplusplus
Add
-mno-cygwin
flag toCXXEXTRA
(CEXTRA already has-mno-cygwin
, but we are compiling a C++ program, and the CEXTRA variable is not used.)
So, yay! The -mno-cygwin
flag does work according to winegcc’s man page.
Reporting the bug upstream
See https://bugs.winehq.org/show_bug.cgi?id=39904
More errors
In file included from ../wine-source/include/windows.h:40:0,
from hello.cpp:4:
hello.cpp: In function 'int WinMain(HINSTANCE, HINSTANCE, LPSTR, int)':
../wine-source/include/winuser.h:737:58: error: cast from 'LPWSTR {aka wchar_t*}' to 'WORD {aka short unsigned int}' loses precision [-fpermissive]
#define MAKEINTRESOURCEW(i) (LPWSTR)((ULONG_PTR)((WORD)(i)))
^
Add -fpermissive
to CXXEXTRA to fix this.
References
Unsorted but useful:
- Module 1. Your First Windows Program
- Get a developer license
- Visual C++ in Visual Studio 2015 > In Visual Studio 2015, Visual C++ is not installed by default. When installing, be sure to choose Custom installation and then choose the C++ components you require. Or, if Visual Studio is already installed, choose File | New | Project | C++ and you will be prompted to install the necessary components.