mirror of https://github.com/python/cpython.git
A directory with a working example of how to build an extension.
This commit is contained in:
parent
5c1d1ee8a8
commit
026f01a297
|
@ -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);
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
EXPORTS
|
||||||
|
initexample
|
|
@ -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
|
||||||
|
################################################################################
|
|
@ -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.
|
Loading…
Reference in New Issue