Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
f70fdd28
Commit
f70fdd28
authored
Apr 14, 2015
by
Steve Dower
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Generates and signs a self-extracting executable containing an embedded Python.
parent
7c63fd3d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
206 additions
and
0 deletions
+206
-0
Tools/msi/buildrelease.bat
Tools/msi/buildrelease.bat
+9
-0
Tools/msi/make_zip.proj
Tools/msi/make_zip.proj
+37
-0
Tools/msi/make_zip.py
Tools/msi/make_zip.py
+160
-0
No files found.
Tools/msi/buildrelease.bat
View file @
f70fdd28
...
...
@@ -64,6 +64,13 @@ for %%f in (%_DLLTOOL_PATH%) do set PATH=%PATH%;%%~dpf
set
_DLLTOOL_PATH
=
:skipdlltoolsearch
where
rar
/q
&&
goto
skiprarsearch
set
_RAR_PATH
=
where
/R
"
%ProgramFiles%
\WinRAR"
rar
>
"
%TEMP%
\rar.loc"
2
>
nul
&&
set
/P
_RAR_PATH
=
<
"
%TEMP%
\rar.loc"
&
del
"
%TEMP%
\rar.loc"
where
/R
"
%ProgramFiles
(x86)
%
\WinRAR"
rar
>
"
%TEMP%
\rar.loc"
2
>
nul
&&
set
/P
_RAR_PATH
=
<
"
%TEMP%
\rar.loc"
&
del
"
%TEMP%
\rar.loc"
if
not
exist
"
%_RAR_PATH%
"
echo
Cannot
find
WinRAR
on
PATH
or
in
external
&&
pause
:skiprarsearch
if
defined
BUILDX86
(
call
:build
x86
if
errorlevel
1
exit
/B
...
...
@@ -135,6 +142,8 @@ if errorlevel 1 exit /B
msbuild
"
%D%
bundle\releaseweb.wixproj"
/t
:Rebuild
%BUILDOPTS%
%CERTOPTS%
/p
:RebuildAll
=
false
if
errorlevel
1
exit
/B
if
defined
_RAR_PATH
msbuild
"
%D%
make_zip.proj"
/t
:Build
%BUILDOPTS%
%CERTOPTS%
"/p:RAR=
%_RAR_PATH%
"
if
not
"
%OUTDIR%
"
EQU
""
(
mkdir
"
%OUTDIR%
\
%OUTDIR_PLAT%
"
copy
/Y
"
%BUILD%
en-us\*.cab"
"
%OUTDIR%
\
%OUTDIR_PLAT%
"
...
...
Tools/msi/make_zip.proj
0 → 100644
View file @
f70fdd28
<?xml version="1.0" encoding="utf-8"?>
<Project
ToolsVersion=
"4.0"
DefaultTargets=
"Build"
xmlns=
"http://schemas.microsoft.com/developer/msbuild/2003"
>
<PropertyGroup>
<ProjectGuid>
{10487945-15D1-4092-A214-338395C4116B}
</ProjectGuid>
<OutputName>
python
</OutputName>
<OutputSuffix></OutputSuffix>
</PropertyGroup>
<Import
Project=
"msi.props"
/>
<PropertyGroup>
<TargetName>
python-$(PythonVersion)-embed-$(ArchName)
</TargetName>
<TargetExt>
.exe
</TargetExt>
<TargetPath>
$(OutputPath)\en-us\$(TargetName)$(TargetExt)
</TargetPath>
<Arguments>
"$(PythonExe)" "$(MSBuildThisFileDirectory)\make_zip.py"
</Arguments>
<Arguments>
$(Arguments) -e -o "$(TargetPath)" -t "$(IntermediateOutputPath)\zip_$(ArchName)" -a $(ArchName)
</Arguments>
<Arguments
Condition=
"Exists('$(RAR)')"
>
$(Arguments) --rar "$(RAR)"
</Arguments>
<Environment>
set DOC_FILENAME=python$(PythonVersion).chm
</Environment>
</PropertyGroup>
<Target
Name=
"_Build"
>
<Exec
Command=
"setlocal
$(Environment)
$(Arguments)"
/>
</Target>
<Target
Name=
"AfterBuild"
/>
<Target
Name=
"Build"
DependsOnTargets=
"_Build;AfterBuild"
/>
<Target
Name=
"ShowHashes"
>
<ItemGroup>
<UserFiles
Include=
"@(File)"
Condition=
"'%(File.CopyTo)' == '$(EXETarget)'"
/>
</ItemGroup>
<Exec
Command=
""$(PythonExe)" generate_md5.py @(UserFiles->'"%(FullPath)"',' ')"
/>
</Target>
</Project>
Tools/msi/make_zip.py
0 → 100644
View file @
f70fdd28
import
argparse
import
re
import
sys
import
shutil
import
os
import
tempfile
from
pathlib
import
Path
from
zipfile
import
ZipFile
,
ZIP_DEFLATED
import
subprocess
TKTCL_RE
=
re
.
compile
(
r'^(_?tk|tcl).+\
.(pyd|dll)
', re.IGNORECASE)
DEBUG_RE = re.compile(r'
_d
\
.(
pyd
|
dll
|
exe
)
$
', re.IGNORECASE)
PYTHON_DLL_RE = re.compile(r'
python
\
d
\
d
?
\
.
dll
$
', re.IGNORECASE)
def is_not_debug(p):
return not DEBUG_RE.search(p.name) and not TKTCL_RE.search(p.name)
def is_not_debug_or_python(p):
return is_not_debug(p) and not PYTHON_DLL_RE.search(p.name)
def include_in_lib(p):
name = p.name.lower()
if p.is_dir():
if name in {'
__pycache__
', '
ensurepip
', '
idlelib
', '
pydoc_data
', '
tkinter
', '
turtledemo
'}:
return False
if name.startswith('
plat
-
'):
return False
if name == '
test
' and p.parts[-2].lower() == '
lib
':
return False
return True
if name in {'
_ctypes_test
.
pyd
', '
_testbuffer
.
pyd
', '
_testcapi
.
pyd
', '
_testimportmultiple
.
pyd
', '
xxlimited
.
pyd
'}:
return False
return p.suffix.lower() not in {'
.
pyc
', '
.
pyo
'}
def include_in_tools(p):
if p.is_dir() and p.name.lower() in {'
scripts
', '
i18n
', '
pynche
', '
demo
', '
parser
'}:
return True
return p.suffix.lower() in {'
.
py
', '
.
pyw
', '
.
txt
'}
FULL_LAYOUT = [
('
/
', '
PCBuild
/
$
arch
', '
python
*
.
exe
', is_not_debug),
('
/
', '
PCBuild
/
$
arch
', '
python
*
.
dll
', is_not_debug),
('
DLLs
/
', '
PCBuild
/
$
arch
', '
*
.
pyd
', is_not_debug),
('
DLLs
/
', '
PCBuild
/
$
arch
', '
*
.
dll
', is_not_debug),
('
include
/
', '
include
', '
*
.
h
', None),
('
include
/
', '
PC
', '
pyconfig
.
h
', None),
('
Lib
/
', '
Lib
', '
**/*
', include_in_lib),
('
Tools
/
', '
Tools
', '
**/*
', include_in_tools),
]
if os.getenv('
DOC_FILENAME
'):
FULL_LAYOUT.append(('
Doc
/
', '
Doc
/
build
/
htmlhelp
', os.getenv('
DOC_FILENAME
'), None))
EMBED_LAYOUT = [
('
/
', '
PCBuild
/
$
arch
', '
python
*
.
exe
', is_not_debug),
('
/
', '
PCBuild
/
$
arch
', '
*
.
pyd
', is_not_debug),
('
/
', '
PCBuild
/
$
arch
', '
*
.
dll
', is_not_debug),
('
python35
.
zip
', '
Lib
', '
**/*
', include_in_lib),
]
def copy_to_layout(target, source, rel_sources):
count = 0
if target.suffix.lower() == '
.
zip
':
if target.exists():
target.unlink()
with ZipFile(str(target), '
w
', ZIP_DEFLATED) as f:
for s, rel in rel_sources:
f.write(str(s), str(rel))
count += 1
else:
for s, rel in rel_sources:
try:
(target / rel).parent.mkdir(parents=True)
except FileExistsError:
pass
shutil.copy(str(s), str(target / rel))
count += 1
return count
def rglob(root, pattern, condition):
dirs = [root]
recurse = pattern[:3] in {'
**/
', '
**
\\
'}
while dirs:
d = dirs.pop(0)
for f in d.glob(pattern[3:] if recurse else pattern):
if recurse and f.is_dir() and (not condition or condition(f)):
dirs.append(f)
elif f.is_file() and (not condition or condition(f)):
yield f, f.relative_to(root)
def main():
parser = argparse.ArgumentParser()
parser.add_argument('
-
s
', '
--
source
', metavar='
dir
', help='
The
directory
containing
the
repository
root
', type=Path)
parser.add_argument('
-
o
', '
--
out
', metavar='
file
', help='
The
name
of
the
output
self
-
extracting
archive
', type=Path, required=True)
parser.add_argument('
-
t
', '
--
temp
', metavar='
dir
', help='
A
directory
to
temporarily
extract
files
into
', type=Path, default=None)
parser.add_argument('
-
e
', '
--
embed
', help='
Create
an
embedding
layout
', action='
store_true
', default=False)
parser.add_argument('
-
a
', '
--
arch
', help='
Specify
the
architecture
to
use
(
win32
/
amd64
)
', type=str, default="win32")
parser.add_argument('
--
rar
', help='
Full
path
to
WinRAR
compressor
(
rar
.
exe
)
', type=Path, default=Path("rar.exe"))
ns = parser.parse_args()
source = ns.source or (Path(__file__).parent.parent.parent)
out = ns.out
arch = ns.arch
rar = getattr(ns, '
rar
')
assert isinstance(source, Path)
assert isinstance(out, Path)
assert isinstance(arch, str)
assert isinstance(rar, Path)
if ns.temp:
temp = ns.temp
delete_temp = False
else:
temp = Path(tempfile.mkdtemp())
delete_temp = True
try:
out.parent.mkdir(parents=True)
except FileExistsError:
pass
try:
temp.mkdir(parents=True)
except FileExistsError:
pass
layout = EMBED_LAYOUT if ns.embed else FULL_LAYOUT
try:
for t, s, p, c in layout:
s = source / s.replace("$arch", arch)
copied = copy_to_layout(
temp / t.rstrip('
/
'),
source,
rglob(s, p, c)
)
print('
Copied
{}
files
'.format(copied))
if rar and rar.is_file():
subprocess.check_call([
str(rar),
"a",
"-m5", "-ed", "-ep1", "-s", "-r",
"-sfxwincon.sfx",
str(out),
str(temp / '
*
')
])
finally:
if delete_temp:
shutil.rmtree(temp, True)
if __name__ == "__main__":
sys.exit(int(main() or 0))
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment