llvm-build: Add --configure-target-def-file option.
- Can be used to generate the substitution values we currently use for the various target related .def files. llvm-svn: 144345
This commit is contained in:
parent
6d617b48c7
commit
f258ad81c0
|
@ -0,0 +1,66 @@
|
||||||
|
"""
|
||||||
|
Defines utilities useful for performing standard "configuration" style tasks.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
|
||||||
|
def configure_file(input_path, output_path, substitutions):
|
||||||
|
"""configure_file(input_path, output_path, substitutions) -> bool
|
||||||
|
|
||||||
|
Given an input and output path, "configure" the file at the given input path
|
||||||
|
by replacing variables in the file with those given in the substitutions
|
||||||
|
list. Returns true if the output file was written.
|
||||||
|
|
||||||
|
The substitutions list should be given as a list of tuples (regex string,
|
||||||
|
replacement), where the regex and replacement will be used as in 're.sub' to
|
||||||
|
execute the variable replacement.
|
||||||
|
|
||||||
|
The output path's parent directory need not exist (it will be created).
|
||||||
|
|
||||||
|
If the output path does exist and the configured data is not different than
|
||||||
|
it's current contents, the output file will not be modified. This is
|
||||||
|
designed to limit the impact of configured files on build dependencies.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Read in the input data.
|
||||||
|
f = open(input_path, "rb")
|
||||||
|
try:
|
||||||
|
data = f.read()
|
||||||
|
finally:
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
# Perform the substitutions.
|
||||||
|
for regex_string,replacement in substitutions:
|
||||||
|
regex = re.compile(regex_string)
|
||||||
|
data = regex.sub(replacement, data)
|
||||||
|
|
||||||
|
# Ensure the output parent directory exists.
|
||||||
|
output_parent_path = os.path.dirname(os.path.abspath(output_path))
|
||||||
|
if not os.path.exists(output_parent_path):
|
||||||
|
os.makedirs(output_parent_path)
|
||||||
|
|
||||||
|
# If the output path exists, load it and compare to the configured contents.
|
||||||
|
if os.path.exists(output_path):
|
||||||
|
current_data = None
|
||||||
|
try:
|
||||||
|
f = open(output_path, "rb")
|
||||||
|
try:
|
||||||
|
current_data = f.read()
|
||||||
|
except:
|
||||||
|
current_data = None
|
||||||
|
f.close()
|
||||||
|
except:
|
||||||
|
current_data = None
|
||||||
|
|
||||||
|
if current_data is not None and current_data == data:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Write the output contents.
|
||||||
|
f = open(output_path, "wb")
|
||||||
|
try:
|
||||||
|
f.write(data)
|
||||||
|
finally:
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
return True
|
|
@ -2,6 +2,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import componentinfo
|
import componentinfo
|
||||||
|
import configutil
|
||||||
|
|
||||||
from util import *
|
from util import *
|
||||||
|
|
||||||
|
@ -616,6 +617,9 @@ def main():
|
||||||
help=(
|
help=(
|
||||||
"If given, an alternate path to search for LLVMBuild.txt files"),
|
"If given, an alternate path to search for LLVMBuild.txt files"),
|
||||||
action="store", default=None, metavar="PATH")
|
action="store", default=None, metavar="PATH")
|
||||||
|
group.add_option("", "--build-root", dest="build_root", metavar="PATH",
|
||||||
|
help="Path to the build directory (if needed) [%default]",
|
||||||
|
action="store", default=None)
|
||||||
parser.add_option_group(group)
|
parser.add_option_group(group)
|
||||||
|
|
||||||
group = OptionGroup(parser, "Output Options")
|
group = OptionGroup(parser, "Output Options")
|
||||||
|
@ -637,6 +641,14 @@ def main():
|
||||||
dest="write_make_fragment", metavar="PATH",
|
dest="write_make_fragment", metavar="PATH",
|
||||||
help="Write the Makefile project information to PATH",
|
help="Write the Makefile project information to PATH",
|
||||||
action="store", default=None)
|
action="store", default=None)
|
||||||
|
group.add_option("", "--configure-target-def-file",
|
||||||
|
dest="configure_target_def_files",
|
||||||
|
help="""Configure the given file at SUBPATH (relative to
|
||||||
|
the inferred or given source root, and with a '.in' suffix) by replacing certain
|
||||||
|
substitution variables with lists of targets that support certain features (for
|
||||||
|
example, targets with AsmPrinters) and write the result to the build root (as
|
||||||
|
given by --build-root) at the same SUBPATH""",
|
||||||
|
metavar="SUBPATH", action="append", default=None)
|
||||||
parser.add_option_group(group)
|
parser.add_option_group(group)
|
||||||
|
|
||||||
group = OptionGroup(parser, "Configuration Options")
|
group = OptionGroup(parser, "Configuration Options")
|
||||||
|
@ -701,5 +713,40 @@ def main():
|
||||||
if opts.write_cmake_fragment:
|
if opts.write_cmake_fragment:
|
||||||
project_info.write_cmake_fragment(opts.write_cmake_fragment)
|
project_info.write_cmake_fragment(opts.write_cmake_fragment)
|
||||||
|
|
||||||
|
# Configure target definition files, if requested.
|
||||||
|
if opts.configure_target_def_files:
|
||||||
|
# Verify we were given a build root.
|
||||||
|
if not opts.build_root:
|
||||||
|
parser.error("must specify --build-root when using "
|
||||||
|
"--configure-target-def-file")
|
||||||
|
|
||||||
|
# Create the substitution list.
|
||||||
|
available_targets = [ci for ci in project_info.component_infos
|
||||||
|
if ci.type_name == 'TargetGroup']
|
||||||
|
substitutions = [
|
||||||
|
("@LLVM_ENUM_TARGETS@",
|
||||||
|
' '.join('LLVM_TARGET(%s)' % ci.name
|
||||||
|
for ci in available_targets)),
|
||||||
|
("@LLVM_ENUM_ASM_PRINTERS@",
|
||||||
|
' '.join('LLVM_ASM_PRINTER(%s)' % ci.name
|
||||||
|
for ci in available_targets
|
||||||
|
if ci.has_asmprinter)),
|
||||||
|
("@LLVM_ENUM_ASM_PARSERS@",
|
||||||
|
' '.join('LLVM_ASM_PARSER(%s)' % ci.name
|
||||||
|
for ci in available_targets
|
||||||
|
if ci.has_asmparser)),
|
||||||
|
("@LLVM_ENUM_DISASSEMBLERS@",
|
||||||
|
' '.join('LLVM_DISASSEMBLER(%s)' % ci.name
|
||||||
|
for ci in available_targets
|
||||||
|
if ci.has_disassembler))]
|
||||||
|
|
||||||
|
# Configure the given files.
|
||||||
|
for subpath in opts.configure_target_def_files:
|
||||||
|
inpath = os.path.join(source_root, subpath + '.in')
|
||||||
|
outpath = os.path.join(opts.build_root, subpath)
|
||||||
|
result = configutil.configure_file(inpath, outpath, substitutions)
|
||||||
|
if not result:
|
||||||
|
note("configured file %r hasn't changed" % outpath)
|
||||||
|
|
||||||
if __name__=='__main__':
|
if __name__=='__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -1,16 +1,9 @@
|
||||||
import inspect
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
def _write_message(kind, message):
|
def _write_message(kind, message):
|
||||||
# Get the file/line where this message was generated.
|
program = os.path.basename(sys.argv[0])
|
||||||
f = inspect.currentframe()
|
print >>sys.stderr, '%s: %s: %s' % (program, kind, message)
|
||||||
# Step out of _write_message, and then out of wrapper.
|
|
||||||
f = f.f_back.f_back
|
|
||||||
file,line,_,_,_ = inspect.getframeinfo(f)
|
|
||||||
location = '%s:%d' % (os.path.basename(file), line)
|
|
||||||
|
|
||||||
print >>sys.stderr, '%s: %s: %s' % (location, kind, message)
|
|
||||||
|
|
||||||
note = lambda message: _write_message('note', message)
|
note = lambda message: _write_message('note', message)
|
||||||
warning = lambda message: _write_message('warning', message)
|
warning = lambda message: _write_message('warning', message)
|
||||||
|
|
Loading…
Reference in New Issue