Adding autogenerated Ceres config.h to #define Ceres compile options.

- Previously we passed all compile options to Ceres via add_definitions
  in CMake.  This was fine for private definitions (used only by Ceres)
  but required additional work for public definitions to ensure they
  were correctly propagated to clients via CMake using
  target_compile_definitions() (>= 2.8.11) or add_definitions().
- A drawback to these approaches is that they did not work for chained
  dependencies on Ceres, as in if in the users project B <- A <- Ceres,
  then although the required Ceres public compile definitions would
  be used when compiling A, they would not be propagated to B.

- This patch replaces the addition of compile definitions via
  add_definitions() with an autogenerated config.h header which
  is installed with Ceres and defines all of the enabled Ceres compile
  options.
- This removes the need for the user to propagate any compile
  definitions in their projects, and additionally allows post-install
  inspect of the options with which Ceres was compiled.

Change-Id: Idbdb6abdad0eb31e7540370e301afe87a07f2260
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d959669..9e17604 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,7 +26,8 @@
 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 # POSSIBILITY OF SUCH DAMAGE.
 #
-# Author: keir@google.com (Keir Mierle)
+# Authors: keir@google.com (Keir Mierle)
+#          alexs.mac@gmail.com (Alex Stewart)
 
 CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)
 CMAKE_POLICY(VERSION 2.8)
@@ -179,6 +180,8 @@
   ENDIF (DEFINED ${LEGACY_VAR})
 ENDMACRO(HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT)
 
+UNSET(CERES_COMPILE_OPTIONS)
+
 # Eigen.
 HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(EIGEN_INCLUDE EIGEN_INCLUDE_DIR_HINTS)
 FIND_PACKAGE(Eigen REQUIRED)
@@ -207,11 +210,11 @@
     # when updating it to disable use of LAPACK.
     GET_PROPERTY(HELP_STRING CACHE LAPACK PROPERTY HELPSTRING)
     SET(LAPACK OFF CACHE BOOL "${HELP_STRING}" FORCE)
-    ADD_DEFINITIONS(-DCERES_NO_LAPACK)
+    LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_LAPACK)
   ENDIF (NOT (LAPACK_FOUND AND BLAS_FOUND))
 ELSE (LAPACK)
   MESSAGE("-- Building without LAPACK.")
-  ADD_DEFINITIONS(-DCERES_NO_LAPACK)
+  LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_LAPACK)
 ENDIF (LAPACK)
 
 # SuiteSparse.
@@ -262,11 +265,11 @@
     # when updating it to disable use of SuiteSparse.
     GET_PROPERTY(HELP_STRING CACHE SUITESPARSE PROPERTY HELPSTRING)
     SET(SUITESPARSE OFF CACHE BOOL "${HELP_STRING}" FORCE)
-    ADD_DEFINITIONS(-DCERES_NO_SUITESPARSE)
+    LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_SUITESPARSE)
   ENDIF (SUITESPARSE_FOUND)
 ELSE (SUITESPARSE)
   MESSAGE("-- Building without SuiteSparse.")
-  ADD_DEFINITIONS(-DCERES_NO_SUITESPARSE)
+  LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_SUITESPARSE)
 ENDIF (SUITESPARSE)
 
 # CXSparse.
@@ -285,11 +288,11 @@
     # when updating it to disable use of CXSparse.
     GET_PROPERTY(HELP_STRING CACHE CXSPARSE PROPERTY HELPSTRING)
     SET(CXSPARSE OFF CACHE BOOL "${HELP_STRING}" FORCE)
-    ADD_DEFINITIONS(-DCERES_NO_CXSPARSE)
+    LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_CXSPARSE)
   ENDIF (CXSPARSE_FOUND)
 ELSE (CXSPARSE)
   MESSAGE("-- Building without CXSparse.")
-  ADD_DEFINITIONS(-DCERES_NO_CXSPARSE)
+  LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_CXSPARSE)
   # Mark as advanced (remove from default GUI view) the CXSparse search
   # variables in case user enabled CXSPARSE, FindCXSparse did not find it, so
   # made search variables visible in GUI for user to set, but then user disables
@@ -314,11 +317,9 @@
     # when updating it to disable use of gflags.
     GET_PROPERTY(HELP_STRING CACHE GFLAGS PROPERTY HELPSTRING)
     SET(GFLAGS OFF CACHE BOOL "${HELP_STRING}" FORCE)
-    ADD_DEFINITIONS(-DCERES_NO_GFLAGS)
   ENDIF (GFLAGS_FOUND)
 ELSE (GFLAGS)
   MESSAGE("-- Google Flags disabled; no tests or tools will be built!")
-  ADD_DEFINITIONS(-DCERES_NO_GFLAGS)
   # Mark as advanced (remove from default GUI view) the gflags search
   # variables in case user enabled GFLAGS, FindGflags did not find it, so
   # made search variables visible in GUI for user to set, but then user disables
@@ -357,12 +358,12 @@
 ENDIF (MINIGLOG)
 
 IF (NOT SCHUR_SPECIALIZATIONS)
-  ADD_DEFINITIONS(-DCERES_RESTRICT_SCHUR_SPECIALIZATION)
+  LIST(APPEND CERES_COMPILE_OPTIONS CERES_RESTRICT_SCHUR_SPECIALIZATION)
   MESSAGE("-- Disabling Schur specializations (faster compiles)")
 ENDIF (NOT SCHUR_SPECIALIZATIONS)
 
 IF (NOT CUSTOM_BLAS)
-  ADD_DEFINITIONS(-DCERES_NO_CUSTOM_BLAS)
+  LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_CUSTOM_BLAS)
   MESSAGE("-- Disabling custom blas")
 ENDIF (NOT CUSTOM_BLAS)
 
@@ -374,20 +375,20 @@
     GET_PROPERTY(HELP_STRING CACHE OPENMP PROPERTY HELPSTRING)
     SET(OPENMP OFF CACHE BOOL "${HELP_STRING}" FORCE)
     MESSAGE("-- Compiler is Clang, disabling OpenMP.")
