"""This file contains BUILD extensions for generating source code from LLVM's table definition files using the TableGen tool. See http://llvm.org/cmds/tblgen.html for more information on the TableGen tool. TODO(chandlerc): Currently this expresses include-based dependencies as "sources", and has no transitive understanding due to these files not being correctly understood by the build system. """ def gentbl(name, tblgen, td_file, td_srcs, tbl_outs, library = True, **kwargs): """gentbl() generates tabular code from a table definition file. Args: name: The name of the build rule for use in dependencies. tblgen: The binary used to produce the output. td_file: The primary table definitions file. td_srcs: A list of table definition files included transitively. tbl_outs: A list of tuples (opts, out), where each opts is a string of options passed to tblgen, and the out is the corresponding output file produced. library: Whether to bundle the generated files into a library. **kwargs: Keyword arguments to pass to subsidiary cc_library() rule. """ if td_file not in td_srcs: td_srcs += [td_file] includes = [] for (opts, out) in tbl_outs: outdir = out[:out.rindex("/")] if outdir not in includes: includes.append(outdir) rule_suffix = "_".join(opts.replace("-", "_").replace("=", "_").split(" ")) native.genrule( name="%s_%s_genrule" % (name, rule_suffix), srcs=td_srcs, outs=[out], tools=[tblgen], message="Generating code from table: %s" % td_file, cmd=(("$(location %s) " + "-I external/llvm/include " + "-I external/llvm/tools/clang/include " + "-I $$(dirname $(location %s)) " + "%s $(location %s) -o $@") % ( tblgen, td_file, opts, td_file))) # For now, all generated files can be assumed to comprise public interfaces. # If this is not true, you should specify library = False # and list the generated '.inc' files in "srcs". if library: native.cc_library(name=name, textual_hdrs=[f for (_, f) in tbl_outs], includes=includes, **kwargs) def llvm_target_cmake_vars(native_arch, target_triple): return { "LLVM_HOST_TRIPLE": target_triple, "LLVM_DEFAULT_TARGET_TRIPLE": target_triple, "LLVM_NATIVE_ARCH": native_arch, } def _quote(s): """Quotes the given string for use in a shell command. This function double-quotes the given string (in case it contains spaces or other special characters) and escapes any special characters (dollar signs, double-quotes, and backslashes) that may be present. Args: s: The string to quote. Returns: An escaped and quoted version of the string that can be passed to a shell command. """ return ('"' + s.replace("\\", "\\\\").replace("$", "\\$").replace('"', '\\"') + '"') def cmake_var_string(cmake_vars): """Converts a dictionary to an input suitable for expand_cmake_vars. Ideally we would jist stringify in the expand_cmake_vars() rule, but select() interacts badly with genrules. TODO(phawkins): replace the genrule() with native rule and delete this rule. Args: cmake_vars: a dictionary with string keys and values that are convertable to strings. """ return " ".join([_quote("{}={}".format(k, str(v))) for (k, v) in cmake_vars.items()]) def expand_cmake_vars(name, src, dst, cmake_vars): """Expands #cmakedefine, #cmakedefine01, and CMake variables in a text file. Args: name: the name of the rule src: the input of the rule dst: the output of the rule cmake_vars: a string containing the CMake variables, as generated by cmake_var_string. """ expand_cmake_vars_tool = Label("@org_tensorflow//third_party/llvm:expand_cmake_vars") native.genrule( name = name, srcs = [src], tools = [expand_cmake_vars_tool], outs = [dst], cmd = ("$(location {}) ".format(expand_cmake_vars_tool) + cmake_vars + "< $< > $@") ) # TODO(phawkins): the set of CMake variables was hardcoded for expediency. # However, we should really detect many of these via configure-time tests. # The set of CMake variables common to all targets. cmake_vars = { # Headers "HAVE_DIRENT_H": 1, "HAVE_DLFCN_H": 1, "HAVE_ERRNO_H": 1, "HAVE_EXECINFO_H": 1, "HAVE_FCNTL_H": 1, "HAVE_INTTYPES_H": 1, "HAVE_PTHREAD_H": 1, "HAVE_SIGNAL_H": 1, "HAVE_STDINT_H": 1, "HAVE_SYS_IOCTL_H": 1, "HAVE_SYS_MMAN_H": 1, "HAVE_SYS_PARAM_H": 1, "HAVE_SYS_RESOURCE_H": 1, "HAVE_SYS_STAT_H": 1, "HAVE_SYS_TIME_H": 1, "HAVE_SYS_TYPES_H": 1, "HAVE_TERMIOS_H": 1, "HAVE_UNISTD_H": 1, "HAVE_ZLIB_H": 1, # Features "HAVE_BACKTRACE": 1, "BACKTRACE_HEADER": "execinfo.h", "HAVE_DLOPEN": 1, "HAVE_FUTIMES": 1, "HAVE_GETCWD": 1, "HAVE_GETPAGESIZE": 1, "HAVE_GETRLIMIT": 1, "HAVE_GETRUSAGE": 1, "HAVE_GETTIMEOFDAY": 1, "HAVE_INT64_T": 1, "HAVE_ISATTY": 1, "HAVE_LIBEDIT": 1, "HAVE_LIBPTHREAD": 1, "HAVE_LIBZ": 1, "HAVE_MKDTEMP": 1, "HAVE_MKSTEMP": 1, "HAVE_MKTEMP": 1, "HAVE_PREAD": 1, "HAVE_PTHREAD_GETSPECIFIC": 1, "HAVE_PTHREAD_MUTEX_LOCK": 1, "HAVE_PTHREAD_RWLOCK_INIT": 1, "HAVE_REALPATH": 1, "HAVE_SBRK": 1, "HAVE_SETENV": 1, "HAVE_SETRLIMIT": 1, "HAVE_SIGALTSTACK": 1, "HAVE_STRERROR": 1, "HAVE_STRERROR_R": 1, "HAVE_STRTOLL": 1, "HAVE_SYSCONF": 1, "HAVE_UINT64_T": 1, "HAVE__UNWIND_BACKTRACE": 1, # LLVM features "ENABLE_BACKTRACES": 1, "LLVM_BINDIR": "/dev/null", "LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING": 0, "LLVM_ENABLE_ABI_BREAKING_CHECKS": 0, "LLVM_ENABLE_THREADS": 1, "LLVM_ENABLE_ZLIB": 1, "LLVM_HAS_ATOMICS": 1, "LLVM_INCLUDEDIR": "/dev/null", "LLVM_INFODIR": "/dev/null", "LLVM_MANDIR": "/dev/null", "LLVM_NATIVE_TARGET": 1, "LLVM_NATIVE_TARGETINFO": 1, "LLVM_NATIVE_TARGETMC": 1, "LLVM_NATIVE_ASMPRINTER": 1, "LLVM_NATIVE_ASMPARSER": 1, "LLVM_NATIVE_DISASSEMBLER": 1, "LLVM_ON_UNIX": 1, "LLVM_PREFIX": "/dev/null", "LLVM_VERSION_MAJOR": 0, "LLVM_VERSION_MINOR": 0, "LLVM_VERSION_PATCH": 0, "LTDL_SHLIB_EXT": ".so", "PACKAGE_NAME": "llvm", "PACKAGE_STRING": "llvm tensorflow-trunk", "PACKAGE_VERSION": "tensorflow-trunk", "RETSIGTYPE": "void", } # CMake variables specific to the Linux platform linux_cmake_vars = { "HAVE_MALLOC_H": 1, "HAVE_LINK_H": 1, "HAVE_MALLINFO": 1, "HAVE_FUTIMENS": 1, } # CMake variables specific to the Darwin (Mac OS X) platform. darwin_cmake_vars = { "HAVE_MALLOC_MALLOC_H": 1, } # Select a set of CMake variables based on the platform. # TODO(phawkins): use a better method to select the right host triple, rather # than hardcoding x86_64. llvm_all_cmake_vars = select({ "@org_tensorflow//tensorflow:darwin": cmake_var_string( cmake_vars + llvm_target_cmake_vars("X86", "x86_64-apple-darwin") + darwin_cmake_vars), "@org_tensorflow//tensorflow:linux_ppc64le": cmake_var_string( cmake_vars + llvm_target_cmake_vars("PowerPC", "powerpc64le-unknown-linux_gnu") + linux_cmake_vars, ), "//conditions:default": cmake_var_string( cmake_vars + llvm_target_cmake_vars("X86", "x86_64-unknown-linux_gnu") + linux_cmake_vars), }) LLVM_LINKOPTS = ["-ldl", "-lm", "-lpthread"] LLVM_DEFINES = [ "LLVM_ENABLE_STATS", "__STDC_LIMIT_MACROS", "__STDC_CONSTANT_MACROS", "__STDC_FORMAT_MACROS", "_DEBUG", "LLVM_BUILD_GLOBAL_ISEL", ] LLVM_COPTS = []