Export Ceres build directory into local CMake package registry.

- Optionally use CMake's export() functionality to export the Ceres
  build directory as a package into the local CMake package registry.
- This enables the detection & use of Ceres from CMake *without*
  requiring that Ceres be installed.

Change-Id: Ib5a7588446f490e1b405878475b6b1dd13accd1f
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e3d3cc7..803a7c5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -37,7 +37,7 @@
   CMAKE_POLICY(SET CMP0042 NEW)
 ENDIF()
 
-PROJECT(CERES C CXX)
+PROJECT(Ceres C CXX)
 
 # Make CMake aware of the cmake folder for local FindXXX scripts,
 # append rather than set in case the user has passed their own
@@ -114,6 +114,8 @@
    under the MPL."
   OFF)
 OPTION(CXX11 "Enable use of C++11 if available (requires client code use C++11)." OFF)
+OPTION(EXPORT_BUILD_DIR
+  "Export build directory using CMake (enables external use without install)." OFF)
 OPTION(BUILD_TESTING "Enable tests" ON)
 OPTION(BUILD_DOCUMENTATION "Build User's Guide (html)" OFF)
 OPTION(BUILD_EXAMPLES "Build examples" ON)
@@ -767,13 +769,13 @@
 LIST(REMOVE_DUPLICATES CERES_COMPILE_OPTIONS)
 INCLUDE(CreateCeresConfig)
 CREATE_CERES_CONFIG("${CERES_COMPILE_OPTIONS}"
-  ${CMAKE_CURRENT_BINARY_DIR}/config/ceres/internal)
+  ${CMAKE_BINARY_DIR}/config/ceres/internal)
 # Force the location containing the configured config.h to the front of the
 # include_directories list (by default it is appended to the back) to ensure
 # that if the user has an installed version of Ceres in the same location as one
 # of the dependencies (e.g. /usr/local) that we find the config.h we just
 # configured, not the (older) installed config.h.
-INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/config)
+INCLUDE_DIRECTORIES(BEFORE ${CMAKE_BINARY_DIR}/config)
 
 ADD_SUBDIRECTORY(internal/ceres)
 
@@ -806,10 +808,9 @@
 
 # Also setup installation of Ceres config.h configured with the current
 # build options into the installed headers directory.
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/config/ceres/internal/config.h
+INSTALL(FILES ${CMAKE_BINARY_DIR}/config/ceres/internal/config.h
         DESTINATION include/ceres/internal)
 
-
 IF (MINIGLOG)
   # Install miniglog header if being used as logging #includes appear in
   # installed public Ceres headers.
@@ -817,58 +818,109 @@
           DESTINATION include/ceres/internal/miniglog/glog)
 ENDIF (MINIGLOG)
 
-# Add an uninstall target to remove all installed files.
-CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/cmake/uninstall.cmake.in"
-               "${CMAKE_BINARY_DIR}/cmake/uninstall.cmake"
-               IMMEDIATE @ONLY)
+# Ceres supports two mechanisms by which it can be detected & imported into
+# client code which uses CMake via find_package(Ceres):
+#
+#   1) Installation (e.g. to /usr/local), using CMake's install() function.
+#
+#   2) (Optional) Export of the current build directory into the local CMake
+#      package registry, using CMake's export() function.  This allows use of
+#      Ceres from other projects without requiring installation.
+#
+# In both cases, we need to generate a configured CeresConfig.cmake which
+# includes additional autogenerated files which in concert create an imported
+# target for Ceres in a client project when find_package(Ceres) is invoked.
+# The key distinctions are where this file is located, and whether client code
+# references installed copies of the compiled Ceres headers/libraries,
+# (option #1: installation), or the originals in the source/build directories
+# (option #2: export of build directory).
+#
+# NOTE: If Ceres is both exported and installed, provided that the installation
+#       path is present in CMAKE_MODULE_PATH when find_package(Ceres) is called,
+#       the installed version is preferred.
 
-ADD_CUSTOM_TARGET(uninstall
-                  COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cmake/uninstall.cmake)
+# Create a CeresConfigVersion.cmake file containing the version information,
+# used by both export() & install().
+CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/cmake/CeresConfigVersion.cmake.in"
+               "${CMAKE_BINARY_DIR}/CeresConfigVersion.cmake" @ONLY)
 