-    ADD_DEFINITIONS(-DCERES_NO_THREADS)
+    LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_THREADS)
   ELSE (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
     # Find quietly s/t as we can continue without OpenMP if it is not found.
     FIND_PACKAGE(OpenMP QUIET)
     IF (OPENMP_FOUND)
       MESSAGE("-- Building with OpenMP.")
-      ADD_DEFINITIONS(-DCERES_USE_OPENMP)
+      LIST(APPEND CERES_COMPILE_OPTIONS CERES_USE_OPENMP)
       SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
       IF (UNIX)
         # At least on Linux, we need pthreads to be enabled for mutex to
         # compile.  This may not work on Windows or Android.
         FIND_PACKAGE(Threads REQUIRED)
-        ADD_DEFINITIONS(-DCERES_HAVE_PTHREAD)
-        ADD_DEFINITIONS(-DCERES_HAVE_RWLOCK)
+        LIST(APPEND CERES_COMPILE_OPTIONS CERES_HAVE_PTHREAD)
+        LIST(APPEND CERES_COMPILE_OPTIONS CERES_HAVE_RWLOCK)
       ENDIF (UNIX)
     ELSE (OPENMP_FOUND)
       MESSAGE("-- Failed to find OpenMP, disabling.")
@@ -395,12 +396,12 @@
       # when updating it to disable use of OPENMP.
       GET_PROPERTY(HELP_STRING CACHE OPENMP PROPERTY HELPSTRING)
       SET(OPENMP OFF CACHE BOOL "${HELP_STRING}" FORCE)
-      ADD_DEFINITIONS(-DCERES_NO_THREADS)
+      LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_THREADS)
     ENDIF (OPENMP_FOUND)
   ENDIF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
 ELSE (OPENMP)
   MESSAGE("-- Building without OpenMP (disabling multithreading).")
-  ADD_DEFINITIONS(-DCERES_NO_THREADS)
+  LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_THREADS)
 ENDIF (OPENMP)
 
 INCLUDE(CheckIncludeFileCXX)
