[llvm] r201053 - Provide CMake package modules in install tree

NAKAMURA Takumi geek4civic at gmail.com
Sun Feb 9 08:37:03 PST 2014


Author: chapuni
Date: Sun Feb  9 10:37:02 2014
New Revision: 201053

URL: http://llvm.org/viewvc/llvm-project?rev=201053&view=rev
Log:
Provide CMake package modules in install tree

Teach the Makefile build system to generate and install CMake modules
LLVMConfig.cmake and LLVMConfigVersion.cmake so that applications that
build with CMake can use 'find_package(LLVM)' even when LLVM is not
built with CMake.  These modules tell such applications about available
LLVM libraries and their dependencies.

Run llvm-config to generate the list of libraries and use the results of
llvm-build to generate the library dependencies.  Use sed to perform
substitutions in the LLVMConfig.cmake.in and LLVMConfigVersion.cmake.in
sources that our CMake build system uses.

Teach the Makefile build system to generate the LLVMExports.cmake file
with content similar to that produced by the CMake install(EXPORT)
command.  Extend llvm-build with an option to generate the library
dependencies fragment for this file.

Contributed by Brad King.

Added:
    llvm/trunk/cmake/Makefile
    llvm/trunk/cmake/modules/Makefile
Modified:
    llvm/trunk/Makefile
    llvm/trunk/Makefile.rules
    llvm/trunk/utils/llvm-build/llvmbuild/main.py

Modified: llvm/trunk/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile?rev=201053&r1=201052&r2=201053&view=diff
==============================================================================
--- llvm/trunk/Makefile (original)
+++ llvm/trunk/Makefile Sun Feb  9 10:37:02 2014
@@ -15,7 +15,7 @@ LEVEL := .
 #   3. Build IR, which builds the Intrinsics.inc file used by libs.
 #   4. Build libs, which are needed by llvm-config.
 #   5. Build llvm-config, which determines inter-lib dependencies for tools.
-#   6. Build tools and docs.
+#   6. Build tools, docs, and cmake modules.
 #
 # When cross-compiling, there are some things (tablegen) that need to
 # be build for the build system first.
@@ -31,7 +31,7 @@ ifeq ($(BUILD_DIRS_ONLY),1)
   OPTIONAL_DIRS := tools/clang/utils/TableGen
 else
   DIRS := lib/Support lib/TableGen utils lib/IR lib tools/llvm-shlib \
-          tools/llvm-config tools docs unittests
+          tools/llvm-config tools docs cmake unittests
   OPTIONAL_DIRS := projects bindings
 endif
 

Modified: llvm/trunk/Makefile.rules
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile.rules?rev=201053&r1=201052&r2=201053&view=diff
==============================================================================
--- llvm/trunk/Makefile.rules (original)
+++ llvm/trunk/Makefile.rules Sun Feb  9 10:37:02 2014
@@ -78,6 +78,12 @@ LLVMBuildTool	:= $(PROJ_SRC_ROOT)/utils/
 
 # The files we are going to generate using llvm-build.
 LLVMBuildMakeFrag := $(PROJ_OBJ_ROOT)/Makefile.llvmbuild
+LLVMBuildCMakeFrag := $(PROJ_OBJ_ROOT)/LLVMBuild.cmake
+LLVMBuildCMakeExportsFrag := $(PROJ_OBJ_ROOT)/cmake/modules/LLVMBuildExports.cmake
+LLVMBuildMakeFrags := \
+	$(LLVMBuildMakeFrag) \
+	$(LLVMBuildCMakeFrag) \
+	$(LLVMBuildCMakeExportsFrag)
 LLVMConfigLibraryDependenciesInc := \
 	$(PROJ_OBJ_ROOT)/tools/llvm-config/LibraryDependencies.inc
 
@@ -94,18 +100,20 @@ endif
 #
 # We include a dependency on this Makefile to ensure that changes to the
 # generation command get picked up.
