| 1 | /* $Id: Porting.txt,v 1.2 2000-08-11 10:54:06 sandervl Exp $ */
 | 
|---|
| 2 | 
 | 
|---|
| 3 |             Porting Win32 applications to OS/2 using Odin - 991212
 | 
|---|
| 4 |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
|---|
| 5 | 
 | 
|---|
| 6 | 1.0 Introduction
 | 
|---|
| 7 | ----------------
 | 
|---|
| 8 | 
 | 
|---|
| 9 | Although Odin's primary goal is to run win32 applications in OS/2 without
 | 
|---|
| 10 | requiring a recompile, it is possible to port Win95/98/NT apps to OS/2
 | 
|---|
| 11 | with minimal effort.
 | 
|---|
| 12 | This is the first draft of this porting guide. If anything is unclear or
 | 
|---|
| 13 | not mentioned, please contact the author (sandervl@xs4all.nl)
 | 
|---|
| 14 | 
 | 
|---|
| 15 | 1.1 Odin32
 | 
|---|
| 16 | -----------
 | 
|---|
| 17 | 
 | 
|---|
| 18 | Odin32 is the win32 compatible API provided with the Odin alpha (or daily builds).
 | 
|---|
| 19 | It's consists of hundreds of win32 APIs in several dlls (kernel32, user32, gdi32 etc).
 | 
|---|
| 20 | Keep in mind that Odin is still alpha software, so don't expect all apis to
 | 
|---|
| 21 | work exactly like those in Windows NT.
 | 
|---|
| 22 | If you find bugs, please contact the developers or send an email to the 
 | 
|---|
| 23 | Odin programmers mailinglist (win32os2-wai@egroups.com).
 | 
|---|
| 24 | 
 | 
|---|
| 25 | 1.2 Required tools for porting win32 apps to OS/2
 | 
|---|
| 26 | -------------------------------------------------
 | 
|---|
| 27 | - IBM VisualAge C++ 3.08
 | 
