Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
13399445
Kaydet (Commit)
13399445
authored
Mar 30, 2014
tarafından
Ned Deily
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Issue #20022: Eliminate use of deprecated bundlebuilder in OS X builds.
üst
502ef90a
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
16 additions
and
953 deletions
+16
-953
Info.plist.in
Mac/PythonLauncher/Info.plist.in
+2
-2
Makefile.in
Mac/PythonLauncher/Makefile.in
+13
-17
bundlebuilder.py
Mac/Tools/bundlebuilder.py
+0
-934
NEWS
Misc/NEWS
+1
-0
No files found.
Mac/PythonLauncher/Info.plist.in
Dosyayı görüntüle @
13399445
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple
Computer
//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist
version=
"1.0"
>
<plist
version=
"1.0"
>
<dict>
<dict>
<key>
CFBundleDevelopmentRegion
</key>
<key>
CFBundleDevelopmentRegion
</key>
...
@@ -38,7 +38,7 @@
...
@@ -38,7 +38,7 @@
</dict>
</dict>
</array>
</array>
<key>
CFBundleExecutable
</key>
<key>
CFBundleExecutable
</key>
<string>
PythonLauncher
</string>
<string>
Python
Launcher
</string>
<key>
CFBundleGetInfoString
</key>
<key>
CFBundleGetInfoString
</key>
<string>
%VERSION%, © 2001-2014 Python Software Foundation
</string>
<string>
%VERSION%, © 2001-2014 Python Software Foundation
</string>
<key>
CFBundleIconFile
</key>
<key>
CFBundleIconFile
</key>
...
...
Mac/PythonLauncher/Makefile.in
Dosyayı görüntüle @
13399445
...
@@ -15,12 +15,10 @@ BUILDPYTHON= $(builddir)/python$(BUILDEXE)
...
@@ -15,12 +15,10 @@ BUILDPYTHON= $(builddir)/python$(BUILDEXE)
PYTHONFRAMEWORK
=
@PYTHONFRAMEWORK@
PYTHONFRAMEWORK
=
@PYTHONFRAMEWORK@
# Deployment target selected during configure, to be checked
# Deployment target selected during configure, to be checked
# by distutils
# by distutils
MACOSX_DEPLOYMENT_TARGET
=
@CONFIGURE_MACOSX_DEPLOYMENT_TARGET@
MACOSX_DEPLOYMENT_TARGET
=
@CONFIGURE_MACOSX_DEPLOYMENT_TARGET@
@EXPORT_MACOSX_DEPLOYMENT_TARGET@
export
MACOSX_DEPLOYMENT_TARGET
@EXPORT_MACOSX_DEPLOYMENT_TARGET@
export
MACOSX_DEPLOYMENT_TARGET
BUNDLEBULDER
=
$(srcdir)
/../Tools/bundlebuilder.py
PYTHONAPPSDIR
=
@FRAMEWORKINSTALLAPPSPREFIX@/
$(PYTHONFRAMEWORK)
$(VERSION)
PYTHONAPPSDIR
=
@FRAMEWORKINSTALLAPPSPREFIX@/
$(PYTHONFRAMEWORK)
$(VERSION)
OBJECTS
=
FileSettings.o MyAppDelegate.o MyDocument.o PreferencesWindowController.o doscript.o main.o
OBJECTS
=
FileSettings.o MyAppDelegate.o MyDocument.o PreferencesWindowController.o doscript.o main.o
...
@@ -30,10 +28,10 @@ install: Python\ Launcher.app
...
@@ -30,10 +28,10 @@ install: Python\ Launcher.app
/bin/cp
-r
"Python Launcher.app"
"
$(DESTDIR)$(PYTHONAPPSDIR)
"
/bin/cp
-r
"Python Launcher.app"
"
$(DESTDIR)$(PYTHONAPPSDIR)
"
touch
"
$(DESTDIR)$(PYTHONAPPSDIR)
/Python Launcher.app"
touch
"
$(DESTDIR)$(PYTHONAPPSDIR)
/Python Launcher.app"
clean
:
clean
:
rm
-f
*
.o
"Python Launcher"
rm
-f
*
.o
"Python Launcher"
rm
-rf
"Python Launcher.app"
rm
-rf
"Python Launcher.app"
rm
-f
Info.plist
Python\ Launcher.app
:
Info.plist
\
Python\ Launcher.app
:
Info.plist
\
Python
\
Launcher $(srcdir)/../Icons/PythonLauncher.icns
\
Python
\
Launcher $(srcdir)/../Icons/PythonLauncher.icns
\
...
@@ -41,20 +39,18 @@ Python\ Launcher.app: Info.plist \
...
@@ -41,20 +39,18 @@ Python\ Launcher.app: Info.plist \
$(srcdir)/../Icons/PythonCompiled.icns
\
$(srcdir)/../Icons/PythonCompiled.icns
\
$(srcdir)/factorySettings.plist
$(srcdir)/factorySettings.plist
rm
-fr
"Python Launcher.app"
rm
-fr
"Python Launcher.app"
$(RUNSHARED)
$(BUILDPYTHON)
$(BUNDLEBULDER)
\
mkdir
"Python Launcher.app"
--builddir
=
.
\
mkdir
"Python Launcher.app/Contents"
--name
=
"Python Launcher"
\
mkdir
"Python Launcher.app/Contents/MacOS"
--executable
=
"Python Launcher"
\
mkdir
"Python Launcher.app/Contents/Resources"
--iconfile
=
$(srcdir)
/../Icons/PythonLauncher.icns
\
cp
"Python Launcher"
"Python Launcher.app/Contents/MacOS"
--bundle-id
=
org.python.PythonLauncher
\
cp
Info.plist
"Python Launcher.app/Contents"
--resource
=
$(srcdir)
/../Icons/PythonSource.icns
\
cp
$(srcdir)
/../Icons/PythonLauncher.icns
"Python Launcher.app/Contents/Resources"
--resource
=
$(srcdir)
/../Icons/PythonCompiled.icns
\
cp
$(srcdir)
/../Icons/PythonSource.icns
"Python Launcher.app/Contents/Resources"
--resource
=
$(srcdir)
/English.lproj
\
cp
$(srcdir)
/../Icons/PythonCompiled.icns
"Python Launcher.app/Contents/Resources"
--resource
=
$(srcdir)
/factorySettings.plist
\
cp
$(srcdir)
/factorySettings.plist
"Python Launcher.app/Contents/Resources"
--plist
Info.plist
\
cp
-R
$(srcdir)
/English.lproj
"Python Launcher.app/Contents/Resources"
build
find
"Python Launcher.app"
-name
'.svn'
-print0
| xargs
-0
rm
-r
find
"Python Launcher.app"
-name
'.svn'
-print0
| xargs
-0
rm
-r
FileSettings.o
:
$(srcdir)/FileSettings.m
FileSettings.o
:
$(srcdir)/FileSettings.m
$(CC)
$(CFLAGS)
-o
$@
-c
$(srcdir)
/FileSettings.m
$(CC)
$(CFLAGS)
-o
$@
-c
$(srcdir)
/FileSettings.m
...
...
Mac/Tools/bundlebuilder.py
deleted
100755 → 0
Dosyayı görüntüle @
502ef90a
#! /usr/bin/env python
"""
\
bundlebuilder.py -- Tools to assemble MacOS X (application) bundles.
This module contains two classes to build so called "bundles" for
MacOS X. BundleBuilder is a general tool, AppBuilder is a subclass
specialized in building application bundles.
[Bundle|App]Builder objects are instantiated with a bunch of keyword
arguments, and have a build() method that will do all the work. See
the class doc strings for a description of the constructor arguments.
The module contains a main program that can be used in two ways:
%
python bundlebuilder.py [options] build
%
python buildapp.py [options] build
Where "buildapp.py" is a user-supplied setup.py-like script following
this model:
from bundlebuilder import buildapp
buildapp(<lots-of-keyword-args>)
"""
__all__
=
[
"BundleBuilder"
,
"BundleBuilderError"
,
"AppBuilder"
,
"buildapp"
]
import
sys
import
os
,
errno
,
shutil
import
imp
,
marshal
import
re
from
copy
import
deepcopy
import
getopt
from
plistlib
import
Plist
from
types
import
FunctionType
as
function
class
BundleBuilderError
(
Exception
):
pass
class
Defaults
:
"""Class attributes that don't start with an underscore and are
not functions or classmethods are (deep)copied to self.__dict__.
This allows for mutable default values.
"""
def
__init__
(
self
,
**
kwargs
):
defaults
=
self
.
_getDefaults
()
defaults
.
update
(
kwargs
)
self
.
__dict__
.
update
(
defaults
)
def
_getDefaults
(
cls
):
defaults
=
{}
for
base
in
cls
.
__bases__
:
if
hasattr
(
base
,
"_getDefaults"
):
defaults
.
update
(
base
.
_getDefaults
())
for
name
,
value
in
list
(
cls
.
__dict__
.
items
()):
if
name
[
0
]
!=
"_"
and
not
isinstance
(
value
,
(
function
,
classmethod
)):
defaults
[
name
]
=
deepcopy
(
value
)
return
defaults
_getDefaults
=
classmethod
(
_getDefaults
)
class
BundleBuilder
(
Defaults
):
"""BundleBuilder is a barebones class for assembling bundles. It
knows nothing about executables or icons, it only copies files
and creates the PkgInfo and Info.plist files.
"""
# (Note that Defaults.__init__ (deep)copies these values to
# instance variables. Mutable defaults are therefore safe.)
# Name of the bundle, with or without extension.
name
=
None
# The property list ("plist")
plist
=
Plist
(
CFBundleDevelopmentRegion
=
"English"
,
CFBundleInfoDictionaryVersion
=
"6.0"
)
# The type of the bundle.
type
=
"BNDL"
# The creator code of the bundle.
creator
=
None
# the CFBundleIdentifier (this is used for the preferences file name)
bundle_id
=
None
# List of files that have to be copied to <bundle>/Contents/Resources.
resources
=
[]
# List of (src, dest) tuples; dest should be a path relative to the bundle
# (eg. "Contents/Resources/MyStuff/SomeFile.ext).
files
=
[]
# List of shared libraries (dylibs, Frameworks) to bundle with the app
# will be placed in Contents/Frameworks
libs
=
[]
# Directory where the bundle will be assembled.
builddir
=
"build"
# Make symlinks instead copying files. This is handy during debugging, but
# makes the bundle non-distributable.
symlink
=
0
# Verbosity level.
verbosity
=
1
# Destination root directory
destroot
=
""
def
setup
(
self
):
# XXX rethink self.name munging, this is brittle.
self
.
name
,
ext
=
os
.
path
.
splitext
(
self
.
name
)
if
not
ext
:
ext
=
".bundle"
bundleextension
=
ext
# misc (derived) attributes
self
.
bundlepath
=
pathjoin
(
self
.
builddir
,
self
.
name
+
bundleextension
)
plist
=
self
.
plist
plist
.
CFBundleName
=
self
.
name
plist
.
CFBundlePackageType
=
self
.
type
if
self
.
creator
is
None
:
if
hasattr
(
plist
,
"CFBundleSignature"
):
self
.
creator
=
plist
.
CFBundleSignature
else
:
self
.
creator
=
"????"
plist
.
CFBundleSignature
=
self
.
creator
if
self
.
bundle_id
:
plist
.
CFBundleIdentifier
=
self
.
bundle_id
elif
not
hasattr
(
plist
,
"CFBundleIdentifier"
):
plist
.
CFBundleIdentifier
=
self
.
name
def
build
(
self
):
"""Build the bundle."""
builddir
=
self
.
builddir
if
builddir
and
not
os
.
path
.
exists
(
builddir
):
os
.
mkdir
(
builddir
)
self
.
message
(
"Building
%
s"
%
repr
(
self
.
bundlepath
),
1
)
if
os
.
path
.
exists
(
self
.
bundlepath
):
shutil
.
rmtree
(
self
.
bundlepath
)
if
os
.
path
.
exists
(
self
.
bundlepath
+
'~'
):
shutil
.
rmtree
(
self
.
bundlepath
+
'~'
)
bp
=
self
.
bundlepath
# Create the app bundle in a temporary location and then
# rename the completed bundle. This way the Finder will
# never see an incomplete bundle (where it might pick up
# and cache the wrong meta data)
self
.
bundlepath
=
bp
+
'~'
try
:
os
.
mkdir
(
self
.
bundlepath
)
self
.
preProcess
()
self
.
_copyFiles
()
self
.
_addMetaFiles
()
self
.
postProcess
()
os
.
rename
(
self
.
bundlepath
,
bp
)
finally
:
self
.
bundlepath
=
bp
self
.
message
(
"Done."
,
1
)
def
preProcess
(
self
):
"""Hook for subclasses."""
pass
def
postProcess
(
self
):
"""Hook for subclasses."""
pass
def
_addMetaFiles
(
self
):
contents
=
pathjoin
(
self
.
bundlepath
,
"Contents"
)
makedirs
(
contents
)
#
# Write Contents/PkgInfo
assert
len
(
self
.
type
)
==
len
(
self
.
creator
)
==
4
,
\
"type and creator must be 4-byte strings."
pkginfo
=
pathjoin
(
contents
,
"PkgInfo"
)
f
=
open
(
pkginfo
,
"wb"
)
f
.
write
((
self
.
type
+
self
.
creator
)
.
encode
(
'latin1'
))
f
.
close
()
#
# Write Contents/Info.plist
infoplist
=
pathjoin
(
contents
,
"Info.plist"
)
self
.
plist
.
write
(
infoplist
)
def
_copyFiles
(
self
):
files
=
self
.
files
[:]
for
path
in
self
.
resources
:
files
.
append
((
path
,
pathjoin
(
"Contents"
,
"Resources"
,
os
.
path
.
basename
(
path
))))
for
path
in
self
.
libs
:
files
.
append
((
path
,
pathjoin
(
"Contents"
,
"Frameworks"
,
os
.
path
.
basename
(
path
))))
if
self
.
symlink
:
self
.
message
(
"Making symbolic links"
,
1
)
msg
=
"Making symlink from"
else
:
self
.
message
(
"Copying files"
,
1
)
msg
=
"Copying"
files
.
sort
()
for
src
,
dst
in
files
:
if
os
.
path
.
isdir
(
src
):
self
.
message
(
"
%
s
%
s/ to
%
s/"
%
(
msg
,
src
,
dst
),
2
)
else
:
self
.
message
(
"
%
s
%
s to
%
s"
%
(
msg
,
src
,
dst
),
2
)
dst
=
pathjoin
(
self
.
bundlepath
,
dst
)
if
self
.
symlink
:
symlink
(
src
,
dst
,
mkdirs
=
1
)
else
:
copy
(
src
,
dst
,
mkdirs
=
1
)
def
message
(
self
,
msg
,
level
=
0
):
if
level
<=
self
.
verbosity
:
indent
=
""
if
level
>
1
:
indent
=
(
level
-
1
)
*
" "
sys
.
stderr
.
write
(
indent
+
msg
+
"
\n
"
)
def
report
(
self
):
# XXX something decent
pass
if
__debug__
:
PYC_EXT
=
".pyc"
else
:
PYC_EXT
=
".pyo"
MAGIC
=
imp
.
get_magic
()
USE_ZIPIMPORT
=
"zipimport"
in
sys
.
builtin_module_names
# For standalone apps, we have our own minimal site.py. We don't need
# all the cruft of the real site.py.
SITE_PY
=
"""
\
import sys
if not
%(semi_standalone)
s:
del sys.path[1:] # sys.path[0] is Contents/Resources/
"""
if
USE_ZIPIMPORT
:
ZIP_ARCHIVE
=
"Modules.zip"
SITE_PY
+=
"sys.path.append(sys.path[0] + '/
%
s')
\n
"
%
ZIP_ARCHIVE
def
getPycData
(
fullname
,
code
,
ispkg
):
if
ispkg
:
fullname
+=
".__init__"
path
=
fullname
.
replace
(
"."
,
os
.
sep
)
+
PYC_EXT
return
path
,
MAGIC
+
'
\0\0\0\0
'
+
marshal
.
dumps
(
code
)
#
# Extension modules can't be in the modules zip archive, so a placeholder
# is added instead, that loads the extension from a specified location.
#
EXT_LOADER
=
"""
\
def __load():
import imp, sys, os
for p in sys.path:
path = os.path.join(p, "
%(filename)
s")
if os.path.exists(path):
break
else:
assert 0, "file not found:
%(filename)
s"
mod = imp.load_dynamic("
%(name)
s", path)
__load()
del __load
"""
MAYMISS_MODULES
=
[
'mac'
,
'nt'
,
'ntpath'
,
'dos'
,
'dospath'
,
'win32api'
,
'ce'
,
'_winreg'
,
'nturl2path'
,
'sitecustomize'
,
'org.python.core'
,
'riscos'
,
'riscosenviron'
,
'riscospath'
]
STRIP_EXEC
=
"/usr/bin/strip"
#
# We're using a stock interpreter to run the app, yet we need
# a way to pass the Python main program to the interpreter. The
# bootstrapping script fires up the interpreter with the right
# arguments. os.execve() is used as OSX doesn't like us to
# start a real new process. Also, the executable name must match
# the CFBundleExecutable value in the Info.plist, so we lie
# deliberately with argv[0]. The actual Python executable is
# passed in an environment variable so we can "repair"
# sys.executable later.
#
BOOTSTRAP_SCRIPT
=
"""
\
#!
%(hashbang)
s
import sys, os
execdir = os.path.dirname(sys.argv[0])
executable = os.path.join(execdir, "
%(executable)
s")
resdir = os.path.join(os.path.dirname(execdir), "Resources")
libdir = os.path.join(os.path.dirname(execdir), "Frameworks")
mainprogram = os.path.join(resdir, "
%(mainprogram)
s")
sys.argv.insert(1, mainprogram)
if
%(standalone)
s or
%(semi_standalone)
s:
os.environ["PYTHONPATH"] = resdir
if
%(standalone)
s:
os.environ["PYTHONHOME"] = resdir
else:
pypath = os.getenv("PYTHONPATH", "")
if pypath:
pypath = ":" + pypath
os.environ["PYTHONPATH"] = resdir + pypath
os.environ["PYTHONEXECUTABLE"] = executable
os.environ["DYLD_LIBRARY_PATH"] = libdir
os.environ["DYLD_FRAMEWORK_PATH"] = libdir
os.execve(executable, sys.argv, os.environ)
"""
#
# Optional wrapper that converts "dropped files" into sys.argv values.
#
ARGV_EMULATOR
=
"""
\
import argvemulator, os
argvemulator.ArgvCollector().mainloop()
execfile(os.path.join(os.path.split(__file__)[0], "
%(realmainprogram)
s"))
"""
#
# When building a standalone app with Python.framework, we need to copy
# a subset from Python.framework to the bundle. The following list
# specifies exactly what items we'll copy.
#
PYTHONFRAMEWORKGOODIES
=
[
"Python"
,
# the Python core library
"Resources/English.lproj"
,
"Resources/Info.plist"
,
"Resources/version.plist"
,
]
def
isFramework
():
return
sys
.
exec_prefix
.
find
(
"Python.framework"
)
>
0
LIB
=
os
.
path
.
join
(
sys
.
prefix
,
"lib"
,
"python"
+
sys
.
version
[:
3
])
SITE_PACKAGES
=
os
.
path
.
join
(
LIB
,
"site-packages"
)
class
AppBuilder
(
BundleBuilder
):
# Override type of the bundle.
type
=
"APPL"
# platform, name of the subfolder of Contents that contains the executable.
platform
=
"MacOS"
# A Python main program. If this argument is given, the main
# executable in the bundle will be a small wrapper that invokes
# the main program. (XXX Discuss why.)
mainprogram
=
None
# The main executable. If a Python main program is specified
# the executable will be copied to Resources and be invoked
# by the wrapper program mentioned above. Otherwise it will
# simply be used as the main executable.
executable
=
None
# The name of the main nib, for Cocoa apps. *Must* be specified
# when building a Cocoa app.
nibname
=
None
# The name of the icon file to be copied to Resources and used for
# the Finder icon.
iconfile
=
None
# Symlink the executable instead of copying it.
symlink_exec
=
0
# If True, build standalone app.
standalone
=
0
# If True, build semi-standalone app (only includes third-party modules).
semi_standalone
=
0
# If set, use this for #! lines in stead of sys.executable
python
=
None
# If True, add a real main program that emulates sys.argv before calling
# mainprogram
argv_emulation
=
0
# The following attributes are only used when building a standalone app.
# Exclude these modules.
excludeModules
=
[]
# Include these modules.
includeModules
=
[]
# Include these packages.
includePackages
=
[]
# Strip binaries from debug info.
strip
=
0
# Found Python modules: [(name, codeobject, ispkg), ...]
pymodules
=
[]
# Modules that modulefinder couldn't find:
missingModules
=
[]
maybeMissingModules
=
[]
def
setup
(
self
):
if
((
self
.
standalone
or
self
.
semi_standalone
)
and
self
.
mainprogram
is
None
):
raise
BundleBuilderError
(
"must specify 'mainprogram' when "
"building a standalone application."
)
if
self
.
mainprogram
is
None
and
self
.
executable
is
None
:
raise
BundleBuilderError
(
"must specify either or both of "
"'executable' and 'mainprogram'"
)
self
.
execdir
=
pathjoin
(
"Contents"
,
self
.
platform
)
if
self
.
name
is
not
None
:
pass
elif
self
.
mainprogram
is
not
None
:
self
.
name
=
os
.
path
.
splitext
(
os
.
path
.
basename
(
self
.
mainprogram
))[
0
]
elif
executable
is
not
None
:
self
.
name
=
os
.
path
.
splitext
(
os
.
path
.
basename
(
self
.
executable
))[
0
]
if
self
.
name
[
-
4
:]
!=
".app"
:
self
.
name
+=
".app"
if
self
.
executable
is
None
:
if
not
self
.
standalone
and
not
isFramework
():
self
.
symlink_exec
=
1
if
self
.
python
:
self
.
executable
=
self
.
python
else
:
self
.
executable
=
sys
.
executable
if
self
.
nibname
:
self
.
plist
.
NSMainNibFile
=
self
.
nibname
if
not
hasattr
(
self
.
plist
,
"NSPrincipalClass"
):
self
.
plist
.
NSPrincipalClass
=
"NSApplication"
if
self
.
standalone
and
isFramework
():
self
.
addPythonFramework
()
BundleBuilder
.
setup
(
self
)
self
.
plist
.
CFBundleExecutable
=
self
.
name
if
self
.
standalone
or
self
.
semi_standalone
:
self
.
findDependencies
()
def
preProcess
(
self
):
resdir
=
"Contents/Resources"
if
self
.
executable
is
not
None
:
if
self
.
mainprogram
is
None
:
execname
=
self
.
name
else
:
execname
=
os
.
path
.
basename
(
self
.
executable
)
execpath
=
pathjoin
(
self
.
execdir
,
execname
)
if
not
self
.
symlink_exec
:
self
.
files
.
append
((
self
.
destroot
+
self
.
executable
,
execpath
))
self
.
execpath
=
execpath
if
self
.
mainprogram
is
not
None
:
mainprogram
=
os
.
path
.
basename
(
self
.
mainprogram
)
self
.
files
.
append
((
self
.
mainprogram
,
pathjoin
(
resdir
,
mainprogram
)))
if
self
.
argv_emulation
:
# Change the main program, and create the helper main program (which
# does argv collection and then calls the real main).
# Also update the included modules (if we're creating a standalone
# program) and the plist
realmainprogram
=
mainprogram
mainprogram
=
'__argvemulator_'
+
mainprogram
resdirpath
=
pathjoin
(
self
.
bundlepath
,
resdir
)
mainprogrampath
=
pathjoin
(
resdirpath
,
mainprogram
)
makedirs
(
resdirpath
)
open
(
mainprogrampath
,
"w"
)
.
write
(
ARGV_EMULATOR
%
locals
())
if
self
.
standalone
or
self
.
semi_standalone
:
self
.
includeModules
.
append
(
"argvemulator"
)
self
.
includeModules
.
append
(
"os"
)
if
"CFBundleDocumentTypes"
not
in
self
.
plist
:
self
.
plist
[
"CFBundleDocumentTypes"
]
=
[
{
"CFBundleTypeOSTypes"
:
[
"****"
,
"fold"
,
"disk"
],
"CFBundleTypeRole"
:
"Viewer"
}]
# Write bootstrap script
executable
=
os
.
path
.
basename
(
self
.
executable
)
execdir
=
pathjoin
(
self
.
bundlepath
,
self
.
execdir
)
bootstrappath
=
pathjoin
(
execdir
,
self
.
name
)
makedirs
(
execdir
)
if
self
.
standalone
or
self
.
semi_standalone
:
# XXX we're screwed when the end user has deleted
# /usr/bin/python
hashbang
=
"/usr/bin/python"
elif
self
.
python
:
hashbang
=
self
.
python
else
:
hashbang
=
os
.
path
.
realpath
(
sys
.
executable
)
standalone
=
self
.
standalone
semi_standalone
=
self
.
semi_standalone
open
(
bootstrappath
,
"w"
)
.
write
(
BOOTSTRAP_SCRIPT
%
locals
())
os
.
chmod
(
bootstrappath
,
0
o775
)
if
self
.
iconfile
is
not
None
:
iconbase
=
os
.
path
.
basename
(
self
.
iconfile
)
self
.
plist
.
CFBundleIconFile
=
iconbase
self
.
files
.
append
((
self
.
iconfile
,
pathjoin
(
resdir
,
iconbase
)))
def
postProcess
(
self
):
if
self
.
standalone
or
self
.
semi_standalone
:
self
.
addPythonModules
()
if
self
.
strip
and
not
self
.
symlink
:
self
.
stripBinaries
()
if
self
.
symlink_exec
and
self
.
executable
:
self
.
message
(
"Symlinking executable
%
s to
%
s"
%
(
self
.
executable
,
self
.
execpath
),
2
)
dst
=
pathjoin
(
self
.
bundlepath
,
self
.
execpath
)
makedirs
(
os
.
path
.
dirname
(
dst
))
os
.
symlink
(
os
.
path
.
abspath
(
self
.
executable
),
dst
)
if
self
.
missingModules
or
self
.
maybeMissingModules
:
self
.
reportMissing
()
def
addPythonFramework
(
self
):
# If we're building a standalone app with Python.framework,
# include a minimal subset of Python.framework, *unless*
# Python.framework was specified manually in self.libs.
for
lib
in
self
.
libs
:
if
os
.
path
.
basename
(
lib
)
==
"Python.framework"
:
# a Python.framework was specified as a library
return
frameworkpath
=
sys
.
exec_prefix
[:
sys
.
exec_prefix
.
find
(
"Python.framework"
)
+
len
(
"Python.framework"
)]
version
=
sys
.
version
[:
3
]
frameworkpath
=
pathjoin
(
frameworkpath
,
"Versions"
,
version
)
destbase
=
pathjoin
(
"Contents"
,
"Frameworks"
,
"Python.framework"
,
"Versions"
,
version
)
for
item
in
PYTHONFRAMEWORKGOODIES
:
src
=
pathjoin
(
frameworkpath
,
item
)
dst
=
pathjoin
(
destbase
,
item
)
self
.
files
.
append
((
src
,
dst
))
def
_getSiteCode
(
self
):
return
compile
(
SITE_PY
%
{
"semi_standalone"
:
self
.
semi_standalone
},
"<-bundlebuilder.py->"
,
"exec"
)
def
addPythonModules
(
self
):
self
.
message
(
"Adding Python modules"
,
1
)
if
USE_ZIPIMPORT
:
# Create a zip file containing all modules as pyc.
import
zipfile
relpath
=
pathjoin
(
"Contents"
,
"Resources"
,
ZIP_ARCHIVE
)
abspath
=
pathjoin
(
self
.
bundlepath
,
relpath
)
zf
=
zipfile
.
ZipFile
(
abspath
,
"w"
,
zipfile
.
ZIP_DEFLATED
)
for
name
,
code
,
ispkg
in
self
.
pymodules
:
self
.
message
(
"Adding Python module
%
s"
%
name
,
2
)
path
,
pyc
=
getPycData
(
name
,
code
,
ispkg
)
zf
.
writestr
(
path
,
pyc
)
zf
.
close
()
# add site.pyc
sitepath
=
pathjoin
(
self
.
bundlepath
,
"Contents"
,
"Resources"
,
"site"
+
PYC_EXT
)
writePyc
(
self
.
_getSiteCode
(),
sitepath
)
else
:
# Create individual .pyc files.
for
name
,
code
,
ispkg
in
self
.
pymodules
:
if
ispkg
:
name
+=
".__init__"
path
=
name
.
split
(
"."
)
path
=
pathjoin
(
"Contents"
,
"Resources"
,
*
path
)
+
PYC_EXT
if
ispkg
:
self
.
message
(
"Adding Python package
%
s"
%
path
,
2
)
else
:
self
.
message
(
"Adding Python module
%
s"
%
path
,
2
)
abspath
=
pathjoin
(
self
.
bundlepath
,
path
)
makedirs
(
os
.
path
.
dirname
(
abspath
))
writePyc
(
code
,
abspath
)
def
stripBinaries
(
self
):
if
not
os
.
path
.
exists
(
STRIP_EXEC
):
self
.
message
(
"Error: can't strip binaries: no strip program at "
"
%
s"
%
STRIP_EXEC
,
0
)
else
:
import
stat
self
.
message
(
"Stripping binaries"
,
1
)
def
walk
(
top
):
for
name
in
os
.
listdir
(
top
):
path
=
pathjoin
(
top
,
name
)
if
os
.
path
.
islink
(
path
):
continue
if
os
.
path
.
isdir
(
path
):
walk
(
path
)
else
:
mod
=
os
.
stat
(
path
)[
stat
.
ST_MODE
]
if
not
(
mod
&
0
o100
):
continue
relpath
=
path
[
len
(
self
.
bundlepath
):]
self
.
message
(
"Stripping
%
s"
%
relpath
,
2
)
inf
,
outf
=
os
.
popen4
(
"
%
s -S
\"
%
s
\"
"
%
(
STRIP_EXEC
,
path
))
output
=
outf
.
read
()
.
strip
()
if
output
:
# usually not a real problem, like when we're
# trying to strip a script
self
.
message
(
"Problem stripping
%
s:"
%
relpath
,
3
)
self
.
message
(
output
,
3
)
walk
(
self
.
bundlepath
)
def
findDependencies
(
self
):
self
.
message
(
"Finding module dependencies"
,
1
)
import
modulefinder
mf
=
modulefinder
.
ModuleFinder
(
excludes
=
self
.
excludeModules
)
if
USE_ZIPIMPORT
:
# zipimport imports zlib, must add it manually
mf
.
import_hook
(
"zlib"
)
# manually add our own site.py
site
=
mf
.
add_module
(
"site"
)
site
.
__code__
=
self
.
_getSiteCode
()
mf
.
scan_code
(
site
.
__code__
,
site
)
# warnings.py gets imported implicitly from C
mf
.
import_hook
(
"warnings"
)
includeModules
=
self
.
includeModules
[:]
for
name
in
self
.
includePackages
:
includeModules
.
extend
(
list
(
findPackageContents
(
name
)
.
keys
()))
for
name
in
includeModules
:
try
:
mf
.
import_hook
(
name
)
except
ImportError
:
self
.
missingModules
.
append
(
name
)
mf
.
run_script
(
self
.
mainprogram
)
modules
=
list
(
mf
.
modules
.
items
())
modules
.
sort
()
for
name
,
mod
in
modules
:
path
=
mod
.
__file__
if
path
and
self
.
semi_standalone
:
# skip the standard library
if
path
.
startswith
(
LIB
)
and
not
path
.
startswith
(
SITE_PACKAGES
):
continue
if
path
and
mod
.
__code__
is
None
:
# C extension
filename
=
os
.
path
.
basename
(
path
)
pathitems
=
name
.
split
(
"."
)[:
-
1
]
+
[
filename
]
dstpath
=
pathjoin
(
*
pathitems
)
if
USE_ZIPIMPORT
:
if
name
!=
"zlib"
:
# neatly pack all extension modules in a subdirectory,
# except zlib, since it's necessary for bootstrapping.
dstpath
=
pathjoin
(
"ExtensionModules"
,
dstpath
)
# Python modules are stored in a Zip archive, but put
# extensions in Contents/Resources/. Add a tiny "loader"
# program in the Zip archive. Due to Thomas Heller.
source
=
EXT_LOADER
%
{
"name"
:
name
,
"filename"
:
dstpath
}
code
=
compile
(
source
,
"<dynloader for
%
s>"
%
name
,
"exec"
)
mod
.
__code__
=
code
self
.
files
.
append
((
path
,
pathjoin
(
"Contents"
,
"Resources"
,
dstpath
)))
if
mod
.
__code__
is
not
None
:
ispkg
=
mod
.
__path__
is
not
None
if
not
USE_ZIPIMPORT
or
name
!=
"site"
:
# Our site.py is doing the bootstrapping, so we must
# include a real .pyc file if USE_ZIPIMPORT is True.
self
.
pymodules
.
append
((
name
,
mod
.
__code__
,
ispkg
))
if
hasattr
(
mf
,
"any_missing_maybe"
):
missing
,
maybe
=
mf
.
any_missing_maybe
()
else
:
missing
=
mf
.
any_missing
()
maybe
=
[]
self
.
missingModules
.
extend
(
missing
)
self
.
maybeMissingModules
.
extend
(
maybe
)
def
reportMissing
(
self
):
missing
=
[
name
for
name
in
self
.
missingModules
if
name
not
in
MAYMISS_MODULES
]
if
self
.
maybeMissingModules
:
maybe
=
self
.
maybeMissingModules
else
:
maybe
=
[
name
for
name
in
missing
if
"."
in
name
]
missing
=
[
name
for
name
in
missing
if
"."
not
in
name
]
missing
.
sort
()
maybe
.
sort
()
if
maybe
:
self
.
message
(
"Warning: couldn't find the following submodules:"
,
1
)
self
.
message
(
" (Note that these could be false alarms -- "
"it's not always"
,
1
)
self
.
message
(
" possible to distinguish between
\"
from package "
"import submodule
\"
"
,
1
)
self
.
message
(
" and
\"
from package import name
\"
)"
,
1
)
for
name
in
maybe
:
self
.
message
(
" ? "
+
name
,
1
)
if
missing
:
self
.
message
(
"Warning: couldn't find the following modules:"
,
1
)
for
name
in
missing
:
self
.
message
(
" ? "
+
name
,
1
)
def
report
(
self
):
# XXX something decent
import
pprint
pprint
.
pprint
(
self
.
__dict__
)
if
self
.
standalone
or
self
.
semi_standalone
:
self
.
reportMissing
()
#
# Utilities.
#
SUFFIXES
=
[
_suf
for
_suf
,
_mode
,
_tp
in
imp
.
get_suffixes
()]
identifierRE
=
re
.
compile
(
r"[_a-zA-z][_a-zA-Z0-9]*$"
)
def
findPackageContents
(
name
,
searchpath
=
None
):
head
=
name
.
split
(
"."
)[
-
1
]
if
identifierRE
.
match
(
head
)
is
None
:
return
{}
try
:
fp
,
path
,
(
ext
,
mode
,
tp
)
=
imp
.
find_module
(
head
,
searchpath
)
except
ImportError
:
return
{}
modules
=
{
name
:
None
}
if
tp
==
imp
.
PKG_DIRECTORY
and
path
:
files
=
os
.
listdir
(
path
)
for
sub
in
files
:
sub
,
ext
=
os
.
path
.
splitext
(
sub
)
fullname
=
name
+
"."
+
sub
if
sub
!=
"__init__"
and
fullname
not
in
modules
:
modules
.
update
(
findPackageContents
(
fullname
,
[
path
]))
return
modules
def
writePyc
(
code
,
path
):
f
=
open
(
path
,
"wb"
)
f
.
write
(
MAGIC
)
f
.
write
(
"
\0
"
*
4
)
# don't bother about a time stamp
marshal
.
dump
(
code
,
f
)
f
.
close
()
def
copy
(
src
,
dst
,
mkdirs
=
0
):
"""Copy a file or a directory."""
if
mkdirs
:
makedirs
(
os
.
path
.
dirname
(
dst
))
if
os
.
path
.
isdir
(
src
):
shutil
.
copytree
(
src
,
dst
,
symlinks
=
1
)
else
:
shutil
.
copy2
(
src
,
dst
)
def
copytodir
(
src
,
dstdir
):
"""Copy a file or a directory to an existing directory."""
dst
=
pathjoin
(
dstdir
,
os
.
path
.
basename
(
src
))
copy
(
src
,
dst
)
def
makedirs
(
dir
):
"""Make all directories leading up to 'dir' including the leaf
directory. Don't moan if any path element already exists."""
try
:
os
.
makedirs
(
dir
)
except
OSError
as
why
:
if
why
.
errno
!=
errno
.
EEXIST
:
raise
def
symlink
(
src
,
dst
,
mkdirs
=
0
):
"""Copy a file or a directory."""
if
not
os
.
path
.
exists
(
src
):
raise
IOError
(
"No such file or directory: '
%
s'"
%
src
)
if
mkdirs
:
makedirs
(
os
.
path
.
dirname
(
dst
))
os
.
symlink
(
os
.
path
.
abspath
(
src
),
dst
)
def
pathjoin
(
*
args
):
"""Safe wrapper for os.path.join: asserts that all but the first
argument are relative paths."""
for
seg
in
args
[
1
:]:
assert
seg
[
0
]
!=
"/"
return
os
.
path
.
join
(
*
args
)
cmdline_doc
=
"""
\
Usage:
python bundlebuilder.py [options] command
python mybuildscript.py [options] command
Commands:
build build the application
report print a report
Options:
-b, --builddir=DIR the build directory; defaults to "build"
-n, --name=NAME application name
-r, --resource=FILE extra file or folder to be copied to Resources
-f, --file=SRC:DST extra file or folder to be copied into the bundle;
DST must be a path relative to the bundle root
-e, --executable=FILE the executable to be used
-m, --mainprogram=FILE the Python main program
-a, --argv add a wrapper main program to create sys.argv
-p, --plist=FILE .plist file (default: generate one)
--nib=NAME main nib name
-c, --creator=CCCC 4-char creator code (default: '????')
--iconfile=FILE filename of the icon (an .icns file) to be used
as the Finder icon
--bundle-id=ID the CFBundleIdentifier, in reverse-dns format
(eg. org.python.BuildApplet; this is used for
the preferences file name)
-l, --link symlink files/folder instead of copying them
--link-exec symlink the executable instead of copying it
--standalone build a standalone application, which is fully
independent of a Python installation
--semi-standalone build a standalone application, which depends on
an installed Python, yet includes all third-party
modules.
--python=FILE Python to use in #! line in stead of current Python
--lib=FILE shared library or framework to be copied into
the bundle
-x, --exclude=MODULE exclude module (with --(semi-)standalone)
-i, --include=MODULE include module (with --(semi-)standalone)
--package=PACKAGE include a whole package (with --(semi-)standalone)
--strip strip binaries (remove debug info)
-v, --verbose increase verbosity level
-q, --quiet decrease verbosity level
-h, --help print this message
"""
def
usage
(
msg
=
None
):
if
msg
:
print
(
msg
)
print
(
cmdline_doc
)
sys
.
exit
(
1
)
def
main
(
builder
=
None
):
if
builder
is
None
:
builder
=
AppBuilder
(
verbosity
=
1
)
shortopts
=
"b:n:r:f:e:m:c:p:lx:i:hvqa"
longopts
=
(
"builddir="
,
"name="
,
"resource="
,
"file="
,
"executable="
,
"mainprogram="
,
"creator="
,
"nib="
,
"plist="
,
"link"
,
"link-exec"
,
"help"
,
"verbose"
,
"quiet"
,
"argv"
,
"standalone"
,
"exclude="
,
"include="
,
"package="
,
"strip"
,
"iconfile="
,
"lib="
,
"python="
,
"semi-standalone"
,
"bundle-id="
,
"destroot="
)
try
:
options
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
shortopts
,
longopts
)
except
getopt
.
error
:
usage
()
for
opt
,
arg
in
options
:
if
opt
in
(
'-b'
,
'--builddir'
):
builder
.
builddir
=
arg
elif
opt
in
(
'-n'
,
'--name'
):
builder
.
name
=
arg
elif
opt
in
(
'-r'
,
'--resource'
):
builder
.
resources
.
append
(
os
.
path
.
normpath
(
arg
))
elif
opt
in
(
'-f'
,
'--file'
):
srcdst
=
arg
.
split
(
':'
)
if
len
(
srcdst
)
!=
2
:
usage
(
"-f or --file argument must be two paths, "
"separated by a colon"
)
builder
.
files
.
append
(
srcdst
)
elif
opt
in
(
'-e'
,
'--executable'
):
builder
.
executable
=
arg
elif
opt
in
(
'-m'
,
'--mainprogram'
):
builder
.
mainprogram
=
arg
elif
opt
in
(
'-a'
,
'--argv'
):
builder
.
argv_emulation
=
1
elif
opt
in
(
'-c'
,
'--creator'
):
builder
.
creator
=
arg
elif
opt
==
'--bundle-id'
:
builder
.
bundle_id
=
arg
elif
opt
==
'--iconfile'
:
builder
.
iconfile
=
arg
elif
opt
==
"--lib"
:
builder
.
libs
.
append
(
os
.
path
.
normpath
(
arg
))
elif
opt
==
"--nib"
:
builder
.
nibname
=
arg
elif
opt
in
(
'-p'
,
'--plist'
):
builder
.
plist
=
Plist
.
fromFile
(
arg
)
elif
opt
in
(
'-l'
,
'--link'
):
builder
.
symlink
=
1
elif
opt
==
'--link-exec'
:
builder
.
symlink_exec
=
1
elif
opt
in
(
'-h'
,
'--help'
):
usage
()
elif
opt
in
(
'-v'
,
'--verbose'
):
builder
.
verbosity
+=
1
elif
opt
in
(
'-q'
,
'--quiet'
):
builder
.
verbosity
-=
1
elif
opt
==
'--standalone'
:
builder
.
standalone
=
1
elif
opt
==
'--semi-standalone'
:
builder
.
semi_standalone
=
1
elif
opt
==
'--python'
:
builder
.
python
=
arg
elif
opt
in
(
'-x'
,
'--exclude'
):
builder
.
excludeModules
.
append
(
arg
)
elif
opt
in
(
'-i'
,
'--include'
):
builder
.
includeModules
.
append
(
arg
)
elif
opt
==
'--package'
:
builder
.
includePackages
.
append
(
arg
)
elif
opt
==
'--strip'
:
builder
.
strip
=
1
elif
opt
==
'--destroot'
:
builder
.
destroot
=
arg
if
len
(
args
)
!=
1
:
usage
(
"Must specify one command ('build', 'report' or 'help')"
)
command
=
args
[
0
]
if
command
==
"build"
:
builder
.
setup
()
builder
.
build
()
elif
command
==
"report"
:
builder
.
setup
()
builder
.
report
()
elif
command
==
"help"
:
usage
()
else
:
usage
(
"Unknown command '
%
s'"
%
command
)
def
buildapp
(
**
kwargs
):
builder
=
AppBuilder
(
**
kwargs
)
main
(
builder
)
if
__name__
==
"__main__"
:
main
()
Misc/NEWS
Dosyayı görüntüle @
13399445
...
@@ -176,6 +176,7 @@ Build
...
@@ -176,6 +176,7 @@ Build
-
Issue
#
15968
:
Incorporated
Tcl
,
Tk
,
and
Tix
builds
into
the
Windows
build
-
Issue
#
15968
:
Incorporated
Tcl
,
Tk
,
and
Tix
builds
into
the
Windows
build
solution
.
solution
.
-
Issue
#
20022
:
Eliminate
use
of
deprecated
bundlebuilder
in
OS
X
builds
.
What
's New in Python 3.4.0?
What
's New in Python 3.4.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