@@ -420,7 +421,7 @@
                              }"
                             HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
   IF (HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
-    ADD_DEFINITIONS(-DCERES_STD_UNORDERED_MAP)
+    LIST(APPEND CERES_COMPILE_OPTIONS CERES_STD_UNORDERED_MAP)
     MESSAGE("-- Found unordered_map/set in std namespace.")
   ELSE (HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
     CHECK_CXX_SOURCE_COMPILES("#include <unordered_map>
@@ -430,24 +431,24 @@
                                }"
                               HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
     IF (HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
-      ADD_DEFINITIONS(-DCERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE)
+      LIST(APPEND CERES_COMPILE_OPTIONS CERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE)
       MESSAGE("-- Found unordered_map/set in std::tr1 namespace.")
     ELSE (HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
       MESSAGE("-- Found <unordered_map> but cannot find either std::unordered_map "
               "or std::tr1::unordered_map.")
       MESSAGE("-- Replacing unordered_map/set with map/set (warning: slower!)")
-      ADD_DEFINITIONS(-DCERES_NO_UNORDERED_MAP)
+      LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_UNORDERED_MAP)
     ENDIF (HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
   ENDIF (HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
 ELSE (HAVE_STD_UNORDERED_MAP_HEADER)
   CHECK_INCLUDE_FILE_CXX("tr1/unordered_map" HAVE_TR1_UNORDERED_MAP_HEADER)
   IF (HAVE_TR1_UNORDERED_MAP_HEADER)
-    ADD_DEFINITIONS(-DCERES_TR1_UNORDERED_MAP)
+    LIST(APPEND CERES_COMPILE_OPTIONS CERES_TR1_UNORDERED_MAP)
     MESSAGE("-- Found tr1/unordered_map/set in std::tr1 namespace.")
   ELSE (HAVE_TR1_UNORDERED_MAP_HEADE)
     MESSAGE("-- Unable to find <unordered_map> or <tr1/unordered_map>. ")
     MESSAGE("-- Replacing unordered_map/set with map/set (warning: slower!)")
-    ADD_DEFINITIONS(-DCERES_NO_UNORDERED_MAP)
+    LIST(APPEND CERES_COMPILE_OPTIONS CERES_NO_UNORDERED_MAP)
   ENDIF (HAVE_TR1_UNORDERED_MAP_HEADER)
 ENDIF (HAVE_STD_UNORDERED_MAP_HEADER)
 
@@ -455,10 +456,10 @@
 FIND_SHARED_PTR()
 IF (SHARED_PTR_FOUND)
   IF (SHARED_PTR_TR1_MEMORY_HEADER)
-    ADD_DEFINITIONS(-DCERES_TR1_MEMORY_HEADER)
+    LIST(APPEND CERES_COMPILE_OPTIONS CERES_TR1_MEMORY_HEADER)
   ENDIF (SHARED_PTR_TR1_MEMORY_HEADER)
   IF (SHARED_PTR_TR1_NAMESPACE)
-    ADD_DEFINITIONS(-DCERES_TR1_SHARED_PTR)
+    LIST(APPEND CERES_COMPILE_OPTIONS CERES_TR1_SHARED_PTR)
   ENDIF (SHARED_PTR_TR1_NAMESPACE)
 ELSE (SHARED_PTR_FOUND)
   MESSAGE(FATAL_ERROR "Unable to find shared_ptr.")
@@ -485,7 +486,12 @@
 
 IF (BUILD_SHARED_LIBS)
   MESSAGE("-- Building Ceres as a shared library.")
+  # The CERES_BUILDING_SHARED_LIBRARY compile definition is NOT stored in
+  # CERES_COMPILE_OPTIONS as it must only be defined when Ceres is compiled
+  # not when it is used as it controls the CERES_EXPORT macro which provides
+  # dllimport/export support in MSVC.
   ADD_DEFINITIONS(-DCERES_BUILDING_SHARED_LIBRARY)
+  LIST(APPEND CERES_COMPILE_OPTIONS CERES_USING_SHARED_LIBRARY)
 ELSE (BUILD_SHARED_LIBS)
   MESSAGE("-- Building Ceres as a static library.")
 ENDIF (BUILD_SHARED_LIBS)
@@ -647,22 +653,12 @@
     CLANG_VERSION VERSION_LESS 4.2)
 ENDIF (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
 
-# Get the complete list of any added compile definitions so that we can
-# export them.  Currently we export all Ceres compile definitions to users
-# of Ceres via FindPackage() except CERES_BUILDING_SHARED_LIBRARY (if present)
-# which controls the behaviour of the CERES_EXPORT macro for MSVC, which
-# we substitute for CERES_USING_SHARED_LIBRARY, which is what users of
-# Ceres should call in MSVC.
-GET_DIRECTORY_PROPERTY(CERES_INTERFACE_COMPILE_DEFINITIONS
-  DIRECTORY ${CMAKE_SOURCE_DIR} COMPILE_DEFINITIONS)
-# Substitute CERES_BUILDING_SHARED_LIBRARY with CERES_USING_SHARED_LIBRARY
-# if building Ceres as a shared library.
-IF (BUILD_SHARED_LIBS)
-  LIST(REMOVE_ITEM CERES_INTERFACE_COMPILE_DEFINITIONS
-    CERES_BUILDING_SHARED_LIBRARY)
-  LIST(APPEND CERES_INTERFACE_COMPILE_DEFINITIONS
-    CERES_USING_SHARED_LIBRARY)
-ENDIF()
+# Configure the Ceres config.h compile options header using the current
+# compile options and put the configured header into the Ceres source tree.
+LIST(REMOVE_DUPLICATES CERES_COMPILE_OPTIONS)
+INCLUDE(CreateCeresConfig)
+CREATE_CERES_CONFIG("${CERES_COMPILE_OPTIONS}"
+  ${CMAKE_SOURCE_DIR}/include/ceres/internal)
 
 ADD_SUBDIRECTORY(internal/ceres)
 
diff --git a/cmake/CeresConfig.cmake.in b/cmake/CeresConfig.cmake.in
index 5550fd0..0e13d9e 100644
--- a/cmake/CeresConfig.cmake.in
+++ b/cmake/CeresConfig.cmake.in
@@ -57,17 +57,6 @@
 #                     dependencies that were disabled when Ceres was
 #                     compiled.
 #
-# CERES_INTERFACE_COMPILE_DEFINITIONS: List of compile definitions
-#                                   which should be used when
-#                                   compiling a target that uses Ceres
-#                                   Note that these variables will NOT
-#                                   have a -D prefix appended.
-#
-# IMPORTANT: The contents of CERES_INTERFACE_COMPILE_DEFINITIONS will
-#            be AUTOMATICALLY added for you, either via the CMake
-#            function target_compile_definitions() in CMake >= 2.8.11,
-#            or via a call to add_definitions() in CMake < 2.8.11.
-#
 # The following variables are also defined for legacy compatibility
 # only.  Any new code should not use them as they do not conform to
 # the standard CMake FindPackage naming conventions.
@@ -84,7 +73,6 @@
   SET(CERES_FOUND FALSE)
   UNSET(CERES_INCLUDE_DIRS)
   UNSET(CERES_LIBRARIES)
-  UNSET(CERES_INTERFACE_COMPILE_DEFINITIONS)
 
   # Reset the CMake module path to its state when this script was called.
   SET(CMAKE_MODULE_PATH ${CALLERS_CMAKE_MODULE_PATH})
@@ -209,24 +197,6 @@
 # Set the expected XX_LIBRARIES variable for FindPackage().
 SET(CERES_LIBRARIES ceres)
 
-# If Ceres was compiled with CMake < 2.8.11, we were not able to use
-# the new (in 2.8.11) target_compile_definitions() function to append
-# the required compile definitions to use when compiling a target that
-# uses Ceres to the Ceres library target.  As such, we need to use
-# add_definitions() to ensure that they will be present.  This is a
-# blunt instrument, as it will add the Ceres definitions to _all_
-# targets declared from this point on in the caller's project.
-# Hoever, without requiring the user to explicitly set the flags
-# themselves, this is the only way in CMake versions < 2.8.11.
-SET (CERES_COMPILED_CMAKE_VERSION @CMAKE_VERSION@)
-SET (CERES_INTERFACE_COMPILE_DEFINITIONS @CERES_INTERFACE_COMPILE_DEFINITIONS@)
-IF (CERES_COMPILED_CMAKE_VERSION VERSION_LESS 2.8.11)
-  # The definitions will have been stripped of -D, add it back.
-  FOREACH(DEF ${CERES_INTERFACE_COMPILE_DEFINITIONS})
-    ADD_DEFINITIONS("-D${DEF}")
-  ENDFOREACH()
-ENDIF()
-
 # Set legacy include directories variable for backwards compatibility.
 SET(CERES_INCLUDES ${CERES_INCLUDE_DIRS})
 
diff --git a/cmake/CreateCeresConfig.cmake b/cmake/CreateCeresConfig.cmake
new file mode 100644
index 0000000..43f4d17
--- /dev/null
+++ b/cmake/CreateCeresConfig.cmake
@@ -0,0 +1,110 @@
+# Ceres Solver - A fast non-linear least squares minimizer
+# Copyright 2014 Google Inc. All rights reserved.
+# http://code.google.com/p/ceres-solver/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+#   this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of Google Inc. nor the names of its contributors may be
+#   used to endorse or promote products derived from this software without
+#   specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# Author: alexs.mac@gmail.com (Alex Stewart)
+
+# This must take place outside of CONFIGURE_CERES_CONFIG() in order that
+# we can determine where *this* file is, and thus the relative path to
+# config.h.in.  Inside of CONFIGURE_CERES_CONFIG(), CMAKE_CURRENT_LIST_DIR
+# refers to the caller of CONFIGURE_CERES_CONFIG(), not this file.
+SET(CERES_CONFIG_IN_FILE "${CMAKE_CURRENT_LIST_DIR}/config.h.in")
+
+# CreateCeresConfig.cmake - Create the config.h for Ceres.
+#
+# This function configures the Ceres config.h file based on the current
+# compile options and copies it into the specified location.  It should be
+# called before Ceres is built so that the correct config.h is used when
+# Ceres is compiled.
+#
+# INPUTS:
+#   CURRENT_CERES_COMPILE_OPTIONS: List of currently enabled Ceres compile
+#                                  options. These are compared against the
+#                                  full list of valid options, which are read
+#                                  from config.h.in.  Any options present
+#                                  which are not part of the valid set will
+#                                  invoke an error.  Any valid option present
+#                                  will be enabled in the resulting config.h,
+#                                  all other options will be disabled.
+#
+#   CERES_CONFIG_OUTPUT_DIRECTORY: Path to output directory in which to save
+#                                  the configured config.h.  Typically this
+#                                  will be <src>/include/ceres/internal.
+
+FUNCTION(CREATE_CERES_CONFIG CURRENT_CERES_COMPILE_OPTIONS CERES_CONFIG_OUTPUT_DIRECTORY)
+  # Verify that the specified output directory is valid.
+  IF (NOT (EXISTS "${CERES_CONFIG_OUTPUT_DIRECTORY}" AND
+        IS_DIRECTORY "${CERES_CONFIG_OUTPUT_DIRECTORY}"))
+    MESSAGE(FATAL_ERROR "Ceres Bug: Specified CERES_CONFIG_OUTPUT_DIRECTORY: "
+      "${CERES_CONFIG_OUTPUT_DIRECTORY} does not exist, or is not a directory.")
+  ENDIF()
+
+  # Read all possible configurable compile options from config.h.in, this avoids
+  # us having to hard-code in this file what the valid options are.
+  FILE(READ ${CERES_CONFIG_IN_FILE} CERES_CONFIG_IN_CONTENTS)
+  STRING(REGEX MATCHALL "@[^@ $]+@"
+    ALL_CONFIGURABLE_CERES_OPTIONS "${CERES_CONFIG_IN_CONTENTS}")
+  # Removing @ symbols at beginning and end of each option.
+  STRING(REPLACE "@" ""
+    ALL_CONFIGURABLE_CERES_OPTIONS "${ALL_CONFIGURABLE_CERES_OPTIONS}")
+
+  # Ensure that there are no repetitions in the current compile options.
+  LIST(REMOVE_DUPLICATES CURRENT_CERES_COMPILE_OPTIONS)
+
+  FOREACH (CERES_OPTION ${ALL_CONFIGURABLE_CERES_OPTIONS})
+    # Try and find the option in the list of current compile options, if it
+    # is present, then the option is enabled, otherwise it is disabled.
+    LIST(FIND CURRENT_CERES_COMPILE_OPTIONS ${CERES_OPTION} OPTION_ENABLED)
+
+    # list(FIND ..) returns -1 if the element was not in the list, but CMake
+    # interprets if (VAR) to be true if VAR is any non-zero number, even
+    # negative ones, hence we have to explicitly check for >= 0.
+    IF (OPTION_ENABLED GREATER -1)
+      MESSAGE(STATUS "Enabling ${CERES_OPTION} in Ceres config.h")
+      SET(${CERES_OPTION} "#define ${CERES_OPTION}")
+
+      # Remove the item from the list of current options so that we can identify
+      # any options that were in CURRENT_CERES_COMPILE_OPTIONS, but not in
+      # ALL_CONFIGURABLE_CERES_OPTIONS (which is an error).
+      LIST(REMOVE_ITEM CURRENT_CERES_COMPILE_OPTIONS ${CERES_OPTION})
+    ELSE()
+      SET(${CERES_OPTION} "// #define ${CERES_OPTION}")
+    ENDIF()
+  ENDFOREACH()
+
+  # CURRENT_CERES_COMPILE_OPTIONS should now be an empty list, any elements
+  # remaining were not present in ALL_CONFIGURABLE_CERES_OPTIONS read from
+  # config.h.in.
+  IF (CURRENT_CERES_COMPILE_OPTIONS)
+    MESSAGE(FATAL_ERROR "Ceres Bug: CURRENT_CERES_COMPILE_OPTIONS contained "
+      "the following options which were not present in config.h.in: "
+      "${CURRENT_CERES_COMPILE_OPTIONS}")
+  ENDIF()
+
+  CONFIGURE_FILE(${CERES_CONFIG_IN_FILE}
+    "${CERES_CONFIG_OUTPUT_DIRECTORY}/config.h" @ONLY)
+ENDFUNCTION()
diff --git a/cmake/config.h.in b/cmake/config.h.in
new file mode 100644
index 0000000..49319dd
--- /dev/null
+++ b/cmake/config.h.in
@@ -0,0 +1,89 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: alexs.mac@gmail.com (Alex Stewart)
+
+// Configuration options for Ceres.
+//
+// Do not edit this file, it was automatically configured by CMake when
+// Ceres was compiled with the relevant configuration for the machine
+// on which Ceres was compiled.
+//
+// Ceres Developers: All options should have the same name as their mapped
+//                   CMake options, in the preconfigured version of this file
+//                   all options should be enclosed in '@'.
+
+#ifndef CERES_PUBLIC_INTERNAL_CONFIG_H_
+#define CERES_PUBLIC_INTERNAL_CONFIG_H_
+
+// If defined, Ceres was compiled without LAPACK.
+@CERES_NO_LAPACK@
+
+// If defined, Ceres was compiled without SuiteSparse.
+@CERES_NO_SUITESPARSE@
+
+// If defined, Ceres was compiled without CXSparse.
+@CERES_NO_CXSPARSE@
+
+// If defined, Ceres was compiled without Schur specializations.
+@CERES_RESTRICT_SCHUR_SPECIALIZATION@
+
+// If defined, Ceres was compiled to use Eigen instead of hardcoded BLAS
+// routines.
+@CERES_NO_CUSTOM_BLAS@
+
+// If defined, Ceres was compiled without multithreading support.
+@CERES_NO_THREADS@
+// If defined Ceres was compiled with OpenMP multithreading support.
+@CERES_USE_OPENMP@
+// Additionally defined on *nix if Ceres was compiled with OpenMP support,
+// as in this case pthreads is also required.
+@CERES_HAVE_PTHREAD@
+@CERES_HAVE_RWLOCK@
+
+// Which version of unordered map was used when Ceres was compiled. Exactly
+// one of these will be defined for any given build.
+@CERES_STD_UNORDERED_MAP@
+@CERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE@
+@CERES_TR1_UNORDERED_MAP@
+@CERES_NO_UNORDERED_MAP@
+
+// If defined Ceres was compiled for Android with noalias() removed from
+// matrix-matrix multiplies to work around a bug in the Android NDK.
+@CERES_WORK_AROUND_ANDROID_NDK_COMPILER_BUG@
+
+// If defined, the memory header is in <tr1/memory>, otherwise <memory>.
+@CERES_TR1_MEMORY_HEADER@
+
+// If defined shared_ptr is in std::tr1 namespace, otherwise std.
+@CERES_TR1_SHARED_PTR@
+
+// If defined, Ceres was built as a shared library.
+@CERES_USING_SHARED_LIBRARY@
+
+#endif  // CERES_PUBLIC_INTERNAL_CONFIG_H_
diff --git a/docs/source/building.rst b/docs/source/building.rst
index 14ff68e..5b6846e 100644
--- a/docs/source/building.rst
+++ b/docs/source/building.rst
@@ -310,9 +310,6 @@
 
 #. The default build is Debug; consider switching it to release mode.
 #. Currently ``system_test`` is not working properly.
-#. If you build Ceres as a DLL with Visual Studio (BUILD_SHARED_LIBS),
-   you have to compile your own code with the flag
-   CERES_USING_SHARED_LIBRARY.
 #. CMake puts the resulting test binaries in ``ceres-bin/examples/Debug``
    by default.
 #. The solvers supported on Windows are ``DENSE_QR``, ``DENSE_SCHUR``,
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index eda929b..dff6ef0 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -28,8 +28,11 @@
 #
 # Author: keir@google.com (Keir Mierle)
 
+# Only Ceres itself should be compiled with CERES_BUILDING_SHARED_LIBRARY
+# defined, any users of Ceres will have CERES_USING_SHARED_LIBRARY defined
+# for them in Ceres' config.h if appropriate.
 IF (BUILD_SHARED_LIBS)
-  ADD_DEFINITIONS(-DCERES_USING_SHARED_LIBRARY)
+  REMOVE_DEFINITIONS(-DCERES_BUILDING_SHARED_LIBRARY)
 ENDIF()
 
 ADD_EXECUTABLE(helloworld helloworld.cc)
diff --git a/include/ceres/internal/config.h b/include/ceres/internal/config.h
new file mode 100644
index 0000000..c9d2c16
--- /dev/null
+++ b/include/ceres/internal/config.h
@@ -0,0 +1,45 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: alexs.mac@gmail.com (Alex Stewart)
+
+// Default (empty) configuration options for Ceres.
+//
+// IMPORTANT: Most users of Ceres will not use this file, when compiling Ceres
+//            with CMake, CMake will configure a new config.h with the currently
+//            selected Ceres compile options and copy it into the source
+//            directory before compilation.  However, for some users of Ceres
+//            who compile without CMake, this file ensures that Ceres will
+//            compile, with the user either specifying manually the Ceres
+//            compile options, or passing them directly through the compiler.
+
+#ifndef CERES_PUBLIC_INTERNAL_CONFIG_H_
+#define CERES_PUBLIC_INTERNAL_CONFIG_H_
+
+
+#endif  // CERES_PUBLIC_INTERNAL_CONFIG_H_
diff --git a/include/ceres/internal/port.h b/include/ceres/internal/port.h
index 7bcb1a7..e38eb71 100644
--- a/include/ceres/internal/port.h
+++ b/include/ceres/internal/port.h
@@ -36,6 +36,8 @@
 
 #include <string>
 
+#include "ceres/internal/config.h"
+
 #if defined(CERES_TR1_MEMORY_HEADER)
 #include <tr1/memory>
 #else
@@ -64,12 +66,21 @@
 
 #endif  // __cplusplus
 
-// A macro to signal wich functions and classes are exported when
-// bulding a DLL with MSC.
-#if defined(_MSC_VER) && defined(CERES_USING_SHARED_LIBRARY)
-# define CERES_EXPORT __declspec(dllimport)
-#elif defined(_MSC_VER) && defined(CERES_BUILDING_SHARED_LIBRARY)
+// A macro to signal which functions and classes are exported when
+// building a DLL with MSVC.
+//
+// Note that the ordering here is important, CERES_BUILDING_SHARED_LIBRARY
+// is only defined locally when Ceres is compiled, it is never exported to
+// users.  However, in order that we do not have to configure config.h
+// separately for building vs installing, if we are using MSVC and building
+// a shared library, then both CERES_BUILDING_SHARED_LIBRARY and
+// CERES_USING_SHARED_LIBRARY will be defined when Ceres is compiled.
+// Hence it is important that the check for CERES_BUILDING_SHARED_LIBRARY
+// happens first.
+#if defined(_MSC_VER) && defined(CERES_BUILDING_SHARED_LIBRARY)
 # define CERES_EXPORT __declspec(dllexport)
+#elif defined(_MSC_VER) && defined(CERES_USING_SHARED_LIBRARY)
+# define CERES_EXPORT __declspec(dllimport)
 #else
 # define CERES_EXPORT
 #endif
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index f077547..9475b21 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -177,21 +177,6 @@
   SOVERSION ${CERES_VERSION_MAJOR}
 )
 
-# If we are using CMake >= 2.8.11, make use of the target_compile_definitions()
-# function to append the compile definitions to the exported ceres target, thus
-# any library that finds Ceres via CMake, then adds Ceres to one of its own
-# targets will be compiled with the Ceres compile definitions defined.  This
-# is important for any defines that appear in the installed Ceres header files
-# e.g those related to shared_ptr.
-#
-# If we are using CMake < 2.8.11, then we will have added an add_definitions()
-# call in the CeresConfig.cmake file, which whilst achieving a similar effect,
-# is more of a blunt instrument, as the Ceres definitions will also be added
-# to targets in the users project that do not use Ceres.
-IF (CMAKE_VERSION VERSION_EQUAL 2.8.11 OR
-    CMAKE_VERSION VERSION_GREATER 2.8.11)
-  TARGET_COMPILE_DEFINITIONS(ceres INTERFACE ${CERES_INTERFACE_COMPILE_DEFINITIONS})
-ENDIF()
 TARGET_LINK_LIBRARIES(ceres ${CERES_LIBRARY_DEPENDENCIES})
 
 INSTALL(TARGETS ceres
diff --git a/internal/ceres/blas.cc b/internal/ceres/blas.cc
index f79b1eb..b919e13 100644
--- a/internal/ceres/blas.cc
+++ b/internal/ceres/blas.cc
@@ -29,6 +29,7 @@
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
 #include "ceres/blas.h"
+#include "ceres/internal/port.h"
 #include "glog/logging.h"
 
 extern "C" void dsyrk_(char* uplo,
diff --git a/internal/ceres/canonical_views_clustering.cc b/internal/ceres/canonical_views_clustering.cc
index 044d438..2f032e6 100644
--- a/internal/ceres/canonical_views_clustering.cc
+++ b/internal/ceres/canonical_views_clustering.cc
@@ -29,6 +29,9 @@
 // Author: David Gallup (dgallup@google.com)
 //         Sameer Agarwal (sameeragarwal@google.com)
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_NO_SUITESPARSE
 
 #include "ceres/canonical_views_clustering.h"
diff --git a/internal/ceres/canonical_views_clustering.h b/internal/ceres/canonical_views_clustering.h
index 06d80c8..1b4c4ee 100644
--- a/internal/ceres/canonical_views_clustering.h
+++ b/internal/ceres/canonical_views_clustering.h
@@ -41,6 +41,9 @@
 #ifndef CERES_INTERNAL_CANONICAL_VIEWS_CLUSTERING_H_
 #define CERES_INTERNAL_CANONICAL_VIEWS_CLUSTERING_H_
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_NO_SUITESPARSE
 
 #include <vector>
diff --git a/internal/ceres/canonical_views_clustering_test.cc b/internal/ceres/canonical_views_clustering_test.cc
index f4f9e2d..f86084a 100644
--- a/internal/ceres/canonical_views_clustering_test.cc
+++ b/internal/ceres/canonical_views_clustering_test.cc
@@ -29,6 +29,9 @@
 // Author: Sameer Agarwal (sameeragarwal@google.com)
 //         David Gallup (dgallup@google.com)
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_NO_SUITESPARSE
 
 #include "ceres/canonical_views_clustering.h"
diff --git a/internal/ceres/collections_port.h b/internal/ceres/collections_port.h
index e37be52..3f976b9 100644
--- a/internal/ceres/collections_port.h
+++ b/internal/ceres/collections_port.h
@@ -33,6 +33,8 @@
 #ifndef CERES_INTERNAL_COLLECTIONS_PORT_H_
 #define CERES_INTERNAL_COLLECTIONS_PORT_H_
 
+#include "ceres/internal/port.h"
+
 #if defined(CERES_NO_UNORDERED_MAP)
 #  include <map>
 #  include <set>
diff --git a/internal/ceres/cxsparse.cc b/internal/ceres/cxsparse.cc
index 7145f73..87503d0 100644
--- a/internal/ceres/cxsparse.cc
+++ b/internal/ceres/cxsparse.cc
@@ -28,6 +28,9 @@
 //
 // Author: strandmark@google.com (Petter Strandmark)
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_NO_CXSPARSE
 
 #include "ceres/cxsparse.h"
diff --git a/internal/ceres/cxsparse.h b/internal/ceres/cxsparse.h
index cd87908..1fed82f 100644
--- a/internal/ceres/cxsparse.h
+++ b/internal/ceres/cxsparse.h
@@ -31,6 +31,9 @@
 #ifndef CERES_INTERNAL_CXSPARSE_H_
 #define CERES_INTERNAL_CXSPARSE_H_
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_NO_CXSPARSE
 
 #include <vector>
diff --git a/internal/ceres/generate_eliminator_specialization.py b/internal/ceres/generate_eliminator_specialization.py
index 37b1fd7..2ec3c5b 100644
--- a/internal/ceres/generate_eliminator_specialization.py
+++ b/internal/ceres/generate_eliminator_specialization.py
@@ -126,6 +126,9 @@
 """
 
 SPECIALIZATION_FILE = """
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generate_partitioned_matrix_view_specializations.py b/internal/ceres/generate_partitioned_matrix_view_specializations.py
index a352d29..c9bdf23 100644
--- a/internal/ceres/generate_partitioned_matrix_view_specializations.py
+++ b/internal/ceres/generate_partitioned_matrix_view_specializations.py
@@ -124,6 +124,9 @@
 """
 
 SPECIALIZATION_FILE = """
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_2_2.cc b/internal/ceres/generated/partitioned_matrix_view_2_2_2.cc
index d7bd14c..a7d802a 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_2_2.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_2_2.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_2_3.cc b/internal/ceres/generated/partitioned_matrix_view_2_2_3.cc
index 6fca7b3..89e6f77 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_2_3.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_2_3.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_2_4.cc b/internal/ceres/generated/partitioned_matrix_view_2_2_4.cc
index 73c9100..3a3e8b6 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_2_4.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_2_4.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_2_d.cc b/internal/ceres/generated/partitioned_matrix_view_2_2_d.cc
index 8315e6a..661f135 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_2_d.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_2_d.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_3_3.cc b/internal/ceres/generated/partitioned_matrix_view_2_3_3.cc
index dc62c20..e79e001 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_3_3.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_3_3.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_3_4.cc b/internal/ceres/generated/partitioned_matrix_view_2_3_4.cc
index de63651..2f1ae68 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_3_4.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_3_4.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_3_9.cc b/internal/ceres/generated/partitioned_matrix_view_2_3_9.cc
index f85bd62..ab40550 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_3_9.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_3_9.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_3_d.cc b/internal/ceres/generated/partitioned_matrix_view_2_3_d.cc
index 2fe07be..89ecff7 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_3_d.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_3_d.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_4_3.cc b/internal/ceres/generated/partitioned_matrix_view_2_4_3.cc
index ed87dcf..182707d 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_4_3.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_4_3.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_4_4.cc b/internal/ceres/generated/partitioned_matrix_view_2_4_4.cc
index 5e9a339..a2cf8f4 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_4_4.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_4_4.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_4_8.cc b/internal/ceres/generated/partitioned_matrix_view_2_4_8.cc
index aef7048..a263769 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_4_8.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_4_8.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_4_9.cc b/internal/ceres/generated/partitioned_matrix_view_2_4_9.cc
index 8fea0bd..d853860 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_4_9.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_4_9.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_4_d.cc b/internal/ceres/generated/partitioned_matrix_view_2_4_d.cc
index d9e743b..7d622fc 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_4_d.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_4_d.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_d_d.cc b/internal/ceres/generated/partitioned_matrix_view_2_d_d.cc
index 1f26134..31981ca 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_d_d.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_d_d.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_4_4_2.cc b/internal/ceres/generated/partitioned_matrix_view_4_4_2.cc
index c3c0610..d51ab5f 100644
--- a/internal/ceres/generated/partitioned_matrix_view_4_4_2.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_4_4_2.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_4_4_3.cc b/internal/ceres/generated/partitioned_matrix_view_4_4_3.cc
index 34a0944..4b17fbd 100644
--- a/internal/ceres/generated/partitioned_matrix_view_4_4_3.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_4_4_3.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_4_4_4.cc b/internal/ceres/generated/partitioned_matrix_view_4_4_4.cc
index a790d0d..7b5fe0f 100644
--- a/internal/ceres/generated/partitioned_matrix_view_4_4_4.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_4_4_4.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/partitioned_matrix_view_4_4_d.cc b/internal/ceres/generated/partitioned_matrix_view_4_4_d.cc
index 467fb0e..c31fed3 100644
--- a/internal/ceres/generated/partitioned_matrix_view_4_4_d.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_4_4_d.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_partitioned_matrix_view_specializations.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_2_2_2.cc b/internal/ceres/generated/schur_eliminator_2_2_2.cc
index 696632b..db2a4dc 100644
--- a/internal/ceres/generated/schur_eliminator_2_2_2.cc
+++ b/internal/ceres/generated/schur_eliminator_2_2_2.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_2_2_3.cc b/internal/ceres/generated/schur_eliminator_2_2_3.cc
index 2b92a16..f53c12a 100644
--- a/internal/ceres/generated/schur_eliminator_2_2_3.cc
+++ b/internal/ceres/generated/schur_eliminator_2_2_3.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_2_2_4.cc b/internal/ceres/generated/schur_eliminator_2_2_4.cc
index 5ed1625..9e29383 100644
--- a/internal/ceres/generated/schur_eliminator_2_2_4.cc
+++ b/internal/ceres/generated/schur_eliminator_2_2_4.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_2_2_d.cc b/internal/ceres/generated/schur_eliminator_2_2_d.cc
index 4a73090..541def6 100644
--- a/internal/ceres/generated/schur_eliminator_2_2_d.cc
+++ b/internal/ceres/generated/schur_eliminator_2_2_d.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_2_3_3.cc b/internal/ceres/generated/schur_eliminator_2_3_3.cc
index a425560..e450263 100644
--- a/internal/ceres/generated/schur_eliminator_2_3_3.cc
+++ b/internal/ceres/generated/schur_eliminator_2_3_3.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_2_3_4.cc b/internal/ceres/generated/schur_eliminator_2_3_4.cc
index b71a48c..0618c68 100644
--- a/internal/ceres/generated/schur_eliminator_2_3_4.cc
+++ b/internal/ceres/generated/schur_eliminator_2_3_4.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_2_3_9.cc b/internal/ceres/generated/schur_eliminator_2_3_9.cc
index e0c265f..c1ca665 100644
--- a/internal/ceres/generated/schur_eliminator_2_3_9.cc
+++ b/internal/ceres/generated/schur_eliminator_2_3_9.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_2_3_d.cc b/internal/ceres/generated/schur_eliminator_2_3_d.cc
index 31d5d6b..1b6092c 100644
--- a/internal/ceres/generated/schur_eliminator_2_3_d.cc
+++ b/internal/ceres/generated/schur_eliminator_2_3_d.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_2_4_3.cc b/internal/ceres/generated/schur_eliminator_2_4_3.cc
index cc8270d..edce8ef 100644
--- a/internal/ceres/generated/schur_eliminator_2_4_3.cc
+++ b/internal/ceres/generated/schur_eliminator_2_4_3.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_2_4_4.cc b/internal/ceres/generated/schur_eliminator_2_4_4.cc
index d600a8b..a6f3c52 100644
--- a/internal/ceres/generated/schur_eliminator_2_4_4.cc
+++ b/internal/ceres/generated/schur_eliminator_2_4_4.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_2_4_8.cc b/internal/ceres/generated/schur_eliminator_2_4_8.cc
index 81e6bd6..bf2f0ab 100644
--- a/internal/ceres/generated/schur_eliminator_2_4_8.cc
+++ b/internal/ceres/generated/schur_eliminator_2_4_8.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_2_4_9.cc b/internal/ceres/generated/schur_eliminator_2_4_9.cc
index 6de47d5..a63d0bb 100644
--- a/internal/ceres/generated/schur_eliminator_2_4_9.cc
+++ b/internal/ceres/generated/schur_eliminator_2_4_9.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_2_4_d.cc b/internal/ceres/generated/schur_eliminator_2_4_d.cc
index 716e789..b3a7fff 100644
--- a/internal/ceres/generated/schur_eliminator_2_4_d.cc
+++ b/internal/ceres/generated/schur_eliminator_2_4_d.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_2_d_d.cc b/internal/ceres/generated/schur_eliminator_2_d_d.cc
index 4b420c3..f4d28cd 100644
--- a/internal/ceres/generated/schur_eliminator_2_d_d.cc
+++ b/internal/ceres/generated/schur_eliminator_2_d_d.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_4_4_2.cc b/internal/ceres/generated/schur_eliminator_4_4_2.cc
index f944f74..d1eadc1 100644
--- a/internal/ceres/generated/schur_eliminator_4_4_2.cc
+++ b/internal/ceres/generated/schur_eliminator_4_4_2.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_4_4_3.cc b/internal/ceres/generated/schur_eliminator_4_4_3.cc
index 9787b96..c340dbf 100644
--- a/internal/ceres/generated/schur_eliminator_4_4_3.cc
+++ b/internal/ceres/generated/schur_eliminator_4_4_3.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_4_4_4.cc b/internal/ceres/generated/schur_eliminator_4_4_4.cc
index 1a25bd0..b7d58ad 100644
--- a/internal/ceres/generated/schur_eliminator_4_4_4.cc
+++ b/internal/ceres/generated/schur_eliminator_4_4_4.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/generated/schur_eliminator_4_4_d.cc b/internal/ceres/generated/schur_eliminator_4_4_d.cc
index 7ddea9f..47e0059 100644
--- a/internal/ceres/generated/schur_eliminator_4_4_d.cc
+++ b/internal/ceres/generated/schur_eliminator_4_4_d.cc
@@ -40,6 +40,9 @@
 // This file is generated using generate_eliminator_specialization.py.
 // Editing it manually is not recommended.
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
diff --git a/internal/ceres/mutex.h b/internal/ceres/mutex.h
index 564c39f..97e2cd3 100644
--- a/internal/ceres/mutex.h
+++ b/internal/ceres/mutex.h
@@ -95,6 +95,8 @@
 #ifndef CERES_INTERNAL_MUTEX_H_
 #define CERES_INTERNAL_MUTEX_H_
 
+#include "ceres/internal/port.h"
+
 #if defined(CERES_NO_THREADS)
   typedef int MutexType;      // to keep a lock-count
 #elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__)
diff --git a/internal/ceres/program_evaluator.h b/internal/ceres/program_evaluator.h
index a06dc8c..672c233 100644
--- a/internal/ceres/program_evaluator.h
+++ b/internal/ceres/program_evaluator.h
@@ -79,6 +79,9 @@
 #ifndef CERES_INTERNAL_PROGRAM_EVALUATOR_H_
 #define CERES_INTERNAL_PROGRAM_EVALUATOR_H_
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifdef CERES_USE_OPENMP
 #include <omp.h>
 #endif
diff --git a/internal/ceres/schur_eliminator_impl.h b/internal/ceres/schur_eliminator_impl.h
index c09b7fb..305d94e 100644
--- a/internal/ceres/schur_eliminator_impl.h
+++ b/internal/ceres/schur_eliminator_impl.h
@@ -45,6 +45,9 @@
 
 #define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 10
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifdef CERES_USE_OPENMP
 #include <omp.h>
 #endif
diff --git a/internal/ceres/single_linkage_clustering.cc b/internal/ceres/single_linkage_clustering.cc
index 54b4379..0a8b20c 100644
--- a/internal/ceres/single_linkage_clustering.cc
+++ b/internal/ceres/single_linkage_clustering.cc
@@ -28,6 +28,9 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_NO_SUITESPARSE
 
 #include "ceres/single_linkage_clustering.h"
diff --git a/internal/ceres/single_linkage_clustering.h b/internal/ceres/single_linkage_clustering.h
index 9b137cf..e6fdeab 100644
--- a/internal/ceres/single_linkage_clustering.h
+++ b/internal/ceres/single_linkage_clustering.h
@@ -31,6 +31,9 @@
 #ifndef CERES_INTERNAL_SINGLE_LINKAGE_CLUSTERING_H_
 #define CERES_INTERNAL_SINGLE_LINKAGE_CLUSTERING_H_
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_NO_SUITESPARSE
 
 #include "ceres/collections_port.h"
diff --git a/internal/ceres/single_linkage_clustering_test.cc b/internal/ceres/single_linkage_clustering_test.cc
index 42cbda3..1cbc5be 100644
--- a/internal/ceres/single_linkage_clustering_test.cc
+++ b/internal/ceres/single_linkage_clustering_test.cc
@@ -28,6 +28,9 @@
 //
 // Author: Sameer Agarwal (sameeragarwal@google.com)
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_NO_SUITESPARSE
 
 #include "ceres/single_linkage_clustering.h"
diff --git a/internal/ceres/small_blas.h b/internal/ceres/small_blas.h
index e14e664..26228e4 100644
--- a/internal/ceres/small_blas.h
+++ b/internal/ceres/small_blas.h
@@ -35,6 +35,7 @@
 #ifndef CERES_INTERNAL_SMALL_BLAS_H_
 #define CERES_INTERNAL_SMALL_BLAS_H_
 
+#include "ceres/internal/port.h"
 #include "ceres/internal/eigen.h"
 #include "glog/logging.h"
 
diff --git a/internal/ceres/sparse_normal_cholesky_solver.cc b/internal/ceres/sparse_normal_cholesky_solver.cc
index 07537e3..cf5bb23 100644
--- a/internal/ceres/sparse_normal_cholesky_solver.cc
+++ b/internal/ceres/sparse_normal_cholesky_solver.cc
@@ -28,6 +28,9 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #if !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARSE)
 
 #include "ceres/sparse_normal_cholesky_solver.h"
diff --git a/internal/ceres/sparse_normal_cholesky_solver.h b/internal/ceres/sparse_normal_cholesky_solver.h
index ea91534..ed777a1 100644
--- a/internal/ceres/sparse_normal_cholesky_solver.h
+++ b/internal/ceres/sparse_normal_cholesky_solver.h
@@ -34,6 +34,9 @@
 #ifndef CERES_INTERNAL_SPARSE_NORMAL_CHOLESKY_SOLVER_H_
 #define CERES_INTERNAL_SPARSE_NORMAL_CHOLESKY_SOLVER_H_
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #if !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARSE)
 
 #include "ceres/cxsparse.h"
diff --git a/internal/ceres/suitesparse.cc b/internal/ceres/suitesparse.cc
index 8079bc1..1df7566 100644
--- a/internal/ceres/suitesparse.cc
+++ b/internal/ceres/suitesparse.cc
@@ -28,6 +28,9 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_NO_SUITESPARSE
 #include "ceres/suitesparse.h"
 
diff --git a/internal/ceres/suitesparse.h b/internal/ceres/suitesparse.h
index 832f103..0a7ea97 100644
--- a/internal/ceres/suitesparse.h
+++ b/internal/ceres/suitesparse.h
@@ -33,6 +33,8 @@
 #ifndef CERES_INTERNAL_SUITESPARSE_H_
 #define CERES_INTERNAL_SUITESPARSE_H_
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
 
 #ifndef CERES_NO_SUITESPARSE
 
diff --git a/internal/ceres/visibility.cc b/internal/ceres/visibility.cc
index acfa45b..b3ee185 100644
--- a/internal/ceres/visibility.cc
+++ b/internal/ceres/visibility.cc
@@ -28,6 +28,9 @@
 //
 // Author: kushalav@google.com (Avanish Kushal)
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_NO_SUITESPARSE
 
 #include "ceres/visibility.h"
diff --git a/internal/ceres/visibility.h b/internal/ceres/visibility.h
index 2d1e6f8..5ddd3a5 100644
--- a/internal/ceres/visibility.h
+++ b/internal/ceres/visibility.h
@@ -35,6 +35,9 @@
 #ifndef CERES_INTERNAL_VISIBILITY_H_
 #define CERES_INTERNAL_VISIBILITY_H_
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_NO_SUITESPARSE
 
 #include <set>
diff --git a/internal/ceres/visibility_based_preconditioner.cc b/internal/ceres/visibility_based_preconditioner.cc
index a3bebed..695eedc 100644
--- a/internal/ceres/visibility_based_preconditioner.cc
+++ b/internal/ceres/visibility_based_preconditioner.cc
@@ -28,6 +28,9 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_NO_SUITESPARSE
 
 #include "ceres/visibility_based_preconditioner.h"
diff --git a/internal/ceres/visibility_based_preconditioner_test.cc b/internal/ceres/visibility_based_preconditioner_test.cc
index 2edbb18..c718b5e 100644
--- a/internal/ceres/visibility_based_preconditioner_test.cc
+++ b/internal/ceres/visibility_based_preconditioner_test.cc
@@ -28,6 +28,9 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_NO_SUITESPARSE
 
 #include "ceres/visibility_based_preconditioner.h"
diff --git a/internal/ceres/visibility_test.cc b/internal/ceres/visibility_test.cc
index 3cfb232..0e22f88 100644
--- a/internal/ceres/visibility_test.cc
+++ b/internal/ceres/visibility_test.cc
@@ -29,6 +29,9 @@
 // Author: kushalav@google.com (Avanish Kushal)
 //         sameeragarwal@google.com (Sameer Agarwal)
 
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
 #ifndef CERES_NO_SUITESPARSE
 
 #include "ceres/visibility.h"
diff --git a/jni/Android.mk b/jni/Android.mk
index 941c89a..7027146 100644
--- a/jni/Android.mk
+++ b/jni/Android.mk
@@ -96,7 +96,6 @@
 LOCAL_CFLAGS := $(CERES_EXTRA_DEFINES) \
                 -DCERES_NO_LAPACK \
                 -DCERES_NO_SUITESPARSE \
-                -DCERES_NO_GFLAGS \
                 -DCERES_NO_THREADS \
                 -DCERES_NO_CXSPARSE \
                 -DCERES_STD_UNORDERED_MAP \