|---|
| 28 | - OS/2 Warp 4 Toolkit (project apparently doesn't compile with 
 | 
|---|
| 29 |   VAC's OS/2 headers)
 | 
|---|
| 30 |   Might also work with EMX headers. (haven't tried this)
 | 
|---|
| 31 | - ALP 4.0 (IBM Assembly Language Processor)
 | 
|---|
| 32 |   Download the tools zipfile from http://service.boulder.ibm.com/ddk/
 | 
|---|
| 33 |   (you need to register, but it's free)
 | 
|---|
| 34 | 
 | 
|---|
| 35 | It should also be possible to use Watcom or EMX to do the job, but you might
 | 
|---|
| 36 | need to make some changes to our headers to make this work.
 | 
|---|
| 37 | 
 | 
|---|
| 38 | 2.0 Porting Win32 applications to OS/2
 | 
|---|
| 39 | --------------------------------------
 | 
|---|
| 40 | In order to port win32 apps a few things have to be done:
 | 
|---|
| 41 | - Change all the makefiles for VAC (or any other OS/2 compiler)
 | 
|---|
| 42 | - Use Wine RC (wrc.exe) to compile the resources
 | 
|---|
| 43 | - Add the Odin executable and/or dll wrapper files to the project
 | 
|---|
| 44 | - Change the source code in case of compile problems
 | 
|---|
| 45 | 
 | 
|---|
| 46 | 2.1 Changing the makefile(s)
 | 
|---|
| 47 | ----------------------------
 | 
|---|
| 48 | This will probably be the most time consuming (and boring) part of the port.
 | 
|---|
| 49 | You have to make sure all compiler options are correct for the project and
 | 
|---|
| 50 | make some changes for compiling the resource script. (see 2.2)
 | 
|---|
| 51 | 
 | 
|---|
| 52 | To build the ported application, you must link with the necessary Odin libraries
 | 
|---|
| 53 | in your makefile. These libraries (i.e. kernel32.lib, user32.lib etc) are
 | 
|---|
| 54 | built when compiling Odin itself.
 | 
|---|
| 55 | 
 | 
|---|
| 56 | Paragraph 2.6 contains a skeleton makefile.
 | 
|---|
| 57 | 
 | 
|---|
| 58 | 2.2 Wine's resource compiler (wrc)
 | 
|---|
| 59 | ----------------------------------
 | 
|---|
| 60 | Wrc must be used to compile the resources of the win32 project.
 | 
|---|
| 61 | Unfortunately wrc isn't completely compatible with Microsoft's rc.exe.
 | 
|---|
| 62 | You might need to make some changes to the resource script in order to
 | 
|---|
| 63 | make wrc happy.
 | 
|---|
| 64 | 
 | 
|---|
| 65 | Wrc produces an assembly file with the a resource tree and binary resources.
 | 
|---|
| 66 | This resembles the resource section in win32 (PE) executables/dlls.
 | 
|---|
| 67 | This assembly file should be added to the list of objects files in the makefile.
 | 
|---|
| 68 | 
 | 
|---|
| 69 | 2.3 Odin's entrypoint wrappers
 | 
|---|
| 70 | ------------------------------
 | 
|---|
| 71 | Kernel32 keeps track of all loaded executables and dlls. The PE loader makes
 | 
|---|
| 72 | sure image objects are created when loading a win32 executable.
 | 
|---|
| 73 | A ported win32 app must do this manually by calling certain kernel32 exports.
 | 
|---|
| 74 | 
 | 
|---|
| 75 | In the src\Odin32API directory of the Odin CVS tree, you'll find two wrappers:
 | 
|---|
| 76 | - odinexe.cpp: Executable entrypoint (main)
 | 
|---|
| 77 | - odindll.cpp: Dll entrypoint (_DLL_InitTerm)
 | 
|---|
| 78 | 
 | 
|---|
| 79 | The executable wrapper calls RegisterLXExe (exported api in kernel32) to create
 | 
|---|
| 80 | an executable object and tell kernel32 where to find it's win32 entrypoint
 | 
|---|
| 81 | (usually WinMain) and resources.
 | 
|---|
| 82 | The dll version does the same thing. It calls RegisterLXDll to create the dll
 | 
|---|
| 83 | object during a dll load and UnregisterLXDll when the dll is unloaded.
 | 
|---|
| 84 | It's parameters are the dll module handle, the win32 dll entrypoint (LibMain)
 | 
|---|
| 85 | and, again, a pointer to the resource object. (as produced by wrc)
 | 
|---|
| 86 | The resource pointer can be NULL.
 | 
|---|
| 87 | The handle returned by RegisterLxDll must be used when calling UnregisterLxDll.
 | 
|---|
| 88 | 
 | 
|---|
| 89 | In the skeleton dll entrypoint we also call ctordtorInit/Term to create/destroy
 | 
|---|
| 90 | and static C++ objects.
 | 
|---|
| 91 | If you don't link with odincrt.lib for the runtime C/C++ functions, you must
 | 
|---|
| 92 | also call CRT_init/CRT_term (before _ctordtorInit, after ctordtorTerm).
 | 
|---|
| 93 | 
 | 
|---|
| 94 | After RegisterLXExe/Dll has finished it's job in kernel32, it will
 | 
|---|
| 95 | call the exe/dll entrypoint.
 | 
|---|
| 96 | 
 | 
|---|
| 97 | 2.4 Win32 source code changes
 | 
|---|
| 98 | -----------------------------
 | 
|---|
| 99 | Usually you shouldn't have to make many changes to the existing win32
 | 
|---|
| 100 | source code. 
 | 
|---|
| 101 | However, there might be a few differences between the MS SDK and Odin
 | 
|---|
| 102 | headers. If you find such problems, please correct them and notify
 | 
|---|
| 103 | the Odin developers.
 | 
|---|
| 104 | 
 | 
|---|
| 105 | Complex applications might be hard to port to OS/2 for several reasons:
 | 
|---|
| 106 | - Compiler differences (i.e. VAC 3.08 doesn't support unnamed unions)
 | 
|---|
| 107 |   VAC 3.6.5 should be a better choice for compiling win32 sources, but 
 | 
|---|
| 108 |   it has it's own share of problems (bugs).
 | 
|---|
| 109 | - TLS (thread local storage) data; VAC has no facilities to support this,
 | 
|---|
| 110 |   so this could require a major rewrite.
 | 
|---|
| 111 |   Other compilers (Watcom) may have better support for this.
 | 
|---|
| 112 |   You can recognize this type of data by the __declspec(thread) keyword.
 | 
|---|
| 113 |   Using the TLS apis (i.e. TlsAlloc) is no problem.
 | 
|---|
| 114 | - OLE/COM objects. Wine headers aren't exactly built with C++ in mind, 
 | 
|---|
| 115 |   so you'll most likely run into a lot of problems if the app uses
 | 
|---|
| 116 |   these win32 features.
 | 
|---|
| 117 | 
 | 
|---|
| 118 | 2.5 Exception handling
 | 
|---|
| 119 | ----------------------
 | 
|---|
| 120 | 
 | 
|---|
| 121 | RegisterLXExe/RegisterLXDll in kernel32 registers an exception handler
 | 
|---|
| 122 | for Odin. This handler is used to support file mappings.
 | 
|---|
| 123 | You must make sure that your code doesn't remove this handler from
 | 
|---|
| 124 | the chain of exception handlers. 
 | 
|---|
| 125 | To create a thread, use CreateThread; not _beginthread or DosCreateThread.
 | 
|---|
| 126 | CreateThread takes care of setting up an exception handler, creates TLS
 | 
|---|
| 127 | structures and calls dll entrypoints. 
 | 
|---|
| 128 | 
 | 
|---|
| 129 | 2.6 Sample makefile
 | 
|---|
| 130 | -------------------
 | 
|---|
| 131 | This makefile is used to compile the MS SDK generic sample in OS/2:
 | 
|---|
| 132 | 
 | 
|---|
| 133 | PDWIN32_INCLUDE = k:\source\odin32\include
 | 
|---|
| 134 | PDWIN32_LIB = k:\source\odin32\lib
 | 
|---|
| 135 | PDWIN32_BIN = k:\source\odin32\bin
 | 
|---|
| 136 | 
 | 
|---|
| 137 | !include $(PDWIN32_INCLUDE)/pdwin32.mk
 | 
|---|
| 138 | 
 | 
|---|
| 139 | PROJ = GENERIC
 | 
|---|
| 140 | 
 | 
|---|
| 141 | all: $(PROJ).exe
 | 
|---|
| 142 | 
 | 
|---|
| 143 | RC = wrc
 | 
|---|
| 144 | RCFLAGS = -s -I. -I$(CPPMAIN)\include -I$(PDWIN32_INCLUDE) -I$(PDWIN32_INCLUDE)\win
 | 
|---|
| 145 | 
 | 
|---|
| 146 | # Define project specific macros
 | 
|---|
| 147 | PROJ_OBJS  = generic.obj 
 | 
|---|
| 148 | BASE_OBJS  = resource.obj odinexe.obj 
 | 
|---|
| 149 | EXTRA_LIBS = $(PDWIN32_LIB)\version.lib
 | 
|---|
| 150 | GLOBAL_DEP = generic.h resource.h
 | 
|---|
| 151 | RC_DEP     = resource.h
 | 
|---|
| 152 | 
 | 
|---|
| 153 | 
 | 
|---|
| 154 | CFLAGS           = -Q  -Si -Ti -Tm+ -Ge- -Ss+ -W3 -Gm+ /Gn+ -I$(PDWIN32_INCLUDE)\Win -D__WIN32OS2__ -DDEBUG -D__i386__
 | 
|---|
| 155 | CXXFLAGS         = -Q  -Si -Ti -Tm+ -Ge- -Ss+ -W3 -Gm+ /Gn+ -I$(PDWIN32_INCLUDE)\Win -D__WIN32OS2__ -DDEBUG -D__i386__
 | 
|---|
| 156 | 
 | 
|---|
| 157 | CFLAGS = $(CFLAGS) /Ge+ -I$(PDWIN32_INCLUDE)
 | 
|---|
| 158 | CXXFLAGS = $(CXXFLAGS) /Ge+ -I$(PDWIN32_INCLUDE)
 | 
|---|
| 159 | LDFLAGSEXE = $(LDFLAGS) /Ge+ /B"/pmtype:pm /stack:0x30000 /NOBASE /Map" \
 | 
|---|
| 160 |              $(EXTRA_LIBS) $(PDWIN32_LIB)\kernel32.lib $(PDWIN32_LIB)\user32.lib \
 | 
|---|
| 161 |              $(PDWIN32_LIB)\gdi32.lib os2386.lib $(PDWIN32_LIB)\odincrt.lib $(RTLLIB_O)
 | 
|---|
| 162 | 
 | 
|---|
| 163 | resource.obj: resource.asm
 | 
|---|
| 164 | 
 | 
|---|
| 165 | # Build rule for resource file
 | 
|---|
| 166 | resource.asm: $(PROJ).rc $(RC_DEP)
 | 
|---|
| 167 |     $(RC) $(RCFLAGS) -o resource.asm $(PROJ).rc 
 | 
|---|
| 168 | 
 | 
|---|
| 169 | # Build rule for EXE
 | 
|---|
| 170 | $(PROJ).EXE: $(BASE_OBJS) $(PROJ_OBJS) resource.asm
 | 
|---|
| 171 |         $(LD) $(LDFLAGSEXE) -Fe$@ $(PROJ_OBJS) $(BASE_OBJS)
 | 
|---|
| 172 | 
 | 
|---|
| 173 | # Build rule for help file
 | 
|---|
| 174 | #$(PROJ).hlp: $(PROJ).rtf $(PROJ).hpj
 | 
|---|
| 175 | #    $(hc) generic.hpj
 | 
|---|
| 176 | 
 | 
|---|
| 177 | 
 | 
|---|
| 178 | # Rules for cleaning out those old files
 | 
|---|
| 179 | clean:
 | 
|---|
| 180 |     del *.bak *.pdb *.obj *.res *.exp *.map *.sbr *.bsc
 | 
|---|
| 181 | 
 | 
|---|
| 182 | 
 | 
|---|
| 183 | 3.0 Project participation
 | 
|---|
| 184 | -------------------------
 | 
|---|
| 185 | 
 | 
|---|
| 186 | As ODIN became an open source project, everybody is kindly invited to 
 | 
|---|
| 187 | contribute his/her share to the progress of the project. May it be
 | 
|---|
| 188 | active coding, fixing bugs or just providing detailed information about 
 | 
|---|
| 189 | examined problems.
 | 
|---|
| 190 | 
 | 
|---|
| 191 | We suggest you subscribe to win32os2-wai and the corresponsing mailing lists
 | 
|---|
| 192 | on http://www.egroups.com.
 | 
|---|
| 193 | In case you are interested in participating, every member of the project will 
 | 
|---|
| 194 | be happy to give you direction to the right places and to give a personal 
 | 
|---|
| 195 | introduction to further development of the particular modules.
 | 
|---|
| 196 | 
 | 
|---|