|
2 | 2 | import os |
3 | 3 | import sys |
4 | 4 | import errno |
| 5 | +from subprocess import call |
5 | 6 | from glob import glob |
6 | | -from os.path import dirname, basename, abspath, isdir, join, exists |
| 7 | +from os.path import dirname, basename, abspath, isdir, join |
| 8 | +from shutil import rmtree |
7 | 9 |
|
8 | | -libs_root = dirname(abspath(__file__)) |
| 10 | +DEPS = dirname(abspath(__file__)) |
| 11 | +PYTHON = sys.executable |
9 | 12 |
|
10 | | -def build_libraries(dst_root): |
11 | | - print("\nCompiling required c-extensions") |
| 13 | +## Helpers ## |
| 14 | + |
| 15 | +def build(extension): |
| 16 | + """Run setup.py within a given c-extension's folder""" |
| 17 | + result = call([PYTHON, 'setup.py', '-q', 'build'], cwd=join(DEPS, extension)) |
| 18 | + if result > 0: |
| 19 | + raise OSError("Could not build %s" % extension) |
| 20 | + |
| 21 | +def make(target, **envvars): |
| 22 | + """Build the specified target in the vendor Makefile""" |
| 23 | + os.chdir('%s/vendor'%DEPS) |
| 24 | + env = {"PYTHON":PYTHON, "PATH":os.environ['PATH']} |
| 25 | + env.update(envvars) |
| 26 | + result = call('make -s %s'%target, env=env, shell=True) |
| 27 | + if result > 0: |
| 28 | + raise OSError("Could not make %s" % target) |
| 29 | + os.chdir(DEPS) |
12 | 30 |
|
| 31 | +def clean(): |
| 32 | + """Delete build folders in dependency subdirs""" |
| 33 | + build_dirs = glob('%s/*/build'%DEPS) |
| 34 | + for build_dir in build_dirs: |
| 35 | + lib_name = dirname(build_dir) |
| 36 | + print("Cleaning", lib_name) |
| 37 | + call('rm -r "%s"' % build_dir) |
| 38 | + make('clean') |
| 39 | + |
| 40 | +## Recipes ## |
| 41 | + |
| 42 | +def build_extensions(): |
13 | 43 | # Find all setup.py files in the current folder |
14 | | - setup_scripts = glob('%s/*/setup.py'%libs_root) |
15 | | - for setup_script in setup_scripts: |
| 44 | + print("\nCompiling required c-extensions") |
| 45 | + for setup_script in glob('%s/*/setup.py'%DEPS): |
16 | 46 | lib_name = basename(dirname(setup_script)) |
17 | 47 | print("Building %s..."% lib_name) |
18 | | - os.chdir(dirname(setup_script)) |
19 | | - result = os.system(sys.executable+' setup.py -q build') # call the lib's setup.py |
20 | | - if result > 0: |
21 | | - raise OSError("Could not build %s" % lib_name) |
22 | | - os.chdir(libs_root) |
| 48 | + build(lib_name) |
| 49 | + |
| 50 | + print("Building pyobjc...") |
| 51 | + make('pyobjc') |
23 | 52 |
|
| 53 | +def install_extensions(ext_root): |
| 54 | + """Install the c-extensions and PyObjC site dir within the plotdevice module""" |
24 | 55 | # Make sure the destination folder exists. |
25 | | - if not isdir(dst_root): |
26 | | - os.makedirs(dst_root) |
| 56 | + if not isdir(ext_root): |
| 57 | + os.makedirs(ext_root) |
27 | 58 |
|
28 | | - # Copy all build results to the ../../build/deps folder. |
29 | | - build_dirs = glob("%s/*/build/lib*"%libs_root) |
30 | | - for build_dir in build_dirs: |
31 | | - lib_name = dirname(dirname(build_dir)) |
32 | | - cmd = 'cp -R -p %s/* %s' % (build_dir, dst_root) |
33 | | - print(cmd) |
34 | | - result = os.system(cmd) |
| 59 | + # Copy all build results to plotdevice/lib dir |
| 60 | + for extension in glob("%s/*/build/lib*"%DEPS): |
| 61 | + cmd = 'cp -R -p %s/* %s' % (extension, ext_root) |
| 62 | + result = call(cmd, shell=True) |
35 | 63 | if result > 0: |
| 64 | + lib_name = dirname(dirname(extension)) |
36 | 65 | raise OSError("Could not copy %s" % lib_name) |
37 | 66 | print() |
38 | 67 |
|
39 | | -def clean_build_files(): |
40 | | - print("Cleaning all library build files...") |
41 | | - |
42 | | - build_dirs = glob('%s/*/build'%libs_root) |
43 | | - for build_dir in build_dirs: |
44 | | - lib_name = dirname(build_dir) |
45 | | - print("Cleaning", lib_name) |
46 | | - os.system('rm -r "%s"' % build_dir) |
| 68 | +def install_http_libs(mod_root): |
| 69 | + """Install the http modules into the Resources/python subdir""" |
| 70 | + if 'ACTION' not in os.environ: |
| 71 | + # the ACTION env var will be defined for app and py2app builds, in which |
| 72 | + # case we should install the http libs into Resources/python (for non-GUI |
| 73 | + # builds, setup.py's install_requires will pull in dependencies automatically) |
| 74 | + return |
| 75 | + print("Bundling requests module...") |
| 76 | + make('http', DSTROOT=mod_root) # makefile uses DSTROOT to target install |
47 | 77 |
|
48 | 78 | if __name__=='__main__': |
49 | | - import sys |
50 | | - |
51 | 79 | if len(sys.argv)>1: |
52 | 80 | arg = sys.argv[1] |
53 | 81 | if arg=='clean': |
54 | | - clean_build_files() |
| 82 | + print("Cleaning dependency build files...") |
| 83 | + clean() |
55 | 84 | else: |
56 | | - dst_root = join(arg, 'plotdevice/lib') |
57 | | - build_libraries(dst_root) |
| 85 | + mod_root = arg |
| 86 | + ext_root = join(mod_root, 'plotdevice/lib') |
| 87 | + build_extensions() |
| 88 | + install_http_libs(mod_root) |
| 89 | + install_extensions(ext_root) |
58 | 90 | else: |
59 | 91 | print("usage: python build.py <destination-path>") |
0 commit comments