Commit 4d6a8c28 authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki

add slapos.extension.strip.

parent 85830c30
Changes
=======
0.1 (2014-10-22)
------------------
* Initial release.
Buildout Extension to strip binaries
====================================
slapos.extension.strip is a buildout extension that finds shared
libraries, binary executables and static libraries, and calls strip(1)
against them to reduce the size. It is triggered at the end of the
buildout process.
Usage
-----
Add ``slapos.extension.strip`` in ``[buildout]`` section's ``extensions`` option like :
::
[buildout]
extensions = slapos.extension.strip
Requirements
------------
The following programs are required. If any of them is missing, this
extension does nothing.
- ``file``
- ``find``
- ``strip``
Supported Options
-----------------
``file-binary``
Path to ``file`` program. Defaults to 'file' which should work on
any system that has the make program available in the system
``PATH``.
``find-binary``
Path to ``find`` program. Defaults to 'find' which should work on
any system that has the make program available in the system
``PATH``.
``strip-binary``
Path to ``strip`` program. Defaults to 'strip' which should work on
any system that has the make program available in the system
``PATH``.
from setuptools import setup, find_packages
import os
version = '0.1'
name = 'slapos.extension.strip'
def read(*rnames):
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
setup(
name=name,
version=version,
description="zc.buildout extension to strip binaries.",
long_description=(
read('README.rst')
+ '\n' +
read('CHANGES.txt')
+ '\n' +
'Download\n'
'***********************\n'
),
classifiers=[
'Framework :: Buildout :: Extension',
'License :: OSI Approved :: BSD License',
'Programming Language :: Python',
'Topic :: Software Development :: Build Tools',
],
keywords='buildout extension strip',
author='Kazuhiko Shiozaki',
author_email='kazuhiko@nexedi.com',
url='http://git.erp5.org/gitweb/slapos.extension.strip',
license='BSD',
packages=find_packages(exclude=['ez_setup']),
namespace_packages=['slapos', 'slapos.extension'],
include_package_data=True,
zip_safe=False,
install_requires=[
'zc.buildout',
],
entry_points = {
'zc.buildout.unloadextension': [
'default = slapos.extension.strip:finish',
],
},
)
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
try:
__import__('pkg_resources').declare_namespace(__name__)
except ImportError:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
try:
__import__('pkg_resources').declare_namespace(__name__)
except ImportError:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
import os
import re
import stat
import subprocess
def finish(buildout):
print 'Stripping binaries ...'
buildout_directory = buildout['buildout']['directory']
file_binary = buildout['buildout'].get('file-binary', 'file')
find_binary = buildout['buildout'].get('find-binary', 'find')
strip_binary = buildout['buildout'].get('strip-binary', 'strip')
def run_strip(path, strip_args):
mode = os.stat(path).st_mode
writable_mode = mode | stat.S_IWUSR
if mode != writable_mode:
os.chmod(path, writable_mode)
args = [strip_binary,] + strip_args + [path,]
p = subprocess.Popen(args, stdout=subprocess.PIPE)
result, _ = p.communicate()
if mode != writable_mode:
os.chmod(path, mode)
# Same logic as Debian's dh_strip script.
args = [find_binary, buildout_directory, '-type', 'f']
try:
p = subprocess.Popen(args, stdout=subprocess.PIPE)
file_list, _ = p.communicate()
shared_lib_list = []
executable_list = []
static_lib_list = []
for path in file_list.splitlines():
file_name = os.path.basename(path)
if re.match('.*\.(so(\..+)?|cmxs)$', file_name):
args = [file_binary, path]
p = subprocess.Popen(args, stdout=subprocess.PIPE)
result, _ = p.communicate()
if re.match('.*ELF.*shared.*not stripped', result):
shared_lib_list.append(path)
elif os.stat(path).st_mode & stat.S_IEXEC:
args = [file_binary, path]
p = subprocess.Popen(args, stdout=subprocess.PIPE)
result, _ = p.communicate()
if re.match('.*ELF.*(executable|shared).* not stripped', result):
executable_list.append(path)
elif re.match('lib.*\.a$', file_name):
static_lib_list.append(path)
for path in shared_lib_list:
strip_args = [
'--remove-section=.comment',
'--remove-section=.note',
'--strip-unneeded',
]
run_strip(path, strip_args)
for path in executable_list:
strip_args = [
'--remove-section=.comment',
'--remove-section=.note',
]
run_strip(path, strip_args)
for path in shared_lib_list:
strip_args = [
'--strip-debug',
]
run_strip(path, strip_args)
print 'Done.'
except OSError, e:
print 'Command failed: %s: %s' % (e, args)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment