Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 110f365

Browse files
committed
Additions for Mark Hammond's Win32 specific hacks.
1 parent e194beb commit 110f365

3 files changed

Lines changed: 398 additions & 0 deletions

File tree

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
"""Extension management for Windows.
2+
3+
Under Windows it is unlikely the .obj files are of use, as special compiler options
4+
are needed (primarily to toggle the behaviour of "public" symbols.
5+
6+
I dont consider it worth parsing the MSVC makefiles for compiler options. Even if
7+
we get it just right, a specific freeze application may have specific compiler
8+
options anyway (eg, to enable or disable specific functionality)
9+
10+
So my basic stragtegy is:
11+
12+
* Have a Windows INI file which "describes" an extension module.
13+
* This description can include:
14+
- The MSVC .dsp file for the extension. The .c source file names
15+
are extraced from there.
16+
- Specific compiler options
17+
- Flag to indicate if Unicode compilation is expected.
18+
19+
At the moment the name and location of this INI file is hardcoded,
20+
but an obvious enhancement would be to provide command line options.
21+
"""
22+
23+
import os, win32api, string, sys
24+
25+
class CExtension:
26+
"""An abstraction of an extension implemented in C/C++
27+
"""
28+
def __init__(self, name, sourceFiles):
29+
self.name = name
30+
# A list of strings defining additional compiler options.
31+
self.sourceFiles = sourceFiles
32+
# A list of special compiler options to be applied to
33+
# all source modules in this extension.
34+
self.compilerOptions = []
35+
# A list of .lib files the final .EXE will need.
36+
self.linkerLibs = []
37+
38+
def GetSourceFiles(self):
39+
return self.sourceFiles
40+
41+
def AddCompilerOption(self, option):
42+
self.compilerOptions.append(option)
43+
def GetCompilerOptions(self):
44+
return self.compilerOptions
45+
46+
def AddLinkerLib(self, lib):
47+
self.linkerLibs.append(lib)
48+
def GetLinkerLibs(self):
49+
return self.linkerLibs
50+
51+
def checkextensions(unknown, ignored):
52+
# Create a table of frozen extensions
53+
54+
mapFileName = os.path.join( os.path.split(sys.argv[0])[0], "extensions_win32.ini")
55+
ret = []
56+
for mod in unknown:
57+
defn = get_extension_defn( mod, mapFileName )
58+
if defn is not None:
59+
ret.append( defn )
60+
return ret
61+
62+
def get_extension_defn(moduleName, mapFileName):
63+
dsp = win32api.GetProfileVal(moduleName, "dsp", "", mapFileName)
64+
if dsp=="":
65+
sys.stderr.write("No definition of module %s in map file '%s'\n" % (moduleName, mapFileName))
66+
return None
67+
68+
# We allow environment variables in the file name
69+
dsp = win32api.ExpandEnvironmentStrings(dsp)
70+
sourceFiles = parse_dsp(dsp)
71+
if sourceFiles is None:
72+
return None
73+
74+
module = CExtension(moduleName, sourceFiles)
75+
76+
cl_options = win32api.GetProfileVal(moduleName, "cl", "", mapFileName)
77+
if cl_options:
78+
module.AddCompilerOption(win32api.ExpandEnvironmentStrings(cl_options))
79+
80+
exclude = win32api.GetProfileVal(moduleName, "exclude", "", mapFileName)
81+
exclude = string.split(exclude)
82+
83+
if win32api.GetProfileVal(moduleName, "Unicode", 0, mapFileName):
84+
module.AddCompilerOption('/D UNICODE /D _UNICODE')
85+
86+
libs = string.split(win32api.GetProfileVal(moduleName, "libs", "", mapFileName))
87+
for lib in libs:
88+
module.AddLinkerLib(lib)
89+
90+
for exc in exclude:
91+
if exc in module.sourceFiles:
92+
modules.sourceFiles.remove(exc)
93+
94+
return module
95+
96+
# Given an MSVC DSP file, locate C source files it uses
97+
# returns a list of source files.
98+
def parse_dsp(dsp):
99+
# print "Processing", dsp
100+
# For now, only support
101+
ret = []
102+
dsp_path, dsp_name = os.path.split(dsp)
103+
try:
104+
lines = open(dsp, "r").readlines()
105+
except IOError, msg:
106+
sys.stderr.write("%s: %s\n" % (dsp, msg))
107+
return None
108+
for line in lines:
109+
fields = string.split(string.strip(line), "=", 2)
110+
if fields[0]=="SOURCE":
111+
if string.lower(os.path.splitext(fields[1])[1]) in ['.cpp', '.c']:
112+
ret.append( win32api.GetFullPathName(os.path.join(dsp_path, fields[1] ) ) )
113+
return ret
114+
115+
def write_extension_table(fname, modules):
116+
fp = open(fname, "w")
117+
try:
118+
fp.write (ext_src_header)
119+
# Write fn protos
120+
for module in modules:
121+
# bit of a hack for .pyd's as part of packages.
122+
name = string.split(module.name,'.')[-1]
123+
fp.write('extern void init%s(void);\n' % (name) )
124+
# Write the table
125+
fp.write (ext_tab_header)
126+
for module in modules:
127+
name = string.split(module.name,'.')[-1]
128+
fp.write('\t{"%s", init%s},\n' % (name, name) )
129+
130+
fp.write (ext_tab_footer)
131+
fp.write(ext_src_footer)
132+
finally:
133+
fp.close()
134+
135+
136+
ext_src_header = """\
137+
#include "Python.h"
138+
"""
139+
140+
ext_tab_header = """\
141+
142+
static struct _inittab extensions[] = {
143+
"""
144+
145+
ext_tab_footer = """\
146+
/* Sentinel */
147+
{0, 0}
148+
};
149+
"""
150+
151+
ext_src_footer = """\
152+
extern int PyImport_ExtendInittab(struct _inittab *newtab);
153+
154+
int PyInitFrozenExtensions()
155+
{
156+
return PyImport_ExtendInittab(extensions);
157+
}
158+
159+
"""
160+
161+

