forked from OSchip/llvm-project
[gn build] Process .def.in files in llvm/Config and add lib/Target/BUILD.gn
Tweak write_cmake_config.py to also handle variable references looking @FOO@ (matching CMake's configure_file() function), and make it replace '\' 'n' in values with a newline literal since there's no good portable way of passing a real newline literal on a command line. Use that to process all the .def.in files in llvm/include/Config and add llvm/lib/Target/BUILD.gn, which (indirectly, through llvm-c/Target.h) includes them. Differential Revision: https://reviews.llvm.org/D55184 llvm-svn: 348503
This commit is contained in:
parent
96f6963708
commit
1be23a901f
|
@ -2,16 +2,17 @@
|
||||||
"""Emulates the bits of CMake's configure_file() function needed in LLVM.
|
"""Emulates the bits of CMake's configure_file() function needed in LLVM.
|
||||||
|
|
||||||
The CMake build uses configure_file() for several things. This emulates that
|
The CMake build uses configure_file() for several things. This emulates that
|
||||||
function for the GN build. In the GN build, this runs at build time, instead
|
function for the GN build. In the GN build, this runs at build time instead
|
||||||
of at generator time.
|
of at generator time.
|
||||||
|
|
||||||
Takes a list of KEY=VALUE pairs (where VALUE can be empty).
|
Takes a list of KEY=VALUE pairs (where VALUE can be empty).
|
||||||
|
|
||||||
On each line, replaces ${KEY} with VALUE.
|
The sequence `\` `n` in each VALUE is replaced by a newline character.
|
||||||
|
|
||||||
After that, also handles these special cases (note that FOO= sets the value of
|
On each line, replaces '${KEY}' or '@KEY@' with VALUE.
|
||||||
FOO to the empty string, which is falsy, but FOO=0 sets it to '0' which is
|
|
||||||
truthy):
|
Then, handles these special cases (note that FOO= sets the value of FOO to the
|
||||||
|
empty string, which is falsy, but FOO=0 sets it to '0' which is truthy):
|
||||||
|
|
||||||
1.) #cmakedefine01 FOO
|
1.) #cmakedefine01 FOO
|
||||||
Checks if key FOO is set to a truthy value, and depending on that prints
|
Checks if key FOO is set to a truthy value, and depending on that prints
|
||||||
|
@ -28,8 +29,7 @@ truthy):
|
||||||
/* #undef FOO */
|
/* #undef FOO */
|
||||||
|
|
||||||
Fails if any of the KEY=VALUE arguments aren't needed for processing the
|
Fails if any of the KEY=VALUE arguments aren't needed for processing the
|
||||||
.h.cmake file, or if the .h.cmake file has unreplaced ${VAR} references after
|
input file, or if the input file references keys that weren't passed in.
|
||||||
processing all values.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
@ -53,18 +53,19 @@ def main():
|
||||||
values = {}
|
values = {}
|
||||||
for value in args.values:
|
for value in args.values:
|
||||||
key, val = value.split('=', 1)
|
key, val = value.split('=', 1)
|
||||||
values[key] = val
|
values[key] = val.replace('\\n', '\n')
|
||||||
unused_values = set(values.keys())
|
unused_values = set(values.keys())
|
||||||
|
|
||||||
# Matches e.g. '${CLANG_FOO}' and captures CLANG_FOO in group 1.
|
# Matches e.g. '${FOO}' or '@FOO@' and captures FOO in group 1 or 2.
|
||||||
var_re = re.compile(r'\$\{([^}]*)\}')
|
var_re = re.compile(r'\$\{([^}]*)\}|@([^@]*)@')
|
||||||
|
|
||||||
in_lines = open(args.input).readlines()
|
in_lines = open(args.input).readlines()
|
||||||
out_lines = []
|
out_lines = []
|
||||||
for in_line in in_lines:
|
for in_line in in_lines:
|
||||||
def repl(m):
|
def repl(m):
|
||||||
unused_values.discard(m.group(1))
|
key = m.group(1) or m.group(2)
|
||||||
return values[m.group(1)]
|
unused_values.discard(key)
|
||||||
|
return values[key]
|
||||||
in_line = var_re.sub(repl, in_line)
|
in_line = var_re.sub(repl, in_line)
|
||||||
if in_line.startswith('#cmakedefine01 '):
|
if in_line.startswith('#cmakedefine01 '):
|
||||||
_, var = in_line.split()
|
_, var = in_line.split()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
group("default") {
|
group("default") {
|
||||||
deps = [
|
deps = [
|
||||||
"//llvm/lib/Object",
|
"//llvm/lib/Object",
|
||||||
|
"//llvm/lib/Target",
|
||||||
"//llvm/tools/llvm-undname",
|
"//llvm/tools/llvm-undname",
|
||||||
"//llvm/utils/TableGen:llvm-tblgen",
|
"//llvm/utils/TableGen:llvm-tblgen",
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,7 +7,8 @@ import("//llvm/utils/gn/build/libs/xml/enable.gni")
|
||||||
import("//llvm/utils/gn/build/libs/zlib/enable.gni")
|
import("//llvm/utils/gn/build/libs/zlib/enable.gni")
|
||||||
import("//llvm/version.gni")
|
import("//llvm/version.gni")
|
||||||
|
|
||||||
# Contains actions to create config.h, llvm-config.h and abi-breaking.h.
|
# Contains actions to create config.h, llvm-config.h, abi-breaking.h,
|
||||||
|
# and the various .def files used by llvm/lib/Target.
|
||||||
# Other than in the cmake build, these are created at build time, not at
|
# Other than in the cmake build, these are created at build time, not at
|
||||||
# config time. That way, they can run in parallel, and this pattern means that
|
# config time. That way, they can run in parallel, and this pattern means that
|
||||||
# e.g. creating the clang config header (which happens in another gn file)
|
# e.g. creating the clang config header (which happens in another gn file)
|
||||||
|
@ -19,6 +20,9 @@ import("//llvm/version.gni")
|
||||||
# Other than in the cmake build, header generation doesn't do any feature
|
# Other than in the cmake build, header generation doesn't do any feature
|
||||||
# checking. See also "Philosophy" in llvm/utils/gn/README.rst.
|
# checking. See also "Philosophy" in llvm/utils/gn/README.rst.
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# config.h, llvm-config.h, abi-breaking.h
|
||||||
|
|
||||||
# FIXME: Several of the config settings go in a global config header but
|
# FIXME: Several of the config settings go in a global config header but
|
||||||
# are only used in a single translation unit -- so toggling that value
|
# are only used in a single translation unit -- so toggling that value
|
||||||
# causes a full rebuild when it really only has to rebuild a single file.
|
# causes a full rebuild when it really only has to rebuild a single file.
|
||||||
|
@ -356,3 +360,71 @@ action("llvm-config") {
|
||||||
args += [ "LLVM_ENABLE_THREADS=" ]
|
args += [ "LLVM_ENABLE_THREADS=" ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# .def files used by llvm/lib/Target
|
||||||
|
|
||||||
|
template("write_target_def_file") {
|
||||||
|
assert(defined(invoker.key), "callers must set key")
|
||||||
|
assert(defined(invoker.value), "callers must set value")
|
||||||
|
|
||||||
|
action(target_name) {
|
||||||
|
visibility = [ ":write_target_def_files" ]
|
||||||
|
script = "//llvm/utils/gn/build/write_cmake_config.py"
|
||||||
|
|
||||||
|
sources = [
|
||||||
|
"$target_name.in",
|
||||||
|
]
|
||||||
|
outputs = [
|
||||||
|
"$target_gen_dir/$target_name",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Build something like
|
||||||
|
# `LLVM_ENUM_ASM_PARSERS=LLVM_ASM_PARSER(ARM)\nLLVM_ASM_PARSER(X86)\n`. Note
|
||||||
|
# that \n is a literal '\' followed by a literal 'n', not a newline
|
||||||
|
# character. (write_cmake_config.py replaces that with a real newline).
|
||||||
|
value = ""
|
||||||
|
foreach(target, llvm_targets_to_build) {
|
||||||
|
value = "$value${invoker.value}($target)\n"
|
||||||
|
}
|
||||||
|
args = [
|
||||||
|
"-o",
|
||||||
|
rebase_path(outputs[0], root_out_dir),
|
||||||
|
rebase_path(sources[0], root_out_dir),
|
||||||
|
"${invoker.key}=$value",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
write_target_def_file("AsmParsers.def") {
|
||||||
|
key = "LLVM_ENUM_ASM_PARSERS"
|
||||||
|
value = "LLVM_ASM_PARSER"
|
||||||
|
}
|
||||||
|
|
||||||
|
write_target_def_file("AsmPrinters.def") {
|
||||||
|
key = "LLVM_ENUM_ASM_PRINTERS"
|
||||||
|
value = "LLVM_ASM_PRINTER"
|
||||||
|
}
|
||||||
|
|
||||||
|
write_target_def_file("Disassemblers.def") {
|
||||||
|
key = "LLVM_ENUM_DISASSEMBLERS"
|
||||||
|
value = "LLVM_DISASSEMBLER"
|
||||||
|
}
|
||||||
|
|
||||||
|
write_target_def_file("Targets.def") {
|
||||||
|
key = "LLVM_ENUM_TARGETS"
|
||||||
|
value = "LLVM_TARGET"
|
||||||
|
}
|
||||||
|
|
||||||
|
group("write_target_def_files") {
|
||||||
|
visibility = [
|
||||||
|
"//llvm/lib/Support",
|
||||||
|
"//llvm/lib/Target",
|
||||||
|
]
|
||||||
|
deps = [
|
||||||
|
":AsmParsers.def",
|
||||||
|
":AsmPrinters.def",
|
||||||
|
":Disassemblers.def",
|
||||||
|
":Targets.def",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ static_library("Support") {
|
||||||
# both Support and ADT.
|
# both Support and ADT.
|
||||||
"//llvm/include/llvm/Config:abi-breaking",
|
"//llvm/include/llvm/Config:abi-breaking",
|
||||||
"//llvm/include/llvm/Config:llvm-config",
|
"//llvm/include/llvm/Config:llvm-config",
|
||||||
|
# public_dep because public header TargetSelect.h includes these .def files.
|
||||||
|
"//llvm/include/llvm/Config:write_target_def_files",
|
||||||
]
|
]
|
||||||
include_dirs = [
|
include_dirs = [
|
||||||
"Unix",
|
"Unix",
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
import("//llvm/lib/Target/targets.gni")
|
||||||
|
|
||||||
|
static_library("Target") {
|
||||||
|
output_name = "LLVMTarget"
|
||||||
|
deps = [
|
||||||
|
"//llvm/lib/Analysis",
|
||||||
|
"//llvm/lib/IR",
|
||||||
|
"//llvm/lib/MC",
|
||||||
|
"//llvm/lib/Support",
|
||||||
|
]
|
||||||
|
public_deps = [
|
||||||
|
# This is a bit of a hack: llvm-c/Target.h includes llvm/Config/Targets.def,
|
||||||
|
# but there's no target corresponding to llvm-c. Since the functions
|
||||||
|
# declared in llvm-c/Target.h are defined in llvm/lib/Target, clients of
|
||||||
|
# it must depend on llvm/lib/Target, so add the public_dep for Targets.def
|
||||||
|
# here.
|
||||||
|
"//llvm/include/llvm/Config:write_target_def_files",
|
||||||
|
]
|
||||||
|
sources = [
|
||||||
|
"Target.cpp",
|
||||||
|
"TargetIntrinsicInfo.cpp",
|
||||||
|
"TargetLoweringObjectFile.cpp",
|
||||||
|
"TargetMachine.cpp",
|
||||||
|
"TargetMachineC.cpp",
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue