A directory with a working example of how to build an extension.

This commit is contained in:
Guido van Rossum 1996-09-06 21:16:21 +00:00
parent 5c1d1ee8a8
commit 026f01a297
4 changed files with 417 additions and 0 deletions

21
PC/example_nt/example.c Normal file
View file

@ -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);
}

View file

@ -0,0 +1,2 @@
EXPORTS
initexample

285
PC/example_nt/example.mak Normal file
View file

@ -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
################################################################################

109
PC/example_nt/readme.txt Normal file
View file

@ -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.