1010
1111ROOT_DIR = os .path .abspath (os .path .join (__file__ , '..' , '..' ))
1212
13- def install_and_rebuild (args , install_args ):
13+ # Run install.py to install headers.
14+ def generate_headers (headers_dir , install_args ):
15+ print ('Generating headers' )
16+ subprocess .check_call ([
17+ sys .executable ,
18+ os .path .join (ROOT_DIR , 'tools/install.py' ),
19+ 'install' ,
20+ '--silent' ,
21+ '--headers-only' ,
22+ '--prefix' , '/' ,
23+ '--dest-dir' , headers_dir ,
24+ ] + install_args )
25+
26+ # Rebuild addons in parallel.
27+ def rebuild_addons (args ):
28+ headers_dir = os .path .abspath (args .headers_dir )
1429 out_dir = os .path .abspath (args .out_dir )
1530 node_bin = os .path .join (out_dir , 'node' )
1631 if args .is_win :
@@ -21,71 +36,57 @@ def install_and_rebuild(args, install_args):
2136 else :
2237 node_gyp = os .path .join (ROOT_DIR , args .node_gyp )
2338
24- # Create a temporary directory for node headers.
25- with tempfile .TemporaryDirectory () as headers_dir :
26- # Run install.py to install headers.
27- print ('Generating headers' )
28- subprocess .check_call ([
29- sys .executable ,
30- os .path .join (ROOT_DIR , 'tools/install.py' ),
31- 'install' ,
32- '--silent' ,
33- '--headers-only' ,
34- '--prefix' , '/' ,
35- '--dest-dir' , headers_dir ,
36- ] + install_args )
37-
38- # Copy node.lib.
39- if args .is_win :
40- node_lib_dir = os .path .join (headers_dir , 'Release' )
41- os .makedirs (node_lib_dir )
42- shutil .copy2 (os .path .join (args .out_dir , 'node.lib' ),
43- os .path .join (node_lib_dir , 'node.lib' ))
39+ # Copy node.lib.
40+ if args .is_win :
41+ node_lib_dir = os .path .join (headers_dir , 'Release' )
42+ os .makedirs (node_lib_dir )
43+ shutil .copy2 (os .path .join (args .out_dir , 'node.lib' ),
44+ os .path .join (node_lib_dir , 'node.lib' ))
4445
45- def rebuild_addon (test_dir ):
46- print ('Building addon in' , test_dir )
47- try :
48- process = subprocess .Popen ([
49- node_bin ,
50- node_gyp ,
51- 'rebuild' ,
52- '--directory' , test_dir ,
53- '--nodedir' , headers_dir ,
54- '--python' , sys .executable ,
55- '--loglevel' , args .loglevel ,
56- ], stdout = subprocess .PIPE , stderr = subprocess .PIPE )
46+ def node_gyp_rebuild (test_dir ):
47+ print ('Building addon in' , test_dir )
48+ try :
49+ process = subprocess .Popen ([
50+ node_bin ,
51+ node_gyp ,
52+ 'rebuild' ,
53+ '--directory' , test_dir ,
54+ '--nodedir' , headers_dir ,
55+ '--python' , sys .executable ,
56+ '--loglevel' , args .loglevel ,
57+ ], stdout = subprocess .PIPE , stderr = subprocess .PIPE )
5758
58- # We buffer the output and print it out once the process is done in order
59- # to avoid interleaved output from multiple builds running at once.
60- return_code = process .wait ()
61- stdout , stderr = process .communicate ()
62- if return_code != 0 :
63- print (f'Failed to build addon in { test_dir } :' )
64- if stdout :
65- print (stdout .decode ())
66- if stderr :
67- print (stderr .decode ())
59+ # We buffer the output and print it out once the process is done in order
60+ # to avoid interleaved output from multiple builds running at once.
61+ return_code = process .wait ()
62+ stdout , stderr = process .communicate ()
63+ if return_code != 0 :
64+ print (f'Failed to build addon in { test_dir } :' )
65+ if stdout :
66+ print (stdout .decode ())
67+ if stderr :
68+ print (stderr .decode ())
6869
69- except Exception as e :
70- print (f'Unexpected error when building addon in { test_dir } . Error: { e } ' )
70+ except Exception as e :
71+ print (f'Unexpected error when building addon in { test_dir } . Error: { e } ' )
7172
72- test_dirs = []
73- skip_tests = args .skip_tests .split (',' )
74- only_tests = args .only_tests .split (',' ) if args .only_tests else None
75- for child_dir in os .listdir (args .target ):
76- full_path = os .path .join (args .target , child_dir )
77- if not os .path .isdir (full_path ):
78- continue
79- if 'binding.gyp' not in os .listdir (full_path ):
80- continue
81- if child_dir in skip_tests :
82- continue
83- if only_tests and child_dir not in only_tests :
84- continue
85- test_dirs .append (full_path )
73+ test_dirs = []
74+ skip_tests = args .skip_tests .split (',' )
75+ only_tests = args .only_tests .split (',' ) if args .only_tests else None
76+ for child_dir in os .listdir (args .target ):
77+ full_path = os .path .join (args .target , child_dir )
78+ if not os .path .isdir (full_path ):
79+ continue
80+ if 'binding.gyp' not in os .listdir (full_path ):
81+ continue
82+ if child_dir in skip_tests :
83+ continue
84+ if only_tests and child_dir not in only_tests :
85+ continue
86+ test_dirs .append (full_path )
8687
87- with ThreadPoolExecutor () as executor :
88- executor .map (rebuild_addon , test_dirs )
88+ with ThreadPoolExecutor () as executor :
89+ executor .map (node_gyp_rebuild , test_dirs )
8990
9091def main ():
9192 if sys .platform == 'cygwin' :
@@ -94,6 +95,10 @@ def main():
9495 parser = argparse .ArgumentParser (
9596 description = 'Install headers and rebuild child directories' )
9697 parser .add_argument ('target' , help = 'target directory to build addons' )
98+ parser .add_argument ('--headers-dir' ,
99+ help = 'path to node headers directory, if not specified '
100+ 'new headers will be generated for building' ,
101+ default = None )
97102 parser .add_argument ('--out-dir' , help = 'path to the output directory' ,
98103 default = 'out/Release' )
99104 parser .add_argument ('--loglevel' , help = 'loglevel of node-gyp' ,
@@ -108,7 +113,17 @@ def main():
108113 action = 'store_true' , default = (sys .platform == 'win32' ))
109114 args , unknown_args = parser .parse_known_args ()
110115
111- install_and_rebuild (args , unknown_args )
116+ if args .headers_dir :
117+ rebuild_addons (args )
118+ else :
119+ # When --headers-dir is not specified, generate headers into a temp dir and
120+ # build with the new headers.
121+ try :
122+ args .headers_dir = tempfile .mkdtemp ()
123+ generate_headers (args .headers_dir , unknown_args )
124+ rebuild_addons (args )
125+ finally :
126+ shutil .rmtree (args .headers_dir )
112127
113128if __name__ == '__main__' :
114129 main ()
0 commit comments