######################################################################
#
#          Top-Level Makefile for Building Python for OS/2
#
# This makefile was developed for use with IBM's VisualAge C/C++
# for OS/2 compiler, version 3.0, with Fixpack 8 applied.  It uses
# version 4.0 of the NMAKE tool that comes with that package.
#
# The output of the build is a largish Python15.DLL containing the
# essential modules of Python and a small Python.exe program to start
# the interpreter.  When embedding Python within another program, only
# Python15.DLL is needed.
#
# These two binaries can be statically linked with the VisualAge C/C++
# runtime library (producing larger binaries), or dynamically linked
# to make smaller ones that require the compiler to be installed on
# any system Python is used on.  Review the /Gd+ compiler option for
# how to do this.
#
# NOTE: IBM's NMAKE 4.0 is rather dumb, requiring this makefile to
#       be much more complicated than necessary.  I use OpusMAKE
#       myself for a much more powerful MAKE tool but not everyone
#       wishes to buy it.  However, as a result I didn't hook in
#       the dependencies on the include files as NMAKE has no easy
#       way to do this without explicitly spelling it all out.
#
# History (Most Recent First)
#
# 27-Jun-99 jrr Retested and adjusted for building w/Python 1.5.2
# 24-Mar-99 jrr Retested and adjusted for building w/Python 1.5.2b1
# 26-Sep-98 jrr Retested and adjusted for building w/Python 1.5.2a1
# 20-Nov-97 jrr Cleaned Up for Applying to Distribution
# 29-Oct-97 jrr Modified for Use with Python 1.5 Alpha 4
# 03-Aug-96 jrr Original for Use with Python 1.4 Release
#
######################################################################

###################
# Places and Things
###################
PY_MODULES      = ..\..\Modules
PY_OBJECTS      = ..\..\Objects
PY_PARSER       = ..\..\Parser
PY_PYTHON       = ..\..\Python
PY_INCLUDE      = ..\..\Include

PY_INCLUDES     = .;$(PY_INCLUDE);$(PY_MODULES);$(PY_OBJECTS);$(PY_PARSER);$(PY_PYTHON)

# File to Collect Wordy Compiler Output re Errors
ERRS		= make.out

# Where to Find the IBM TCP/IP Socket Includes and Libraries
OS2TCPIP        = C:\MPTN

# Where to Put the .OBJ Files, To Keep Them Out of the Way
PATHOBJ		= obj

# Search Path for Include Files
PROJINCLUDE	= .;$(OS2TCPIP)\Include;$(PY_INCLUDES)

# Place to Search for Sources re OpusMAKE Dependency Generator (Commercial)
MKMF_SRCS	= $(PY_MODULES)\*.c $(PY_OBJECTS)\*.c $(PY_PARSER)\*.c $(PY_PYTHON)\*.c

OTHERLIBS	= $(OS2TCPIP)\lib\so32dll.lib $(OS2TCPIP)\lib\tcp32dll.lib

#################
# Inference Rules
#################
{$(PY_MODULES)\}.c{$(PATHOBJ)\}.obj:	# Compile C Code into a .OBJ File
	@ Echo Compiling $<
	@ $(CC) -c $(CFLAGS) -Fo$@ $< >>$(ERRS)

{$(PY_OBJECTS)\}.c{$(PATHOBJ)\}.obj:	# Compile C Code into a .OBJ File
	@ Echo Compiling $<
	@ $(CC) -c $(CFLAGS) -Fo$@ $< >>$(ERRS)

{$(PY_PARSER)\}.c{$(PATHOBJ)\}.obj:	# Compile C Code into a .OBJ File
	@ Echo Compiling $<
	@ $(CC) -c $(CFLAGS) -Fo$@ $< >>$(ERRS)

{$(PY_PYTHON)\}.c{$(PATHOBJ)\}.obj:	# Compile C Code into a .OBJ File
	@ Echo Compiling $<
	@ $(CC) -c $(CFLAGS) -Fo$@ $< >>$(ERRS)

.c{$(PATHOBJ)\}.obj:			# Compile C Code into a .OBJ File
	@ Echo Compiling $<
	@ $(CC) -c $(CFLAGS) -Fo$@ $< >>$(ERRS)

###################
# Python Subsystems
###################

