Use Ceres_[SOURCE/BINARY]_DIR not CMAKE_XXX_DIR to support nesting.

- Using Ceres_[SOURCE/BINARY]_DIR (which are defined by CMake when
  project(Ceres) is called, in favour of CMAKE_[SOURCE/BINARY]_DIR
  enables Ceres to be nested within (and built by) a larger CMake
  project (which also contains other projects).
- CMAKE_[SOURCE/BINARY]_DIR always refers to the top-level source
  and binary directories (i.e. the first encountered), as a result if
  Ceres is a nested project within a larger project, these would not
  correctly identify the source/binary directories for Ceres (as they
  would refer to the root project in which Ceres is nested).
- Using Ceres_[SOURCE/BINARY]_DIR should ensure that Ceres always uses
  the correct source/binary directories, irrespective of whether Ceres
  is nested or not.

Change-Id: I62226ea3f6552b1d7e2bdac1aef02f1f489ae55e
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cf5f845..a782c34 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -39,15 +39,24 @@
 
 project(Ceres C CXX)
 
+# NOTE: The 'generic' CMake variables CMAKE_[SOURCE/BINARY]_DIR should not be
+#       used.  Always use the project-specific variants (generated by CMake):
+#       <PROJECT_NAME_MATCHING_CASE>_[SOURCE/BINARY]_DIR, e.g.
+#       Ceres_SOURCE_DIR (note, *not* CERES_SOURCE_DIR) instead, as these will
+#       always point to the correct directories for the Ceres project, even if
+#       it is nested inside another source tree, whereas the 'generic'
+#       CMake variables refer to the *first* project() declaration, i.e. the
+#       top-level project, not Ceres, if Ceres is nested.
+
 # Make CMake aware of the cmake folder for local FindXXX scripts,
 # append rather than set in case the user has passed their own
 # additional paths via -D.
-list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+list(APPEND CMAKE_MODULE_PATH "${Ceres_SOURCE_DIR}/cmake")
 include(UpdateCacheVariable)
 
 # Set up the git hook to make Gerrit Change-Id: lines in commit messages.
 include(AddGerritCommitHook)
-add_gerrit_commit_hook()
+add_gerrit_commit_hook(${Ceres_SOURCE_DIR} ${Ceres_BINARY_DIR})
 
 # On OS X, add the Homebrew prefix to the set of prefixes searched by
 # CMake in find_path & find_library.  This should ensure that we can
@@ -67,9 +76,9 @@
   endif()
 endif()
 
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${Ceres_BINARY_DIR}/bin)
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${Ceres_BINARY_DIR}/lib)
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${Ceres_BINARY_DIR}/lib)
 # Set postfixes for generated libraries based on buildtype.
 set(CMAKE_RELEASE_POSTFIX "")
 set(CMAKE_DEBUG_POSTFIX "-debug")
@@ -77,7 +86,7 @@
 # Read the Ceres version from the source, such that we only ever have a single
 # definition of the Ceres version.
 include(ReadCeresVersionFromSource)
-read_ceres_version_from_source(${CMAKE_SOURCE_DIR})
+read_ceres_version_from_source(${Ceres_SOURCE_DIR})
 
 enable_testing()
 
@@ -724,13 +733,13 @@
 list(REMOVE_DUPLICATES CERES_COMPILE_OPTIONS)
 include(CreateCeresConfig)
 create_ceres_config("${CERES_COMPILE_OPTIONS}"
-  ${CMAKE_BINARY_DIR}/config/ceres/internal)
+  ${Ceres_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_BINARY_DIR}/config)
+include_directories(BEFORE ${Ceres_BINARY_DIR}/config)
 
 add_subdirectory(internal/ceres)
 
@@ -758,21 +767,21 @@
 endif (BUILD_EXAMPLES)
 
 # Setup installation of Ceres public headers.