-$(LLVMBuildMakeFrag): $(PROJ_SRC_ROOT)/Makefile.rules \
-		      $(PROJ_OBJ_ROOT)/Makefile.config
+$(LLVMBuildMakeFrags): $(PROJ_SRC_ROOT)/Makefile.rules \
+		       $(PROJ_OBJ_ROOT)/Makefile.config
 	$(Echo) Constructing LLVMBuild project information.
 	$(Verb)$(PYTHON) $(LLVMBuildTool) \
 	  --native-target "$(TARGET_NATIVE_ARCH)" \
 	  --enable-targets "$(TARGETS_TO_BUILD)" \
 	  --enable-optional-components "$(OPTIONAL_COMPONENTS)" \
 	  --write-library-table $(LLVMConfigLibraryDependenciesInc) \
-	  --write-make-fragment $(LLVMBuildMakeFrag)
+	  --write-make-fragment $(LLVMBuildMakeFrag) \
+	  --write-cmake-fragment $(LLVMBuildCMakeFrag) \
+	  --write-cmake-exports-fragment $(LLVMBuildCMakeExportsFrag)
 
 # For completeness, let Make know how the extra files are generated.
-$(LLVMConfigLibraryDependenciesInc): $(LLVMBuildMakeFrag)
+$(LLVMConfigLibraryDependenciesInc): $(LLVMBuildMakeFrags)
 
 # Include the generated Makefile fragment.
 #
@@ -120,7 +128,7 @@ LLVMBUILD_INCLUDE_DEPENDENCIES := 1
 
 # Clean the generated makefile fragment at the top-level.
 clean-local::
-	-$(Verb) $(RM) -f $(LLVMBuildMakeFrag)
+	-$(Verb) $(RM) -f $(LLVMBuildMakeFrags)
 endif
 -include $(LLVMBuildMakeFrag)
 

Added: llvm/trunk/cmake/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/Makefile?rev=201053&view=auto
==============================================================================
--- llvm/trunk/cmake/Makefile (added)
+++ llvm/trunk/cmake/Makefile Sun Feb  9 10:37:02 2014
@@ -0,0 +1,12 @@
+##===- cmake/Makefile --------------------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ..
+DIRS := modules
+
+include $(LEVEL)/Makefile.common