# PYTHON is the central core, containing the builtins and interpreter.
PYTHON		=                               \
                  $(PATHOBJ)\BltinModule.obj    \
                  $(PATHOBJ)\CEval.obj          \
                  $(PATHOBJ)\Compile.obj        \
                  $(PATHOBJ)\Errors.obj         \
                  $(PATHOBJ)\Frozen.obj         \
                  $(PATHOBJ)\Getargs.obj        \
                  $(PATHOBJ)\GetCompiler.obj    \
                  $(PATHOBJ)\GetCopyright.obj   \
                  $(PATHOBJ)\GetMTime.obj       \
                  $(PATHOBJ)\GetOpt.obj         \
                  $(PATHOBJ)\GetPlatform.obj    \
                  $(PATHOBJ)\GetVersion.obj     \
                  $(PATHOBJ)\GramInit.obj       \
                  $(PATHOBJ)\Import.obj         \
                  $(PATHOBJ)\ImportDL.obj       \
                  $(PATHOBJ)\Marshal.obj        \
                  $(PATHOBJ)\ModSupport.obj     \
                  $(PATHOBJ)\MyStrtoul.obj      \
                  $(PATHOBJ)\PyState.obj        \
                  $(PATHOBJ)\PythonRun.obj      \
                  $(PATHOBJ)\StructMember.obj   \
                  $(PATHOBJ)\SysModule.obj      \
                  $(PATHOBJ)\Thread.obj         \
                  $(PATHOBJ)\TraceBack.obj      \
                  $(PATHOBJ)\FrozenMain.obj

# Python's Internal Parser
PARSER		=                              \
                  $(PATHOBJ)\Acceler.obj       \
                  $(PATHOBJ)\Grammar1.obj      \
                  $(PATHOBJ)\MyReadline.obj    \
                  $(PATHOBJ)\Node.obj          \
                  $(PATHOBJ)\Parser.obj        \
                  $(PATHOBJ)\ParseTok.obj      \
                  $(PATHOBJ)\Tokenizer.obj

# Python Object Types
OBJECTS		=                              \
                  $(PATHOBJ)\Abstract.obj      \
                  $(PATHOBJ)\BufferObject.obj  \
                  $(PATHOBJ)\ClassObject.obj   \
                  $(PATHOBJ)\CObject.obj       \
                  $(PATHOBJ)\ComplexObject.obj \
                  $(PATHOBJ)\DictObject.obj    \
                  $(PATHOBJ)\FileObject.obj    \
                  $(PATHOBJ)\FloatObject.obj   \
                  $(PATHOBJ)\FrameObject.obj   \
                  $(PATHOBJ)\FuncObject.obj    \
                  $(PATHOBJ)\IntObject.obj     \
                  $(PATHOBJ)\ListObject.obj    \
                  $(PATHOBJ)\LongObject.obj    \
                  $(PATHOBJ)\MethodObject.obj  \
                  $(PATHOBJ)\ModuleObject.obj  \
                  $(PATHOBJ)\Object.obj        \
                  $(PATHOBJ)\RangeObject.obj   \
                  $(PATHOBJ)\SliceObject.obj   \
                  $(PATHOBJ)\StringObject.obj  \
                  $(PATHOBJ)\TupleObject.obj   \
                  $(PATHOBJ)\TypeObject.obj

# Extension Modules (Built-In or as Separate DLLs)
MODULES		=                               \
                  $(PATHOBJ)\ArrayModule.obj    \
                  $(PATHOBJ)\BinAscii.obj       \
                  $(PATHOBJ)\CMathModule.obj    \
                  $(PATHOBJ)\cPickle.obj        \
                  $(PATHOBJ)\cStringIO.obj      \
                  $(PATHOBJ)\ErrnoModule.obj    \
                  $(PATHOBJ)\GetBuildInfo.obj   \
                  $(PATHOBJ)\GetPathP.obj       \
                  $(PATHOBJ)\Main.obj           \
                  $(PATHOBJ)\MathModule.obj     \
                  $(PATHOBJ)\MD5c.obj           \
                  $(PATHOBJ)\MD5Module.obj      \
                  $(PATHOBJ)\NewModule.obj      \
                  $(PATHOBJ)\Operator.obj       \
                  $(PATHOBJ)\ParserModule.obj   \
                  $(PATHOBJ)\_LocaleModule.obj  \
                  $(PATHOBJ)\PCREModule.obj     \
                  $(PATHOBJ)\PyPCRE.obj         \
                  $(PATHOBJ)\RotorModule.obj    \
                  $(PATHOBJ)\PosixModule.obj    \
                  $(PATHOBJ)\RegexModule.obj    \
                  $(PATHOBJ)\RegExpr.obj        \
                  $(PATHOBJ)\SelectModule.obj   \
                  $(PATHOBJ)\ShaModule.obj      \
                  $(PATHOBJ)\SignalModule.obj   \
                  $(PATHOBJ)\SocketModule.obj   \
                  $(PATHOBJ)\SoundEx.obj        \
                  $(PATHOBJ)\StropModule.obj    \
                  $(PATHOBJ)\StructModule.obj   \
                  $(PATHOBJ)\TimeModule.obj     \
                  $(PATHOBJ)\ThreadModule.obj   \
                  $(PATHOBJ)\YUVConvert.obj

