Filter libraries that are not installed out of CMake exports (currently
[oota-llvm.git] / utils / llvm-build / llvmbuild / main.py
index 36c7d53add1321df4c5775c871bb4bb6932324ef..78bd7967ad01010ba040303373930c4f4e511041 100644 (file)
@@ -1,4 +1,5 @@
 from __future__ import absolute_import
+import filecmp
 import os
 import sys
 
@@ -382,7 +383,7 @@ subdirectories = %s
 
         # Write out the library table.
         make_install_dir(os.path.dirname(output_path))
-        f = open(output_path, 'w')
+        f = open(output_path+'.new', 'w')
         f.write("""\
 //===- llvm-build generated file --------------------------------*- C++ -*-===//
 //
@@ -420,6 +421,14 @@ subdirectories = %s
         f.write('};\n')
         f.close()
 
+        if not os.path.isfile(output_path):
+            os.rename(output_path+'.new', output_path)
+        elif filecmp.cmp(output_path, output_path+'.new'):
+            os.remove(output_path+'.new')
+        else:
+            os.remove(output_path)
+            os.rename(output_path+'.new', output_path)
+
     def get_required_libraries_for_component(self, ci, traverse_groups = False):
         """
         get_required_libraries_for_component(component_info) -> iter
@@ -492,6 +501,33 @@ subdirectories = %s
             if (path.startswith(self.source_root) and os.path.exists(path)):
                 yield path
 
+    def foreach_cmake_library(self, f,
+                              enabled_optional_components,
+                              skip_disabled,
+                              skip_not_installed):
+        for ci in self.ordered_component_infos:
+            # Skip optional components which are not enabled.
+            if ci.type_name == 'OptionalLibrary' \
+                and ci.name not in enabled_optional_components:
+                continue
+
+            # We only write the information for libraries currently.
+            if ci.type_name not in ('Library', 'OptionalLibrary'):
+                continue
+
+            # Skip disabled targets.
+            if skip_disabled:
+                tg = ci.get_parent_target_group()
+                if tg and not tg.enabled:
+                    continue
+
+            # Skip targets that will not be installed
+            if skip_not_installed and not ci.installed:
+                continue
+
+            f(ci)
+
+
     def write_cmake_fragment(self, output_path, enabled_optional_components):
         """
         write_cmake_fragment(output_path) -> None
@@ -560,21 +596,18 @@ configure_file(\"%s\"
 # The following property assignments effectively create a map from component
 # names to required libraries, in a way that is easily accessed from CMake.
 """)
-        for ci in self.ordered_component_infos:
-            # Skip optional components which are not enabled.
-            if ci.type_name == 'OptionalLibrary' \
-                and ci.name not in enabled_optional_components:
-                continue
-
-            # We only write the information for certain components currently.
-            if ci.type_name not in ('Library', 'OptionalLibrary'):
-                continue
-
-            f.write("""\
+        self.foreach_cmake_library(
+            lambda ci:
+              f.write("""\
 set_property(GLOBAL PROPERTY LLVMBUILD_LIB_DEPS_%s %s)\n""" % (
                 ci.get_prefixed_library_name(), " ".join(sorted(
                      dep.get_prefixed_library_name()
                      for dep in self.get_required_libraries_for_component(ci)))))
+            ,
+            enabled_optional_components,
+            skip_disabled = False,
+            skip_not_installed = False # Dependency info must be emitted for internals libs too
+            )
 
         f.close()
 
@@ -599,30 +632,22 @@ set_property(GLOBAL PROPERTY LLVMBUILD_LIB_DEPS_%s %s)\n""" % (
 # The following property assignments tell CMake about link
 # dependencies of libraries imported from LLVM.
 """)
-        for ci in self.ordered_component_infos:
-            # Skip optional components which are not enabled.
-            if ci.type_name == 'OptionalLibrary' \
-                and ci.name not in enabled_optional_components:
-                continue
-
-            # We only write the information for libraries currently.
-            if ci.type_name not in ('Library', 'OptionalLibrary'):
-                continue
-
-            # Skip disabled targets.
-            tg = ci.get_parent_target_group()
-            if tg and not tg.enabled:
-                continue
-
-            f.write("""\
+        self.foreach_cmake_library(
+            lambda ci:
+              f.write("""\
 set_property(TARGET %s PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES %s)\n""" % (
                 ci.get_prefixed_library_name(), " ".join(sorted(
                      dep.get_prefixed_library_name()
                      for dep in self.get_required_libraries_for_component(ci)))))
+            ,
+            enabled_optional_components,
+            skip_disabled = True,
+            skip_not_installed = True # Do not export internal libraries like gtest
+            )
 
         f.close()
 
-    def write_make_fragment(self, output_path):
+    def write_make_fragment(self, output_path, enabled_optional_components):
         """
         write_make_fragment(output_path) -> None
 
@@ -688,6 +713,19 @@ set_property(TARGET %s PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES %s)\n""" % (
             f.write("%s:\n" % (mk_quote_string_for_target(dep),))
         f.write('endif\n')
 
+        f.write("""
+# List of libraries to be exported for use by applications.
+# See 'cmake/modules/Makefile'.
+LLVM_LIBS_TO_EXPORT :=""")
+        self.foreach_cmake_library(
+            lambda ci:
+                f.write(' \\\n  %s' % ci.get_prefixed_library_name())
+            ,
+            enabled_optional_components,
+            skip_disabled = True,
+            skip_not_installed = True # Do not export internal libraries like gtest
+            )
+        f.write('\n')
         f.close()
 
 def add_magic_target_components(parser, project, opts):
@@ -911,7 +949,8 @@ given by --build-root) at the same SUBPATH""",
 
     # Write out the make fragment, if requested.
     if opts.write_make_fragment:
-        project_info.write_make_fragment(opts.write_make_fragment)
+        project_info.write_make_fragment(opts.write_make_fragment,
+                                         opts.optional_components)
 
     # Write out the cmake fragment, if requested.
     if opts.write_cmake_fragment: