update setup.py for bug fixing
we should update setup.py as below to support building .whl
#!/usr/bin/env python
from setuptools import setup
from distutils.extension import Extension
setup(
name = 'zbar',
version = '0.23.1',
author = 'Jeff Brown',
author_email = '[email protected]',
url = 'https://github.com/mchehab/zbar',
description = 'read barcodes from images or video',
license = 'LGPL',
long_description = open('README').read(),
classifiers = [
'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'Environment :: Console',
'Environment :: X11 Applications',
'Environment :: Win32 (MS Windows)',
'Operating System :: POSIX',
'Operating System :: Unix',
'Operating System :: Microsoft :: Windows',
'Topic :: Communications',
'Topic :: Multimedia :: Graphics',
'Topic :: Software Development :: Libraries',
],
ext_modules = [
Extension('zbar', [
'zbarmodule.c',
'enum.c',
'exception.c',
'symbol.c',
'symbolset.c',
'symboliter.c',
'image.c',
'processor.c',
'imagescanner.c',
'decoder.c',
'scanner.c',
],
libraries = [ 'zbar' ],
include_dirs = ['../include']
),
],
)
First i want to build the wheel with libzbar so that we can upload it to pypi and easy to install.
Second, using a pythonic way to wrap zbar maybe better such as what pyzbar did.
for the first thing, we can modify the setup.py like below
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
from setuptools import Extension
from setuptools import find_packages
from setuptools import setup
CUR_DIR = os.path.realpath(os.path.dirname(__file__))
zbar_init_path = os.path.join(CUR_DIR, "zbar_init")
SYS_MAP = {"msys": ["msys-zbar", ".dll"],
"win32": ["libzbar", ".dll"],
"linux": ["libzbar", ".so"],
"gnu": ["libzbar", ".so"]}
SYSTEM_KEY = [x for x in SYS_MAP.keys() if x.startswith(sys.platform)]
SYSTEM_KEY = SYSTEM_KEY[0] if SYSTEM_KEY else ""
LIB_PATTERN = SYS_MAP.get(SYSTEM_KEY, [])
def get_lib_path(lib_dir, lib_pattern):
"""
:param lib_dir:
:param lib_pattern: [prefix,postfix]
:return:
"""
path = ""
if os.path.isdir(lib_dir) and lib_pattern:
file_list = os.listdir(lib_dir)
start, end = lib_pattern
for f in file_list:
if f.startswith(start) and f.endswith(end):
path = os.path.join(lib_dir, f)
return path
LIB_PATH = get_lib_path(zbar_init_path, LIB_PATTERN)
WITH_LIB = bool(LIB_PATH)
print("#####")
print("setup zbar {} zbar lib".format("with" if WITH_LIB else "without"))
print("#####")
setup(
name='zbar',
version='0.23.1',
author='Jeff Brown',
author_email='[email protected]',
url='https://github.com/mchehab/zbar',
description='read barcodes from images or video',
license='LGPL',
long_description=open('README').read(),
classifiers=[
'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'Environment :: Console',
'Environment :: X11 Applications',
'Environment :: Win32 (MS Windows)',
'Operating System :: POSIX',
'Operating System :: Unix',
'Operating System :: Microsoft :: Windows',
'Topic :: Communications',
'Topic :: Multimedia :: Graphics',
'Topic :: Software Development :: Libraries',
],
packages=find_packages() if WITH_LIB else [],
package_data={"zbar_init": [os.path.basename(LIB_PATH)]} if WITH_LIB else {},
ext_modules=[
Extension('zbar', [
'zbarmodule.c',
'enum.c',
'exception.c',
'symbol.c',
'symbolset.c',
'symboliter.c',
'image.c',
'processor.c',
'imagescanner.c',
'decoder.c',
'scanner.c',
],
libraries=['zbar'],
include_dirs=['../include']
),
],
)
And then we can move the .so to ./zbar_initand rename to libzbar.so if we want to build a wheel with .so to migrate conveniently.
After that we meet a problem that how can python find the libzbar.so in the wheel.
so that i make a init module to load it explicitly. like below
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
from ctypes import CDLL
SYS_MAP = {"msys": ["msys-zbar", ".dll"],
"win32": ["libzbar", ".dll"],
"linux": ["libzbar", ".so"],
"gnu": ["libzbar", ".so"]}
SYSTEM_KEY = [x for x in SYS_MAP.keys() if x.startswith(sys.platform)]
SYSTEM_KEY = SYSTEM_KEY[0] if SYSTEM_KEY else ""
LIB_PATTERN = SYS_MAP.get(SYSTEM_KEY, [])
print("system platform is {}".format(SYSTEM_KEY)
if SYSTEM_KEY else "No valid zbar lib in this whl for {}".format(sys.platform))
def get_lib_path(lib_dir, lib_pattern):
"""
:param lib_dir:
:param lib_pattern: [prefix,postfix]
:return:
"""
path = ""
if os.path.isdir(lib_dir) and lib_pattern:
file_list = os.listdir(lib_dir)
start, end = lib_pattern
for f in file_list:
if f.startswith(start) and f.endswith(end):
path = os.path.join(lib_dir, f)
return path
CUR_DIR = os.path.realpath(os.path.dirname(__file__))
ZBAR_LIB_PATH = get_lib_path(CUR_DIR, LIB_PATTERN)
try:
import zbar
except ImportError as err:
print("warning : {}".format(err))
print("warning : Fail to get so or dll in the default path")
print("try to load {} ".format(ZBAR_LIB_PATH))
CDLL(ZBAR_LIB_PATH)
import zbar
if you have libzar in your environment, you can use
import zbar
print(zbar.version())
to check whether it works.
if you don`t have libzar ,and install a wheel with libzbar.so you can use
from zbar_init import zbar
print(zbar.version())
to check
For this to work, we need to first define how a zbar-lite will work properly:
- a new
configure.acoption is needed in order to enable/disable such feature; - a new test to be run with
make testsshould test the functionality provided by the new python modules; - it doesn't make sense to copy source files. Instead,
./configure --with-zbar-liteshould be setting the makefiles to properly build it; - any new functions that may be needed for this to work should be inside the already-existing ZBar libraries, as we don't want the same symbols to be added on both
libzbarand on alibzbar-litethat would contain a sub/superset oflibzbar; - whatever is needed for
setup.py, it should never includeconfig.h,Makefileor any other symbol produced byautotools, as this would be a mess to maintain and probably useless for the user, as their enviroment will be different than the ones used by developers; - Let's try to use the same version number for zbar-lite, as keeping a different one for it is a maintainance nightmare.
- The version number of zbar-lite is a software number,and libzbar version is a core version number. These are two differnt things. Whenever i add some new feature by Python to zbar-lite, it should not update the core version for core code of zbar is not changed. In the other hand, if java add some new feature, i don`t think my zbar-lite version should be changed, because nothing changed for Python