# Standalone Parser Generator Program (Shares Some of Python's Modules)
#PGEN            =                              \
#                  $(PATHOBJ)\PGenMain.obj      \
#                  $(PATHOBJ)\PGen.obj          \
#                  $(PATHOBJ)\PrintGrammar.obj  \
#                  $(PATHOBJ)\ListNode.obj      \
#                  $(PATHOBJ)\Grammar.obj       \
#                  $(PATHOBJ)\BitSet.obj        \
#                  $(PATHOBJ)\FirstSets.obj     \
#                  $(PATHOBJ)\MetaGrammar.obj

##################
# Macros and Flags
##################
_BASE		= /Q /W2 /I$(PROJINCLUDE)
		# /Q   = Omit IBM Copyright
		# /W2  = Show Warnings/Errors Only
		# /W3  = Show All Informationals/Warnings/Errors
		# /Fi  = Create Precompiled Headers
		# /Si  = Utilize Precompiled Headers

_GEN		= /G4 /Gm /Gd- /B"/STACK:360000"
		# /G4  = Generate Code for 486 (Use 386 for Debugger)
		# /Gm  = Use Multithread Runtime
		# /Gd  = Dynamically Load Runtime
		# /Gs  = Remove Code for Stack Probes
		# /Gx  = Remove C++ Exception-Handling Info
		# /Tdp = Generate Code for C++ Templates
		# /Rn  = Generate Code without a Runtime
		# /Ms  = Use _System Calling Convention (vs _Optlink)
		#        (to allow non-VAC++ code to call into Python15.dll)
		# /B"/STACK:n" = Set Stack Size

_OPT		= /O /Gl
		# /O   = Enable Speed-Optimizations
		# /Ol  = Pass Code Thru Intermediate Linker
		# /Gu  = Advise Linker All Ext Data is ID'd
		# /Gl  = Have Linker Remove Unused Fns

_DBG		= /Wpro- /Ti- /DHAVE_CONFIG_H /DUSE_SOCKET
                # /Wall= Generate All Compiler Warnings
                # /Wpro= Generate Compiler Warnings re Missing Prototypes
		# /Ti  = Embed Debugger/Analyzer Recs
		# /Tm  = Enable Debug Memory Fns
		# /Tx  = Request Full Dump Upon Exception
		# /DHAVE_CONFIG_H = Causes Use of CONFIG.H Settings
                # /DUSE_SOCKET = Enables Building In of Socket API

_OUT		= /B"/NOE"
		# /Fb  = Embed Browser Recs
		# /Gh  = Generate Code for Profiler Hooks
		# /Fl  = Output C/C++ Listing Files
                # /Lf  = Provide Full (Detailed) Listing Files
		# /Fm. = Output Linker Map File
		# /Ft. = Output C++ Template Resolution Files

_MAP		= /FmNoise\$(@R).map

_DLL		= /Ge-
_EXE		= /Ge
		# /Ge = Create an EXE, not DLL

CFLAGS		= $(_BASE) $(_GEN) $(_OPT) $(_DBG) $(_OUT) $(_EXE) /Ss

###################
# Primary Target(s)
###################
All:  obj noise PyCore.lib Python15.lib Python.exe PythonPM.exe Python15.dll

Modules: $(MODULES)
Objects: $(OBJECTS)
Parser:  $(PARSER)
Python:  $(PYTHON)

# Directory to Keep .OBJ Files Out of the Way
obj:
	@-mkdir obj >>NUL

# Directory to Keep .MAP and Such Text Files Out of the Way
noise:
	@-mkdir noise >>NUL

##############
#
##############

# Object Library of All Essential Python Routines
PyCore.lib: $(MODULES) $(OBJECTS) $(PARSER) $(PYTHON) $(PATHOBJ)\Config.obj
	@ Echo Adding Updated Object Files to Link Library $@
	@ ! ILIB $@ /NOLOGO /NOBACKUP -+$? ; >>$(ERRS)