Added: llvm/trunk/cmake/modules/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/Makefile?rev=201053&view=auto
==============================================================================
--- llvm/trunk/cmake/modules/Makefile (added)
+++ llvm/trunk/cmake/modules/Makefile Sun Feb  9 10:37:02 2014
@@ -0,0 +1,106 @@
+##===- cmake/modules/Makefile ------------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+
+LINK_COMPONENTS := all
+
+include $(LEVEL)/Makefile.common
+
+PROJ_cmake := $(DESTDIR)$(PROJ_prefix)/share/llvm/cmake
+
+OBJMODS := LLVMConfig.cmake LLVMConfigVersion.cmake LLVMExports.cmake
+
+# TODO: Teach LLVM-Config.cmake to work without explicit terminfo libs.
+TERMINFO_LIBS := tinfo terminfo curses ncurses ncursesw
+TERMINFO_LIBS := $(filter $(TERMINFO_LIBS),$(subst -l,,$(LIBS)))
+
+$(PROJ_OBJ_DIR)/LLVMConfig.cmake: LLVMConfig.cmake.in $(LLVMBuildCMakeFrag)
+	$(Echo) 'Generating LLVM CMake package config file'
+	$(Verb) ( \
+	 cat $< | sed \
+	  -e 's/@LLVM_CONFIG_CODE@/set(LLVM_INSTALL_PREFIX "'"$(subst /,\/,$(PROJ_prefix))"'")/' \
+	  -e 's/@LLVM_VERSION_MAJOR@/'"$(LLVM_VERSION_MAJOR)"'/' \
+	  -e 's/@LLVM_VERSION_MINOR@/'"$(LLVM_VERSION_MINOR)"'/' \
+	  -e 's/@PACKAGE_VERSION@/'"$(LLVMVersion)"'/' \
+	  -e 's/@LLVM_COMMON_DEPENDS@//' \
+	  -e 's/"@llvm_libs@"/'"$(subst -l,,$(LLVMConfigLibs))"'/' \
+	  -e 's/@LLVM_ALL_TARGETS@/'"$(ALL_TARGETS)"'/' \
+	  -e 's/@LLVM_TARGETS_TO_BUILD@/'"$(TARGETS_TO_BUILD)"'/' \
+	  -e 's/@LLVM_TARGETS_WITH_JIT@/'"$(TARGETS_WITH_JIT)"'/' \
+	  -e 's/@TARGET_TRIPLE@/'"$(TARGET_TRIPLE)"'/' \
+	  -e 's/@LLVM_ENABLE_TERMINFO@/'"$(ENABLE_TERMINFO)"'/' \
+	  -e 's/@LLVM_ENABLE_THREADS@/'"$(ENABLE_THREADS)"'/' \
+	  -e 's/@LLVM_ENABLE_ZLIB@/'"$(ENABLE_ZLIB)"'/' \
+	  -e 's/@LLVM_NATIVE_ARCH@/'"$(LLVM_NATIVE_ARCH)"'/' \
+	  -e 's/@LLVM_ENABLE_PIC@/'"$(ENABLE_PIC)"'/' \
+	  -e 's/@HAVE_TERMINFO@/'"$(HAVE_TERMINFO)"'/' \
+	  -e 's/@TERMINFO_LIBS@/'"$(TERMINFO_LIBS)"'/' \
+	  -e 's/@HAVE_LIBDL@/'"$(HAVE_DLOPEN)"'/' \
+	  -e 's/@HAVE_LIBPTHREAD@/'"$(HAVE_PTHREAD)"'/' \
+	  -e 's/@HAVE_LIBZ@/'"$(HAVE_LIBZ)"'/' \
+	  -e 's/@LLVM_ON_UNIX@/'"$(LLVM_ON_UNIX)"'/' \
+	  -e 's/@LLVM_ON_WIN32@/'"$(LLVM_ON_WIN32)"'/' \
+	  -e 's/@LLVM_CONFIG_INCLUDE_DIRS@/'"$(subst /,\/,$(PROJ_includedir))"'/' \
+	  -e 's/@LLVM_CONFIG_LIBRARY_DIRS@/'"$(subst /,\/,$(PROJ_libdir))"'/' \
+	  -e 's/@LLVM_CONFIG_CMAKE_DIR@/'"$(subst /,\/,$(PROJ_cmake))"'/' \
+	  -e 's/@LLVM_CONFIG_EXPORTS_FILE@/$${LLVM_CMAKE_DIR}\/LLVMExports.cmake/' \
+	  -e 's/@all_llvm_lib_deps@//' \
+	 && \
+	 # TODO: Teach LLVM-Config.cmake to use builtin CMake features     \
+	 # for library dependencies.  For now add the generated fragments. \
+	 grep '^set_property.*LLVMBUILD_LIB_DEPS_' "$(LLVMBuildCMakeFrag)" \
+	) > $@
+
+$(PROJ_OBJ_DIR)/LLVMConfigVersion.cmake: LLVMConfigVersion.cmake.in
+	$(Echo) 'Generating LLVM CMake package version file'
+	$(Verb) cat $< | sed \
+	  -e 's/@PACKAGE_VERSION@/'"$(LLVMVersion)"'/' \
+	  > $@
+
+$(PROJ_OBJ_DIR)/LLVMExports.cmake: $(LLVMBuildCMakeExportsFrag)
+	$(Echo) 'Generating LLVM CMake target exports file'
+	$(Verb) ( \
+	  echo '# LLVM CMake target exports.  Do not include directly.' && \
+	  for lib in $(subst -l,,$(LLVMConfigLibs)); do \
+	    echo 'add_library('"$$lib"' STATIC IMPORTED)' && \
+	    echo 'set_property(TARGET '"$$lib"' PROPERTY IMPORTED_LOCATION "'"$(PROJ_libdir)/lib$$lib.a"'")' ; \
+	  done && \
+	  cat "$(LLVMBuildCMakeExportsFrag)" \
+	) > $@
+
+all-local:: $(addprefix $(PROJ_OBJ_DIR)/, $(OBJMODS))
+
+SKIPSRCMODS := \
+  CheckAtomic.cmake \
+  GetHostTriple.cmake \
+  LLVMBuildExports.cmake \
+  LLVMConfig.cmake \
+  LLVMConfigVersion.cmake \
+  LLVMExports.cmake \
+  VersionFromVCS.cmake
+
+SRCMODS := $(notdir $(wildcard $(PROJ_SRC_DIR)/*.cmake))
+SRCMODS := $(filter-out $(SKIPSRCMODS),$(SRCMODS))
+INSTSRCMODS := $(addprefix $(PROJ_cmake)/, $(SRCMODS))
+INSTOBJMODS := $(addprefix $(PROJ_cmake)/, $(OBJMODS))
+
+$(PROJ_cmake):
+	$(Echo) Making install directory: $@
+	$(Verb) $(MKDIR) $@
+
+$(INSTSRCMODS): $(PROJ_cmake)/%.cmake: $(PROJ_SRC_DIR)/%.cmake | $(PROJ_cmake)
+	$(Echo) Installing cmake modules: $(notdir $<)
+	$(Verb) $(DataInstall) $< $(PROJ_cmake)
+
+$(INSTOBJMODS): $(PROJ_cmake)/%.cmake: $(PROJ_OBJ_DIR)/%.cmake | $(PROJ_cmake)
+	$(Echo) Installing cmake modules: $(notdir $<)
+	$(Verb) $(DataInstall) $< $(PROJ_cmake)
+
+install-local:: $(INSTSRCMODS) $(INSTOBJMODS)

Modified: llvm/trunk/utils/llvm-build/llvmbuild/main.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/llvm-build/llvmbuild/main.py?rev=201053&r1=201052&r2=201053&view=diff
==============================================================================
--- llvm/trunk/utils/llvm-build/llvmbuild/main.py (original)
+++ llvm/trunk/utils/llvm-build/llvmbuild/main.py Sun Feb  9 10:37:02 2014
@@ -573,6 +573,40 @@ set_property(GLOBAL PROPERTY LLVMBUILD_L
 
         f.close()
 
+    def write_cmake_exports_fragment(self, output_path):
+        """
+        write_cmake_exports_fragment(output_path) -> None
+
+        Generate a CMake fragment which includes LLVMBuild library
+        dependencies expressed similarly to how CMake would write
+        them via install(EXPORT).
+        """
+
+        dependencies = list(self.get_fragment_dependencies())
+
+        # Write out the CMake exports fragment.
+        make_install_dir(os.path.dirname(output_path))
+        f = open(output_path, 'w')
+
+        f.write("""\
+# Explicit library dependency information.
+#
+# The following property assignments tell CMake about link
+# dependencies of libraries imported from LLVM.
+""")
+        for ci in self.ordered_component_infos:
+            # We only write the information for libraries currently.
+            if ci.type_name != 'Library':
+                continue
+
+            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)))))
+
+        f.close()
+
     def write_make_fragment(self, output_path):
         """
         write_make_fragment(output_path) -> None
@@ -780,6 +814,10 @@ def main():
                      dest="write_cmake_fragment", metavar="PATH",
                      help="Write the CMake project information to PATH",
                      action="store", default=None)
+    group.add_option("", "--write-cmake-exports-fragment",
+                     dest="write_cmake_exports_fragment", metavar="PATH",
+                     help="Write the CMake exports information to PATH",
+                     action="store", default=None)
     group.add_option("", "--write-make-fragment",
                       dest="write_make_fragment", metavar="PATH",
                      help="Write the Makefile project information to PATH",
@@ -861,6 +899,8 @@ given by --build-root) at the same SUBPA
     # Write out the cmake fragment, if requested.
     if opts.write_cmake_fragment:
         project_info.write_cmake_fragment(opts.write_cmake_fragment)
+    if opts.write_cmake_exports_fragment:
+        project_info.write_cmake_exports_fragment(opts.write_cmake_exports_fragment)
 
     # Configure target definition files, if requested.
     if opts.configure_target_def_files:





More information about the llvm-commits mailing list