Standardize path handling using GNUInstallDirs

Fixes #649

Change-Id: Iefb3e7be69a04474db0fc768b47f4f3636c8a587
diff --git a/CMakeLists.txt b/CMakeLists.txt
index eeb2c7a..c218882 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -90,6 +90,7 @@
 include(AddCompileFlagsIfSupported)
 include(CheckCXXCompilerFlag)
 include(CheckLibraryExists)
+include(GNUInstallDirs)
 include(UpdateCacheVariable)
 
 check_cxx_compiler_flag(/bigobj HAVE_BIGOBJ)
@@ -170,35 +171,11 @@
   option(ANDROID_STRIP_DEBUG_SYMBOLS "Strip debug symbols from Android builds (reduces file sizes)" ON)
 endif()
 if (MSVC)
+  # TODO Not needed starting CMake 3.15 which provides CMAKE_MSVC_RUNTIME_LIBRARY
   option(MSVC_USE_STATIC_CRT
     "MS Visual Studio: Use static C-Run Time Library in place of shared." OFF)
 endif()
 
-# Allow user to specify a suffix for the library install directory, the only
-# really sensible option (other than "") being "64", such that:
-# ${CMAKE_INSTALL_PREFIX}/lib -> ${CMAKE_INSTALL_PREFIX}/lib64.
-#
-# Heuristic for determining LIB_SUFFIX. FHS recommends that 64-bit systems
-# install native libraries to lib64 rather than lib. Most distros seem to
-# follow this convention with a couple notable exceptions (Debian-based and
-# Arch-based distros) which we try to detect here.
-if (CMAKE_SYSTEM_NAME MATCHES "Linux" AND
-    NOT DEFINED LIB_SUFFIX AND
-    NOT CMAKE_CROSSCOMPILING AND
-    CMAKE_SIZEOF_VOID_P EQUAL "8" AND
-    NOT EXISTS "/etc/debian_version" AND
-    NOT EXISTS "/etc/arch-release")
-  message("-- Detected non-Debian/Arch-based 64-bit Linux distribution. "
-    "Defaulting to library install directory: lib${LIB_SUFFIX}. You can "
-    "override this by specifying LIB_SUFFIX.")
-  set(LIB_SUFFIX "64")
-endif ()
-# Only create the cache variable (for the CMake GUI) after attempting to detect
-# the suffix *if not specified by the user* (NOT DEFINED LIB_SUFFIX in if())
-# s/t the user could override our autodetected suffix with "" if desired.
-set(LIB_SUFFIX "${LIB_SUFFIX}" CACHE STRING
-  "Suffix of library install directory (to support lib/lib64)." FORCE)
-
 # IOS is defined iff using the iOS.cmake CMake toolchain to build a static
 # library for iOS.
 if (IOS)
@@ -644,14 +621,11 @@
 list(REMOVE_DUPLICATES CERES_COMPILE_OPTIONS)
 include(CreateCeresConfig)
 create_ceres_config("${CERES_COMPILE_OPTIONS}"
-  ${Ceres_BINARY_DIR}/include/ceres/internal)
+  ${Ceres_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/ceres/internal)
 
 add_subdirectory(internal/ceres)
 
 if (BUILD_DOCUMENTATION)
-  set(CERES_DOCS_INSTALL_DIR "share/doc/ceres" CACHE STRING
-      "Ceres docs install path relative to CMAKE_INSTALL_PREFIX")
-
   find_package(Sphinx)
   if (NOT SPHINX_FOUND)
     message("-- Failed to find Sphinx and/or its dependencies, disabling build of documentation.")