Python15.dll: $(PATHOBJ)\Compile.obj PyCore.lib Python.def
	@ Echo Linking $@ As DLL
	@ $(CC) $(CFLAGS) /B"/NOE" $(_DLL) /Fe$@ $(_MAP) $** $(OTHERLIBS) >>$(ERRS)
	@ Echo Compressing $@ with LxLite
	@ lxlite $@

# IBM Linker Requires One Explicit .OBJ To Build a .DLL from a .LIB
$(PATHOBJ)\Compile.obj: $(PY_PYTHON)\Compile.c
	@ Echo Compiling $**
	@ $(CC) -c $(CFLAGS) $(_DLL) -Fo$@ $** >>$(ERRS)

# Import Library for Using the Python15.dll
Python15.lib: Python.def
	@ Echo Making $@
	@ IMPLIB /NOLOGO /NOIGNORE $@ $** >>$(ERRS)
	@ ILIB /NOLOGO /CONVFORMAT /NOEXTDICTIONARY /NOBROWSE /NOBACKUP $@; >>$(ERRS)

# Small Command-Line Program to Start Interpreter in Python15.dll
Python.exe: $(PATHOBJ)\Python.obj Python15.lib
	@ Echo Linking $@ As EXE
	@ $(CC) $(CFLAGS) $(_EXE) /B"/PM:VIO /STACK:360000" /Fe$@ $(_MAP) $** $(OTHERLIBS) >>$(ERRS)

# Small PM-GUI Program to Start Interpreter in Python15.dll
PythonPM.exe: $(PATHOBJ)\Python.obj Python15.lib
	@ Echo Linking $@ As EXE
	@ $(CC) $(CFLAGS) $(_EXE) /B"/PM:PM /STACK:360000" /Fe$@ $(_MAP) $** $(OTHERLIBS) >>$(ERRS)

#PGen.exe: $(PGEN) PyCore.lib
#	@ Echo Linking $@ As EXE
#	@ $(CC) $(CFLAGS) $(_EXE) /B"/STACK:360000" /Fe$@ $(_MAP) $** $(OTHERLIBS) >>$(ERRS)

#######################
# Miscellaneous Targets
#######################

# Remove Intermediate Targets but Leave Executable Binaries
clean:
	-- Del    $(PATHOBJ)\*.obj		>NUL 2>&1
	-- Del    /Y Noise			>NUL 2>&1
	-- Del    $(ERRS)			>NUL 2>&1

# Remove All Targets, Including Final Binaries
distclean: clean
        -- Del    PyCore.lib Python15.lib       >NUL 2>&1
        -- Del    Python15.dll PGen.exe         >NUL 2>&1
        -- Del    Python.exe PythonPM.exe	>NUL 2>&1

test:
        python ..\..\lib\test\regrtest.py

bins:   PY2B152.ZIP PY2S152.ZIP PY2D152.ZIP

allpkg: binpkg srcpkg docpkg
binpkg: PY2B152.ZIP
srcpkg: PY2S152.ZIP
docpkg: PY2D152.ZIP

PY2B152.ZIP: Python.exe Python15.lib Python15.dll
	cd ..\..
	-- Del       py2b152.zip >NUL 2>&1
        zip -r -9    py2b152.zip Demo Tools Misc
        zip    -9    py2b152.zip lib\*.*
        zip -r -9    py2b152.zip lib\dos-8x3 lib\lib-old lib\lib-tk
        zip -r -9    py2b152.zip lib\lib-dynload lib\site-packages
        zip -r -9    py2b152.zip lib\plat-win lib\test
	zip -j -9    py2b152.zip PC\OS2Vacpp\Python.exe PC\OS2Vacpp\*.dll
	zip -j -9    py2b152.zip PC\OS2Vacpp\Python15.lib
        zip -j -9    py2b152.zip NEWS README README.OS2
	cd PC\OS2Vacpp

PY2S152.ZIP:
	cd ..\..
	-- Del       py2s152.zip >NUL 2>&1
        zip -r -9    py2s152.zip Include Modules Objects Parser Python Add-Ons
        zip -r -9    py2s152.zip PC -x *.obj -x *.map -x *.exe -x *.dll -x *.lib -x make.out
        zip -j -9    py2s152.zip NEWS README README.OS2
	cd PC\OS2Vacpp

PY2D152.ZIP:
	cd ..\..
	-- Del       py2d152.zip >NUL 2>&1
        zip -r -9    py2d152.zip html
	cd PC\OS2Vacpp