-# Set relative install paths, which are appended to CMAKE_INSTALL_PREFIX to
-# generate the absolute install paths.
+# Install method #1: Put Ceres in CMAKE_INSTALL_PREFIX: /usr/local or equivalent.
+
+# Set the install path for the installed CeresConfig.cmake configuration file
+# relative to CMAKE_INSTALL_PREFIX.
 IF (WIN32)
   SET(RELATIVE_CMAKECONFIG_INSTALL_DIR CMake)
 ELSE ()
   SET(RELATIVE_CMAKECONFIG_INSTALL_DIR share/Ceres)
 ENDIF ()
 
-# This "exports" all targets which have been put into the export set
-# "CeresExport". This means that CMake generates a file with the given
-# filename, which can later on be loaded by projects using this package.
-# This file contains ADD_LIBRARY(bar IMPORTED) statements for each target
-# in the export set, so when loaded later on CMake will create "imported"
-# library targets from these, which can be used in many ways in the same way
-# as a normal library target created via a normal ADD_LIBRARY().
+# This "exports" for installation all targets which have been put into the
+# export set "CeresExport". This generates a CeresTargets.cmake file which,
+# when read in by a client project as part of find_package(Ceres) creates
+# imported library targets for Ceres (with dependency relations) which can be
+# used in target_link_libraries() calls in the client project to use Ceres.
 INSTALL(EXPORT CeresExport
         DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR} FILE CeresTargets.cmake)
 
-# Figure out the relative path from the installed Config.cmake file to the
-# install prefix (which may be at runtime different from the chosen
-# CMAKE_INSTALL_PREFIX if under Windows the package was installed anywhere)
-# This relative path will be configured into the CeresConfig.cmake.
+# Save the relative path from the installed CeresConfig.cmake file to the
+# install prefix.  We do not save an absolute path in case the installed package
+# is subsequently relocated after installation (on Windows).
 FILE(RELATIVE_PATH INSTALL_ROOT_REL_CONFIG_INSTALL_DIR
      ${CMAKE_INSTALL_PREFIX}/${RELATIVE_CMAKECONFIG_INSTALL_DIR}
      ${CMAKE_INSTALL_PREFIX})
 
-# Create a CeresConfig.cmake file. <name>Config.cmake files are searched by
-# FIND_PACKAGE() automatically. We configure that file so that we can put any
-# information we want in it, e.g. version numbers, include directories, etc.
+# Configure a CeresConfig.cmake file for an installed version of Ceres from the
+# template, reflecting the current build options.
+#
+# NOTE: The -install suffix is necessary to distinguish the install version from
+#       the exported version, which must be named CeresConfig.cmake in
+#       CMAKE_BINARY_DIR to be detected.  The suffix is removed when
+#       it is installed.
+SET(SETUP_CERES_CONFIG_FOR_INSTALLATION TRUE)
 CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/cmake/CeresConfig.cmake.in"
-               "${CMAKE_CURRENT_BINARY_DIR}/CeresConfig.cmake" @ONLY)
+               "${CMAKE_BINARY_DIR}/CeresConfig-install.cmake" @ONLY)
 
-# Additionally, when CMake has found a CeresConfig.cmake, it can check for a
-# CeresConfigVersion.cmake in the same directory when figuring out the version
-# of the package when a version has been specified in the FIND_PACKAGE() call,
-# e.g. FIND_PACKAGE(Ceres [1.4.2] REQUIRED). The version argument is optional.
-CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/cmake/CeresConfigVersion.cmake.in"
-               "${CMAKE_CURRENT_BINARY_DIR}/CeresConfigVersion.cmake" @ONLY)
-
-# Install these files into the same directory as the generated exports-file,
-# we include the FindPackage scripts for libraries whose headers are included
-# in the public API of Ceres and should thus be present in CERES_INCLUDE_DIRS.
-INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/CeresConfig.cmake"
-              "${CMAKE_CURRENT_BINARY_DIR}/CeresConfigVersion.cmake"
+# Install the configuration files into the same directory as the autogenerated
+# CeresTargets.cmake file.  We include the find_package() scripts for libraries
+# whose headers are included in the public API of Ceres and should thus be
+# present in CERES_INCLUDE_DIRS.
+INSTALL(FILES "${CMAKE_BINARY_DIR}/CeresConfig-install.cmake"
+        RENAME CeresConfig.cmake
+        DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR})
+INSTALL(FILES "${CMAKE_BINARY_DIR}/CeresConfigVersion.cmake"
               "${CMAKE_SOURCE_DIR}/cmake/FindEigen.cmake"
               "${CMAKE_SOURCE_DIR}/cmake/FindGlog.cmake"
         DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR})