Tools/freeze/extensions_win32.ini

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
; This is a list of modules generally build as .pyd files.
2+
;
3+
; Each section contains enough information about a module for
4+
; freeze to include the module as a static, built-in module
5+
; in a frozen .EXE/.DLL.
6+
7+
; This is all setup for all the win32 extension modules
8+
; released by Mark Hammond.
9+
; You must ensure that the environment variable PYTHONEX is set
10+
; to point to the root win32 extensions directory
11+
12+
13+
;--------------------------------------------------------------
14+
;
15+
; Win32 Projects.
16+
;
17+
[perfmon]
18+
dsp=%PYTHONEX%\win32\perfmon.dsp
19+
cl=/I %PYTHONEX%\win32\src
20+
Unicode=1
21+
22+
[pywintypes]
23+
dsp=%PYTHONEX%\win32\pywintypes.dsp
24+
cl=/I %PYTHONEX%\win32\src
25+
libs=ole32.lib oleaut32.lib
26+
27+
[win32api]
28+
dsp=%PYTHONEX%\win32\win32api.dsp
29+
cl=/I %PYTHONEX%\win32\src
30+
libs=kernel32.lib user32.lib shell32.lib advapi32.lib
31+
32+
[win32service]
33+
dsp=%PYTHONEX%\win32\win32service.dsp
34+
cl=/I %PYTHONEX%\win32\src
35+
Unicode=1
36+
libs=advapi32.lib
37+
38+
[win32evtlog]
39+
dsp=%PYTHONEX%\win32\win32evtlog.dsp
40+
cl=/I %PYTHONEX%\win32\src
41+
42+
[win32event]
43+
dsp=%PYTHONEX%\win32\win32event.dsp
44+
cl=/I %PYTHONEX%\win32\src
45+
46+
[win32file]
47+
dsp=%PYTHONEX%\win32\win32file.dsp
48+
cl=/I %PYTHONEX%\win32\src
49+
50+
[win32net]
51+
dsp=%PYTHONEX%\win32\win32net.dsp
52+
cl=/I %PYTHONEX%\win32\src
53+
libs=netapi32.lib
54+
55+
[win32pdh]
56+
dsp=%PYTHONEX%\win32\win32pdh.dsp
57+
cl=/I %PYTHONEX%\win32\src
58+
59+
[win32pipe]
60+
dsp=%PYTHONEX%\win32\win32pipe.dsp
61+
cl=/I %PYTHONEX%\win32\src
62+
63+
[win32security]
64+
dsp=%PYTHONEX%\win32\win32security.dsp
65+
cl=/I %PYTHONEX%\win32\src
66+
67+
[win32service]
68+
dsp=%PYTHONEX%\win32\win32service.dsp
69+
cl=/I %PYTHONEX%\win32\src
70+
71+
[win32trace]
72+
dsp=%PYTHONEX%\win32\win32trace.dsp
73+
cl=/I %PYTHONEX%\win32\src
74+
75+
;--------------------------------------------------------------
76+
;
77+
; COM Projects.
78+
;
79+
80+
[pythoncom]
81+
dsp=%PYTHONEX%\com\win32com.dsp
82+
cl=/I %PYTHONEX%\com\win32com\src\include /I %PYTHONEX%\win32\src
83+
libs=uuid.lib
84+
85+
[win32com.axscript.axscript]
86+
dsp=%PYTHONEX%\com\Active Scripting.dsp
87+
cl=/I %PYTHONEX%\win32\src /I %PYTHONEX%\com\win32com\src\include
88+
89+
[win32com.axdebug.axdebug]
90+
dsp=%PYTHONEX%\com\Active Debugging.dsp
91+
cl=/I %PYTHONEX%\win32\src /I %PYTHONEX%\com\win32com\src\include
92+
93+
[win32com.mapi.mapi]
94+
dsp=%PYTHONEX%\com\mapi.dsp
95+
cl=/I %PYTHONEX%\win32\src /I %PYTHONEX%\com\win32com\src\include
96+
libs=MBLOGON.lib ADDRLKUP.LIB mapi32.lib version.lib
97+
98+
[win32com.mapi.exchange]
99+
dsp=%PYTHONEX%\com\exchange.dsp
100+
cl=/I %PYTHONEX%\win32\src /I %PYTHONEX%\com\win32com\src\include
101+
libs=MBLOGON.lib ADDRLKUP.LIB exchinst.lib EDKCFG.LIB EDKUTILS.LIB EDKMAPI.LIB mapi32.lib version.lib
102+
103+
[win32com.mapi.exchdapi]
104+
dsp=%PYTHONEX%\com\exchdapi.dsp
105+
cl=/I %PYTHONEX%\win32\src /I %PYTHONEX%\com\win32com\src\include
106+
libs=DAPI.LIB
107+
108+
[servicemanager]
109+
dsp=%PYTHONEX%\win32\PythonService EXE.dsp
110+
Unicode = 1
111+
112+
; Pythonwin
113+
[win32ui]
114+
dsp=%PYTHONEX%\Pythonwin\win32ui.dsp
115+
cl=/I %PYTHONEX%\win32\src
116+
libs=mfc42.lib
117+

0 commit comments

Comments
 (0)