Distributing a binary utility in setuptools
distutils, python-3.x, setuptools
Solution
My solution was as follows:
- Create a wrapper module `foowrapper`.
- `foowrapper` contains `foo` (but renamed to `foo_bin`) and a new script called `foo`, contents below:
.
#!python
file = __file__
import os.path
cmd = os.path.join(os.path.dirname(__file__),"foo_bin")
import subprocess
subprocess.call([cmd] + sys.argv[1:])
- Update setup.py to contain foowrapper, foo, and foo_bin
.
setup(
...
package_data={
'foowrapper':['foo_bin']
},
packages=['foowrapper],
scripts=['foowrapper/foo']
...
)
Problem
I have a command-line program (`foo`) written in an esoteric programming language. I'd like to distribute this program as part of an existing python package that uses setuptools. `foo` should appear in the user's path and be executable from the command line, much like the behavior of distutil's scripts or setuptools' entry_points. It's feasible for me to cross-compile the program for every platform and then build a different egg for each platform with a platform-specific binary of `foo`. The problem is, I don't know how to convince setuptools to copy the binary to a platform-appropriate place on the target system. For example, I tried using the `scripts` directive: ``` setup( ... scripts=["foo"] ... ) ``` but it appears setuptools doesn't like a "script" with non-utf8 data. ``` UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcf in position 0: invalid continuation byte ``` I could declare it as a resource, but that wouldn't put it in the user's path. How do I ship a binary command-line utility as part of a python package?