+
+# Create an uninstall target to remove all installed files.
+CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/cmake/uninstall.cmake.in"
+               "${CMAKE_BINARY_DIR}/cmake/uninstall.cmake"
+               @ONLY)
+ADD_CUSTOM_TARGET(uninstall
+                  COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cmake/uninstall.cmake)
+
+# Install method #2: Put Ceres build into local CMake registry.
+#
+# Optionally export the Ceres build directory into the local CMake package
+# registry (~/.cmake/packages on *nix & OS X).  This allows the detection &
+# use of Ceres without requiring that it be installed.
+IF (EXPORT_BUILD_DIR)
+  MESSAGE("-- Export Ceres build directory to local CMake package registry.")
+
+  # Save the relative path from the build directory to the source directory.
+  FILE(RELATIVE_PATH INSTALL_ROOT_REL_CONFIG_INSTALL_DIR
+    ${CMAKE_BINARY_DIR}
+    ${CMAKE_SOURCE_DIR})
+
+  # Analogously to install(EXPORT ...), export the Ceres target from the build
+  # directory as a package called Ceres into the local CMake package registry.
+  EXPORT(TARGETS ceres FILE ${CMAKE_BINARY_DIR}/CeresTargets.cmake)
+  EXPORT(PACKAGE ${CMAKE_PROJECT_NAME})
+
+  # Configure a CeresConfig.cmake file for the export of the Ceres build
+  # directory from the template, reflecting the current build options.
+  SET(SETUP_CERES_CONFIG_FOR_INSTALLATION FALSE)
+  CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/cmake/CeresConfig.cmake.in"
+    "${CMAKE_BINARY_DIR}/CeresConfig.cmake" @ONLY)
+
+ENDIF (EXPORT_BUILD_DIR)
diff --git a/cmake/CeresConfig.cmake.in b/cmake/CeresConfig.cmake.in
index d4cf7c2..6b89e96 100644
--- a/cmake/CeresConfig.cmake.in
+++ b/cmake/CeresConfig.cmake.in
@@ -32,8 +32,10 @@
 
 # Config file for Ceres Solver - Find Ceres & dependencies.
 #
-# This file is used by CMake when FIND_PACKAGE( Ceres ) is invoked (and
-# the directory containing this file is present in CMAKE_MODULE_PATH).
+# This file is used by CMake when find_package(Ceres) is invoked and either
+# the directory containing this file either is present in CMAKE_MODULE_PATH
+# (if Ceres was installed), or exists in the local CMake package registry if
+# the Ceres build directory was exported.
 #
 # This module defines the following variables:
 #
@@ -64,7 +66,7 @@
 #
 # CERES_INCLUDES = ${CERES_INCLUDE_DIRS}.
 
-# Called if we failed to find Ceres or any of it's required dependencies,
+# Called if we failed to find Ceres or any of its required dependencies,
 # unsets all public (designed to be used externally) variables and reports
 # error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument.
 MACRO(CERES_REPORT_NOT_FOUND REASON_MSG)
@@ -92,55 +94,99 @@
   RETURN()
 ENDMACRO(CERES_REPORT_NOT_FOUND)
 
