12 Detects the number of CPUs on a system. Cribbed from pp.
14 # Linux, Unix and MacOS:
15 if hasattr(os, "sysconf"):
16 if "SC_NPROCESSORS_ONLN" in os.sysconf_names:
18 ncpus = os.sysconf("SC_NPROCESSORS_ONLN")
19 if isinstance(ncpus, int) and ncpus > 0:
22 return int(capture(['sysctl', '-n', 'hw.ncpu']))
24 if "NUMBER_OF_PROCESSORS" in os.environ:
25 ncpus = int(os.environ["NUMBER_OF_PROCESSORS"])
31 """mkdir_p(path) - Make the "path" directory, if it does not exist; this
32 will also make directories for any missing parent directories."""
33 if not path or os.path.exists(path):
36 parent = os.path.dirname(path)
44 # Ignore EEXIST, which may occur during a race condition.
45 if e.errno != errno.EEXIST:
48 def capture(args, env=None):
49 """capture(command) - Run the given command (or argv list) in a shell and
50 return the standard output."""
51 p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
53 out,_ = p.communicate()
56 def which(command, paths = None):
57 """which(command, [paths]) - Look up the given command in the paths string
58 (or the PATH environment variable, if unspecified)."""
61 paths = os.environ.get('PATH','')
63 # Check for absolute match first.
64 if os.path.isfile(command):
67 # Would be nice if Python had a lib function for this.
71 # Get suffixes to search.
72 # On Cygwin, 'PATHEXT' may exist but it should not be used.
74 pathext = os.environ.get('PATHEXT', '').split(';')
79 for path in paths.split(os.pathsep):
81 p = os.path.join(path, command + ext)
87 def checkToolsPath(dir, tools):
89 if not os.path.exists(os.path.join(dir, tool)):
93 def whichTools(tools, paths):
94 for path in paths.split(os.pathsep):
95 if checkToolsPath(path, tools):
99 def printHistogram(items, title = 'Items'):
100 items.sort(key = lambda item: item[1])
102 maxValue = max([v for _,v in items])
104 # Select first "nice" bar height that produces more than 10 bars.
105 power = int(math.ceil(math.log(maxValue, 10)))
106 for inc in itertools.cycle((5, 2, 2.5, 1)):
107 barH = inc * 10**power
108 N = int(math.ceil(maxValue / barH))
114 histo = [set() for i in range(N)]
116 bin = min(int(N * v/maxValue), N-1)
120 hr = '-' * (barW + 34)
121 print('\nSlowest %s:' % title)
123 for name,value in items[-20:]:
124 print('%.2fs: %s' % (value, name))
125 print('\n%s Times:' % title)
127 pDigits = int(math.ceil(math.log(maxValue, 10)))
128 pfDigits = max(0, 3-pDigits)
130 pDigits += pfDigits + 1
131 cDigits = int(math.ceil(math.log(len(items), 10)))
132 print("[%s] :: [%s] :: [%s]" % ('Range'.center((pDigits+1)*2 + 3),
133 'Percentage'.center(barW),
134 'Count'.center(cDigits*2 + 1)))
136 for i,row in enumerate(histo):
137 pct = float(len(row)) / len(items)
139 print("[%*.*fs,%*.*fs) :: [%s%s] :: [%*d/%*d]" % (
140 pDigits, pfDigits, i*barH, pDigits, pfDigits, (i+1)*barH,
141 '*'*w, ' '*(barW-w), cDigits, len(row), cDigits, len(items)))
143 # Close extra file handles on UNIX (on Windows this cannot be done while
144 # also redirecting input).
145 kUseCloseFDs = not (platform.system() == 'Windows')
146 def executeCommand(command, cwd=None, env=None):
147 p = subprocess.Popen(command, cwd=cwd,
148 stdin=subprocess.PIPE,
149 stdout=subprocess.PIPE,
150 stderr=subprocess.PIPE,
151 env=env, close_fds=kUseCloseFDs)
152 out,err = p.communicate()
155 # Detect Ctrl-C in subprocess.
156 if exitCode == -signal.SIGINT:
157 raise KeyboardInterrupt
159 # Ensure the resulting output is always of string type.
161 out = str(out.decode('ascii'))
165 err = str(err.decode('ascii'))
169 return out, err, exitCode
171 def usePlatformSdkOnDarwin(config, lit_config):
172 # On Darwin, support relocatable SDKs by providing Clang with a
173 # default system root path.
174 if 'darwin' in config.target_triple:
176 cmd = subprocess.Popen(['xcrun', '--show-sdk-path'],
177 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
178 out, err = cmd.communicate()
185 lit_config.note('using SDKROOT: %r' % sdk_path)
186 config.environment['SDKROOT'] = sdk_path