From 026f01a29751e7bd91b0f62b54beb5b9eb24e73f Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 6 Sep 1996 21:16:21 +0000 Subject: [PATCH] A directory with a working example of how to build an extension. --- PC/example_nt/example.c | 21 +++ PC/example_nt/example.def | 2 + PC/example_nt/example.mak | 285 ++++++++++++++++++++++++++++++++++++++ PC/example_nt/readme.txt | 109 +++++++++++++++ 4 files changed, 417 insertions(+) create mode 100644 PC/example_nt/example.c create mode 100644 PC/example_nt/example.def create mode 100644 PC/example_nt/example.mak create mode 100644 PC/example_nt/readme.txt diff --git a/PC/example_nt/example.c b/PC/example_nt/example.c new file mode 100644 index 00000000000..dd8964bbb04 --- /dev/null +++ b/PC/example_nt/example.c @@ -0,0 +1,21 @@ +#include "Python.h" + +static PyObject * +ex_foo(self, args) + PyObject *self, *args; +{ + printf("Hello, world\n"); + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef example_methods[] = { + {"foo", ex_foo, 1, "foo() doc string"}, + {NULL, NULL} +}; + +void +initexample() +{ + Py_InitModule("example", example_methods); +} diff --git a/PC/example_nt/example.def b/PC/example_nt/example.def new file mode 100644 index 00000000000..96b69a52ddc --- /dev/null +++ b/PC/example_nt/example.def @@ -0,0 +1,2 @@ +EXPORTS + initexample diff --git a/PC/example_nt/example.mak b/PC/example_nt/example.mak new file mode 100644 index 00000000000..b6563583c07 --- /dev/null +++ b/PC/example_nt/example.mak @@ -0,0 +1,285 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +!IF "$(CFG)" == "" +CFG=example - Win32 Debug +!MESSAGE No configuration specified. Defaulting to example - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "example - Win32 Release" && "$(CFG)" !=\ + "example - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Release" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "example - Win32 Debug" +CPP=cl.exe +RSC=rc.exe +MTL=mktyplib.exe + +!IF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "$(OUTDIR)\example.dll" + +CLEAN : + -@erase ".\Release\example.dll" + -@erase ".\Release\example.obj" + -@erase ".\Release\example.lib" + -@erase ".\Release\example.exp" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../Include" /I "../PC" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +CPP_PROJ=/nologo /MT /W3 /GX /O2 /I "../Include" /I "../PC" /D "WIN32" /D\ + "NDEBUG" /D "_WINDOWS" /Fp"$(INTDIR)/example.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS= +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/example.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\ + /pdb:"$(OUTDIR)/example.pdb" /machine:I386 /def:".\example.def"\ + /out:"$(OUTDIR)/example.dll" /implib:"$(OUTDIR)/example.lib" +DEF_FILE= \ + ".\example.def" +LINK32_OBJS= \ + "$(INTDIR)/example.obj" \ + "..\vc40\python14.lib" + +"$(OUTDIR)\example.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +OUTDIR=.\Debug +INTDIR=.\Debug + +ALL : "$(OUTDIR)\example.dll" + +CLEAN : + -@erase ".\Debug\example.dll" + -@erase ".\Debug\example.obj" + -@erase ".\Debug\example.ilk" + -@erase ".\Debug\example.lib" + -@erase ".\Debug\example.exp" + -@erase ".\Debug\example.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "../Include" /I "../PC" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +CPP_PROJ=/nologo /MTd /W3 /Gm /GX /Zi /Od /I "../Include" /I "../PC" /D "WIN32"\ + /D "_DEBUG" /D "_WINDOWS" /Fp"$(INTDIR)/example.pch" /YX /Fo"$(INTDIR)/"\ + /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/example.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:windows /dll /incremental:yes\ + /pdb:"$(OUTDIR)/example.pdb" /debug /machine:I386 /def:".\example.def"\ + /out:"$(OUTDIR)/example.dll" /implib:"$(OUTDIR)/example.lib" +DEF_FILE= \ + ".\example.def" +LINK32_OBJS= \ + "$(INTDIR)/example.obj" \ + "..\vc40\python14.lib" + +"$(OUTDIR)\example.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "example - Win32 Release" +# Name "example - Win32 Debug" + +!IF "$(CFG)" == "example - Win32 Release" + +!ELSEIF "$(CFG)" == "example - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\example.c +DEP_CPP_EXAMP=\ + ".\../Include\Python.h"\ + "..\Include\allobjects.h"\ + ".\../PC\config.h"\ + "..\Include\myproto.h"\ + "..\Include\object.h"\ + "..\Include\objimpl.h"\ + "..\Include\pydebug.h"\ + "..\Include\accessobject.h"\ + "..\Include\intobject.h"\ + "..\Include\longobject.h"\ + "..\Include\floatobject.h"\ + "..\Include\complexobject.h"\ + "..\Include\rangeobject.h"\ + "..\Include\stringobject.h"\ + "..\Include\tupleobject.h"\ + "..\Include\listobject.h"\ + "..\Include\mappingobject.h"\ + "..\Include\methodobject.h"\ + "..\Include\moduleobject.h"\ + "..\Include\funcobject.h"\ + "..\Include\classobject.h"\ + "..\Include\fileobject.h"\ + "..\Include\cobject.h"\ + "..\Include\traceback.h"\ + "..\Include\sliceobject.h"\ + "..\Include\pyerrors.h"\ + "..\Include\mymalloc.h"\ + "..\Include\modsupport.h"\ + "..\Include\ceval.h"\ + "..\Include\pythonrun.h"\ + "..\Include\sysmodule.h"\ + "..\Include\intrcheck.h"\ + "..\Include\import.h"\ + "..\Include\bltinmodule.h"\ + "..\Include\abstract.h"\ + "..\Include\rename2.h"\ + "..\Include\thread.h"\ + + +"$(INTDIR)\example.obj" : $(SOURCE) $(DEP_CPP_EXAMP) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\example.def + +!IF "$(CFG)" == "example - Win32 Release" + +!ELSEIF "$(CFG)" == "example - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\vc40\python14.lib + +!IF "$(CFG)" == "example - Win32 Release" + +!ELSEIF "$(CFG)" == "example - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\readme.txt + +!IF "$(CFG)" == "example - Win32 Release" + +!ELSEIF "$(CFG)" == "example - Win32 Debug" + +!ENDIF + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/PC/example_nt/readme.txt b/PC/example_nt/readme.txt new file mode 100644 index 00000000000..9189c4d4b1b --- /dev/null +++ b/PC/example_nt/readme.txt @@ -0,0 +1,109 @@ +Example Python extension for Windows NT +======================================= + +This directory contains everything you need to build a Python +extension module using Microsoft VC++ 4.x ("Developer Studio"), except +for the Python distribution. It has only been tested with version +4.0, but should work with higher versions. + +The "example" subdirectory should be an immediate subdirectory of the +Python source directory -- a direct sibling of Include and PC, in +particular, which are referenced as "..\Include" and "..\PC". +In other words, it should *not* be used "as is". Copy or move it up +one level or you will regret it! (This is done to keep all the PC +specific files inside the PC subdirectory of the distribution, where +they belong.) + +It is also assumed that the build results of Python are in the +directory ..\vc40. In particular, the python14.lib file is referred +to as "..\vc40\python14.lib". + +In order to use the example project from Developer Studio, use the +"File->Open Workspace..." dialog (*not* the "File->Open..." dialog!). +Change the pattern to "*.mak" and select the file "example.mak". Now +choose "File->Save All" and the othe project files will be created. + +In order to check that everything is set up right, try building: +choose "Build->Build example.dll". This creates all intermediate and +result files in a subdirectory which is called either Debug or Release +depending on which configuration you have chosen (as distributed, +Debug is selected as the default configuration). + +Once the build has succeeded, test the resulting DLL. In a DOS +command window, chdir to that directory. You should now be able to +repeat the following session "(C>" is the DOS prompt, ">>>" is the +Python prompt): + + C> ..\..\vc40\python.exe + >>> import example + >>> example.foo() + Hello, world + >>> + + +Creating the project +-------------------- + +There are two ways to use this example to create a project for your +own module. First, choose a name ("spam" is always a winner :-) and +create a directory for it. Copy your C sources into it. Note that +the module source file name does not necessarily have to match the +module name, but the "init" function name should match the module name +-- i.e. you can only import a module "spam" if its init function is +called "initspam()", and it should call Py_InitModule with the string +"spam" as its first argument. By convention, it lives in a file +called "spam.c" or "spammodule.c". The output file should be called +"spam.dll" or "spam.pyd" (the latter is supported to avoid confusion +with a system library "spam.dll" to which your module could be a +Python interface). + +Now your options are: + +1) Clone example.mak. Start by copying example\example.mak to +spam\spam.mak. Do a global edit on spam.mak, replacing all +occurrences of the string "example" by "spam", and all occurrences of +"DEP_CPP_EXAMP" by something like "DEP_CPP_SPAM". You can now use +this makefile to create a project file by opening it as a workspace +(you have to change the pattern to *.mak first). + +2) Create a brand new project; instructions are below. + +In both cases, copy example\example.def to spam\spam.def, and edit +spam\spam.def so its second line contains the string "initspam". +If you created a new project yourself, add the file spam.def to the +project now. + +You are now all set to build your extension, unless it requires other +external libraries, include files, etc. See Python's Extending and +Embedding manual for instructions on how to write an extension. + + +Creating a brand new project +---------------------------- + +If you don't feel comfortable with editing Makefiles, you can create a +brand new project from scratch easily. + +Use the "File->New..." dialog to create a new Project Workspace. +Select Dynamic-Link Library, enter the name ("spam"), and make sure +the "Location" is set to the spam directory you have created (which +should be a direct subdirectory of the Python build tree). Select +Win32 as the platform (in my version, this is the only choice). Click +"Create". + +Now open the "Build->Settings..." dialog. (Impressive, isn't it? :-) +You only need to change a few settings. Make sure you have both the +Debug and the Release configuration selected when you make these +changes. Select the "C/C++" tab. Choose the "Preprocessor" category +in the popup menu at the top. Type the following text in the entry +box labeled "Addditional include directories:" + + ..\Include,..\PC + +You should now first create the file spam.def as instructed in the +previous section. + +Now chose the "Insert->Files into Project..." dialog. Set the pattern +to *.* and select both spam.c and spam.def and click OK. (Inserting +them one by one is fine too.) Using the same dialog, choose the file +..\vc40\python14.lib and insert it into the project.