-# Get the (current, i.e. installed) directory containing this file.
-GET_FILENAME_COMPONENT(CERES_CURRENT_CONFIG_INSTALL_DIR
-  "${CMAKE_CURRENT_LIST_FILE}" PATH)
+# If Ceres was not installed, then by definition it was exported
+# from a build directory.
+SET(CERES_WAS_INSTALLED @SETUP_CERES_CONFIG_FOR_INSTALLATION@)
 
 # Record the state of the CMake module path when this script was
 # called so that we can ensure that we leave it in the same state on
 # exit as it was on entry, but modify it locally.
 SET(CALLERS_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
-# Reset CMake module path to the installation directory of this
-# script, thus we will use the FindPackage() scripts shipped with
-# Ceres to find Ceres' dependencies, even if the user has equivalently
-# named FindPackage() scripts in their project.
-SET(CMAKE_MODULE_PATH ${CERES_CURRENT_CONFIG_INSTALL_DIR})
 
-# Build the absolute root install directory as a relative path
-# (determined when Ceres was configured & built) from the current
-# install directory for this this file.  This allows for the install
-# tree to be relocated, after Ceres was built, outside of CMake.
-GET_FILENAME_COMPONENT(CURRENT_ROOT_INSTALL_DIR
-  ${CERES_CURRENT_CONFIG_INSTALL_DIR}/@INSTALL_ROOT_REL_CONFIG_INSTALL_DIR@ ABSOLUTE)
-IF (NOT EXISTS ${CURRENT_ROOT_INSTALL_DIR})
-  CERES_REPORT_NOT_FOUND(
-    "Ceres install root: ${CURRENT_ROOT_INSTALL_DIR}, "
-    "determined from relative path from CeresConfig.cmake install location: "
-    "${CERES_CURRENT_CONFIG_INSTALL_DIR}, does not exist. Either the install "
-    "directory was deleted, or the install tree was only partially relocated "
-    "outside of CMake after Ceres was built.")
-ENDIF (NOT EXISTS ${CURRENT_ROOT_INSTALL_DIR})
+# Get the (current, i.e. installed) directory containing this file.
+GET_FILENAME_COMPONENT(CERES_CURRENT_CONFIG_DIR
+  "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+IF (CERES_WAS_INSTALLED)
+  # Reset CMake module path to the installation directory of this
+  # script, thus we will use the FindPackage() scripts shipped with
+  # Ceres to find Ceres' dependencies, even if the user has equivalently
+  # named FindPackage() scripts in their project.
+  SET(CMAKE_MODULE_PATH ${CERES_CURRENT_CONFIG_DIR})
+
+  # Build the absolute root install directory as a relative path
+  # (determined when Ceres was configured & built) from the current
+  # install directory for this this file.  This allows for the install
+  # tree to be relocated, after Ceres was built, outside of CMake.
+  GET_FILENAME_COMPONENT(CURRENT_ROOT_INSTALL_DIR
+    ${CERES_CURRENT_CONFIG_DIR}/@INSTALL_ROOT_REL_CONFIG_INSTALL_DIR@
+    ABSOLUTE)
+  IF (NOT EXISTS ${CURRENT_ROOT_INSTALL_DIR})
+    CERES_REPORT_NOT_FOUND(
+      "Ceres install root: ${CURRENT_ROOT_INSTALL_DIR}, "
+      "determined from relative path from CeresConfig.cmake install location: "
+      "${CERES_CURRENT_CONFIG_DIR}, does not exist. Either the install "
+      "directory was deleted, or the install tree was only partially relocated "
+      "outside of CMake after Ceres was built.")
+  ENDIF (NOT EXISTS ${CURRENT_ROOT_INSTALL_DIR})
+
+  # Set the include directories for Ceres (itself).
+  SET(CERES_INCLUDE_DIR "${CURRENT_ROOT_INSTALL_DIR}/include")
+  IF (NOT EXISTS ${CERES_INCLUDE_DIR}/ceres/ceres.h)
+    CERES_REPORT_NOT_FOUND(
+      "Ceres install root: ${CURRENT_ROOT_INSTALL_DIR}, "
+      "determined from relative path from CeresConfig.cmake install location: "
+      "${CERES_CURRENT_CONFIG_DIR}, does not contain Ceres headers. "
+      "Either the install directory was deleted, or the install tree was only "
+      "partially relocated outside of CMake after Ceres was built.")
+  ENDIF (NOT EXISTS ${CERES_INCLUDE_DIR}/ceres/ceres.h)
+  LIST(APPEND CERES_INCLUDE_DIRS ${CERES_INCLUDE_DIR})
+
+ELSE(CERES_WAS_INSTALLED)
+  # Ceres was exported from the build tree.
+  SET(CERES_EXPORTED_BUILD_DIR ${CERES_CURRENT_CONFIG_DIR})
+  GET_FILENAME_COMPONENT(CERES_EXPORTED_SOURCE_DIR
+    ${CERES_EXPORTED_BUILD_DIR}/@INSTALL_ROOT_REL_CONFIG_INSTALL_DIR@
+    ABSOLUTE)
+  IF (NOT EXISTS ${CERES_EXPORTED_SOURCE_DIR})
+    CERES_REPORT_NOT_FOUND(
+      "Ceres exported source directory: ${CERES_EXPORTED_SOURCE_DIR}, "
+      "determined from relative path from CeresConfig.cmake exported build "
+      "directory: ${CERES_EXPORTED_BUILD_DIR} does not exist.")
+  ENDIF()
+
+  # Reset CMake module path to the cmake directory in the Ceres source
+  # tree which was exported, thus we will use the FindPackage() scripts shipped
+  # with Ceres to find Ceres' dependencies, even if the user has equivalently
+  # named FindPackage() scripts in their project.
+  SET(CMAKE_MODULE_PATH ${CERES_EXPORTED_SOURCE_DIR}/cmake)
+
+  # Set the include directories for Ceres (itself).
+  SET(CERES_INCLUDE_DIR "${CERES_EXPORTED_SOURCE_DIR}/include")
+  IF (NOT EXISTS ${CERES_INCLUDE_DIR}/ceres/ceres.h)
+    CERES_REPORT_NOT_FOUND(
+      "Ceres exported source directory: ${CERES_EXPORTED_SOURCE_DIR}, "
+      "determined from relative path from CeresConfig.cmake exported build "
+      "directory: ${CERES_EXPORTED_BUILD_DIR}, does not contain Ceres headers.")
+  ENDIF (NOT EXISTS ${CERES_INCLUDE_DIR}/ceres/ceres.h)
+  LIST(APPEND CERES_INCLUDE_DIRS ${CERES_INCLUDE_DIR})
+
+  # Append the path to the configured config.h in the exported build directory
+  # to the Ceres include directories.
+  SET(CERES_CONFIG_FILE
+    ${CERES_EXPORTED_BUILD_DIR}/config/ceres/internal/config.h)
+  IF (NOT EXISTS ${CERES_CONFIG_FILE})
+    CERES_REPORT_NOT_FOUND(
+      "Ceres exported build directory: ${CERES_EXPORTED_BUILD_DIR}, "
+      "does not contain required configured Ceres config.h, it is not here: "
+      "${CERES_CONFIG_FILE}.")
+  ENDIF (NOT EXISTS ${CERES_CONFIG_FILE})
+  LIST(APPEND CERES_INCLUDE_DIRS ${CERES_EXPORTED_BUILD_DIR}/config)
+ENDIF(CERES_WAS_INSTALLED)
 
 # Set the version.
 SET(CERES_VERSION @CERES_VERSION@ )
 
-# Set the include directories for Ceres (itself).
-SET(CERES_INCLUDE_DIR "${CURRENT_ROOT_INSTALL_DIR}/include")
-IF (NOT EXISTS ${CERES_INCLUDE_DIR}/ceres/ceres.h)
-  CERES_REPORT_NOT_FOUND(
-    "Ceres install root: ${CURRENT_ROOT_INSTALL_DIR}, "
-    "determined from relative path from CeresConfig.cmake install location: "
-    "${CERES_CURRENT_CONFIG_INSTALL_DIR}, does not contain Ceres headers. "
-    "Either the install directory was deleted, or the install tree was only "
-    "partially relocated outside of CMake after Ceres was built.")
-ENDIF (NOT EXISTS ${CERES_INCLUDE_DIR}/ceres/ceres.h)
-
-# Append the include directories for all (potentially optional)
-# dependencies with which Ceres was compiled, the libraries themselves
-# come in via CeresTargets-<release/debug>.cmake as link libraries for
-# Ceres target.
-SET(CERES_INCLUDE_DIRS ${CERES_INCLUDE_DIR})
-
 # Eigen.
 # Flag set during configuration and build of Ceres.
 SET(CERES_EIGEN_VERSION @EIGEN_VERSION@)
@@ -178,14 +224,14 @@
   SET(MINIGLOG_INCLUDE_DIR ${CERES_INCLUDE_DIR}/ceres/internal/miniglog)
   IF (NOT EXISTS ${MINIGLOG_INCLUDE_DIR})
     CERES_REPORT_NOT_FOUND(
-      "Ceres install include directory: "
+      "Ceres include directory: "
       "${CERES_INCLUDE_DIR} does not include miniglog, but Ceres was "
       "compiled with MINIGLOG enabled (in place of Glog).")
   ENDIF (NOT EXISTS ${MINIGLOG_INCLUDE_DIR})
   LIST(APPEND CERES_INCLUDE_DIRS ${MINIGLOG_INCLUDE_DIR})
   # Output message at standard log level (not the lower STATUS) so that
   # the message is output in GUI during configuration to warn user.
-  MESSAGE("-- Found Ceres installation compiled with miniglog substitute "
+  MESSAGE("-- Found Ceres compiled with miniglog substitute "
     "for glog, beware this will likely cause problems if glog is later linked.")
 ELSE (CERES_USES_MINIGLOG)
   # Append the locations of glog when Ceres was built to the search path hints.
@@ -205,9 +251,9 @@
   LIST(APPEND CERES_INCLUDE_DIRS ${GLOG_INCLUDE_DIRS})
 ENDIF (CERES_USES_MINIGLOG)
 
-# Import exported Ceres targets.
+# Import exported Ceres targets, if they have not already been imported.
 IF (NOT TARGET ceres AND NOT Ceres_BINARY_DIR)
-  INCLUDE(${CERES_CURRENT_CONFIG_INSTALL_DIR}/CeresTargets.cmake)
+  INCLUDE(${CERES_CURRENT_CONFIG_DIR}/CeresTargets.cmake)
 ENDIF (NOT TARGET ceres AND NOT Ceres_BINARY_DIR)
 # Set the expected XX_LIBRARIES variable for FindPackage().
 SET(CERES_LIBRARIES ceres)
@@ -220,8 +266,13 @@
 
 # As we use CERES_REPORT_NOT_FOUND() to abort, if we reach this point we have
 # found Ceres and all required dependencies.
-MESSAGE(STATUS "Found Ceres version: ${CERES_VERSION} "
+IF (CERES_WAS_INSTALLED)
+  MESSAGE(STATUS "Found Ceres version: ${CERES_VERSION} "
     "installed in: ${CURRENT_ROOT_INSTALL_DIR}")
+ELSE (CERES_WAS_INSTALLED)
+  MESSAGE(STATUS "Found Ceres version: ${CERES_VERSION} "
+    "exported from build directory: ${CERES_EXPORTED_BUILD_DIR}")
+ENDIF()
 
 # Set CERES_FOUND to be equivalent to Ceres_FOUND, which is set to
 # TRUE by FindPackage() if this file is found and run, and after which
diff --git a/docs/source/building.rst b/docs/source/building.rst
index 9b85a78..8582424 100644
--- a/docs/source/building.rst
+++ b/docs/source/building.rst
@@ -86,7 +86,7 @@
   <https://github.com/xianyi/OpenBLAS/wiki/faq#wiki-multi-threaded>`_
   inside ``OpenBLAS`` as it conflicts with use of threads in Ceres.
 
-  MAC OS X ships with an optimized ``LAPACK`` and ``BLAS``
+  Mac OS X ships with an optimized ``LAPACK`` and ``BLAS``
   implementation as part of the ``Accelerate`` framework. The Ceres
   build system will automatically detect and use it.
 
@@ -111,7 +111,7 @@
  to build Ceres as a *shared* library.  Thus if you want to build
  Ceres as a shared library using SuiteSparse, you must perform a
  source install of SuiteSparse or use an external PPA (see
- https://bugs.launchpad.net/ubuntu/+source/suitesparse/+bug/1333214).
+ `bug report here <https://bugs.launchpad.net/ubuntu/+source/suitesparse/+bug/1333214>`_).
  It is recommended that you use the current version of SuiteSparse
  (4.2.1 at the time of writing).
 
@@ -149,6 +149,9 @@
  cmake ../ceres-solver-1.10.0
  make -j3
  make test
+ # Optionally install Ceres, it can also be exported using CMake which
+ # allows Ceres to be used without requiring installation, see the documentation
+ # for the EXPORT_BUILD_DIR option for more information.
  make install
 
 You can also try running the command line bundling application with one of the
@@ -227,7 +230,7 @@
 
 
 On OS X, you can either use `MacPorts <https://www.macports.org/>`_ or
-`homebrew <http://mxcl.github.com/homebrew/>`_ to install Ceres Solver.
+`Homebrew <http://mxcl.github.com/homebrew/>`_ to install Ceres Solver.
 
 If using `MacPorts <https://www.macports.org/>`_, then
 
@@ -237,7 +240,7 @@
 
 will install the latest version.
 
-If using `homebrew <http://mxcl.github.com/homebrew/>`_ and assuming
+If using `Homebrew <http://mxcl.github.com/homebrew/>`_ and assuming
 that you have the ``homebrew/science`` [#f1]_ tap enabled, then
 
 .. code-block:: bash
@@ -253,7 +256,7 @@
 
 will install the latest version in the git repo.
 
-You can also install each of the dependencies by hand using `homebrew
+You can also install each of the dependencies by hand using `Homebrew
 <http://mxcl.github.com/homebrew/>`_. There is no need to install
 ``BLAS`` or ``LAPACK`` separately as OS X ships with optimized
 ``BLAS`` and ``LAPACK`` routines as part of the `vecLib
@@ -281,6 +284,9 @@
    cmake ../ceres-solver-1.10.0
    make -j3
    make test
+   # Optionally install Ceres, it can also be exported using CMake which
+   # allows Ceres to be used without requiring installation, see the
+   # documentation for the EXPORT_BUILD_DIR option for more information.
    make install
 
 Like the Linux build, you should now be able to run
@@ -306,7 +312,7 @@
 
 .. NOTE::
 
-  If you find the following `CMake` difficult to set up, then you may
+  If you find the following CMake difficult to set up, then you may
   be interested in a `Microsoft Visual Studio wrapper
   <https://github.com/tbennun/ceres-windows>`_ for Ceres Solver by Tal
   Ben-Nun.
@@ -461,7 +467,7 @@
 ``CLUSTER_JACOBI`` and ``CLUSTER_TRIDIAGONAL`` preconditioners).
 
 If you decide to use ``LAPACK`` and ``BLAS``, then you also need to add
-``Accelerate.framework`` to your XCode project's linking dependency.
+``Accelerate.framework`` to your Xcode project's linking dependency.
 
 .. _section-customizing:
 
@@ -543,6 +549,14 @@
    a static library, turn this ``ON`` to instead build Ceres as a
    shared library.
 
+#. ``EXPORT_BUILD_DIR [Default: OFF]``: By default Ceres is configured solely
+   for installation, and so must be installed in order for clients to use it.
+   Turn this ``ON`` to export Ceres' build directory location into the
+   `user's local CMake package registry <http://www.cmake.org/cmake/help/v3.2/manual/cmake-packages.7.html#user-package-registry>`_
+   where it will be detected **without requiring installation** in a client
+   project using CMake when `find_package(Ceres) <http://www.cmake.org/cmake/help/v3.2/command/find_package.html>`_
+   is invoked.
+
 #. ``BUILD_DOCUMENTATION [Default: OFF]``: Use this to enable building
    the documentation, requires `Sphinx <http://sphinx-doc.org/>`_ and the
    `sphinx_rtd_theme <https://pypi.python.org/pypi/sphinx_rtd_theme>`_
@@ -620,13 +634,26 @@
 Using Ceres with CMake
 ======================
 
-Once the library is installed with ``make install``, it is possible to
-use CMake with `find_package()
-<http://www.cmake.org/cmake/help/v3.2/command/find_package.html>`_
-in order to compile **user code** against Ceres. For example, to compile
-`examples/helloworld.cc
+In order to use Ceres in client code with CMake using
+`find_package() <http://www.cmake.org/cmake/help/v3.2/command/find_package.html>`_
+then either:
+
+#. Ceres must have been installed with ``make install``.
+    If the install location is non-standard (i.e. is not in CMake's default
+    search paths) then it will not be detected by default, see:
+    :ref:`section-local-installations`.
+
+    Note that if you are using a non-standard install location you should
+    consider exporting Ceres instead, as this will not require any extra
+    information to be provided in client code for Ceres to be detected.
+
+#. Or Ceres' build directory must have been exported
+    by enabling the ``EXPORT_BUILD_DIR`` option when Ceres was configured.
+
+
+As an example of how to use Ceres, to compile `examples/helloworld.cc
 <https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/helloworld.cc>`_
-in a separate, standalone project, the following CMakeList.txt can be used:
+in a separate standalone project, the following CMakeList.txt can be used:
 
 .. code-block:: cmake
 
@@ -641,6 +668,45 @@
     add_executable(helloworld helloworld.cc)
     target_link_libraries(helloworld ${CERES_LIBRARIES})
 
+Irrespective of whether Ceres was installed or exported, if multiple versions
+are detected, set: ``Ceres_DIR`` to control which is used.  If Ceres was
+installed ``Ceres_DIR`` should be the path to the directory containing the
+installed ``CeresConfig.cmake`` file (e.g. ``/usr/local/share/Ceres``).  If
+Ceres was exported, then ``Ceres_DIR`` should be the path to the exported
+Ceres build directory.
+
+Specify Ceres version
+---------------------
+
+Additionally, when CMake has found Ceres it can optionally check the package
+version, if it has been specified in the `find_package()
+<http://www.cmake.org/cmake/help/v3.2/command/find_package.html>`_
+call.  For example:
+
+.. code-block:: cmake
+
+    find_package(Ceres 1.2.3 REQUIRED)
+
+.. _section-local-installations:
+
+Local installations
+-------------------
+
+If Ceres was installed in a non-standard path by specifying
+``-DCMAKE_INSTALL_PREFIX="/some/where/local"``, then the user should add
+the **PATHS** option to the ``find_package()`` command, e.g.,
+
+.. code-block:: cmake
+
+   find_package(Ceres REQUIRED PATHS "/some/where/local/")
+
+Note that this can be used to have multiple versions of Ceres
+installed.  However, particularly if you have only a single version of Ceres
+which you want to use but do not wish to install to a system location, you
+should consider exporting Ceres using the ``EXPORT_BUILD_DIR`` option instead
+of a local install, as exported versions of Ceres will be automatically detected
+by CMake, irrespective of their location.
+
 Understanding the CMake Package System
 ----------------------------------------
 
@@ -679,15 +745,18 @@
     ``A``, and CMake will understand that this means that ``B`` also depends on
     all of the public dependencies of ``A``.
 
-When a project like Ceres is installed using CMake, in addition to the
-public headers and compiled libraries, a set of CMake-specific project
-configuration files are also installed to: ``<INSTALL_ROOT>/share/Ceres``.
-When `find_package
+When a project like Ceres is installed using CMake, or its build directory is
+exported into the local CMake package registry
+(see :ref:`section-install-vs-export`), in addition to the public
+headers and compiled libraries, a set of CMake-specific project configuration
+files are also installed to: ``<INSTALL_ROOT>/share/Ceres`` (if Ceres is
+installed), or created in the build directory (if Ceres' build directory is
+exported).  When `find_package
 <http://www.cmake.org/cmake/help/v3.2/command/find_package.html>`_
 is invoked, CMake checks various standard install locations (including
-``/usr/local`` on Linux & UNIX systems), for installed CMake configuration files
-for the project to be found (i.e. Ceres in the case of ``find_package(Ceres)``).
-Specifically it looks for:
+``/usr/local`` on Linux & UNIX systems), and the local CMake package registry
+for CMake configuration files for the project to be found (i.e. Ceres in the
+case of ``find_package(Ceres)``).  Specifically it looks for:
 
 - ``<PROJECT_NAME>Config.cmake`` (or ``<lower_case_project_name>-config.cmake``)
 
@@ -708,7 +777,7 @@
 An **imported target** contains the same information about a library as a CMake
 target that was declared locally in the current CMake project using
 ``add_library()``.  However, imported targets refer to objects that have already
-been built previously by a different CMake project.  Principally, an imported
+been built by a different CMake project.  Principally, an imported
 target contains the location of the compiled object and all of its public
 dependencies required to link against it.  Any locally declared target can
 depend on an imported target, and CMake will manage the dependency chain, just
@@ -735,20 +804,30 @@
 ``libceres.a/so/dylib/lib`` without these other public dependencies would
 result in a linker error.
 
-Although this description covers projects that are **installed** using CMake, it
-also holds for projects that are **exported** using CMake using
+Note that this description applies both to projects that are **installed**
+using CMake, and to those whose **build directory is exported** using
 `export() <http://www.cmake.org/cmake/help/v3.2/command/export.html>`_
-instead of
-`install() <http://www.cmake.org/cmake/help/v3.2/command/install.html>`_.
-When a project is *installed*, the compiled libraries and headers are copied
+(instead of
+`install() <http://www.cmake.org/cmake/help/v3.2/command/install.html>`_).
+Ceres supports both installation and export of its build directory if the
+``EXPORT_BUILD_DIR`` option is enabled, see :ref:`section-customizing`.
+
+.. _section-install-vs-export:
+
+Installing a project with CMake vs Exporting its build directory
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When a project is **installed**, the compiled libraries and headers are copied
 from the source & build directory to the install location, and it is these
-copied files that are used by any client code.  When a project is *exported*,
-instead of copying the compiled libraries and headers, CMake creates an entry
-for the project in ``<USER_HOME>/.cmake/packages`` which contains the path to
+copied files that are used by any client code.  When a project's build directory
+is **exported**, instead of copying the compiled libraries and headers, CMake
+creates an entry for the project in the
+`user's local CMake package registry <http://www.cmake.org/cmake/help/v3.2/manual/cmake-packages.7.html#user-package-registry>`_,
+``<USER_HOME>/.cmake/packages`` on Linux & OS X, which contains the path to
 the project's build directory which will be checked by CMake during a call to
 ``find_package()``.  The effect of which is that any client code uses the
-compiled libraries and headers in the build directory directly, thus not
-requiring the project to be installed to be used.
+compiled libraries and headers in the build directory directly, **thus not
+requiring the project to be installed to be used**.
 
 Installing / Exporting a project that uses Ceres
 --------------------------------------------------
@@ -810,31 +889,3 @@
     # CMake's search list before this call.
     include(CMakeFindDependencyMacro)
     find_dependency(Ceres)
-
-Specify Ceres version
----------------------
-
-Additionally, when CMake has found Ceres it can check the package
-version, if it has been specified in the `find_package()
-<http://www.cmake.org/cmake/help/v3.2/command/find_package.html>`_
-call.  For example:
-
-.. code-block:: cmake
-
-    find_package(Ceres 1.2.3 REQUIRED)
-
-The version is an optional argument.
-
-Local installations
--------------------
-
-If Ceres was installed in a non-standard path by specifying
-``-DCMAKE_INSTALL_PREFIX="/some/where/local"``, then the user should add
-the **PATHS** option to the ``find_package()`` command, e.g.,
-
-.. code-block:: cmake
-
-   find_package(Ceres REQUIRED PATHS "/some/where/local/")
-
-Note that this can be used to have multiple versions of Ceres
-installed.