зеркало из https://github.com/microsoft/clang-1.git
Improve ccc:
- Support environment variable CCC_LANGUAGES to control which languages clang is invoked on. If unset clang is invoked for all languages, otherwise CCC_LANGUAGES should be a comma separated list of the languages (as accepted by -x) for which clang should be invoked. Useful for only building C and Objective-C parts of a project with clang, for example. - Add environment variable CCC_FALLBACK. If set and non-empty then ccc will try and compile using the regular compiler if compilation with clang fails. - A few other tweaks to add options, flush stdout, recognize .mm as objective-c++, and infer languages for compile+link style invocations. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55547 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
662174c82e
Коммит
d3d814131b
59
utils/ccc
59
utils/ccc
|
@ -25,6 +25,10 @@ def checkenv(name, alternate=None):
|
||||||
|
|
||||||
CCC_ECHO = checkenv('CCC_ECHO','1')
|
CCC_ECHO = checkenv('CCC_ECHO','1')
|
||||||
CCC_NATIVE = checkenv('CCC_NATIVE')
|
CCC_NATIVE = checkenv('CCC_NATIVE')
|
||||||
|
CCC_FALLBACK = checkenv('CCC_FALLBACK')
|
||||||
|
CCC_LANGUAGES = checkenv('CCC_LANGUAGES')
|
||||||
|
if CCC_LANGUAGES:
|
||||||
|
CCC_LANGUAGES = set([s.strip() for s in CCC_LANGUAGES.split(',')])
|
||||||
|
|
||||||
# We want to support use as CC or LD, so we need different defines.
|
# We want to support use as CC or LD, so we need different defines.
|
||||||
CLANG = checkenv('CLANG', 'clang')
|
CLANG = checkenv('CLANG', 'clang')
|
||||||
|
@ -38,7 +42,7 @@ def error(message):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def quote(arg):
|
def quote(arg):
|
||||||
if '"' in arg:
|
if '"' in arg or ' ' in arg:
|
||||||
return repr(arg)
|
return repr(arg)
|
||||||
return arg
|
return arg
|
||||||
|
|
||||||
|
@ -62,6 +66,7 @@ def stripoutput(args):
|
||||||
def run(args):
|
def run(args):
|
||||||
if CCC_ECHO:
|
if CCC_ECHO:
|
||||||
print ' '.join(map(quote, args))
|
print ' '.join(map(quote, args))
|
||||||
|
sys.stdout.flush()
|
||||||
code = subprocess.call(args)
|
code = subprocess.call(args)
|
||||||
if code > 255:
|
if code > 255:
|
||||||
code = 1
|
code = 1
|
||||||
|
@ -85,6 +90,10 @@ def preprocess(args):
|
||||||
command = [CLANG,'-E']
|
command = [CLANG,'-E']
|
||||||
run(command + args)
|
run(command + args)
|
||||||
|
|
||||||
|
def compile_fallback(args):
|
||||||
|
command = [CC,'-c']
|
||||||
|
run(command + args)
|
||||||
|
|
||||||
def compile(args, native, save_temps=False):
|
def compile(args, native, save_temps=False):
|
||||||
if native:
|
if native:
|
||||||
output,args = stripoutput(args)
|
output,args = stripoutput(args)
|
||||||
|
@ -97,20 +106,35 @@ def compile(args, native, save_temps=False):
|
||||||
bc_output = output + '.bc'
|
bc_output = output + '.bc'
|
||||||
s_output = output + '.s'
|
s_output = output + '.s'
|
||||||
command = [CLANG,'-emit-llvm-bc']
|
command = [CLANG,'-emit-llvm-bc']
|
||||||
run(command + args + ['-o', bc_output])
|
try:
|
||||||
# FIXME: What controls relocation model?
|
run(command + args + ['-o', bc_output])
|
||||||
run([LLC, '-relocation-model=pic', '-f', '-o', s_output, bc_output])
|
# FIXME: What controls relocation model?
|
||||||
run([AS, '-o', output, s_output])
|
run([LLC, '-relocation-model=pic', '-f', '-o', s_output, bc_output])
|
||||||
if not save_temps:
|
run([AS, '-o', output, s_output])
|
||||||
remove(bc_output)
|
finally:
|
||||||
remove(s_output)
|
if not save_temps:
|
||||||
|
remove(bc_output)
|
||||||
|
remove(s_output)
|
||||||
else:
|
else:
|
||||||
command = [CLANG,'-emit-llvm-bc']
|
command = [CLANG,'-emit-llvm-bc']
|
||||||
run(command + args)
|
run(command + args)
|
||||||
|
|
||||||
|
def checked_compile(args, native, language, save_temps):
|
||||||
|
if CCC_LANGUAGES and language and language not in CCC_LANGUAGES:
|
||||||
|
print >>sys.stderr, 'NOTE: ccc: Using fallback compiler for: %s'%(' '.join(map(quote, args)),)
|
||||||
|
compile_fallback(args)
|
||||||
|
elif CCC_FALLBACK:
|
||||||
|
try:
|
||||||
|
compile(args, native, save_temps)
|
||||||
|
except:
|
||||||
|
print >>sys.stderr, 'WARNING: ccc: Using fallback compiler for: %s'%(' '.join(map(quote, args)),)
|
||||||
|
compile_fallback(args)
|
||||||
|
else:
|
||||||
|
compile(args, native, save_temps)
|
||||||
|
|
||||||
def link(args, native):
|
def link(args, native):
|
||||||
if native:
|
if native:
|
||||||
run([LD] + args)
|
run([LD] + args)
|
||||||
else:
|
else:
|
||||||
command = ['llvm-ld', '-native', '-disable-internalize']
|
command = ['llvm-ld', '-native', '-disable-internalize']
|
||||||
run(command + args)
|
run(command + args)
|
||||||
|
@ -123,7 +147,6 @@ def changeextension(path, newext):
|
||||||
if i < 0:
|
if i < 0:
|
||||||
return path
|
return path
|
||||||
j = path.rfind('/', 0, i)
|
j = path.rfind('/', 0, i)
|
||||||
print path
|
|
||||||
if j < 0:
|
if j < 0:
|
||||||
return path[:i] + "." + newext
|
return path[:i] + "." + newext
|
||||||
return path[j+1:i] + "." + newext
|
return path[j+1:i] + "." + newext
|
||||||
|
@ -137,6 +160,8 @@ def inferlanguage(extension):
|
||||||
return "c-cpp-output"
|
return "c-cpp-output"
|
||||||
elif extension == "m":
|
elif extension == "m":
|
||||||
return "objective-c"
|
return "objective-c"
|
||||||
|
elif extension == "mm":
|
||||||
|
return "objective-c++"
|
||||||
elif extension == "mi":
|
elif extension == "mi":
|
||||||
return "objective-c-cpp-output"
|
return "objective-c-cpp-output"
|
||||||
else:
|
else:
|
||||||
|
@ -169,7 +194,8 @@ def main(args):
|
||||||
native = False
|
native = False
|
||||||
|
|
||||||
# Options with no arguments that should pass through
|
# Options with no arguments that should pass through
|
||||||
if arg in ['-v']:
|
if arg in ['-v', '-fobjc-gc', '-fobjc-gc-only', '-fnext-runtime',
|
||||||
|
'-fgnu-runtime']:
|
||||||
compile_opts.append(arg)
|
compile_opts.append(arg)
|
||||||
link_opts.append(arg)
|
link_opts.append(arg)
|
||||||
|
|
||||||
|
@ -199,7 +225,7 @@ def main(args):
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
# Options with one argument that should pass through
|
# Options with one argument that should pass through
|
||||||
if arg in ['-framework']:
|
if arg in ['-framework', '-multiply_defined', '-bundle_loader']:
|
||||||
link_opts.append(arg)
|
link_opts.append(arg)
|
||||||
link_opts.append(args[i+1])
|
link_opts.append(args[i+1])
|
||||||
i += 1
|
i += 1
|
||||||
|
@ -284,16 +310,19 @@ def main(args):
|
||||||
else:
|
else:
|
||||||
coutput = output
|
coutput = output
|
||||||
args = ['-x', language, '-o', coutput, file] + compile_opts
|
args = ['-x', language, '-o', coutput, file] + compile_opts
|
||||||
compile(args, native, save_temps)
|
checked_compile(args, native, language, save_temps)
|
||||||
language = ''
|
language = ''
|
||||||
|
|
||||||
if action == 'link':
|
if action == 'link':
|
||||||
for i, file in enumerate(files):
|
for i, file in enumerate(files):
|
||||||
|
if not language:
|
||||||
|
language = inferlanguage(extension(file))
|
||||||
ext = extension(file)
|
ext = extension(file)
|
||||||
if ext != "o" and ext != "a" and ext != "so":
|
if ext != "o" and ext != "a" and ext != "so":
|
||||||
out = changeextension(file, "o")
|
out = changeextension(file, "o")
|
||||||
args = ['-o', out, file] + compile_opts
|
args = ['-x', language, '-o', out, file] + compile_opts
|
||||||
compile(args, native, save_temps)
|
checked_compile(args, native, language, save_temps)
|
||||||
|
language = ''
|
||||||
files[i] = out
|
files[i] = out
|
||||||
if not output:
|
if not output:
|
||||||
output = 'a.out'
|
output = 'a.out'
|
||||||
|
|
Загрузка…
Ссылка в новой задаче