From 1688961d4e148638f42c19b8d5ede48c63e28510 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 4 Nov 2011 23:10:37 +0000 Subject: [PATCH] llvm-build: Add initial --write-cmake-fragment option. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143744 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/CommandGuide/llvm-build.pod | 7 +++ utils/llvm-build/llvmbuild/main.py | 99 ++++++++++++++++++++++++++---- 2 files changed, 95 insertions(+), 11 deletions(-) diff --git a/docs/CommandGuide/llvm-build.pod b/docs/CommandGuide/llvm-build.pod index 5ce93a90c05..78648ba71e8 100644 --- a/docs/CommandGuide/llvm-build.pod +++ b/docs/CommandGuide/llvm-build.pod @@ -48,6 +48,13 @@ component combinations. Write out new I files based on the loaded components. This is useful for auto-upgrading the schema of the files. +=item B<--write-cmake-fragment> + +Write out the LLVMBuild in the form of a CMake fragment, so it can easily be +consumed by the CMake based build system. The exact contents and format of this +file are closely tied to how LLVMBuild is integrated with CMake, see LLVM's +top-level CMakeLists.txt. + =item B<--write-make-fragment> Write out the LLVMBuild in the form of a Makefile fragment, so it can easily be diff --git a/utils/llvm-build/llvmbuild/main.py b/utils/llvm-build/llvmbuild/main.py index 063dadc8f70..d361559de31 100644 --- a/utils/llvm-build/llvmbuild/main.py +++ b/utils/llvm-build/llvmbuild/main.py @@ -286,22 +286,21 @@ class LLVMProjectInfo(object): print >>f, '};' f.close() - def write_make_fragment(self, output_path): + def get_fragment_dependencies(self): """ - write_make_fragment(output_path) -> None + get_fragment_dependencies() -> iter - Generate a Makefile fragment which includes all of the collated - LLVMBuild information in a format that is easily digestible by a - Makefile. The exact contents of this are closely tied to how the LLVM - Makefiles integrate LLVMBuild, see Makefile.rules in the top-level. + Compute the list of files (as absolute paths) on which the output + fragments depend (i.e., files for which a modification should trigger a + rebuild of the fragment). """ # Construct a list of all the dependencies of the Makefile fragment # itself. These include all the LLVMBuild files themselves, as well as # all of our own sources. - dependencies = [] for ci in self.component_infos: - dependencies.append(os.path.join(self.source_root, ci.subpath[1:])) + yield os.path.join(self.source_root, ci.subpath[1:], + 'LLVMBuild.txt') # Gather the list of necessary sources by just finding all loaded # modules that are inside the LLVM source tree. @@ -320,7 +319,77 @@ class LLVMProjectInfo(object): # If the path exists and is in the source tree, consider it a # dependency. if (path.startswith(self.source_root) and os.path.exists(path)): - dependencies.append(path) + yield path + + def write_cmake_fragment(self, output_path): + """ + write_cmake_fragment(output_path) -> None + + Generate a CMake fragment which includes all of the collated LLVMBuild + information in a format that is easily digestible by a CMake. The exact + contents of this are closely tied to how the CMake configuration + integrates LLVMBuild, see CMakeLists.txt in the top-level. + """ + + dependencies = list(self.get_fragment_dependencies()) + + # Write out the CMake fragment. + f = open(output_path, 'w') + + # Write the header. + header_fmt = '\ +#===-- %s - LLVMBuild Configuration for LLVM %s-*- CMake -*--===#' + header_name = os.path.basename(output_path) + header_pad = '-' * (80 - len(header_fmt % (header_name, ''))) + header_string = header_fmt % (header_name, header_pad) + print >>f, """\ +%s +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===------------------------------------------------------------------------===# +# +# This file contains the LLVMBuild project information in a format easily +# consumed by the CMake based build system. +# +# This file is autogenerated by llvm-build, do not edit! +# +#===------------------------------------------------------------------------===# +""" % header_string + + # Write the dependency information in the best way we can. + print >>f, """ +# LLVMBuild CMake fragment dependencies. +# +# CMake has no builtin way to declare that the configuration depends on +# a particular file. However, a side effect of configure_file is to add +# said input file to CMake's internal dependency list. So, we use that +# and a dummy output file to communicate the dependency information to +# CMake. +# +# FIXME: File a CMake RFE to get a properly supported version of this +# feature.""" + for dep in dependencies: + print >>f, """\ +configure_file(\"%s\" + ${CMAKE_CURRENT_BINARY_DIR}/DummyConfigureOutput)""" % (dep,) + + f.close() + + def write_make_fragment(self, output_path): + """ + write_make_fragment(output_path) -> None + + Generate a Makefile fragment which includes all of the collated + LLVMBuild information in a format that is easily digestible by a + Makefile. The exact contents of this are closely tied to how the LLVM + Makefiles integrate LLVMBuild, see Makefile.rules in the top-level. + """ + + dependencies = list(self.get_fragment_dependencies()) # Write out the Makefile fragment. f = open(output_path, 'w') @@ -390,6 +459,10 @@ def main(): dest="write_library_table", metavar="PATH", help="Write the C++ library dependency table to PATH", action="store", default=None) + parser.add_option("", "--write-cmake-fragment", + dest="write_cmake_fragment", metavar="PATH", + help="Write the CMake project information to PATH", + action="store", default=None) parser.add_option("", "--write-make-fragment", dest="write_make_fragment", metavar="PATH", help="Write the Makefile project information to PATH", @@ -430,13 +503,17 @@ def main(): if opts.write_llvmbuild: project_info.write_components(opts.write_llvmbuild) - # Write out the required librariy, if requested. + # Write out the required library table, if requested. if opts.write_library_table: project_info.write_library_table(opts.write_library_table) - # Write out the required librariy, if requested. + # Write out the make fragment, if requested. if opts.write_make_fragment: project_info.write_make_fragment(opts.write_make_fragment) + # Write out the cmake fragment, if requested. + if opts.write_cmake_fragment: + project_info.write_cmake_fragment(opts.write_cmake_fragment) + if __name__=='__main__': main()