@@ -673,21 +647,22 @@
 
 # Setup installation of Ceres public headers.
 file(GLOB CERES_HDRS ${Ceres_SOURCE_DIR}/include/ceres/*.h)
-install(FILES ${CERES_HDRS} DESTINATION include/ceres)
+install(FILES ${CERES_HDRS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ceres)
 
 file(GLOB CERES_PUBLIC_INTERNAL_HDRS ${Ceres_SOURCE_DIR}/include/ceres/internal/*.h)
-install(FILES ${CERES_PUBLIC_INTERNAL_HDRS} DESTINATION include/ceres/internal)
+install(FILES ${CERES_PUBLIC_INTERNAL_HDRS} DESTINATION
+  ${CMAKE_INSTALL_INCLUDEDIR}/ceres/internal)
 
 # Also setup installation of Ceres config.h configured with the current
 # build options and export.h into the installed headers directory.
-install(DIRECTORY ${Ceres_BINARY_DIR}/include/
-        DESTINATION include)
+install(DIRECTORY ${Ceres_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/
+        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
 
 if (MINIGLOG)
   # Install miniglog header if being used as logging #includes appear in
   # installed public Ceres headers.
   install(FILES ${Ceres_SOURCE_DIR}/internal/ceres/miniglog/glog/logging.h
-          DESTINATION include/ceres/internal/miniglog/glog)
+          DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ceres/internal/miniglog/glog)
 endif (MINIGLOG)
 
 # Ceres supports two mechanisms by which it can be detected & imported into
@@ -729,11 +704,7 @@
 
 # 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 lib${LIB_SUFFIX}/cmake/Ceres)
-endif ()
+set(RELATIVE_CMAKECONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/Ceres)
 
 # This "exports" for installation all targets which have been put into the
 # export set "CeresExport". This generates a CeresTargets.cmake file which,
diff --git a/docs/source/CMakeLists.txt b/docs/source/CMakeLists.txt
index 217a519..cb4b7df 100644
--- a/docs/source/CMakeLists.txt
+++ b/docs/source/CMakeLists.txt
@@ -5,7 +5,7 @@
 
 # Install documentation
 install(DIRECTORY ${SPHINX_HTML_DIR}
-        DESTINATION "${CERES_DOCS_INSTALL_DIR}"
+        DESTINATION ${CMAKE_INSTALL_DOCDIR}
         COMPONENT Doc
         PATTERN "${SPHINX_HTML_DIR}/*")
 
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index 7d9d9a9..ea0bed8 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -71,7 +71,8 @@
 # Depend also on public headers so they appear in IDEs.
 file(GLOB CERES_PUBLIC_HDRS ${Ceres_SOURCE_DIR}/include/ceres/*.h)
 file(GLOB CERES_PUBLIC_INTERNAL_HDRS ${Ceres_SOURCE_DIR}/include/ceres/internal/*.h)
-file(GLOB CERES_PUBLIC_INTERNAL_HDRS ${Ceres_BINARY_DIR}/include/ceres/internal/*.h)
+file(GLOB CERES_PUBLIC_INTERNAL_HDRS
+  ${Ceres_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/ceres/internal/*.h)
 
 # Include the specialized schur solvers.
 if (SCHUR_SPECIALIZATIONS)
@@ -326,10 +327,11 @@
 # of the dependencies (e.g. /usr/local) that we find the config.h we just
 # configured, not the (older) installed config.h.
 target_include_directories(ceres
-  BEFORE PUBLIC $<BUILD_INTERFACE:${Ceres_BINARY_DIR}/include>
+  BEFORE PUBLIC
+  $<BUILD_INTERFACE:${Ceres_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}>
   PRIVATE ${Ceres_SOURCE_DIR}/internal
   PUBLIC $<BUILD_INTERFACE:${Ceres_SOURCE_DIR}/include>
-         $<INSTALL_INTERFACE:include>)
+         $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
 
 # Eigen SparseQR generates various compiler warnings related to unused and
 # uninitialised local variables.  To avoid having to individually suppress these
@@ -355,7 +357,7 @@
   # themselves (intentionally or otherwise) and so break their build.
   target_include_directories(ceres BEFORE PUBLIC
     $<BUILD_INTERFACE:${Ceres_SOURCE_DIR}/internal/ceres/miniglog>
-    $<INSTALL_INTERFACE:include/ceres/internal/miniglog>)
+    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/ceres/internal/miniglog>)
 elseif (NOT FOUND_INSTALLED_GLOG_CMAKE_CONFIGURATION)
   # Only append glog include directories if the glog found was not a CMake
   # exported target that already includes them.
@@ -387,13 +389,14 @@
 
 # Generate an export header for annotating symbols visibility
 include(GenerateExportHeader)
-generate_export_header(ceres EXPORT_FILE_NAME ${Ceres_BINARY_DIR}/include/ceres/internal/export.h)
+generate_export_header(ceres EXPORT_FILE_NAME
+  ${Ceres_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/ceres/internal/export.h)
 
 install(TARGETS ceres
         EXPORT  CeresExport
-        RUNTIME DESTINATION bin
-        LIBRARY DESTINATION lib${LIB_SUFFIX}
-        ARCHIVE DESTINATION lib${LIB_SUFFIX})
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
 
 if (BUILD_TESTING AND GFLAGS)
   add_library(test_util STATIC