Last active
March 31, 2019 17:13
-
-
Save Sh-ui/40b65a9c6ff4ae2216e9c2d369b5e6d7 to your computer and use it in GitHub Desktop.
small tool to compile python to an exec file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from collections import OrderedDict, namedtuple | |
def dicto(ref, name='dictionary_object'): | |
ref = ref.copy() # copy the original dictionary to edit a copy | |
keys = [] | |
vals = [] | |
for k, v in ref.items(): | |
k = ''.join(c for c in k if c.isalpha()) # remove non alphanumeric characters | |
keys += [k] # append keys from ref to list of new keys | |
vals += [v] # append values from ref to list of new values | |
dct = OrderedDict(zip(keys, vals)) # zip both lists into one ordered dictionary | |
dct_obj = namedtuple(name, dct.keys())(*dct.values()) # make each item a class attribute | |
return dct_obj # return the object created from the dictionary |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
(PYCX) PYthon to Cython to eXec, a unix command line util | |
Usage: | |
pycx FILES... [-o DIR --verbose --delete --run] | |
pycx --help | |
Options: | |
FILES one or more python files to compile | |
-o --output=DIR output directory | |
-v --verbose show output while exec compiles | |
-d --delete delete the c file after compiling exec | |
-r --run run the exec after compiling | |
-h --help show this screen | |
""" | |
from os import system as shell | |
from pathlib import Path | |
from docopt import docopt, DocoptExit | |
from dicto import dicto # makes arguments callable as class attributes, without the "--" | |
# the two pathnames below tell gcc where python is so that cython can be compiled to an exec | |
INCLUDE = '/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/include/python3.7m' | |
LIBRARY = '/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib' | |
CONCISE = '&>/dev/null' # tag this onto the end of shell commands to hide their output | |
def main(arg): | |
for file in arg.FILES: | |
path = Path(file) | |
if path.suffix not in ('.py', '.pyx'): | |
raise DocoptExit('add at least one python file\n') # show usage section of doc | |
c_file = path.parent / (path.stem + '.c') | |
output = Path(arg.output or '') / path.stem # just a file name if no argument | |
shell(f'cython --embed -o {c_file} {path}') # compile python to cython C file | |
shell( | |
f'gcc -v -Os -I {INCLUDE} -L {LIBRARY} {c_file} ' # compile C file to exec | |
f'-o {output} -lpython3.7 -lpthread -lm -lutil -ldl ' | |
+ CONCISE if not arg.verbose else '' # hide gcc output if no argument | |
) | |
if arg.delete: | |
shell(f'find {path.parent} -name "{path.stem}.c" -type f|xargs rm -f') | |
if arg.run: | |
shell(f'./{output}') | |
if __name__ == '__main__': | |
main(dicto(docopt(__doc__))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment