Enable parallel builds
This commit is contained in:
parent
ee232fb08c
commit
b5b2f11b18
47
setup.py
47
setup.py
@ -11,6 +11,7 @@ import shutil
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
|
from multiprocessing import cpu_count
|
||||||
|
|
||||||
base = os.path.dirname(os.path.abspath(__file__))
|
base = os.path.dirname(os.path.abspath(__file__))
|
||||||
build_dir = os.path.join(base, 'build')
|
build_dir = os.path.join(base, 'build')
|
||||||
@ -212,10 +213,10 @@ def define(x):
|
|||||||
return '-D' + x
|
return '-D' + x
|
||||||
|
|
||||||
|
|
||||||
def run_tool(cmd):
|
def run_tool(cmd, desc=None):
|
||||||
if isinstance(cmd, str):
|
if isinstance(cmd, str):
|
||||||
cmd = shlex.split(cmd[0])
|
cmd = shlex.split(cmd[0])
|
||||||
print(' '.join(cmd))
|
print(desc or ' '.join(cmd))
|
||||||
p = subprocess.Popen(cmd)
|
p = subprocess.Popen(cmd)
|
||||||
ret = p.wait()
|
ret = p.wait()
|
||||||
if ret != 0:
|
if ret != 0:
|
||||||
@ -262,6 +263,40 @@ def dependecies_for(src, obj, all_headers):
|
|||||||
yield path
|
yield path
|
||||||
|
|
||||||
|
|
||||||
|
def emphasis(text):
|
||||||
|
if sys.stdout.isatty():
|
||||||
|
text = '\033[32m' + text + '\033[39m'
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def parallel_run(todo, desc='Compiling {} ...'):
|
||||||
|
num_workers = max(1, cpu_count())
|
||||||
|
items = list(todo.items())
|
||||||
|
workers = {}
|
||||||
|
failed = None
|
||||||
|
|
||||||
|
def wait():
|
||||||
|
nonlocal failed
|
||||||
|
if not workers:
|
||||||
|
return
|
||||||
|
pid, s = os.wait()
|
||||||
|
name, cmd, w = workers.pop(pid, (None, None, None))
|
||||||
|
if name is not None and ((s & 0xff) != 0 or ((s >> 8) & 0xff) != 0) and failed is None:
|
||||||
|
failed = name, cmd
|
||||||
|
|
||||||
|
while items and failed is None:
|
||||||
|
while len(workers) < num_workers and items:
|
||||||
|
name, cmd = items.pop()
|
||||||
|
print(desc.format(emphasis(name)))
|
||||||
|
w = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
||||||
|
workers[w.pid] = name, cmd, w
|
||||||
|
wait()
|
||||||
|
while len(workers):
|
||||||
|
wait()
|
||||||
|
if failed:
|
||||||
|
run_tool(failed[1])
|
||||||
|
|
||||||
|
|
||||||
def compile_c_extension(module, incremental, compilation_database, sources, headers):
|
def compile_c_extension(module, incremental, compilation_database, sources, headers):
|
||||||
prefix = os.path.basename(module)
|
prefix = os.path.basename(module)
|
||||||
objects = [
|
objects = [
|
||||||
@ -269,6 +304,8 @@ def compile_c_extension(module, incremental, compilation_database, sources, head
|
|||||||
for src in sources
|
for src in sources
|
||||||
]
|
]
|
||||||
|
|
||||||
|
todo = {}
|
||||||
|
|
||||||
for original_src, dest in zip(sources, objects):
|
for original_src, dest in zip(sources, objects):
|
||||||
src = original_src
|
src = original_src
|
||||||
cflgs = cflags[:]
|
cflgs = cflags[:]
|
||||||
@ -286,10 +323,12 @@ def compile_c_extension(module, incremental, compilation_database, sources, head
|
|||||||
):
|
):
|
||||||
cmd += ['-c', src] + ['-o', dest]
|
cmd += ['-c', src] + ['-o', dest]
|
||||||
compilation_database[original_src] = cmd
|
compilation_database[original_src] = cmd
|
||||||
run_tool(cmd)
|
todo[original_src] = cmd
|
||||||
|
if todo:
|
||||||
|
parallel_run(todo)
|
||||||
dest = os.path.join(base, module + '.so')
|
dest = os.path.join(base, module + '.so')
|
||||||
if not incremental or newer(dest, *objects):
|
if not incremental or newer(dest, *objects):
|
||||||
run_tool([cc] + ldflags + objects + ldpaths + ['-o', dest])
|
run_tool([cc] + ldflags + objects + ldpaths + ['-o', dest], desc='Linking {} ...'.format(emphasis(module)))
|
||||||
|
|
||||||
|
|
||||||
def option_parser():
|
def option_parser():
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user