-file(GLOB CERES_HDRS ${CMAKE_SOURCE_DIR}/include/ceres/*.h)
+file(GLOB CERES_HDRS ${Ceres_SOURCE_DIR}/include/ceres/*.h)
 install(FILES ${CERES_HDRS} DESTINATION include/ceres)
 
-file(GLOB CERES_PUBLIC_INTERNAL_HDRS ${CMAKE_SOURCE_DIR}/include/ceres/internal/*.h)
+file(GLOB CERES_PUBLIC_INTERNAL_HDRS ${Ceres_SOURCE_DIR}/include/ceres/internal/*.h)
 install(FILES ${CERES_PUBLIC_INTERNAL_HDRS} DESTINATION include/ceres/internal)
 
 # Also setup installation of Ceres config.h configured with the current
 # build options into the installed headers directory.
-install(FILES ${CMAKE_BINARY_DIR}/config/ceres/internal/config.h
+install(FILES ${Ceres_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.
-  install(FILES ${CMAKE_SOURCE_DIR}/internal/ceres/miniglog/glog/logging.h
+  install(FILES ${Ceres_SOURCE_DIR}/internal/ceres/miniglog/glog/logging.h
           DESTINATION include/ceres/internal/miniglog/glog)
 endif (MINIGLOG)
 
@@ -805,8 +814,8 @@
 
 # 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)
+configure_file("${Ceres_SOURCE_DIR}/cmake/CeresConfigVersion.cmake.in"
+               "${Ceres_BINARY_DIR}/CeresConfigVersion.cmake" @ONLY)
 
 # Install method #1: Put Ceres in CMAKE_INSTALL_PREFIX: /usr/local or equivalent.
 
@@ -838,31 +847,31 @@
 #
 # 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
+#       Ceres_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_BINARY_DIR}/CeresConfig-install.cmake" @ONLY)
+configure_file("${Ceres_SOURCE_DIR}/cmake/CeresConfig.cmake.in"
+               "${Ceres_BINARY_DIR}/CeresConfig-install.cmake" @ONLY)
 
 # 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"
+install(FILES "${Ceres_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"
-              "${CMAKE_SOURCE_DIR}/cmake/FindGflags.cmake"
+install(FILES "${Ceres_BINARY_DIR}/CeresConfigVersion.cmake"
+              "${Ceres_SOURCE_DIR}/cmake/FindEigen.cmake"
+              "${Ceres_SOURCE_DIR}/cmake/FindGlog.cmake"
+              "${Ceres_SOURCE_DIR}/cmake/FindGflags.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"
+configure_file("${Ceres_SOURCE_DIR}/cmake/uninstall.cmake.in"
+               "${Ceres_BINARY_DIR}/cmake/uninstall.cmake"
                @ONLY)
 add_custom_target(uninstall
-                  COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cmake/uninstall.cmake)
+                  COMMAND ${CMAKE_COMMAND} -P ${Ceres_BINARY_DIR}/cmake/uninstall.cmake)
 
 # Install method #2: Put Ceres build into local CMake registry.
 #
@@ -874,18 +883,18 @@
 
   # 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})
+    ${Ceres_BINARY_DIR}
+    ${Ceres_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(TARGETS ceres FILE ${Ceres_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)
+  configure_file("${Ceres_SOURCE_DIR}/cmake/CeresConfig.cmake.in"
+    "${Ceres_BINARY_DIR}/CeresConfig.cmake" @ONLY)
 
 endif (EXPORT_BUILD_DIR)
diff --git a/cmake/AddGerritCommitHook.cmake b/cmake/AddGerritCommitHook.cmake
index 071e84a..4347028 100644
--- a/cmake/AddGerritCommitHook.cmake
+++ b/cmake/AddGerritCommitHook.cmake
@@ -30,20 +30,28 @@
 #          alexs.mac@gmail.com (Alex Stewart)
 
 # Set up the git hook to make Gerrit Change-Id: lines in commit messages.
-function(ADD_GERRIT_COMMIT_HOOK)
+function(ADD_GERRIT_COMMIT_HOOK SOURCE_DIR BINARY_DIR)
+  if (NOT EXISTS ${SOURCE_DIR} AND IS_DIRECTORY ${SOURCE_DIR})
+    message(FATAL_ERROR "Specified SOURCE_DIR: ${SOURCE_DIR} does not exist, "
+      "or is not a directory, cannot add Gerrit commit hook.")
+  endif()
+  if (NOT EXISTS ${BINARY_DIR} AND IS_DIRECTORY ${BINARY_DIR})
+    message(FATAL_ERROR "Specified BINARY_DIR: ${BINARY_DIR} does not exist, "
+      "or is not a directory, cannot add Gerrit commit hook.")
+  endif()
   unset (LOCAL_GIT_DIRECTORY)
-  if (EXISTS ${CMAKE_SOURCE_DIR}/.git)
-    if (IS_DIRECTORY ${CMAKE_SOURCE_DIR}/.git)
+  if (EXISTS ${SOURCE_DIR}/.git)
+    if (IS_DIRECTORY ${SOURCE_DIR}/.git)
       # .git directory can be found on Unix based system, or on Windows with
       # Git Bash (shipped with msysgit).
-      set (LOCAL_GIT_DIRECTORY ${CMAKE_SOURCE_DIR}/.git)
-    else(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/.git)
+      set (LOCAL_GIT_DIRECTORY ${SOURCE_DIR}/.git)
+    else(IS_DIRECTORY ${SOURCE_DIR}/.git)
       # .git is a file, this means Ceres is a git submodule of another project
       # and our .git file contains the path to the git directory which manages
       # Ceres, so we should add the gerrit hook there.
-      file(READ ${CMAKE_SOURCE_DIR}/.git GIT_SUBMODULE_FILE_CONTENTS)
+      file(READ ${SOURCE_DIR}/.git GIT_SUBMODULE_FILE_CONTENTS)
       # Strip any trailing newline characters, s/t we get a valid path.
-      string(REGEX REPLACE "gitdir:[ ]*([^$].*)[\n].*" "${CMAKE_SOURCE_DIR}/\\1"
+      string(REGEX REPLACE "gitdir:[ ]*([^$].*)[\n].*" "${SOURCE_DIR}/\\1"
         GIT_SUBMODULE_GIT_DIRECTORY_PATH "${GIT_SUBMODULE_FILE_CONTENTS}")
       get_filename_component(GIT_SUBMODULE_GIT_DIRECTORY_PATH
         "${GIT_SUBMODULE_GIT_DIRECTORY_PATH}" ABSOLUTE)
@@ -52,9 +60,9 @@
         set(LOCAL_GIT_DIRECTORY "${GIT_SUBMODULE_GIT_DIRECTORY_PATH}")
       endif()
     endif()
-  else (EXISTS ${CMAKE_SOURCE_DIR}/.git)
+  else (EXISTS ${SOURCE_DIR}/.git)
     # TODO(keir) Add proper Windows support.
-  endif (EXISTS ${CMAKE_SOURCE_DIR}/.git)
+  endif (EXISTS ${SOURCE_DIR}/.git)
 
   if (EXISTS ${LOCAL_GIT_DIRECTORY})
     if (NOT EXISTS ${LOCAL_GIT_DIRECTORY}/hooks/commit-msg)
@@ -62,10 +70,10 @@
         "commit hook for Gerrit to: ${LOCAL_GIT_DIRECTORY}")
       # Download the hook only if it is not already present.
       file(DOWNLOAD https://ceres-solver-review.googlesource.com/tools/hooks/commit-msg
-        ${CMAKE_BINARY_DIR}/commit-msg)
+        ${BINARY_DIR}/commit-msg)
 
       # Make the downloaded file executable, since it is not by default.
-      file(COPY ${CMAKE_BINARY_DIR}/commit-msg
+      file(COPY ${BINARY_DIR}/commit-msg
         DESTINATION ${LOCAL_GIT_DIRECTORY}/hooks/
         FILE_PERMISSIONS
         OWNER_READ OWNER_WRITE OWNER_EXECUTE
diff --git a/docs/source/CMakeLists.txt b/docs/source/CMakeLists.txt
index 0f07a5b..70bf998 100644
--- a/docs/source/CMakeLists.txt
+++ b/docs/source/CMakeLists.txt
@@ -1,7 +1,7 @@
 find_package(Sphinx REQUIRED)
 
 # HTML output directory
-set(SPHINX_HTML_DIR "${CMAKE_BINARY_DIR}/docs/html")
+set(SPHINX_HTML_DIR "${Ceres_BINARY_DIR}/docs/html")
 
 # Install documentation
 install(DIRECTORY ${SPHINX_HTML_DIR}
@@ -12,8 +12,8 @@
 # Building using 'make_docs.py' python script
 add_custom_target(ceres_docs ALL
                   python
-                  "${CMAKE_SOURCE_DIR}/scripts/make_docs.py"
-                  "${CMAKE_SOURCE_DIR}"
-                  "${CMAKE_BINARY_DIR}/docs"
+                  "${Ceres_SOURCE_DIR}/scripts/make_docs.py"
+                  "${Ceres_SOURCE_DIR}"
+                  "${Ceres_BINARY_DIR}/docs"
                   "${SPHINX_EXECUTABLE}"
                   COMMENT "Building HTML documentation with Sphinx")
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index 6eb6979..4159e39 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -294,7 +294,7 @@
     add_test(NAME ${NAME}_test
              COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${NAME}_test
              --test_srcdir
-             ${CMAKE_SOURCE_DIR}/data)
+             ${Ceres_SOURCE_DIR}/data)
   endmacro (CERES_TEST)
 
   ceres_test(array_utils)