Windows build with SuiteSparse

5,083 views
Skip to first unread message

js...@demuc.de

unread,
Jan 12, 2014, 4:55:30 PM1/12/14
to ceres-...@googlegroups.com
Hi everyone,

It took me some time to build Ceres with SuiteSparse support on Windows with Visual Studio 12.0 - the way I accomplished it is far from being usable in a stable environment, but in hope it may be useful for other people (and for my own records ;-)):

1. Build Glog, Gflags.
2. Build SuiteSparse.
    => Apply patch:

diff -ur ../SuiteSparse.orig/CHOLMOD/Partition/cholmod_metis.c ./CHOLMOD/Partition/cholmod_metis.c
--- ../SuiteSparse.orig/CHOLMOD/Partition/cholmod_metis.c       2007-05-04 11:47:17.000000000 -0500
+++ ./CHOLMOD/Partition/cholmod_metis.c 2011-10-21 18:21:54.000000000 -0500
@@ -76,7 +76,7 @@
 
#ifdef DUMP_GRAPH
 
#include <stdio.h>
 
/* After dumping the graph with this routine, run "onmetis metisgraph" */
-static void dumpgraph (idxtype *Mp, idxtype *Mi, UF_long n,
+static void dumpgraph (idx_t *Mp, idx_t *Mi, UF_long n,
     cholmod_common
*Common)
 
{
     UF_long i
, j, p, nz ;
@@ -162,7 +162,7 @@
     s
= GUESS ((double) nz, (double) n) ;
     s
*= Common->metis_memory ;
 
-    if (s * sizeof (idxtype) >= ((double) Size_max))
+    if (s * sizeof (idx_t) >= ((double) Size_max))
     
{
       
/* don't even attempt to malloc such a large block */
       
return (FALSE) ;
@@ -173,7 +173,7 @@
     metis_guard
*= Common->metis_memory ;
 
     
/* attempt to malloc the block */
-    p = CHOLMOD(malloc) (metis_guard, sizeof (idxtype), Common) ;
+    p = CHOLMOD(malloc) (metis_guard, sizeof (idx_t), Common) ;
     
if (p == NULL)
     
{
       
/* failure - return out-of-memory condition */
@@ -181,7 +181,7 @@
     
}
 
     
/* success - free the block */
-    CHOLMOD(free) (metis_guard, sizeof (idxtype), p, Common) ;
+    CHOLMOD(free) (metis_guard, sizeof (idx_t), p, Common) ;
     
return (TRUE) ;
 
}
 
@@ -211,7 +211,7 @@
 
)
 
{
     
Int *Ap, *Ai ;
-    idxtype *Mp, *Mi, *Mnw, *Mew, *Mpart ;
+    idx_t *Mp, *Mi, *Mnw, *Mew, *Mpart ;
     
Int n, nleft, nright, j, p, csep, total_weight, lightest, nz ;
     
int Opt [8], nn, csp ;
     size_t n1
;
@@ -260,7 +260,7 @@
     
/* ---------------------------------------------------------------------- */
 
 
#ifdef LONG
-    if (sizeof (Int) > sizeof (idxtype) && MAX (n,nz) > INT_MAX / sizeof (int))
+    if (sizeof (Int) > sizeof (idx_t) && MAX (n,nz) > INT_MAX / sizeof (int))
     
{
       
/* CHOLMOD's matrix is too large for METIS */
       
return (EMPTY) ;
@@ -283,34 +283,34 @@
     DEBUG
(for (j = 0 ; j < n ; j++) ASSERT (Anw [j] > 0)) ;
 
     
/* ---------------------------------------------------------------------- */
-    /* copy Int to METIS idxtype, if necessary */
+    /* copy Int to METIS idx_t, if necessary */
     
/* ---------------------------------------------------------------------- */
 
     DEBUG
(for (j = 0 ; j < nz ; j++) ASSERT (Aew [j] > 0)) ;
-    if (sizeof (Int) == sizeof (idxtype))
+    if (sizeof (Int) == sizeof (idx_t))
     
{
       
/* this is the typical case */
-       Mi    = (idxtype *) Ai ;
-       Mew   = (idxtype *) Aew ;
-       Mp    = (idxtype *) Ap ;
-       Mnw   = (idxtype *) Anw ;
-       Mpart = (idxtype *) Partition ;
+       Mi    = (idx_t *) Ai ;
+       Mew   = (idx_t *) Aew ;
+       Mp    = (idx_t *) Ap ;
+       Mnw   = (idx_t *) Anw ;
+       Mpart = (idx_t *) Partition ;
     
}
     
else
     
{
-       /* idxtype and Int differ; copy the graph into the METIS idxtype */
-       Mi    = CHOLMOD(malloc) (nz, sizeof (idxtype), Common) ;
-       Mew   = CHOLMOD(malloc) (nz, sizeof (idxtype), Common) ;
-       Mp    = CHOLMOD(malloc) (n1, sizeof (idxtype), Common) ;
-       Mnw   = CHOLMOD(malloc) (n,  sizeof (idxtype), Common) ;
-       Mpart = CHOLMOD(malloc) (n,  sizeof (idxtype), Common) ;
+       /* idx_t and Int differ; copy the graph into the METIS idx_t */
+       Mi    = CHOLMOD(malloc) (nz, sizeof (idx_t), Common) ;
+       Mew   = CHOLMOD(malloc) (nz, sizeof (idx_t), Common) ;
+       Mp    = CHOLMOD(malloc) (n1, sizeof (idx_t), Common) ;
+       Mnw   = CHOLMOD(malloc) (n,  sizeof (idx_t), Common) ;
+       Mpart = CHOLMOD(malloc) (n,  sizeof (idx_t), Common) ;
       
if (Common->status < CHOLMOD_OK)
       
{
-           CHOLMOD(free) (nz, sizeof (idxtype), Mi,    Common) ;
-           CHOLMOD(free) (nz, sizeof (idxtype), Mew,   Common) ;
-           CHOLMOD(free) (n1, sizeof (idxtype), Mp,    Common) ;
-           CHOLMOD(free) (n,  sizeof (idxtype), Mnw,   Common) ;
-           CHOLMOD(free) (n,  sizeof (idxtype), Mpart, Common) ;
+           CHOLMOD(free) (nz, sizeof (idx_t), Mi,    Common) ;
+           CHOLMOD(free) (nz, sizeof (idx_t), Mew,   Common) ;
+           CHOLMOD(free) (n1, sizeof (idx_t), Mp,    Common) ;
+           CHOLMOD(free) (n,  sizeof (idx_t), Mnw,   Common) ;
+           CHOLMOD(free) (n,  sizeof (idx_t), Mpart, Common) ;
           
return (EMPTY) ;
       
}
       
for (p = 0 ; p < nz ; p++)
@@ -338,13 +338,13 @@
     
if (!metis_memory_ok (n, nz, Common))
     
{
       
/* METIS might ask for too much memory and thus terminate the program */
-       if (sizeof (Int) != sizeof (idxtype))
+       if (sizeof (Int) != sizeof (idx_t))
       
{
-           CHOLMOD(free) (nz, sizeof (idxtype), Mi,    Common) ;
-           CHOLMOD(free) (nz, sizeof (idxtype), Mew,   Common) ;
-           CHOLMOD(free) (n1, sizeof (idxtype), Mp,    Common) ;
-           CHOLMOD(free) (n,  sizeof (idxtype), Mnw,   Common) ;
-           CHOLMOD(free) (n,  sizeof (idxtype), Mpart, Common) ;
+           CHOLMOD(free) (nz, sizeof (idx_t), Mi,    Common) ;
+           CHOLMOD(free) (nz, sizeof (idx_t), Mew,   Common) ;
+           CHOLMOD(free) (n1, sizeof (idx_t), Mp,    Common) ;
+           CHOLMOD(free) (n,  sizeof (idx_t), Mnw,   Common) ;
+           CHOLMOD(free) (n,  sizeof (idx_t), Mpart, Common) ;
       
}
       
return (EMPTY) ;
     
}
@@ -370,27 +370,27 @@
 
#endif
 
     nn
= n ;
-    METIS_NodeComputeSeparator (&nn, Mp, Mi, Mnw, Mew, Opt, &csp, Mpart) ;
+    METIS_ComputeVertexSeparator (&nn, Mp, Mi, Mnw, Opt, &csp, Mpart) ;
     n
= nn ;
     csep
= csp ;
 
     PRINT1
(("METIS csep "ID"\n", csep)) ;
 
     
/* ---------------------------------------------------------------------- */
-    /* copy the results back from idxtype, if required */
+    /* copy the results back from idx_t, if required */
     
/* ---------------------------------------------------------------------- */
 
-    if (sizeof (Int) != sizeof (idxtype))
+    if (sizeof (Int) != sizeof (idx_t))
     
{
       
for (j = 0 ; j < n ; j++)
       
{
           
Partition [j] = Mpart [j] ;
       
}
-       CHOLMOD(free) (nz, sizeof (idxtype), Mi,    Common) ;
-       CHOLMOD(free) (nz, sizeof (idxtype), Mew,   Common) ;
-       CHOLMOD(free) (n1, sizeof (idxtype), Mp,    Common) ;
-       CHOLMOD(free) (n,  sizeof (idxtype), Mnw,   Common) ;
-       CHOLMOD(free) (n,  sizeof (idxtype), Mpart, Common) ;
+       CHOLMOD(free) (nz, sizeof (idx_t), Mi,    Common) ;
+       CHOLMOD(free) (nz, sizeof (idx_t), Mew,   Common) ;
+       CHOLMOD(free) (n1, sizeof (idx_t), Mp,    Common) ;
+       CHOLMOD(free) (n,  sizeof (idx_t), Mnw,   Common) ;
+       CHOLMOD(free) (n,  sizeof (idx_t), Mpart, Common) ;
     
}
 
     
/* ---------------------------------------------------------------------- */
@@ -508,7 +508,7 @@
 
{
     
double d ;
     
Int *Iperm, *Iwork, *Bp, *Bi ;
-    idxtype *Mp, *Mi, *Mperm, *Miperm ;
+    idx_t *Mp, *Mi, *Mperm, *Miperm ;
     cholmod_sparse
*B ;
     
Int i, j, n, nz, p, identity, uncol ;
     
int Opt [8], nn, zero = 0 ;
@@ -601,7 +601,7 @@
     
/* ---------------------------------------------------------------------- */
 
 
#ifdef LONG
-    if (sizeof (Int) > sizeof (idxtype) && MAX (n,nz) > INT_MAX / sizeof (int))
+    if (sizeof (Int) > sizeof (idx_t) && MAX (n,nz) > INT_MAX / sizeof (int))
     
{
       
/* CHOLMOD's matrix is too large for METIS */
        CHOLMOD
(free_sparse) (&B, Common) ;
@@ -630,29 +630,29 @@
     
/* allocate the METIS input arrays, if needed */
     
/* ---------------------------------------------------------------------- */
 
-    if (sizeof (Int) == sizeof (idxtype))
+    if (sizeof (Int) == sizeof (idx_t))
     
{
       
/* This is the typical case. */
-       Miperm = (idxtype *) Iperm ;
-       Mperm  = (idxtype *) Perm ;
-       Mp     = (idxtype *) Bp ;
-       Mi     = (idxtype *) Bi ;
+       Miperm = (idx_t *) Iperm ;
+       Mperm  = (idx_t *) Perm ;
+       Mp     = (idx_t *) Bp ;
+       Mi     = (idx_t *) Bi ;
     
}
     
else
     
{
-       /* allocate graph for METIS only if Int and idxtype differ */
-       Miperm = CHOLMOD(malloc) (n,  sizeof (idxtype), Common) ;
-       Mperm  = CHOLMOD(malloc) (n,  sizeof (idxtype), Common) ;
-       Mp     = CHOLMOD(malloc) (n1, sizeof (idxtype), Common) ;
-       Mi     = CHOLMOD(malloc) (nz, sizeof (idxtype), Common) ;
+       /* allocate graph for METIS only if Int and idx_t differ */
+       Miperm = CHOLMOD(malloc) (n,  sizeof (idx_t), Common) ;
+       Mperm  = CHOLMOD(malloc) (n,  sizeof (idx_t), Common) ;
+       Mp     = CHOLMOD(malloc) (n1, sizeof (idx_t), Common) ;
+       Mi     = CHOLMOD(malloc) (nz, sizeof (idx_t), Common) ;
       
if (Common->status < CHOLMOD_OK)
       
{
           
/* out of memory */
            CHOLMOD
(free_sparse) (&B, Common) ;
-           CHOLMOD(free) (n,  sizeof (idxtype), Miperm, Common) ;
-           CHOLMOD(free) (n,  sizeof (idxtype), Mperm, Common) ;
-           CHOLMOD(free) (n1, sizeof (idxtype), Mp, Common) ;
-           CHOLMOD(free) (nz, sizeof (idxtype), Mi, Common) ;
+           CHOLMOD(free) (n,  sizeof (idx_t), Miperm, Common) ;
+           CHOLMOD(free) (n,  sizeof (idx_t), Mperm, Common) ;
+           CHOLMOD(free) (n1, sizeof (idx_t), Mp, Common) ;
+           CHOLMOD(free) (nz, sizeof (idx_t), Mi, Common) ;
           
return (FALSE) ;
       
}
       
for (j = 0 ; j <= n ; j++)
@@ -741,16 +741,16 @@
     
/* free the METIS input arrays */
     
/* ---------------------------------------------------------------------- */
 
-    if (sizeof (Int) != sizeof (idxtype))
+    if (sizeof (Int) != sizeof (idx_t))
     
{
       
for (i = 0 ; i < n ; i++)
       
{
           
Perm [i] = (Int) (Mperm [i]) ;
       
}
-       CHOLMOD(free) (n,   sizeof (idxtype), Miperm, Common) ;
-       CHOLMOD(free) (n,   sizeof (idxtype), Mperm, Common) ;
-       CHOLMOD(free) (n+1, sizeof (idxtype), Mp, Common) ;
-       CHOLMOD(free) (nz,  sizeof (idxtype), Mi, Common) ;
+       CHOLMOD(free) (n,   sizeof (idx_t), Miperm, Common) ;
+       CHOLMOD(free) (n,   sizeof (idx_t), Mperm, Common) ;
+       CHOLMOD(free) (n+1, sizeof (idx_t), Mp, Common) ;
+       CHOLMOD(free) (nz,  sizeof (idx_t), Mi, Common) ;
     
}
 
     CHOLMOD
(free_sparse) (&B, Common) ;
Only in .: metis.patch



3. Download Eigen.
4. Download Ceres 1.8.0.
5. Adapt the CMakeLists.txt in Ceres:

# Ceres Solver - A fast non-linear least squares minimizer
# Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
#
# 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: ke...@google.com (Keir Mierle)

CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)
CMAKE_POLICY(VERSION 2.8)

IF (COMMAND cmake_policy)
  CMAKE_POLICY(SET CMP0003 NEW)
ENDIF (COMMAND cmake_policy)

PROJECT(CERES C CXX)

# Set up the git hook to make Gerrit Change-Id: lines in commit messages.
SET (LOCAL_GIT_DIRECTORY)
IF (EXISTS ${CMAKE_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 (EXISTS ${CMAKE_SOURCE_DIR}/.git)
  # TODO(keir) Add proper Windows support
ENDIF (EXISTS ${CMAKE_SOURCE_DIR}/.git)

IF (EXISTS ${LOCAL_GIT_DIRECTORY})
  IF (NOT EXISTS ${LOCAL_GIT_DIRECTORY}/hooks/commit-msg)
    # Download the hook only if it is not already present
         ${CMAKE_BINARY_DIR}/commit-msg)

    # Make the downloaded file executable, since it is not by default.
    FILE(COPY ${CMAKE_BINARY_DIR}/commit-msg
         DESTINATION ${LOCAL_GIT_DIRECTORY}/hooks/
         FILE_PERMISSIONS
           OWNER_READ OWNER_WRITE OWNER_EXECUTE
           GROUP_READ GROUP_WRITE GROUP_EXECUTE
           WORLD_READ WORLD_EXECUTE)
  ENDIF (NOT EXISTS ${LOCAL_GIT_DIRECTORY}/hooks/commit-msg)
ENDIF (EXISTS ${LOCAL_GIT_DIRECTORY})

# Make CMake aware of the cmake folder for local FindXXX scripts.
SET (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")

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 postfixes for generated libraries based on buildtype.
SET(CMAKE_RELEASE_POSTFIX "")
SET(CMAKE_DEBUG_POSTFIX "-debug")

# Important: Always bump the second number (e.g. 1.3.x to 1.4.0) for any
# release that changes the ABI. The ABI changes for almost any modification to
# include/ceres (e.g. the public API). If you are unsure about whether
# something is an ABI change, please ask on the list.
#
# For versions without ABI changes, bump the smallest number in CERES_VERSION,
# but leave the CERES_ABI_VERSION unchanged.
SET(CERES_VERSION_MAJOR 1)
SET(CERES_VERSION_MINOR 8)
SET(CERES_VERSION_PATCH 0)
SET(CERES_VERSION
    ${CERES_VERSION_MAJOR}.${CERES_VERSION_MINOR}.${CERES_VERSION_PATCH})
SET(CERES_ABI_VERSION 1.8.0)

ENABLE_TESTING()

OPTION(MINIGLOG "Use a stripped down version of glog." OFF)
OPTION(GFLAGS "Enable Google Flags." ON)
OPTION(SUITESPARSE "Enable SuiteSparse." ON)
OPTION(CXSPARSE "Enable CXSparse." ON)
OPTION(LAPACK "Enable use of LAPACK." ON)
# Template specializations for the Schur complement based solvers. If
# compile time, binary size or compiler performance is an issue, you
# may consider disabling this.
OPTION(SCHUR_SPECIALIZATIONS "Enable fixed-size schur specializations." ON)
OPTION(CUSTOM_BLAS
       "Use handcoded BLAS routines (usually faster) instead of Eigen."
       ON)
# Multithreading using OpenMP
OPTION(OPENMP "Enable threaded solving in Ceres (requires OpenMP)" ON)
# TODO(sameeragarwal): Replace this with a positive option instead?

# Line search minimizer is useful for large scale problems or when
# sparse linear algebra libraries are not available. If compile time,
# binary size or compiler performance is an issue, consider disabling
# this.
OPTION(LINE_SEARCH_MINIMIZER "Enable the line search minimizer." ON)
OPTION(BUILD_TESTING "Enable tests" ON)
OPTION(BUILD_DOCUMENTATION "Build User's Guide (html)" OFF)
OPTION(BUILD_EXAMPLES "Build examples" ON)
OPTION(BUILD_SHARED_LIBS "Build Ceres as a shared library." OFF)
IF (MSVC)
  OPTION(MSVC_USE_STATIC_CRT
    "MS Visual Studio: Use static C-Run Time Library in place of shared." OFF)
ENDIF (MSVC)

# Prior to October 2013, Ceres used some non-CMake standardised variables to
# hold user-specified (as opposed to FindPackage found) include directory and
# library paths for Ceres dependencies.  These were were of the form:
# <DEPENDENCY>_LIB / <DEPENDENCY>_INCLUDE.  Since then, Ceres now has
# FindPackage() scripts for all of its dependencies which obey the standard
# CMake variables: <DEPENDENCY>_LIBRARIES & <DEPENDENCY>_INCLUDE_DIRS.  In order
# to ensure backwards compatibility, we use convert any legacy variables to
# _directory_ hints for the FindPackage() scripts.
MACRO(HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT
    LEGACY_VAR DIRECTORY_HINT_VAR)
  IF (DEFINED ${LEGACY_VAR})
    # Get the dependency name (all caps) from the hint directory variable
    # for the warning message.
    STRING(REGEX MATCH "^[^_]*" DEPENDENCY_NAME ${DIRECTORY_HINT_VAR})
    MESSAGE(WARNING "You are defining a legacy variable ${LEGACY_VAR} "
      "to specify the include directory for ${DEPENDENCY_NAME}.  This is "
      "deprecated and support for it will be removed in a future release. "
      "Please use either the search directory hints variable: "
      "${DIRECTORY_HINT_VAR} or ${DEPENDENCY_NAME}_INCLUDE_DIR to specify "
      "exactly the directory used (no search performed), see: "
      "for more information.")
    LIST(APPEND ${DIRECTORY_HINT_VAR} ${${LEGACY_VAR}})
  ENDIF (DEFINED ${LEGACY_VAR})
ENDMACRO(HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT)

MACRO(HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT
    LEGACY_VAR DIRECTORY_HINT_VAR)
  IF (DEFINED ${LEGACY_VAR})
    # Get the dependency name (all caps) from the hint directory variable
    # for the warning message.
    STRING(REGEX MATCH "^[^_]*" DEPENDENCY_NAME ${DIRECTORY_HINT_VAR})
    MESSAGE(WARNING "You are defining a legacy variable ${LEGACY_VAR} "
      "to specify the library for ${DEPENDENCY_NAME}.  This is "
      "deprecated and support for it will be removed in a future release. "
      "Please use either the search directory hints variable: "
      "${DIRECTORY_HINT_VAR} or ${DEPENDENCY_NAME}_LIBRARY to specify "
      "exactly the library used (no search performed), see: "
      "for more information.")
    IF (EXISTS ${${LEGACY_VAR}} AND
        NOT IS_DIRECTORY ${${LEGACY_VAR}})
      # User specified an explicit (library) file using the legacy variable
      # interface, hints to FindPackage() scripts are directories so add the
      # parent directory of the specified file.
      GET_FILENAME_COMPONENT(DIR_HINT ${${LEGACY_VAR}} PATH)
      LIST(APPEND ${DIRECTORY_HINT_VAR} ${DIR_HINT})
    ELSEIF (EXISTS ${${LEGACY_VAR}} AND
            IS_DIRECTORY ${${LEGACY_VAR}})
      # User specified a directory hint using the legacy variable, use it.
      LIST(APPEND ${DIRECTORY_HINT_VAR} ${${LEGACY_VAR}})
    ENDIF()
  ENDIF (DEFINED ${LEGACY_VAR})
ENDMACRO(HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT)

# Eigen.
HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(EIGEN_INCLUDE EIGEN_INCLUDE_DIR_HINTS)
FIND_PACKAGE(Eigen REQUIRED)
IF (EIGEN_FOUND)
  MESSAGE("-- Found Eigen version ${EIGEN_VERSION}: ${EIGEN_INCLUDE_DIRS}")
ENDIF (EIGEN_FOUND)

# LAPACK (& BLAS).
IF (LAPACK)
  FIND_PACKAGE(LAPACK QUIET)
  IF (LAPACK_FOUND)
    MESSAGE("-- Found LAPACK library: ${LAPACK_LIBRARIES}")
  ELSE (LAPACK_FOUND)
    MESSAGE("-- Did not find LAPACK library, disabling LAPACK support.")
  ENDIF (LAPACK_FOUND)

  FIND_PACKAGE(BLAS QUIET)
  IF (BLAS_FOUND)
    MESSAGE("-- Found BLAS library: ${BLAS_LIBRARIES}")
  ELSE (BLAS_FOUND)
    MESSAGE("-- Did not find BLAS library, disabling LAPACK support.")
  ENDIF (BLAS_FOUND)

  IF (NOT (LAPACK_FOUND AND BLAS_FOUND))
    # Retain the help string associated with the LAPACK option
    # 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)
  ENDIF (NOT (LAPACK_FOUND AND BLAS_FOUND))
ELSE (LAPACK)
  MESSAGE("-- Building without LAPACK.")
  ADD_DEFINITIONS(-DCERES_NO_LAPACK)
ENDIF (LAPACK)

# SuiteSparse.

SET(SUITESPARSE ON)

IF (SUITESPARSE)
  # By default, if SuiteSparse and all dependencies are found, Ceres is
  # built with SuiteSparse support.

  # Check for SuiteSparse and dependencies.
  FIND_PACKAGE(SuiteSparse)
  IF (SUITESPARSE_FOUND)
    # On Ubuntu the system install of SuiteSparse (v3.4.0) up to at least
    # Ubuntu 13.10 cannot be used to link shared libraries.
    IF (BUILD_SHARED_LIBS AND
        SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION)
      MESSAGE(FATAL_ERROR "You are attempting to build Ceres as a shared "
        "library on Ubuntu using a system package install of SuiteSparse "
        "3.4.0. This package is broken and does not support the "
        "construction of shared libraries (you can still build Ceres as "
        "a static library).  If you wish to build a shared version of Ceres "
        "you should uninstall the system install of SuiteSparse "
        "(libsuitesparse-dev) and perform a source install of SuiteSparse "
        "(we recommend that you use the latest version), "
        "/ceres-solver/dev/building.html for more information.")
    ENDIF (BUILD_SHARED_LIBS AND
      SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION)

    # By default, if all of SuiteSparse's dependencies are found, Ceres is
    # built with SuiteSparse support.
    MESSAGE("-- Found SuiteSparse ${SUITESPARSE_VERSION}, "
            "building with SuiteSparse.")
  ELSE (SUITESPARSE_FOUND)
    # Disable use of SuiteSparse if it cannot be found and continue.
    MESSAGE("-- Did not find all SuiteSparse dependencies, disabling "
      "SuiteSparse support.")
    # Retain the help string associated with the SUITESPARSE option
    # 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)
  ENDIF (SUITESPARSE_FOUND)
ELSE (SUITESPARSE)
  MESSAGE("-- Building without SuiteSparse.")
  ADD_DEFINITIONS(-DCERES_NO_SUITESPARSE)
ENDIF (SUITESPARSE)

# CXSparse.
IF (CXSPARSE)
  # Don't search with REQUIRED as we can continue without CXSparse.
  FIND_PACKAGE(CXSparse)
  IF (CXSPARSE_FOUND)
    # By default, if CXSparse and all dependencies are found, Ceres is
    # built with CXSparse support.
    MESSAGE("-- Found CXSparse version: ${CXSPARSE_VERSION}, "
      "building with CXSparse.")
  ELSE (CXSPARSE_FOUND)
    # Disable use of CXSparse if it cannot be found and continue.
    MESSAGE("-- Did not find CXSparse, Building without CXSparse.")
    # Retain the help string associated with the CXSPARSE option
    # 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)
  ENDIF (CXSPARSE_FOUND)
ELSE (CXSPARSE)
  MESSAGE("-- Building without CXSparse.")
  ADD_DEFINITIONS(-DCERES_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
  # CXSPARSE instead of setting them.
  MARK_AS_ADVANCED(FORCE CXSPARSE_INCLUDE_DIR
                         CXSPARSE_LIBRARY)
ENDIF (CXSPARSE)

# GFlags.
IF (GFLAGS)
  HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(GFLAGS_INCLUDE GFLAGS_INCLUDE_DIR_HINTS)
  HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT(GFLAGS_LIB GFLAGS_LIBRARY_DIR_HINTS)

  # Don't search with REQUIRED as we can continue without gflags.
  FIND_PACKAGE(Gflags)
  IF (GFLAGS_FOUND)
    MESSAGE("-- Found Google Flags header in: ${GFLAGS_INCLUDE_DIRS}")
  ELSE (GFLAGS_FOUND)
    MESSAGE("-- Did not find Google Flags (gflags), Building without gflags "
      "- no tests or tools will be built!")
    # Retain the help string associated with the GFLAGS option
    # 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
  # GFLAGS instead of setting them.
  MARK_AS_ADVANCED(FORCE GFLAGS_INCLUDE_DIR
                         GFLAGS_LIBRARY)
ENDIF (GFLAGS)

# MiniGLog.
IF (MINIGLOG)
  SET(GLOG_LIBRARIES miniglog)
  MESSAGE("-- Using minimal Glog substitute (library): ${GLOG_LIBRARIES}")
  SET(GLOG_INCLUDE_DIRS internal/ceres/miniglog)
  MESSAGE("-- Using minimal Glog substitute (include): ${GLOG_INCLUDE_DIRS}")

  # Mark as advanced (remove from default GUI view) the glog search
  # variables in case user disables MINIGLOG, FindGlog did not find it, so
  # made search variables visible in GUI for user to set, but then user enables
  # MINIGLOG instead of setting them.
  MARK_AS_ADVANCED(FORCE GLOG_INCLUDE_DIR
                         GLOG_LIBRARY)
ELSE (MINIGLOG)
  HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(GLOG_INCLUDE GLOG_INCLUDE_DIR_HINTS)
  HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT(GLOG_LIB GLOG_LIBRARY_DIR_HINTS)

  # Don't search with REQUIRED so that configuration continues if not found and
  # we can output an error messages explaining MINIGLOG option.
  FIND_PACKAGE(Glog)
  IF (GLOG_FOUND)
    MESSAGE("-- Found Google Log header in: ${GLOG_INCLUDE_DIRS}")
  ELSE (GLOG_FOUND)
    MESSAGE(FATAL_ERROR "Can't find Google Log. Please set GLOG_INCLUDE_DIR & "
      "GLOG_LIBRARY or enable MINIGLOG option to use minimal glog "
      "implementation.")
  ENDIF (GLOG_FOUND)
ENDIF (MINIGLOG)

IF (NOT SCHUR_SPECIALIZATIONS)
  ADD_DEFINITIONS(-DCERES_RESTRICT_SCHUR_SPECIALIZATION)
  MESSAGE("-- Disabling Schur specializations (faster compiles)")
ENDIF (NOT SCHUR_SPECIALIZATIONS)

IF (NOT LINE_SEARCH_MINIMIZER)
  ADD_DEFINITIONS(-DCERES_NO_LINE_SEARCH_MINIMIZER)
  MESSAGE("-- Disabling line search minimizer")
ENDIF (NOT LINE_SEARCH_MINIMIZER)

IF (NOT CUSTOM_BLAS)
  ADD_DEFINITIONS(-DCERES_NO_CUSTOM_BLAS)
  MESSAGE("-- Disabling custom blas")
ENDIF (NOT CUSTOM_BLAS)

IF (OPENMP)
  # Clang does not (yet) support OpenMP.
  IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    # Retain the help string associated with the OPENMP option
    # when updating it to disable use of OPENMP.
    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)
  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)
      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)
        SET(STATIC_LIBRARY_FLAGS
          "${STATIC_LIBRARY_FLAGS} ${CMAKE_THREAD_LIBS_INIT}")
        SET(CMAKE_SHARED_LINKER_FLAGS
          "${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_THREAD_LIBS_INIT}")
        ADD_DEFINITIONS(-DCERES_HAVE_PTHREAD)
        ADD_DEFINITIONS(-DCERES_HAVE_RWLOCK)
      ENDIF (UNIX)
    ELSE (OPENMP_FOUND)
      MESSAGE("-- Failed to find OpenMP, disabling.")
      # Retain the help string associated with the OPENMP option
      # 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)
    ENDIF (OPENMP_FOUND)
  ENDIF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
ELSE (OPENMP)
  MESSAGE("-- Building without OpenMP (disabling multithreading).")
  ADD_DEFINITIONS(-DCERES_NO_THREADS)
ENDIF (OPENMP)

Include(CheckIncludeFileCXX)
CHECK_INCLUDE_FILE_CXX(unordered_map UNORDERED_MAP_IN_STD_NAMESPACE)
If (UNORDERED_MAP_IN_STD_NAMESPACE)
  ADD_DEFINITIONS(-DCERES_STD_UNORDERED_MAP)
ELSE (UNORDERED_MAP_IN_STD_NAMESPACE)
  CHECK_INCLUDE_FILE_CXX("tr1/unordered_map" UNORDERED_MAP_IN_TR1_NAMESPACE)
  IF (UNORDERED_MAP_IN_TR1_NAMESPACE)
    ADD_DEFINITIONS(-DCERES_TR1_UNORDERED_MAP)
  ELSE (UNORDERED_MAP_IN_TR1_NAMESPACE)
    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)
  ENDIF (UNORDERED_MAP_IN_TR1_NAMESPACE)
ENDIF (UNORDERED_MAP_IN_STD_NAMESPACE)

INCLUDE_DIRECTORIES(
  include
  internal
  internal/ceres
  ${GLOG_INCLUDE_DIRS}
  ${EIGEN_INCLUDE_DIRS})

IF (SUITESPARSE)
  INCLUDE_DIRECTORIES(${SUITESPARSE_INCLUDE_DIRS})
ENDIF (SUITESPARSE)

IF (CXSPARSE)
  INCLUDE_DIRECTORIES(${CXSPARSE_INCLUDE_DIRS})
ENDIF (CXSPARSE)

IF (GFLAGS)
  INCLUDE_DIRECTORIES(${GFLAGS_INCLUDE_DIRS})
ENDIF (GFLAGS)

IF (BUILD_SHARED_LIBS)
  MESSAGE("-- Building Ceres as a shared library.")
ELSE (BUILD_SHARED_LIBS)
  MESSAGE("-- Building Ceres as a static library.")
ENDIF (BUILD_SHARED_LIBS)

# Change the default build type from Debug to Release, while still
# supporting overriding the build type.
#
# The CACHE STRING logic here and elsewhere is needed to force CMake
# to pay attention to the value of these variables.
IF (NOT CMAKE_BUILD_TYPE)
  MESSAGE("-- No build type specified; defaulting to CMAKE_BUILD_TYPE=Release.")
  SET(CMAKE_BUILD_TYPE Release CACHE STRING
    "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
    FORCE)
ELSE (NOT CMAKE_BUILD_TYPE)
  IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
    MESSAGE("\n=================================================================================")
    MESSAGE("\n-- Build type: Debug. Performance will be terrible!")
    MESSAGE("-- Add -DCMAKE_BUILD_TYPE=Release to the CMake command line to get an optimized build.")
    MESSAGE("\n=================================================================================")
  ENDIF (CMAKE_BUILD_TYPE STREQUAL "Debug")
ENDIF (NOT CMAKE_BUILD_TYPE)

# Set the default Ceres flags to an empty string.
SET (CERES_CXX_FLAGS)

IF (CMAKE_BUILD_TYPE STREQUAL "Release")
  IF (CMAKE_COMPILER_IS_GNUCXX)
    # Linux
    IF (CMAKE_SYSTEM_NAME MATCHES "Linux")
      IF (NOT GCC_VERSION VERSION_LESS 4.2)
        SET (CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -march=native -mtune=native")
      ENDIF (NOT GCC_VERSION VERSION_LESS 4.2)
    ENDIF (CMAKE_SYSTEM_NAME MATCHES "Linux")
    # Mac OS X
    IF (CMAKE_SYSTEM_NAME MATCHES "Darwin")
      SET (CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -msse3")
      # Use of -fast only applicable for Apple's GCC
      # Assume this is being used if GCC version < 4.3 on OSX
      EXECUTE_PROCESS(COMMAND ${CMAKE_C_COMPILER}
        ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
        OUTPUT_VARIABLE GCC_VERSION
        OUTPUT_STRIP_TRAILING_WHITESPACE)
      IF (GCC_VERSION VERSION_LESS 4.3)
        SET (CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -fast")
      ENDIF (GCC_VERSION VERSION_LESS 4.3)
    ENDIF (CMAKE_SYSTEM_NAME MATCHES "Darwin")
  ENDIF (CMAKE_COMPILER_IS_GNUCXX)
  IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    # Use of -O4 requires use of gold linker & LLVM-gold plugin, which might
    # well not be present / in use and without which files will compile, but
    # not link ('file not recognized') so explicitly check for support
    INCLUDE(CheckCXXCompilerFlag)
    CHECK_CXX_COMPILER_FLAG("-O4" HAVE_LTO_SUPPORT)
    IF (HAVE_LTO_SUPPORT)
      MESSAGE(STATUS "Enabling link-time optimization (-O4)")
      SET(CERES_CXX_FLAGS "${CERES_CXX_FLAGS} -O4")
    ELSE ()
      MESSAGE(STATUS "Compiler/linker does not support link-time optimization (-O4), disabling.")
    ENDIF (HAVE_LTO_SUPPORT)
  ENDIF ()
ENDIF (CMAKE_BUILD_TYPE STREQUAL "Release")

SET (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CERES_CXX_FLAGS}")

# After the tweaks for the compile settings, disable some warnings on MSVC.
IF (MSVC)
  # Disable signed/unsigned int conversion warnings.
  ADD_DEFINITIONS("/wd4018")
  # Disable warning about using struct/class for the same symobl.
  ADD_DEFINITIONS("/wd4099")
  # Disable warning about the insecurity of using "std::copy".
  ADD_DEFINITIONS("/wd4996")
  # Disable performance warning about int-to-bool conversion.
  ADD_DEFINITIONS("/wd4800")
  # Disable performance warning about fopen insecurity.
  ADD_DEFINITIONS("/wd4996")
  # Disable warning about int64 to int32 conversion. Disabling
  # this warning may not be correct; needs investigation.
  # TODO(keir): Investigate these warnings in more detail.
  ADD_DEFINITIONS("/wd4244")
  # It's not possible to use STL types in DLL interfaces in a portable and
  # reliable way. However, that's what happens with Google Log and Google Flags
  # on Windows. MSVC gets upset about this and throws warnings that we can't do
  # much about. The real solution is to link static versions of Google Log and
  # Google Test, but that seems tricky on Windows. So, disable the warning.
  ADD_DEFINITIONS("/wd4251")

  # Google Flags doesn't have their DLL import/export stuff set up correctly,
  # which results in linker warnings. This is irrelevant for Ceres, so ignore
  # the warnings.
  SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4049")

  # Update the C/CXX flags for MSVC to use either the static or shared
  # C-Run Time (CRT) library based on the user option: MSVC_USE_STATIC_CRT.
  LIST(APPEND C_CXX_FLAGS
    CMAKE_CXX_FLAGS
    CMAKE_CXX_FLAGS_DEBUG
    CMAKE_CXX_FLAGS_RELEASE
    CMAKE_CXX_FLAGS_MINSIZEREL
    CMAKE_CXX_FLAGS_RELWITHDEBINFO)

  FOREACH(FLAG_VAR ${C_CXX_FLAGS})
    IF (MSVC_USE_STATIC_CRT)
      # Use static CRT.
      IF (${FLAG_VAR} MATCHES "/MD")
        STRING(REGEX REPLACE "/MD" "/MT" ${FLAG_VAR} "${${FLAG_VAR}}")
      ENDIF (${FLAG_VAR} MATCHES "/MD")
    ELSE (MSVC_USE_STATIC_CRT)
      # Use shared, not static, CRT.
      IF (${FLAG_VAR} MATCHES "/MT")
        STRING(REGEX REPLACE "/MT" "/MD" ${FLAG_VAR} "${${FLAG_VAR}}")
      ENDIF (${FLAG_VAR} MATCHES "/MT")
    ENDIF (MSVC_USE_STATIC_CRT)
  ENDFOREACH()

  # Tuple sizes of 10 are used by Gtest.
  ADD_DEFINITIONS("-D_VARIADIC_MAX=10")
ENDIF (MSVC)

IF (UNIX)
  # GCC is not strict enough by default, so enable most of the warnings.
  SET(CMAKE_CXX_FLAGS
    "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-missing-field-initializers")
ENDIF (UNIX)

# Use a larger inlining threshold for Clang, since it hobbles Eigen,
# resulting in an unreasonably slow version of the blas routines. The
# -Qunused-arguments is needed because CMake passes the inline
# threshold to the linker and clang complains about it and dies.
IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  SET(CMAKE_CXX_FLAGS
      "${CMAKE_CXX_FLAGS} -Qunused-arguments -mllvm -inline-threshold=600")
  # Older versions of Clang (<= 2.9) do not support the 'return-type-c-linkage'
  # option, so check for its presence before adding it to the default flags set.
  INCLUDE(CheckCXXCompilerFlag)
  CHECK_CXX_COMPILER_FLAG("-Wno-return-type-c-linkage"
                          HAVE_RETURN_TYPE_C_LINKAGE)
  IF (HAVE_RETURN_TYPE_C_LINKAGE)
    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type-c-linkage")
  ENDIF(HAVE_RETURN_TYPE_C_LINKAGE)
ENDIF ()

# Xcode 4.5.x used Clang 4.1 (Apple version), this has a bug that prevents
# compilation of Ceres.
IF (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  EXECUTE_PROCESS(COMMAND ${CMAKE_CXX_COMPILER}
    ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
    OUTPUT_VARIABLE CLANG_VERSION
    OUTPUT_STRIP_TRAILING_WHITESPACE)
  # Use version > 4.0 & < 4.2 to catch all 4.1(.x) versions.
  IF (CLANG_VERSION VERSION_GREATER 4.0 AND
      CLANG_VERSION VERSION_LESS 4.2)
    MESSAGE(FATAL_ERROR "You are attempting to build Ceres on OS X using Xcode "
      "4.5.x (Clang version: ${CLANG_VERSION}). This version of Clang has a "
      "bug that prevents compilation of Ceres, please update to "
      "Xcode >= 4.6.3.")
  ENDIF (CLANG_VERSION VERSION_GREATER 4.0 AND
    CLANG_VERSION VERSION_LESS 4.2)
ENDIF (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")

ADD_SUBDIRECTORY(internal/ceres)

IF (BUILD_DOCUMENTATION)
  MESSAGE("-- Documentation building is enabled")

  # Generate the User's Guide (html).
  # The corresponding target is UserGuide, but is included in ALL.
  ADD_SUBDIRECTORY(docs)
ENDIF (BUILD_DOCUMENTATION)

IF (BUILD_EXAMPLES)
  MESSAGE("-- Build the examples.")
  ADD_SUBDIRECTORY(examples)
ELSE (BUILD_EXAMPLES)
  MESSAGE("-- Do not build any example.")
ENDIF (BUILD_EXAMPLES)

# Setup installation of Ceres public headers.
FILE(GLOB CERES_HDRS ${CMAKE_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)
INSTALL(FILES ${CERES_PUBLIC_INTERNAL_HDRS} 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
          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)

ADD_CUSTOM_TARGET(uninstall
                  COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cmake/uninstall.cmake)

# Set up install directories. INCLUDE_INSTALL_DIR, LIB_INSTALL_DIR and
# CMAKECONFIG_INSTALL_DIR must not be absolute paths.
IF (WIN32)
  SET(INCLUDE_INSTALL_DIR Include)
  SET(LIB_INSTALL_DIR Lib)
  SET(CMAKECONFIG_INSTALL_DIR CMake)
ELSE ()
  SET(INCLUDE_INSTALL_DIR include)
  SET(LIB_INSTALL_DIR lib)
  SET(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().
INSTALL(EXPORT CeresExport
        DESTINATION ${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.
FILE(RELATIVE_PATH INSTALL_ROOT_REL_CONFIG_INSTALL_DIR
     ${CMAKE_INSTALL_PREFIX}/${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_FILE("${CMAKE_SOURCE_DIR}/cmake/CeresConfig.cmake.in"
               "${CMAKE_CURRENT_BINARY_DIR}/CeresConfig.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"
              "${CMAKE_SOURCE_DIR}/cmake/FindEigen.cmake"
              "${CMAKE_SOURCE_DIR}/cmake/FindGlog.cmake"
        DESTINATION ${CMAKECONFIG_INSTALL_DIR})


6. Adapt the cmake/FindSuiteSparse.cmake in Ceres (replace SP_ROOT):

# Ceres Solver - A fast non-linear least squares minimizer
# Copyright 2013 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: alex...@gmail.com (Alex Stewart)
#


# FindSuiteSparse.cmake - Find SuiteSparse libraries & dependencies.
#
# This module defines the following variables:
#
# SUITESPARSE_FOUND: TRUE iff SuiteSparse and all dependencies have been found.
# SUITESPARSE_INCLUDE_DIRS: Include directories for all SuiteSparse components.
# SUITESPARSE_LIBRARIES: Libraries for all SuiteSparse component libraries and
#                        dependencies.
# SUITESPARSE_VERSION: Extracted from UFconfig.h (<= v3) or
#                      SuiteSparse_config.h (>= v4).
# SUITESPARSE_MAIN_VERSION: Equal to 4 if SUITESPARSE_VERSION = 4.2.1
# SUITESPARSE_SUB_VERSION: Equal to 2 if SUITESPARSE_VERSION = 4.2.1
# SUITESPARSE_SUBSUB_VERSION: Equal to 1 if SUITESPARSE_VERSION = 4.2.1
#
# SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION: TRUE iff running
#     on Ubuntu, SUITESPARSE_VERSION is 3.4.0 and found SuiteSparse is a system
#     install, in which case found version of SuiteSparse cannot be used to link
#     a shared library due to a bug (static linking is unaffected).
#
# The following variables control the behaviour of this module:
#
# SUITESPARSE_INCLUDE_DIR_HINTS: List of additional directories in which to
#                                search for SuiteSparse includes,
#                                e.g: /timbuktu/include.
# SUITESPARSE_LIBRARY_DIR_HINTS: List of additional directories in which to
#                                search for SuiteSparse libraries,
#                                e.g: /timbuktu/lib.
#
# The following variables define the presence / includes & libraries for the
# SuiteSparse components searched for, the SUITESPARSE_XX variables are the
# union of the variables for all components.
#
# == Symmetric Approximate Minimum Degree (AMD)
# AMD_FOUND
# AMD_INCLUDE_DIR
# AMD_LIBRARY
#
# == Constrained Approximate Minimum Degree (CAMD)
# CAMD_FOUND
# CAMD_INCLUDE_DIR
# CAMD_LIBRARY
#
# == Column Approximate Minimum Degree (COLAMD)
# COLAMD_FOUND
# COLAMD_INCLUDE_DIR
# COLAMD_LIBRARY
#
# Constrained Column Approximate Minimum Degree (CCOLAMD)
# CCOLAMD_FOUND
# CCOLAMD_INCLUDE_DIR
# CCOLAMD_LIBRARY
#
# == Sparse Supernodal Cholesky Factorization and Update/Downdate (CHOLMOD)
# CHOLMOD_FOUND
# CHOLMOD_INCLUDE_DIR
# CHOLMOD_LIBRARY
#
# == Multifrontal Sparse QR (SuiteSparseQR)
# SUITESPARSEQR_FOUND
# SUITESPARSEQR_INCLUDE_DIR
# SUITESPARSEQR_LIBRARY
#
# == Common configuration for all but CSparse (SuiteSparse version >= 4).
# SUITESPARSE_CONFIG_FOUND
# SUITESPARSE_CONFIG_INCLUDE_DIR
# SUITESPARSE_CONFIG_LIBRARY
#
# == Common configuration for all but CSparse (SuiteSparse version < 4).
# UFCONFIG_FOUND
# UFCONFIG_INCLUDE_DIR
#
# Optional SuiteSparse Dependencies:
#
# == Serial Graph Partitioning and Fill-reducing Matrix Ordering (METIS)
# METIS_FOUND
# METIS_LIBRARY
#
# == Intel Thread Building Blocks (TBB)
# TBB_FOUND
# TBB_LIBRARIES


# Called if we failed to find SuiteSparse or any of it's required dependencies,
# unsets all public (designed to be used externally) variables and reports
# error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument.
MACRO
(SUITESPARSE_REPORT_NOT_FOUND REASON_MSG)
  UNSET
(SUITESPARSE_FOUND)
  UNSET
(SUITESPARSE_INCLUDE_DIRS)
  UNSET
(SUITESPARSE_LIBRARIES)
  UNSET
(SUITESPARSE_VERSION)
  UNSET
(SUITESPARSE_MAIN_VERSION)
  UNSET
(SUITESPARSE_SUB_VERSION)
  UNSET
(SUITESPARSE_SUBSUB_VERSION)
 
# Do NOT unset SUITESPARSE_FOUND_REQUIRED_VARS here, as it is used by
 
# FindPackageHandleStandardArgs() to generate the automatic error message on
 
# failure which highlights which components are missing.


 
# Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage()
 
# use the camelcase library name, not uppercase.
  IF
(SuiteSparse_FIND_QUIETLY)
    MESSAGE
(STATUS "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
  ELSEIF
(SuiteSparse_FIND_REQUIRED)
    MESSAGE
(FATAL_ERROR "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
  ELSE
()
   
# Neither QUIETLY nor REQUIRED, use no priority which emits a message
   
# but continues configuration and allows generation.
    MESSAGE
("-- Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
  ENDIF
(SuiteSparse_FIND_QUIETLY)


 
# Do not call RETURN(), s/t we keep processing if not called with REQUIRED.
ENDMACRO
(SUITESPARSE_REPORT_NOT_FOUND)


# Specify search directories for include files and libraries (this is the union
# of the search directories for all OSs).  Search user-specified hint
# directories first if supplied, and search user-installed locations first
# so that we prefer user installs to system installs where both exist.
LIST
(APPEND SUITESPARSE_CHECK_INCLUDE_DIRS
  $
{SUITESPARSE_INCLUDE_DIR_HINTS}
 
/opt/local/include
 
/opt/local/include/ufsparse # Mac OS X
 
/usr/local/homebrew/include # Mac OS X
 
/usr/local/include
 
/usr/local/include/suitesparse
 
/usr/include/suitesparse # Ubuntu
 
/usr/include
  SP_ROOT
/suitesparse-metis-for-windows-1.0.0+all_sources/SuiteSparse)
LIST
(APPEND SUITESPARSE_CHECK_LIBRARY_DIRS
  $
{SUITESPARSE_LIBRARY_DIR_HINTS}
 
/opt/local/lib
 
/opt/local/lib/ufsparse # Mac OS X
 
/usr/local/homebrew/lib # Mac OS X
 
/usr/local/lib
 
/usr/local/lib/suitesparse
 
/usr/lib/suitesparse # Ubuntu
 
/usr/lib
  SP_ROOT
/suitesparse-metis-for-windows-1.0.0+all_sources/build/lib/Release)


SET
(COLAMD_INCLUDE_DIR SP_ROOT/suitesparse-metis-for-windows-1.0.0+all_sources/SuiteSparse/COLAMD/Include)
SET
(COLAMD_LIBRARY SP_ROOT/suitesparse-metis-for-windows-1.0.0+all_sources/SuiteSparse/COLAMD/Include)
SET
(AMD_INCLUDE_DIR SP_ROOT/suitesparse-metis-for-windows-1.0.0+all_sources/SuiteSparse/AMD/Include)
SET
(CAMD_INCLUDE_DIR SP_ROOT/suitesparse-metis-for-windows-1.0.0+all_sources/SuiteSparse/CAMD/Include)
SET
(CCOLAMD_INCLUDE_DIR SP_ROOT/suitesparse-metis-for-windows-1.0.0+all_sources/SuiteSparse/CCOLAMD/Include)
SET
(CHOLMOD_INCLUDE_DIR SP_ROOT/suitesparse-metis-for-windows-1.0.0+all_sources/SuiteSparse/CHOLMOD/Include)
SET
(SUITESPARSEQR_INCLUDE_DIR  SP_ROOT/suitesparse-metis-for-windows-1.0.0+all_sources/SuiteSparse/SPQR/Include)


SET
(SUITESPARSE_CONFIG_LIBRARY SP_ROOT/suitesparse-metis-for-windows-1.0.0+all_sources/build/lib/Release/suitesparse.lib)
SET
(SUITESPARSE_CONFIG_INCLUDE_DIR SP_ROOT/suitesparse-metis-for-windows-1.0.0+all_sources/SuiteSparse/SuiteSparse_config)


# Given the number of components of SuiteSparse, and to ensure that the
# automatic failure message generated by FindPackageHandleStandardArgs()
# when not all required components are found is helpful, we maintain a list
# of all variables that must be defined for SuiteSparse to be considered found.
UNSET
(SUITESPARSE_FOUND_REQUIRED_VARS)


# BLAS.
FIND_PACKAGE
(BLAS QUIET)


# LAPACK.
FIND_PACKAGE
(LAPACK QUIET)


# AMD.
SET
(AMD_FOUND TRUE)
SET
(AMD_LIBRARY "")


# CAMD.
SET
(CAMD_FOUND TRUE)
SET
(CAMD_LIBRARY "")


# COLAMD.
SET
(COLAMD_FOUND TRUE)
SET
(COLAMD_LIBRARY "")


# CCOLAMD.
SET
(CCOLAMD_FOUND TRUE)
SET
(CCOLAMD_LIBRARY "")


# CHOLMOD.
SET
(CHOLMOD_FOUND TRUE)
SET
(CHOLMOD_LIBRARY "")


# SuiteSparseQR.
SET
(SUITESPARSEQR_FOUND TRUE)
SET
(SUITESPARSEQR_LIBRARY "")


IF
(SUITESPARSEQR_FOUND)
 
# SuiteSparseQR may be compiled with Intel Threading Building Blocks,
 
# we assume that if TBB is installed, SuiteSparseQR was compiled with
 
# support for it, this will do no harm if it wasn't.
  SET
(TBB_FOUND TRUE)
  FIND_LIBRARY
(TBB_LIBRARIES NAMES tbb
    PATHS $
{SUITESPARSE_CHECK_LIBRARY_DIRS})
  IF
(EXISTS ${TBB_LIBRARIES})
    MESSAGE
(STATUS "Found Intel Thread Building Blocks (TBB) library: "
     
"${TBB_LIBRARIES}, assuming SuiteSparseQR was compiled with TBB.")
  ELSE
(EXISTS ${TBB_LIBRARIES})
    MESSAGE
(STATUS "Did not find Intel TBB library, assuming SuiteSparseQR was "
     
"not compiled with TBB.")
    SET
(TBB_FOUND FALSE)
  ENDIF
(EXISTS ${TBB_LIBRARIES})
  MARK_AS_ADVANCED
(TBB_LIBRARIES)


  IF
(TBB_FOUND)
    FIND_LIBRARY
(TBB_MALLOC_LIB NAMES tbbmalloc
      PATHS $
{SUITESPARSE_CHECK_LIBRARY_DIRS})
    IF
(EXISTS ${TBB_MALLOC_LIB})
      MESSAGE
(STATUS "Found Intel Thread Building Blocks (TBB) Malloc library: "
       
"${TBB_MALLOC_LIB}")
     
# Append TBB malloc library to TBB libraries list whilst retaining
     
# any CMake generated help string (cache variable).
      LIST
(APPEND TBB_LIBRARIES ${TBB_MALLOC_LIB})
      GET_PROPERTY
(HELP_STRING CACHE TBB_LIBRARIES PROPERTY HELPSTRING)
      SET
(TBB_LIBRARIES "${TBB_LIBRARIES}" CACHE STRING ${HELP_STRING})


     
# Add the TBB libraries to the SuiteSparseQR libraries (the only
     
# libraries to optionally depend on TBB).
      LIST
(APPEND SUITESPARSEQR_LIBRARY ${TBB_LIBRARIES})


    ELSE
(EXISTS ${TBB_MALLOC_LIB})
     
# If we cannot find all required TBB components do not include it as
     
# a dependency.
      MESSAGE
(STATUS "Did not find Intel Thread Building Blocks (TBB) Malloc "
       
"Library, discarding TBB as a dependency.")
      SET
(TBB_FOUND FALSE)
    ENDIF
(EXISTS ${TBB_MALLOC_LIB})
    MARK_AS_ADVANCED
(TBB_MALLOC_LIB)
  ENDIF
(TBB_FOUND)
ENDIF
(SUITESPARSEQR_FOUND)


# UFconfig / SuiteSparse_config.
#
# If SuiteSparse version is >= 4 then SuiteSparse_config is required.
# For SuiteSparse 3, UFconfig.h is required.
FIND_LIBRARY
(SUITESPARSE_CONFIG_LIBRARY NAMES suitesparseconfig
  PATHS $
{SUITESPARSE_CHECK_LIBRARY_DIRS})
IF
(EXISTS ${SUITESPARSE_CONFIG_LIBRARY})
  MESSAGE
(STATUS "Found SuiteSparse_config library: "
   
"${SUITESPARSE_CONFIG_LIBRARY}")
ENDIF
(EXISTS ${SUITESPARSE_CONFIG_LIBRARY})
MARK_AS_ADVANCED
(SUITESPARSE_CONFIG_LIBRARY)


FIND_PATH
(SUITESPARSE_CONFIG_INCLUDE_DIR NAMES SuiteSparse_config.h
  PATHS $
{SUITESPARSE_CHECK_INCLUDE_DIRS})
IF
(EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR})
  MESSAGE
(STATUS "Found SuiteSparse_config header in: "
   
"${SUITESPARSE_CONFIG_INCLUDE_DIR}")
ENDIF
(EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR})
MARK_AS_ADVANCED
(SUITESPARSE_CONFIG_INCLUDE_DIR)


SET
(SUITESPARSE_CONFIG_FOUND FALSE)
SET
(UFCONFIG_FOUND FALSE)


IF
(EXISTS ${SUITESPARSE_CONFIG_LIBRARY} AND
    EXISTS $
{SUITESPARSE_CONFIG_INCLUDE_DIR})
  SET
(SUITESPARSE_CONFIG_FOUND TRUE)
 
# SuiteSparse_config (SuiteSparse version >= 4) requires librt library for
 
# timing by default when compiled on Linux or Unix, but not on OSX (which
 
# does not have librt).
  IF
(CMAKE_SYSTEM_NAME MATCHES "Linux" OR UNIX AND NOT APPLE)
    FIND_LIBRARY
(LIBRT_LIBRARY NAMES rt
      PATHS $
{SUITESPARSE_CHECK_LIBRARY_DIRS})
    IF
(LIBRT_LIBRARY)
      MESSAGE
(STATUS "Adding librt: ${LIBRT_LIBRARY} to "
       
"SuiteSparse_config libraries (required on Linux & Unix [not OSX] if "
       
"SuiteSparse is compiled with timing).")
    ELSE
(LIBRT_LIBRARY)
      MESSAGE
(STATUS "Could not find librt, but found SuiteSparse_config, "
       
"assuming that SuiteSparse was compiled without timing.")
    ENDIF
(LIBRT_LIBRARY)
    MARK_AS_ADVANCED
(LIBRT_LIBRARY)
    LIST
(APPEND SUITESPARSE_CONFIG_LIBRARY ${LIBRT_LIBRARY})
  ENDIF
(CMAKE_SYSTEM_NAME MATCHES "Linux" OR UNIX AND NOT APPLE)


ELSE
(EXISTS ${SUITESPARSE_CONFIG_LIBRARY} AND
      EXISTS $
{SUITESPARSE_CONFIG_INCLUDE_DIR})
 
# Failed to find SuiteSparse_config (>= v4 installs), instead look for
 
# UFconfig header which should be present in < v4 installs.
  SET
(SUITESPARSE_CONFIG_FOUND FALSE)
  FIND_PATH
(UFCONFIG_INCLUDE_DIR NAMES UFconfig.h
    PATHS $
{SUITESPARSE_CHECK_INCLUDE_DIRS})
  IF
(EXISTS ${UFCONFIG_INCLUDE_DIR})
    MESSAGE
(STATUS "Found UFconfig header in: ${UFCONFIG_INCLUDE_DIR}")
    SET
(UFCONFIG_FOUND TRUE)
  ENDIF
(EXISTS ${UFCONFIG_INCLUDE_DIR})
  MARK_AS_ADVANCED
(UFCONFIG_INCLUDE_DIR)
ENDIF
(EXISTS ${SUITESPARSE_CONFIG_LIBRARY} AND
       EXISTS $
{SUITESPARSE_CONFIG_INCLUDE_DIR})


IF
(NOT SUITESPARSE_CONFIG_FOUND AND
    NOT UFCONFIG_FOUND
)
  SUITESPARSE_REPORT_NOT_FOUND
(
   
"Failed to find either: SuiteSparse_config header & library (should be "
   
"present in all SuiteSparse >= v4 installs), or UFconfig header (should "
   
"be present in all SuiteSparse < v4 installs).")
ENDIF
(NOT SUITESPARSE_CONFIG_FOUND AND
       NOT UFCONFIG_FOUND
)


# Extract the SuiteSparse version from the appropriate header (UFconfig.h for
# <= v3, SuiteSparse_config.h for >= v4).
LIST
(APPEND SUITESPARSE_FOUND_REQUIRED_VARS SUITESPARSE_VERSION)


IF
(UFCONFIG_FOUND)
 
# SuiteSparse version <= 3.
  SET
(SUITESPARSE_VERSION_FILE ${UFCONFIG_INCLUDE_DIR}/UFconfig.h)
  IF
(NOT EXISTS ${SUITESPARSE_VERSION_FILE})
    SUITESPARSE_REPORT_NOT_FOUND
(
     
"Could not find file: ${SUITESPARSE_VERSION_FILE} containing version "
     
"information for <= v3 SuiteSparse installs, but UFconfig was found "
     
"(only present in <= v3 installs).")
  ELSE
(NOT EXISTS ${SUITESPARSE_VERSION_FILE})
    FILE
(READ ${SUITESPARSE_VERSION_FILE} UFCONFIG_CONTENTS)


    STRING
(REGEX MATCH "#define SUITESPARSE_MAIN_VERSION [0-9]+"
      SUITESPARSE_MAIN_VERSION
"${UFCONFIG_CONTENTS}")
    STRING
(REGEX REPLACE "#define SUITESPARSE_MAIN_VERSION ([0-9]+)" "\\1"
      SUITESPARSE_MAIN_VERSION
"${SUITESPARSE_MAIN_VERSION}")


    STRING
(REGEX MATCH "#define SUITESPARSE_SUB_VERSION [0-9]+"
      SUITESPARSE_SUB_VERSION
"${UFCONFIG_CONTENTS}")
    STRING
(REGEX REPLACE "#define SUITESPARSE_SUB_VERSION ([0-9]+)" "\\1"
      SUITESPARSE_SUB_VERSION
"${SUITESPARSE_SUB_VERSION}")


    STRING
(REGEX MATCH "#define SUITESPARSE_SUBSUB_VERSION [0-9]+"
      SUITESPARSE_SUBSUB_VERSION
"${UFCONFIG_CONTENTS}")
    STRING
(REGEX REPLACE "#define SUITESPARSE_SUBSUB_VERSION ([0-9]+)" "\\1"
      SUITESPARSE_SUBSUB_VERSION
"${SUITESPARSE_SUBSUB_VERSION}")


   
# This is on a single line s/t CMake does not interpret it as a list of
   
# elements and insert ';' separators which would result in 4.;2.;1 nonsense.
    SET
(SUITESPARSE_VERSION
     
"${SUITESPARSE_MAIN_VERSION}.${SUITESPARSE_SUB_VERSION}.${SUITESPARSE_SUBSUB_VERSION}")
  ENDIF
(NOT EXISTS ${SUITESPARSE_VERSION_FILE})
ENDIF
(UFCONFIG_FOUND)


IF
(SUITESPARSE_CONFIG_FOUND)
 
# SuiteSparse version >= 4.
  SET
(SUITESPARSE_VERSION_FILE
    $
{SUITESPARSE_CONFIG_INCLUDE_DIR}/SuiteSparse_config.h)
  IF
(NOT EXISTS ${SUITESPARSE_VERSION_FILE})
    SUITESPARSE_REPORT_NOT_FOUND
(
     
"Could not find file: ${SUITESPARSE_VERSION_FILE} containing version "
     
"information for >= v4 SuiteSparse installs, but SuiteSparse_config was "
     
"found (only present in >= v4 installs).")
  ELSE
(NOT EXISTS ${SUITESPARSE_VERSION_FILE})
    FILE
(READ ${SUITESPARSE_VERSION_FILE} SUITESPARSE_CONFIG_CONTENTS)


    STRING
(REGEX MATCH "#define SUITESPARSE_MAIN_VERSION [0-9]+"
      SUITESPARSE_MAIN_VERSION
"${SUITESPARSE_CONFIG_CONTENTS}")
    STRING
(REGEX REPLACE "#define SUITESPARSE_MAIN_VERSION ([0-9]+)" "\\1"
      SUITESPARSE_MAIN_VERSION
"${SUITESPARSE_MAIN_VERSION}")


    STRING
(REGEX MATCH "#define SUITESPARSE_SUB_VERSION [0-9]+"
      SUITESPARSE_SUB_VERSION
"${SUITESPARSE_CONFIG_CONTENTS}")
    STRING
(REGEX REPLACE "#define SUITESPARSE_SUB_VERSION ([0-9]+)" "\\1"
      SUITESPARSE_SUB_VERSION
"${SUITESPARSE_SUB_VERSION}")


    STRING
(REGEX MATCH "#define SUITESPARSE_SUBSUB_VERSION [0-9]+"
      SUITESPARSE_SUBSUB_VERSION
"${SUITESPARSE_CONFIG_CONTENTS}")
    STRING
(REGEX REPLACE "#define SUITESPARSE_SUBSUB_VERSION ([0-9]+)" "\\1"
      SUITESPARSE_SUBSUB_VERSION
"${SUITESPARSE_SUBSUB_VERSION}")


   
# This is on a single line s/t CMake does not interpret it as a list of
   
# elements and insert ';' separators which would result in 4.;2.;1 nonsense.
    SET
(SUITESPARSE_VERSION
     
"${SUITESPARSE_MAIN_VERSION}.${SUITESPARSE_SUB_VERSION}.${SUITESPARSE_SUBSUB_VERSION}")
  ENDIF
(NOT EXISTS ${SUITESPARSE_VERSION_FILE})
ENDIF
(SUITESPARSE_CONFIG_FOUND)


# METIS (Optional dependency).
FIND_LIBRARY
(METIS_LIBRARY NAMES metis
  PATHS $
{SUITESPARSE_CHECK_LIBRARY_DIRS})
IF
(EXISTS ${METIS_LIBRARY})
  MESSAGE
(STATUS "Found METIS library: ${METIS_LIBRARY}.")
ELSE
(EXISTS ${METIS_LIBRARY})
  MESSAGE
(STATUS "Did not find METIS library (optional SuiteSparse dependency)")
ENDIF
(EXISTS ${METIS_LIBRARY})
MARK_AS_ADVANCED
(METIS_LIBRARY)


# Only mark SuiteSparse as found if all required components and dependencies
# have been found.
SET
(SUITESPARSE_FOUND TRUE)
FOREACH
(REQUIRED_VAR ${SUITESPARSE_FOUND_REQUIRED_VARS})
  IF
(NOT ${REQUIRED_VAR})
    SET
(SUITESPARSE_FOUND FALSE)
  ENDIF
(NOT ${REQUIRED_VAR})
ENDFOREACH
(REQUIRED_VAR ${SUITESPARSE_FOUND_REQUIRED_VARS})


IF
(SUITESPARSE_FOUND)
  LIST
(APPEND SUITESPARSE_INCLUDE_DIRS
    $
{AMD_INCLUDE_DIR}
    $
{CAMD_INCLUDE_DIR}
    $
{COLAMD_INCLUDE_DIR}
    $
{CCOLAMD_INCLUDE_DIR}
    $
{CHOLMOD_INCLUDE_DIR}
    $
{SUITESPARSEQR_INCLUDE_DIR})
 
# Handle config separately, as otherwise at least one of them will be set
 
# to NOTFOUND which would cause any check on SUITESPARSE_INCLUDE_DIRS to fail.
  IF
(SUITESPARSE_CONFIG_FOUND)
    LIST
(APPEND SUITESPARSE_INCLUDE_DIRS
      $
{SUITESPARSE_CONFIG_INCLUDE_DIR})
  ENDIF
(SUITESPARSE_CONFIG_FOUND)
  IF
(UFCONFIG_FOUND)
    LIST
(APPEND SUITESPARSE_INCLUDE_DIRS
      $
{UFCONFIG_INCLUDE_DIR})
  ENDIF
(UFCONFIG_FOUND)
 
# As SuiteSparse includes are often all in the same directory, remove any
 
# repetitions.
  LIST
(REMOVE_DUPLICATES SUITESPARSE_INCLUDE_DIRS)


 
# Important: The ordering of these libraries is *NOT* arbitrary, as these
 
# could potentially be static libraries their link ordering is important.
  LIST
(APPEND SUITESPARSE_LIBRARIES
    $
{SUITESPARSEQR_LIBRARY}
    $
{CHOLMOD_LIBRARY}
    $
{CCOLAMD_LIBRARY}
    $
{CAMD_LIBRARY}
    $
{COLAMD_LIBRARY}
    $
{AMD_LIBRARY}
    $
{LAPACK_LIBRARIES}
    $
{BLAS_LIBRARIES})
  IF
(SUITESPARSE_CONFIG_FOUND)
    LIST
(APPEND SUITESPARSE_LIBRARIES
      $
{SUITESPARSE_CONFIG_LIBRARY})
  ENDIF
(SUITESPARSE_CONFIG_FOUND)
  IF
(METIS_FOUND)
    LIST
(APPEND SUITESPARSE_LIBRARIES
      $
{METIS_LIBRARY})
  ENDIF
(METIS_FOUND)
ENDIF
()


# Determine if we are running on Ubuntu with the package install of SuiteSparse
# which is broken and does not support linking a shared library.
SET
(SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION FALSE)
IF
(CMAKE_SYSTEM_NAME MATCHES "Linux" AND
    SUITESPARSE_VERSION VERSION_EQUAL
3.4.0)
  FIND_PROGRAM
(LSB_RELEASE_EXECUTABLE lsb_release)
  IF
(LSB_RELEASE_EXECUTABLE)
   
# Any even moderately recent Ubuntu release (likely to be affected by
   
# this bug) should have lsb_release, if it isn't present we are likely
   
# on a different Linux distribution (should be fine).


    EXECUTE_PROCESS
(COMMAND ${LSB_RELEASE_EXECUTABLE} -si
      OUTPUT_VARIABLE LSB_DISTRIBUTOR_ID
      OUTPUT_STRIP_TRAILING_WHITESPACE
)


    IF
(LSB_DISTRIBUTOR_ID MATCHES "Ubuntu" AND
        SUITESPARSE_LIBRARIES MATCHES
"/usr/lib/libamd")
     
# We are on Ubuntu, and the SuiteSparse version matches the broken
     
# system install version and is a system install.
      SET
(SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION TRUE)
      MESSAGE
(STATUS "Found system install of SuiteSparse "
       
"${SUITESPARSE_VERSION} running on Ubuntu, which has a known bug "
       
"preventing linking of shared libraries (static linking unaffected).")
    ENDIF
(LSB_DISTRIBUTOR_ID MATCHES "Ubuntu" AND
      SUITESPARSE_LIBRARIES MATCHES
"/usr/lib/libamd")
  ENDIF
(LSB_RELEASE_EXECUTABLE)
ENDIF
(CMAKE_SYSTEM_NAME MATCHES "Linux" AND
  SUITESPARSE_VERSION VERSION_EQUAL
3.4.0)


# Handle REQUIRED and QUIET arguments to FIND_PACKAGE
INCLUDE
(FindPackageHandleStandardArgs)
IF
(SUITESPARSE_FOUND)
  FIND_PACKAGE_HANDLE_STANDARD_ARGS
(SuiteSparse
    REQUIRED_VARS $
{SUITESPARSE_FOUND_REQUIRED_VARS}
    VERSION_VAR SUITESPARSE_VERSION
    FAIL_MESSAGE
"Failed to find some/all required components of SuiteSparse.")
ELSE
(SUITESPARSE_FOUND)
 
# Do not pass VERSION_VAR to FindPackageHandleStandardArgs() if we failed to
 
# find SuiteSparse to avoid a confusing autogenerated failure message
 
# that states 'not found (missing: FOO) (found version: x.y.z)'.
  FIND_PACKAGE_HANDLE_STANDARD_ARGS
(SuiteSparse
    REQUIRED_VARS $
{SUITESPARSE_FOUND_REQUIRED_VARS}
    FAIL_MESSAGE
"Failed to find some/all required components of SuiteSparse.")
ENDIF
(SUITESPARSE_FOUND)

7. Open VS solution file and build Ceres.
8. Make sure to link against the following libraries in your project:

libglog.lib libgflags.lib libblas.lib liblapack.lib suitesparse.lib metis.lib ceres.lib

9. Enjoy the SPARSE_SCHUR solver on Windows (just forget about the Windows part ;-))

Johannes

Johannes Schönberger

unread,
Jan 12, 2014, 5:13:38 PM1/12/14
to ceres-...@googlegroups.com
Forgot about this one: Make sure to grab the curren SuiteSparse 4.2.1 and Metis Libraries 5.1.0.

Sameer Agarwal

unread,
Jan 12, 2014, 5:53:45 PM1/12/14
to ceres-...@googlegroups.com
Johannes,

Thank for sharing instructions. Have you considered sending this patch to Prof. Tim Davis, the author of SuiteSparse?

Sameer


On Sun Jan 12 2014 at 2:13:42 PM, Johannes Schönberger <js...@demuc.de> wrote:
Forgot about this one: Make sure to grab the curren SuiteSparse 4.2.1 and Metis Libraries 5.1.0.

--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/BBDF3401-AA81-41EA-BD60-E0B28D79FC6D%40demuc.de.
For more options, visit https://groups.google.com/groups/opt_out.

Johannes Schönberger

unread,
Jan 12, 2014, 6:01:57 PM1/12/14
to ceres-...@googlegroups.com
Good idea, I'll send him the patch!

On Jan 12, 2014, at 17:53, Sameer Agarwal <sandwi...@gmail.com> wrote:

> Johannes,
>
> Thank for sharing instructions. Have you considered sending this patch to Prof. Tim Davis, the author of SuiteSparse?
>
> Sameer
>
>
> On Sun Jan 12 2014 at 2:13:42 PM, Johannes Schönberger <js...@demuc.de> wrote:
> Forgot about this one: Make sure to grab the curren SuiteSparse 4.2.1 and Metis Libraries 5.1.0.
>
> --
> You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.
> --
> You received this message because you are subscribed to a topic in the Google Groups "Ceres Solver" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/ceres-solver/WX4TZXlG87g/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to ceres-solver...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/7051104582439909411%40gmail297201516.

Sameer Agarwal

unread,
Jan 12, 2014, 6:06:01 PM1/12/14
to ceres-...@googlegroups.com
btw I am wondering if what you are doing in this patch can be achieve via a macro or a typedef for idxtype ?


On Sun Jan 12 2014 at 3:02:01 PM, Johannes Schönberger <js...@demuc.de> wrote:
Good idea, I'll send him the patch!

On Jan 12, 2014, at 17:53, Sameer Agarwal <sandwi...@gmail.com> wrote:

> Johannes,
>
> Thank for sharing instructions. Have you considered sending this patch to Prof. Tim Davis, the author of SuiteSparse?
>
> Sameer
>
>
> On Sun Jan 12 2014 at 2:13:42 PM, Johannes Schönberger <js...@demuc.de> wrote:
> Forgot about this one: Make sure to grab the curren SuiteSparse 4.2.1 and Metis Libraries 5.1.0.
>
> --
> You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver+unsubscribe@googlegroups.com.

> To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/BBDF3401-AA81-41EA-BD60-E0B28D79FC6D%40demuc.de.
> For more options, visit https://groups.google.com/groups/opt_out.
>
> --
> You received this message because you are subscribed to a topic in the Google Groups "Ceres Solver" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/ceres-solver/WX4TZXlG87g/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to ceres-solver+unsubscribe@googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/C2069752-291C-4F6D-BEF6-5CAF6E397A6A%40demuc.de.

Johannes Schönberger

unread,
Jan 12, 2014, 6:13:04 PM1/12/14
to ceres-...@googlegroups.com
The idxtype could be replaced with a typedef definitely. But there is also a non-existent function, see `METIS_ComputeVertexSeparator`.

On Jan 12, 2014, at 18:06, Sameer Agarwal <sandwi...@gmail.com> wrote:

> btw I am wondering if what you are doing in this patch can be achieve via a macro or a typedef for idxtype ?
>
> On Sun Jan 12 2014 at 3:02:01 PM, Johannes Schönberger <js...@demuc.de> wrote:
> Good idea, I'll send him the patch!
>
> On Jan 12, 2014, at 17:53, Sameer Agarwal <sandwi...@gmail.com> wrote:
>
> > Johannes,
> >
> > Thank for sharing instructions. Have you considered sending this patch to Prof. Tim Davis, the author of SuiteSparse?
> >
> > Sameer
> >
> >
> > On Sun Jan 12 2014 at 2:13:42 PM, Johannes Schönberger <js...@demuc.de> wrote:
> > Forgot about this one: Make sure to grab the curren SuiteSparse 4.2.1 and Metis Libraries 5.1.0.
> >
> > --
> > You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
> > To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.
> > To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/BBDF3401-AA81-41EA-BD60-E0B28D79FC6D%40demuc.de.
> > For more options, visit https://groups.google.com/groups/opt_out.
> >
> > --
> > You received this message because you are subscribed to a topic in the Google Groups "Ceres Solver" group.
> > To unsubscribe from this topic, visit https://groups.google.com/d/topic/ceres-solver/WX4TZXlG87g/unsubscribe.
> > To unsubscribe from this group and all its topics, send an email to ceres-solver...@googlegroups.com.
> > To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/7051104582439909411%40gmail297201516.
> > For more options, visit https://groups.google.com/groups/opt_out.
>
> --
> You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.
> --
> You received this message because you are subscribed to a topic in the Google Groups "Ceres Solver" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/ceres-solver/WX4TZXlG87g/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to ceres-solver...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/247280977431891363%40gmail297201516.

Johannes Schönberger

unread,
Jan 12, 2014, 6:20:10 PM1/12/14
to ceres-...@googlegroups.com
I am also happy to answer questions, if the instructions should not work - maybe I forgot about some detail in the list.

Keir Mierle

unread,
Jan 12, 2014, 10:30:22 PM1/12/14
to ceres-...@googlegroups.com
Hi Johannes,

In the past I tried to get SuiteSparse to work on Windows, but I gave up after awhile, so nice work! Ideally we'd get the needed patches into upstream SuiteSparse, and then include these instructions in the Ceres documentation, and make any necessary changes to the Ceres build to make this easy.

Are you willing to push this mini-project along? It would be much appreciated.

Thanks,
Keir


On Sun, Jan 12, 2014 at 3:20 PM, Johannes Schönberger <js...@demuc.de> wrote:
I am also happy to answer questions, if the instructions should not work - maybe I forgot about some detail in the list.
--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.

Johannes Schönberger

unread,
Jan 13, 2014, 6:36:59 AM1/13/14
to ceres-...@googlegroups.com
I already sent the patch to Tim Davis. Let's see if he fixes it.

I could certainly push this project, but someone with more experience
on Windows should definitely review the changes - I was more or less
forced to port my project to Windows :-)
> You received this message because you are subscribed to a topic in the
> Google Groups "Ceres Solver" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/ceres-solver/WX4TZXlG87g/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> ceres-solver...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/ceres-solver/CADpYijH1q0eVHw%2BLojJ-9sYuMi464Xs_5C4CjgMksVMiUk2eVA%40mail.gmail.com.

Johannes Schönberger

unread,
Jan 13, 2014, 8:45:11 AM1/13/14
to ceres-...@googlegroups.com
Tim Davis replied and wrote that he still uses METIS 4; but wants to
apply the patch in future. In the meanwhile we could use SuiteSparse
4.2.1 and METIS 4 for the build instructions on Windows...

Johannes Schönberger

unread,
Jan 13, 2014, 10:50:47 PM1/13/14
to ceres-...@googlegroups.com
I now precisely noted each step, see instructions below. Does it make sense to also link against CXSparse? SuiteSparseQR is not part of the Windows build, I don't know why, but it should not be too hard to create a CMakeLists.txt for it.

All examples and tests run and pass, apart from three failures in problem_test.cc.

1. Install MS Visual Studio 2013, CMake

2. Download
- gflags 2.0
- glog 0.3.3
- Eigen 3.2.0
- Ceres-Solver 1.8.0
- SuiteSparse 4.2.1
- Metis 5.1.0
- https://code.google.com/p/suitesparse-metis-for-windows/

3. Build gflags
- Open solution file
- Open "Configuration Manager"
- Add "x64" build profile ("Active Solution Manager" dropdown)
- Select "Release", "x64" mode
- Build solution

4. Build glog
- Open solution file
- Open "Configuration Manager"
- Add "x64" build profile ("Active Solution Manager" dropdown)
- Add "#include <algorithm>" to the top of "src/logging.cc"
- Select "Release", "x64" mode
- Build solution

5. Build SuiteSparse
- Unpack SuiteSparse 4.2.1 and SuiteSparse-METIS-For-Windows package
- Copy & replace SuiteSparse 4.2.1 to SuiteSparse-METIS-For-Windows folder
- Copy & replace SuiteSparse 5.1.0 to SuiteSparse-METIS-For-Windows folder
- Create "build" dir inside SuiteSparse-METIS-For-Windows folder
- Open CMake
- Select SuiteSparse-METIS-For-Windows source and new "build" folder
- Configure, select VS 12 Win64 compiler
- Remove from "metis/GKlib/gk_arch.h"

#ifdef __MSC__
/* MSC does not have rint() function */
#define rint(x) ((int)((x)+0.5))

/* MSC does not have INFINITY defined */
#ifndef INFINITY
#define INFINITY FLT_MAX
#endif
#endif

- Replace "idxtype" with "idx_t" and "METIS_NodeComputeSeparator" with "METIS_ComputeVertexSeparator" in "SuiteSparse/CHOLMOD/Partition/cholmod_metis.c"
- Open solution file in "build" folder
- Select "Release", "x64" mode
- Build solution

6. Build Ceres-Solver
- Create "build" dir
- Open CMake
- Select Ceres-Solver source and new "build" folder
- Enable "Grouped" and "Advanced" mode
- Set "EIGEN_INCLUDE_DIR" to root folder of Eigen source
- Set "GLOG_LIBRARY" to "x64/Release/libglog.lib"
- Set "GLOG_INCLUDE_DIR" to "src/windows"
- Set "GFLAGS_LIBRARY" to "x64/Release/libgflags.lib"
- Set "GFLAGS_INCLUDE_DIR" to "src/windows"
- Set "SuiteSparse" to "ON"
- Delete in "CMakeLists.txt" of Ceres-Solver, lines 213-223

IF (SUITESPARSE AND NOT LAPACK)
# If user has disabled LAPACK, but left SUITESPARSE ON, turn it OFF,
# LAPACK controls whether Ceres will be linked, directly or indirectly
# via SuiteSparse to LAPACK.
MESSAGE("-- Disabling SuiteSparse as use of LAPACK has been disabled, "
"turn ON LAPACK to enable (optional) building with SuiteSparse.")
# Retain the help string associated with the SUITESPARSE option
# when updating it to disable use of SuiteSparse.
GET_PROPERTY(HELP_STRING CACHE SUITESPARSE PROPERTY HELPSTRING)
SET(SUITESPARSE OFF CACHE BOOL "${HELP_STRING}" FORCE)
ENDIF (SUITESPARSE AND NOT LAPACK)

- Modify "cmake/FindSuiteSparse.cmake" of Ceres-Solver

- Add to the top (adapt SP_ROOT)

SET(SP_ROOT C:/path/to/SuiteSparse-METIS-For-Windows)
SET(COLAMD_INCLUDE_DIR ${SP_ROOT}/SuiteSparse/COLAMD/Include)
SET(COLAMD_LIBRARY ${SP_ROOT}/SuiteSparse/COLAMD/Include)
SET(AMD_INCLUDE_DIR ${SP_ROOT}/SuiteSparse/AMD/Include)
SET(CAMD_INCLUDE_DIR ${SP_ROOT}/SuiteSparse/CAMD/Include)
SET(CCOLAMD_INCLUDE_DIR ${SP_ROOT}/SuiteSparse/CCOLAMD/Include)
SET(CHOLMOD_INCLUDE_DIR ${SP_ROOT}/SuiteSparse/CHOLMOD/Include)
SET(SUITESPARSEQR_INCLUDE_DIR ${SP_ROOT}/SuiteSparse/SPQR/Include)
SET(SUITESPARSE_CONFIG_LIBRARY ${SP_ROOT}/build/lib/Release/suitesparse.lib)
SET(SUITESPARSE_CONFIG_INCLUDE_DIR ${SP_ROOT}/SuiteSparse/SuiteSparse_config)
SET(METIS_LIBRARY ${SP_ROOT}/build/lib/Release/metis.lib)
LIST(APPEND SUITESPARSE_LIBRARIES ${METIS_LIBRARY})

- Replace lines 172-380 with

# BLAS.
SET(BLAS_LIBRARIES ${SP_ROOT}/lapack_windows/x64/libblas.lib)
# LAPACK.
SET(LAPACK_LIBRARIES ${SP_ROOT}/lapack_windows/x64/liblapack.lib)
# AMD.
SET(AMD_FOUND TRUE)
SET(AMD_LIBRARY "")
# CAMD.
SET(CAMD_FOUND TRUE)
SET(CAMD_LIBRARY "")
# COLAMD.
SET(COLAMD_FOUND TRUE)
SET(COLAMD_LIBRARY "")
# CCOLAMD.
SET(CCOLAMD_FOUND TRUE)
SET(CCOLAMD_LIBRARY "")
# CHOLMOD.
SET(CHOLMOD_FOUND TRUE)
SET(CHOLMOD_LIBRARY "")
# SuiteSparseQR.
SET(SUITESPARSEQR_FOUND TRUE)
LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS SUITESPARSEQR_FOUND)
FIND_LIBRARY(SUITESPARSEQR_LIBRARY NAMES spqr
PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
IF (EXISTS ${SUITESPARSEQR_LIBRARY})
MESSAGE(STATUS "Found SuiteSparseQR library: ${SUITESPARSEQR_LIBRARY}")
ELSE (EXISTS ${SUITESPARSEQR_LIBRARY})
SUITESPARSE_REPORT_NOT_FOUND(
"Did not find SuiteSparseQR library (required SuiteSparse component).")
SET(SUITESPARSEQR_FOUND FALSE)
ENDIF (EXISTS ${SUITESPARSEQR_LIBRARY})
MARK_AS_ADVANCED(SUITESPARSEQR_LIBRARY)
FIND_PATH(SUITESPARSEQR_INCLUDE_DIR NAMES SuiteSparseQR.hpp
PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
IF (EXISTS ${SUITESPARSEQR_INCLUDE_DIR})
MESSAGE(STATUS "Found SuiteSparseQR header in: ${SUITESPARSEQR_INCLUDE_DIR}")
ELSE (EXISTS ${SUITESPARSEQR_INCLUDE_DIR})
SUITESPARSE_REPORT_NOT_FOUND(
"Did not find SUITESPARSEQR header (required SuiteSparse component).")
SET(SUITESPARSEQR_FOUND FALSE)
ENDIF (EXISTS ${SUITESPARSEQR_INCLUDE_DIR})
MARK_AS_ADVANCED(SUITESPARSEQR_INCLUDE_DIR)

- Open solution file in "build" folder
- Select "Release", "x64" mode
- Build solution

7. Copy "libglog.dll" and "libgflags.dll" to "build/bin/Release".

8. Run example and test executables in "build/bin/Release".

JanM

unread,
Jan 24, 2014, 2:50:29 PM1/24/14
to ceres-...@googlegroups.com

Hi Johannes,

I followed your procedure and generate ceres.lib. Then I tried run basic example in Matlab and got beck warning from solver, that SuiteParse is not included  in  compiled library.
After carefully reading of Cmake report I realized that SuiteParse actually didn't include it at all, because: missing SUITESPARSEQR_FOUND. That is because there is no SuiteParseQR library file.
How did you compile without SuiteParse without SuiteParseQR library.

PrtScr of CMake attached.
I hope that you can help me with some suggestions.

Best;
Jan

Johannes Schönberger

unread,
Feb 3, 2014, 7:10:03 PM2/3/14
to ceres-...@googlegroups.com
Jan,

Did you successfully build Ceres itself?

JanM

unread,
Feb 11, 2014, 3:52:48 PM2/11/14
to ceres-...@googlegroups.com
Hi Johannes,

I'm using CXSparse for now. It works fast enough to get results back in ~10 seconds. However, please post here if you find any updates about installing SuitSparse

Best;
Jan.

Andreas Franek

unread,
Feb 21, 2014, 10:10:32 AM2/21/14
to ceres-...@googlegroups.com
Hi guys,
I wrote a cmake script, that will automatically download and link together SuiteSparse(with Metis), Eigen and Ceres on probably any platform.
I tested it on linux and windows(vc90).
Hope it helps someone.
The libraries are all put into install/ within the build directory. I want to create a Find* script that will guide other cmake build systems to the include and lib directories, too.

Happy coding
andy
...

Johannes Schönberger

unread,
Feb 21, 2014, 10:14:14 AM2/21/14
to ceres-...@googlegroups.com
Hi Andreas,

That's great news! So, Ceres also supports the Schur solver with this build?

Thanks, Johannes
> --
> You received this message because you are subscribed to a topic in the Google Groups "Ceres Solver" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/ceres-solver/WX4TZXlG87g/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to ceres-solver...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/d9521ae9-6a5d-4335-8bc3-0ac13619a728%40googlegroups.com.

Andreas Franek

unread,
Feb 21, 2014, 10:18:32 AM2/21/14
to ceres-...@googlegroups.com
Actually I have not tried it yet, I am using a hand compiled version on my system still, but it should.
But I will test it in the next days on windows.
However, one thing I am still working on is glog and gflags, the cmake script does not include them yet.

Andreas Franek

unread,
Feb 21, 2014, 10:20:37 AM2/21/14
to ceres-...@googlegroups.com
I just looked at the lib I compiled as a test on my linux system and nm shows, that iterative_schur_complement_solver.cc was compiled into the lib. :-)

Johannes Schönberger

unread,
Feb 21, 2014, 10:28:06 AM2/21/14
to ceres-...@googlegroups.com
I'll try it with VS 2010 later this day and post about the results.

When do you plan to integrate the glog and gflags part?
> To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/eba92c53-b51e-41a9-9c56-26987e81b34c%40googlegroups.com.

Andreas Franek

unread,
Feb 21, 2014, 12:10:02 PM2/21/14
to ceres-...@googlegroups.com
Well, actually you can simply add gflags and glog to the build system by hand.
Since they are no CMake projects, it is a little harder to integrate for me, to integrate them into this cross-platform build system.
But who knows, maybe with the tips you have given here, I can do it rather quick :-)

Pablo Speciale

unread,
Feb 21, 2014, 12:17:16 PM2/21/14
to ceres-solver

On Fri, Feb 21, 2014 at 2:10 PM, Andreas Franek <itfr...@gmail.com> wrote:
Well, actually you can simply add gflags and glog to the build system by hand.
Since they are no CMake projects, it is a little harder to integrate for me, to integrate them into this cross-platform build system.

gflags is migrating to cmake. See in the news:

"The migration of the build system to CMake is almost complete. What remains to be done is rewriting the tests in Python such they can be executed on non-Unix platforms and splitting them up into separate CTest tests. Though merging these changes into the master branch yet remains to be done, it is recommended to already start using the cmake-migration branch."

Andreas Franek

unread,
Feb 21, 2014, 12:24:50 PM2/21/14
to ceres-...@googlegroups.com
Cool, this makes it simple.

Johannes Schönberger

unread,
Mar 14, 2014, 9:17:41 PM3/14/14
to ceres-...@googlegroups.com
Hi Andreas,

Any update on adding glog, gflags?
-       Mi    = <span style="color: #6
...

Andreas Franek

unread,
Mar 15, 2014, 5:37:54 AM3/15/14
to ceres-...@googlegroups.com
Gflags works, but not with the stable version of ceres...

/home/andreas/dev/bfsCeres/build/thirdparty/ceres-prefix/src/ceres/internal/ceres/gmock_main.cc: In function ‘int main(int, char**)’:
/home/andreas/dev/bfsCeres/build/thirdparty/ceres-prefix/src/ceres/internal/ceres/gmock_main.cc:66:3: error: ‘ParseCommandLineFlags’ is not a member of ‘google’
   google::ParseCommandLineFlags(&argc, &argv, true);
   ^
/home/andreas/dev/bfsCeres/build/thirdparty/ceres-prefix/src/ceres/internal/ceres/gmock_main.cc:66:3: note: suggested alternative:
In file included from /home/andreas/dev/bfsCeres/build/thirdparty/ceres-prefix/src/ceres/internal/ceres/gmock_main.cc:33:0:
/home/andreas/dev/bfsCeres/build/install/include/gflags/gflags.h:353:15: note:   ‘gflags::ParseCommandLineFlags’
 extern uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);

So there are two options now:
1. switch to getting ceres from git entirely
2. offer an optional 'unstable'-mode featuring ceres from git and gflags
I am leaning towards the first option, considering that the last stable ceres release is from November 2012
What would you guys say?
...

Johannes Schönberger

unread,
Mar 15, 2014, 7:41:07 AM3/15/14
to <ceres-solver@googlegroups.com>
I am using the dev version anyway, so option 1 works for me. 
--
You received this message because you are subscribed to a topic in the Google Groups "Ceres Solver" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ceres-solver/WX4TZXlG87g/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ceres-solver...@googlegroups.com.

Andreas Franek

unread,
Mar 15, 2014, 8:28:04 AM3/15/14
to ceres-...@googlegroups.com
Well, I looked at the ceres repository and it will not work with that either.
I could create a patch for ceres and push it, would that make sense?
It is not too much, but I am not sure if it would make sense, since it would not work with the currently existing gflags packages.
...
Message has been deleted

Andreas Franek

unread,
Mar 15, 2014, 11:51:04 AM3/15/14
to ceres-...@googlegroups.com
Ok, I filed a change in ceres, let me know, what you think.

Sameer Agarwal

unread,
Mar 15, 2014, 12:18:32 PM3/15/14
to ceres-...@googlegroups.com
Andreas,
Thanks for the patch. The current stable version of gflags I believe is still using the google namespace. I will look into this shortly.
Sameer



--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/3cb87344-08aa-4808-b81b-9e420424476c%40googlegroups.com.

Andreas Franek

unread,
Mar 16, 2014, 3:04:09 AM3/16/14
to ceres-...@googlegroups.com
Yes, it does, that was what I meant.
However the patch makes it possible to use either version.

Andreas Franek

unread,
Mar 17, 2014, 5:28:43 PM3/17/14
to ceres-...@googlegroups.com
I have started a branch that compiles ceres with gflags and glog.
On linux it works already, I will try to get it to work on windows tomorrow.

Johannes Schoenberger

unread,
Mar 21, 2014, 9:17:06 AM3/21/14
to ceres-...@googlegroups.com
So, I tested your branch and it fails:

Error 1 error : The source directory "C:/Users/jsch/Development/ceres-solver-1.8.0/build/thirdparty/glog-prefix/src/glog" does not appear to contain CMakeLists.txt. C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\CUSTOMBUILD glog
Error 59 error LNK1181: cannot open input file '..\..\lib\Release\SuiteSparse_config.lib' C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\8>LINK sscmake
Error 60 error LNK1181: cannot open input file '..\..\lib\Release\SuiteSparse_config.lib' C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\7>LINK sscmake
Error 71 error LNK1181: cannot open input file '..\..\lib\Release\SuiteSparse_config.lib' C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\6>LINK sscmake
Error 78 error LNK1181: cannot open input file '..\..\lib\Release\SuiteSparse_config.lib' C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\9>LINK sscmake
Error 150 error LNK1181: cannot open input file '..\..\lib\Release\SuiteSparse_config.lib' C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\4>LINK sscmake
Error 162 error LNK1181: cannot open input file '..\..\lib\Release\SuiteSparse_config.lib' C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\5>LINK sscmake
Error 450 error LNK2019: unresolved external symbol gk_free referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>graphchk.obj sscmake
Error 462 error LNK2001: unresolved external symbol gk_free C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>io.obj sscmake
Error 463 error LNK2019: unresolved external symbol gk_strdup referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>graphchk.obj sscmake
Error 464 error LNK2019: unresolved external symbol libmetis__CheckGraph referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>graphchk.obj sscmake
Error 465 error LNK2019: unresolved external symbol libmetis__FixGraph referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>graphchk.obj sscmake
Error 466 error LNK2019: unresolved external symbol libmetis__FreeGraph referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>graphchk.obj sscmake
Error 467 error LNK2019: unresolved external symbol gk_fopen referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>io.obj sscmake
Error 472 error LNK2019: unresolved external symbol gk_fclose referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>io.obj sscmake
Error 473 error LNK2019: unresolved external symbol gk_getline referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>io.obj sscmake
Error 474 error LNK2019: unresolved external symbol gk_fexists referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>io.obj sscmake
Error 475 error LNK2019: unresolved external symbol gk_getfilestats referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>io.obj sscmake
Error 476 error LNK2019: unresolved external symbol errexit referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>io.obj sscmake
Error 477 error LNK2019: unresolved external symbol gk_strchr_replace referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>io.obj sscmake
Error 478 error LNK2019: unresolved external symbol libmetis__imax referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>io.obj sscmake
Error 479 error LNK2019: unresolved external symbol libmetis__rscale referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>io.obj sscmake
Error 480 error LNK2019: unresolved external symbol libmetis__imalloc referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>io.obj sscmake
Error 481 error LNK2019: unresolved external symbol libmetis__ismalloc referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>io.obj sscmake
Error 482 error LNK2019: unresolved external symbol libmetis__rsmalloc referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>io.obj sscmake
Error 483 error LNK2019: unresolved external symbol libmetis__CreateGraph referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>io.obj sscmake
Error 484 error LNK2019: unresolved external symbol libmetis__CreateMesh referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>io.obj sscmake
Error 485 error LNK1120: 19 unresolved externals C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\14>C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\sscmake-prefix\src\sscmake-build\bin\Release\graphchk.exe sscmake
Error 489 error LNK2019: unresolved external symbol gk_strdup referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>cmpfillin.obj sscmake
Error 490 error LNK2019: unresolved external symbol libmetis__imalloc referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>cmpfillin.obj sscmake
Error 491 error LNK2001: unresolved external symbol libmetis__imalloc C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>io.obj sscmake
Error 492 error LNK2001: unresolved external symbol libmetis__imalloc C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>smbfactor.obj sscmake
Error 493 error LNK2019: unresolved external symbol libmetis__FreeGraph referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>cmpfillin.obj sscmake
Error 494 error LNK2019: unresolved external symbol gk_fopen referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>io.obj sscmake
Error 495 error LNK2019: unresolved external symbol gk_fclose referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>io.obj sscmake
Error 496 error LNK2019: unresolved external symbol gk_getline referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>io.obj sscmake
Error 497 error LNK2019: unresolved external symbol gk_fexists referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>io.obj sscmake
Error 498 error LNK2019: unresolved external symbol gk_getfilestats referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>io.obj sscmake
Error 499 error LNK2019: unresolved external symbol gk_free referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>io.obj sscmake
Error 500 error LNK2001: unresolved external symbol gk_free C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>smbfactor.obj sscmake
Error 501 error LNK2019: unresolved external symbol errexit referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>io.obj sscmake
Error 502 error LNK2001: unresolved external symbol errexit C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>smbfactor.obj sscmake
Error 503 error LNK2019: unresolved external symbol gk_strchr_replace referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>io.obj sscmake
Error 504 error LNK2019: unresolved external symbol libmetis__imax referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>io.obj sscmake
Error 505 error LNK2019: unresolved external symbol libmetis__rscale referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>io.obj sscmake
Error 506 error LNK2019: unresolved external symbol libmetis__ismalloc referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>io.obj sscmake
Error 507 error LNK2001: unresolved external symbol libmetis__ismalloc C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>smbfactor.obj sscmake
Error 508 error LNK2019: unresolved external symbol libmetis__rsmalloc referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>io.obj sscmake
Error 509 error LNK2019: unresolved external symbol libmetis__CreateGraph referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>io.obj sscmake
Error 510 error LNK2019: unresolved external symbol libmetis__CreateMesh referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>io.obj sscmake
Error 511 error LNK1120: 17 unresolved externals C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\12>C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\sscmake-prefix\src\sscmake-build\bin\Release\cmpfillin.exe sscmake
Error 512 error LNK2019: unresolved external symbol gk_malloc_init referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>m2gmetis.obj sscmake
Error 513 error LNK2019: unresolved external symbol gk_malloc_cleanup referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>m2gmetis.obj sscmake
Error 514 error LNK2019: unresolved external symbol gk_free referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>m2gmetis.obj sscmake
Error 515 error LNK2001: unresolved external symbol gk_free C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>io.obj sscmake
Error 516 error LNK2019: unresolved external symbol gk_GetCurMemoryUsed referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>m2gmetis.obj sscmake
Error 517 error LNK2019: unresolved external symbol gk_GetMaxMemoryUsed referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>m2gmetis.obj sscmake
Error 518 error LNK2019: unresolved external symbol gk_CPUSeconds referenced in function M2GReportResults C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>m2gmetis.obj sscmake
Error 519 error LNK2019: unresolved external symbol libmetis__CreateGraph referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>m2gmetis.obj sscmake
Error 520 error LNK2001: unresolved external symbol libmetis__CreateGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>io.obj sscmake
Error 521 error LNK2019: unresolved external symbol libmetis__FreeGraph referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>m2gmetis.obj sscmake
Error 522 error LNK2019: unresolved external symbol libmetis__FreeMesh referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>m2gmetis.obj sscmake
Error 523 error LNK2019: unresolved external symbol gk_getopt_long_only referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>cmdline_m2gmetis.obj sscmake
Error 524 error LNK2019: unresolved external symbol gk_malloc referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>cmdline_m2gmetis.obj sscmake
Error 525 error LNK2019: unresolved external symbol errexit referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>cmdline_m2gmetis.obj sscmake
Error 526 error LNK2001: unresolved external symbol errexit C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>io.obj sscmake
Error 527 error LNK2019: unresolved external symbol gk_strdup referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>cmdline_m2gmetis.obj sscmake
Error 528 error LNK2019: unresolved external symbol gk_GetStringID referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>cmdline_m2gmetis.obj sscmake
Error 529 error LNK2019: unresolved external symbol gk_optarg referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>cmdline_m2gmetis.obj sscmake
Error 530 error LNK2019: unresolved external symbol gk_optind referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>cmdline_m2gmetis.obj sscmake
Error 531 error LNK2019: unresolved external symbol gk_fopen referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>io.obj sscmake
Error 532 error LNK2019: unresolved external symbol gk_fclose referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>io.obj sscmake
Error 533 error LNK2019: unresolved external symbol gk_getline referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>io.obj sscmake
Error 534 error LNK2019: unresolved external symbol gk_fexists referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>io.obj sscmake
Error 535 error LNK2019: unresolved external symbol gk_getfilestats referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>io.obj sscmake
Error 536 error LNK2019: unresolved external symbol gk_strchr_replace referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>io.obj sscmake
Error 537 error LNK2019: unresolved external symbol libmetis__imax referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>io.obj sscmake
Error 538 error LNK2019: unresolved external symbol libmetis__rscale referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>io.obj sscmake
Error 539 error LNK2019: unresolved external symbol libmetis__imalloc referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>io.obj sscmake
Error 540 error LNK2019: unresolved external symbol libmetis__ismalloc referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>io.obj sscmake
Error 541 error LNK2019: unresolved external symbol libmetis__rsmalloc referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>io.obj sscmake
Error 542 error LNK2019: unresolved external symbol libmetis__CreateMesh referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>io.obj sscmake
Error 543 error LNK1120: 28 unresolved externals C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\15>C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\sscmake-prefix\src\sscmake-build\bin\Release\m2gmetis.exe sscmake
Error 598 error LNK2019: unresolved external symbol gk_malloc_init referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>gpmetis.obj sscmake
Error 600 error LNK2019: unresolved external symbol gk_malloc_cleanup referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>gpmetis.obj sscmake
Error 601 error LNK2019: unresolved external symbol gk_free referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>gpmetis.obj sscmake
Error 602 error LNK2001: unresolved external symbol gk_free C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>io.obj sscmake
Error 603 error LNK2001: unresolved external symbol gk_free C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>stat.obj sscmake
Error 607 error LNK2019: unresolved external symbol gk_GetCurMemoryUsed referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>gpmetis.obj sscmake
Error 608 error LNK2019: unresolved external symbol gk_GetMaxMemoryUsed referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>gpmetis.obj sscmake
Error 609 error LNK2019: unresolved external symbol errexit referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>gpmetis.obj sscmake
Error 610 error LNK2001: unresolved external symbol errexit C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>cmdline_gpmetis.obj sscmake
Error 611 error LNK2001: unresolved external symbol errexit C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>io.obj sscmake
Error 612 error LNK2019: unresolved external symbol gk_CPUSeconds referenced in function GPReportResults C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>gpmetis.obj sscmake
Error 613 error LNK2019: unresolved external symbol libmetis__imalloc referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>gpmetis.obj sscmake
Error 614 error LNK2001: unresolved external symbol libmetis__imalloc C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>io.obj sscmake
Error 615 error LNK2001: unresolved external symbol libmetis__imalloc C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>stat.obj sscmake
Error 616 error LNK2019: unresolved external symbol libmetis__rmalloc referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>gpmetis.obj sscmake
Error 617 error LNK2019: unresolved external symbol libmetis__IsConnected referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>gpmetis.obj sscmake
Error 618 error LNK2001: unresolved external symbol libmetis__IsConnected C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>stat.obj sscmake
Error 619 error LNK2019: unresolved external symbol libmetis__FreeGraph referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>gpmetis.obj sscmake
Error 620 error LNK2019: unresolved external symbol gk_getopt_long_only referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>cmdline_gpmetis.obj sscmake
Error 621 error LNK2019: unresolved external symbol gk_malloc referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>cmdline_gpmetis.obj sscmake
Error 622 error LNK2019: unresolved external symbol gk_strdup referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>cmdline_gpmetis.obj sscmake
Error 623 error LNK2019: unresolved external symbol gk_GetStringID referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>cmdline_gpmetis.obj sscmake
Error 624 error LNK2019: unresolved external symbol gk_optarg referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>cmdline_gpmetis.obj sscmake
Error 625 error LNK2019: unresolved external symbol gk_optind referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>cmdline_gpmetis.obj sscmake
Error 626 error LNK2019: unresolved external symbol gk_fopen referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>io.obj sscmake
Error 627 error LNK2019: unresolved external symbol gk_fclose referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>io.obj sscmake
Error 628 error LNK2019: unresolved external symbol gk_getline referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>io.obj sscmake
Error 629 error LNK2019: unresolved external symbol gk_fexists referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>io.obj sscmake
Error 630 error LNK2019: unresolved external symbol gk_getfilestats referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>io.obj sscmake
Error 631 error LNK2019: unresolved external symbol gk_strchr_replace referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>io.obj sscmake
Error 632 error LNK2019: unresolved external symbol libmetis__imax referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>io.obj sscmake
Error 633 error LNK2001: unresolved external symbol libmetis__imax C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>stat.obj sscmake
Error 634 error LNK2019: unresolved external symbol libmetis__rscale referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>io.obj sscmake
Error 635 error LNK2019: unresolved external symbol libmetis__ismalloc referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>io.obj sscmake
Error 636 error LNK2001: unresolved external symbol libmetis__ismalloc C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>stat.obj sscmake
Error 637 error LNK2019: unresolved external symbol libmetis__rsmalloc referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>io.obj sscmake
Error 638 error LNK2019: unresolved external symbol libmetis__CreateGraph referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>io.obj sscmake
Error 639 error LNK2019: unresolved external symbol libmetis__CreateMesh referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>io.obj sscmake
Error 640 error LNK2019: unresolved external symbol libmetis__iargmax referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>stat.obj sscmake
Error 641 error LNK2019: unresolved external symbol libmetis__isum referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>stat.obj sscmake
Error 642 error LNK2019: unresolved external symbol libmetis__iset referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>stat.obj sscmake
Error 643 error LNK2019: unresolved external symbol libmetis__iarray2csr referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>stat.obj sscmake
Error 644 error LNK2019: unresolved external symbol libmetis__FindPartitionInducedComponents referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>stat.obj sscmake
Error 645 error LNK2019: unresolved external symbol libmetis__ComputeCut referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>stat.obj sscmake
Error 646 error LNK2019: unresolved external symbol libmetis__ComputeVolume referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>stat.obj sscmake
Error 647 error LNK2019: unresolved external symbol libmetis__iargmax_strd referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>stat.obj sscmake
Error 648 error LNK1120: 37 unresolved externals C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\13>C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\sscmake-prefix\src\sscmake-build\bin\Release\gpmetis.exe sscmake
Error 738 error LNK2019: unresolved external symbol gk_malloc_init referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>ndmetis.obj sscmake
Error 739 error LNK2019: unresolved external symbol gk_malloc_cleanup referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>ndmetis.obj sscmake
Error 740 error LNK2019: unresolved external symbol gk_free referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>ndmetis.obj sscmake
Error 741 error LNK2001: unresolved external symbol gk_free C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>io.obj sscmake
Error 742 error LNK2001: unresolved external symbol gk_free C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>smbfactor.obj sscmake
Error 743 error LNK2019: unresolved external symbol gk_GetCurMemoryUsed referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>ndmetis.obj sscmake
Error 744 error LNK2019: unresolved external symbol gk_GetMaxMemoryUsed referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>ndmetis.obj sscmake
Error 745 error LNK2019: unresolved external symbol gk_CPUSeconds referenced in function NDReportResults C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>ndmetis.obj sscmake
Error 746 error LNK2019: unresolved external symbol libmetis__imalloc referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>ndmetis.obj sscmake
Error 747 error LNK2001: unresolved external symbol libmetis__imalloc C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>io.obj sscmake
Error 748 error LNK2001: unresolved external symbol libmetis__imalloc C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>smbfactor.obj sscmake
Error 749 error LNK2019: unresolved external symbol libmetis__FreeGraph referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>ndmetis.obj sscmake
Error 750 error LNK2019: unresolved external symbol gk_getopt_long_only referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>cmdline_ndmetis.obj sscmake
Error 751 error LNK2019: unresolved external symbol gk_malloc referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>cmdline_ndmetis.obj sscmake
Error 752 error LNK2019: unresolved external symbol errexit referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>cmdline_ndmetis.obj sscmake
Error 753 error LNK2001: unresolved external symbol errexit C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>io.obj sscmake
Error 754 error LNK2001: unresolved external symbol errexit C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>smbfactor.obj sscmake
Error 755 error LNK2019: unresolved external symbol gk_strdup referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>cmdline_ndmetis.obj sscmake
Error 756 error LNK2019: unresolved external symbol gk_GetStringID referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>cmdline_ndmetis.obj sscmake
Error 757 error LNK2019: unresolved external symbol gk_optarg referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>cmdline_ndmetis.obj sscmake
Error 758 error LNK2019: unresolved external symbol gk_optind referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>cmdline_ndmetis.obj sscmake
Error 759 error LNK2019: unresolved external symbol gk_fopen referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>io.obj sscmake
Error 760 error LNK2019: unresolved external symbol gk_fclose referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>io.obj sscmake
Error 761 error LNK2019: unresolved external symbol gk_getline referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>io.obj sscmake
Error 762 error LNK2019: unresolved external symbol gk_fexists referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>io.obj sscmake
Error 763 error LNK2019: unresolved external symbol gk_getfilestats referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>io.obj sscmake
Error 764 error LNK2019: unresolved external symbol gk_strchr_replace referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>io.obj sscmake
Error 765 error LNK2019: unresolved external symbol libmetis__imax referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>io.obj sscmake
Error 766 error LNK2019: unresolved external symbol libmetis__rscale referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>io.obj sscmake
Error 767 error LNK2019: unresolved external symbol libmetis__ismalloc referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>io.obj sscmake
Error 768 error LNK2001: unresolved external symbol libmetis__ismalloc C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>smbfactor.obj sscmake
Error 769 error LNK2019: unresolved external symbol libmetis__rsmalloc referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>io.obj sscmake
Error 770 error LNK2019: unresolved external symbol libmetis__CreateGraph referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>io.obj sscmake
Error 771 error LNK2019: unresolved external symbol libmetis__CreateMesh referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>io.obj sscmake
Error 772 error LNK1120: 27 unresolved externals C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\17>C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\sscmake-prefix\src\sscmake-build\bin\Release\ndmetis.exe sscmake
Error 773 error LNK2019: unresolved external symbol gk_malloc_init referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>mpmetis.obj sscmake
Error 774 error LNK2019: unresolved external symbol gk_malloc_cleanup referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>mpmetis.obj sscmake
Error 775 error LNK2019: unresolved external symbol gk_free referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>mpmetis.obj sscmake
Error 776 error LNK2001: unresolved external symbol gk_free C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>io.obj sscmake
Error 777 error LNK2001: unresolved external symbol gk_free C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>stat.obj sscmake
Error 778 error LNK2019: unresolved external symbol gk_GetCurMemoryUsed referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>mpmetis.obj sscmake
Error 779 error LNK2019: unresolved external symbol gk_GetMaxMemoryUsed referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>mpmetis.obj sscmake
Error 780 error LNK2019: unresolved external symbol gk_CPUSeconds referenced in function MPReportResults C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>mpmetis.obj sscmake
Error 781 error LNK2019: unresolved external symbol libmetis__imalloc referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>mpmetis.obj sscmake
Error 782 error LNK2001: unresolved external symbol libmetis__imalloc C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>io.obj sscmake
Error 783 error LNK2001: unresolved external symbol libmetis__imalloc C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>stat.obj sscmake
Error 784 error LNK2019: unresolved external symbol libmetis__FreeMesh referenced in function main C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>mpmetis.obj sscmake
Error 785 error LNK2019: unresolved external symbol gk_getopt_long_only referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>cmdline_mpmetis.obj sscmake
Error 786 error LNK2019: unresolved external symbol gk_malloc referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>cmdline_mpmetis.obj sscmake
Error 787 error LNK2019: unresolved external symbol errexit referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>cmdline_mpmetis.obj sscmake
Error 788 error LNK2001: unresolved external symbol errexit C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>io.obj sscmake
Error 789 error LNK2019: unresolved external symbol gk_strdup referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>cmdline_mpmetis.obj sscmake
Error 790 error LNK2019: unresolved external symbol gk_GetStringID referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>cmdline_mpmetis.obj sscmake
Error 791 error LNK2019: unresolved external symbol gk_optarg referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>cmdline_mpmetis.obj sscmake
Error 792 error LNK2019: unresolved external symbol gk_optind referenced in function parse_cmdline C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>cmdline_mpmetis.obj sscmake
Error 793 error LNK2019: unresolved external symbol gk_fopen referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>io.obj sscmake
Error 794 error LNK2019: unresolved external symbol gk_fclose referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>io.obj sscmake
Error 795 error LNK2019: unresolved external symbol gk_getline referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>io.obj sscmake
Error 796 error LNK2019: unresolved external symbol gk_fexists referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>io.obj sscmake
Error 797 error LNK2019: unresolved external symbol gk_getfilestats referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>io.obj sscmake
Error 798 error LNK2019: unresolved external symbol gk_strchr_replace referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>io.obj sscmake
Error 799 error LNK2019: unresolved external symbol libmetis__imax referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>io.obj sscmake
Error 800 error LNK2001: unresolved external symbol libmetis__imax C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>stat.obj sscmake
Error 801 error LNK2019: unresolved external symbol libmetis__rscale referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>io.obj sscmake
Error 802 error LNK2019: unresolved external symbol libmetis__ismalloc referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>io.obj sscmake
Error 803 error LNK2001: unresolved external symbol libmetis__ismalloc C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>stat.obj sscmake
Error 804 error LNK2019: unresolved external symbol libmetis__rsmalloc referenced in function ReadTPwgts C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>io.obj sscmake
Error 805 error LNK2019: unresolved external symbol libmetis__CreateGraph referenced in function ReadGraph C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>io.obj sscmake
Error 806 error LNK2019: unresolved external symbol libmetis__CreateMesh referenced in function ReadMesh C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>io.obj sscmake
Error 807 error LNK2019: unresolved external symbol libmetis__iargmax referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>stat.obj sscmake
Error 808 error LNK2019: unresolved external symbol libmetis__isum referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>stat.obj sscmake
Error 809 error LNK2019: unresolved external symbol libmetis__iset referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>stat.obj sscmake
Error 810 error LNK2019: unresolved external symbol libmetis__iarray2csr referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>stat.obj sscmake
Error 811 error LNK2019: unresolved external symbol libmetis__FindPartitionInducedComponents referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>stat.obj sscmake
Error 812 error LNK2019: unresolved external symbol libmetis__IsConnected referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>stat.obj sscmake
Error 813 error LNK2019: unresolved external symbol libmetis__ComputeCut referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>stat.obj sscmake
Error 814 error LNK2019: unresolved external symbol libmetis__ComputeVolume referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>stat.obj sscmake
Error 815 error LNK2019: unresolved external symbol libmetis__iargmax_strd referenced in function ComputePartitionInfo C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>stat.obj sscmake
Error 816 error LNK1120: 36 unresolved externals C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\16>C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\sscmake-prefix\src\sscmake-build\bin\Release\mpmetis.exe sscmake
Error 896 error LNK1181: cannot open input file '..\..\lib\Release\SuiteSparse_config.lib' C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\10>LINK sscmake
Error 1128 error LNK1181: cannot open input file '..\..\lib\Release\SuiteSparse_config.lib' C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\11>LINK sscmake
Error 1526 error LNK1181: cannot open input file '..\..\lib\Release\SuiteSparse_config.lib' C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\18>LINK sscmake
Error 1772 error LNK1181: cannot open input file '..\..\lib\Release\SuiteSparse_config.lib' C:\Users\jsch\Development\ceres-solver-1.8.0\build\thirdparty\19>LINK sscmake
Error 1773 error MSB6006: "cmd.exe" exited with code 1. C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.CppCommon.targets 172 5 ceres

Andreas Franek

unread,
Mar 24, 2014, 6:49:11 AM3/24/14
to ceres-...@googlegroups.com
Yeah, I am stalling a bit with glog right now.
I cannot compile glog automatically from cmake on windows, so I am thinking about writing cmake files for it or precompiling them.
I am leaning toward writing cmake files for it, but there are also other problems on the plate.
1. writing a cmake config file, that can be loaded and that defines everything necessary to include ceres in your project (similar to opencv or boost)
2. getting suitesparse-cmake to accept other lapack libs
...

Andreas Franek

unread,
Mar 28, 2014, 9:59:06 AM3/28/14
to ceres-...@googlegroups.com
Ok, I just saw, that ceres already generates a CeresConfig.cmake.
This together with the SuiteSparseConfig.cmake already fulfills my first point, awkward :)
I created an issue for the second point on the SuiteSparse-cmake repo page, but did not get a reply as of yet.
So I guess I will try to write a cmake script for glog on windows.

Sameer Agarwal

unread,
Mar 28, 2014, 10:00:56 AM3/28/14
to ceres-...@googlegroups.com
BTW last week gflag just switched to using cmake as its build system. 
Sameer



--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.

Arturo Flores

unread,
May 3, 2016, 6:40:42 PM5/3/16
to Ceres Solver
Are the steps listed in this thread still valid for building Ceres on Windows?  I am having trouble getting CMake to find suitesparse/lapack/blas.  

hwdo...@gmail.com

unread,
Apr 18, 2017, 6:08:27 AM4/18/17
to Ceres Solver
I tried the above step .but not work.

arrigo

unread,
Apr 18, 2017, 1:23:29 PM4/18/17
to Ceres Solver

I had to manually add to the CMake GUI several entries and go trough several "configure" and "Generate" cycles to make it work. I am pasting my CMake entries above from the last time I built Ceres so you can try them.
-    idxtype *Mp, *Mi, *Mnw, *Mew, *Mpart ;
+    idx_t *Mp, *Mi, *Mnw, *Mew, *Mpart ;
     
Int n, nleft, nright, j, p, csep, total_weight, lightest, nz ;
     
int Opt [8], nn, csp ;
     size_t n1
;
@@ -260,7 +260,7 @@
     
/* ---------------------------------------------------------------------- */
 
 
#ifdef LONG
-    if (sizeof (Int) > sizeof (idxtype) && MAX (n,nz) > INT_MAX / sizeof (int))
+    if (sizeof (Int) > sizeof (idx_t) && MAX (n,nz) > INT_MAX / sizeof (int))
     
{

       
/* CHOLMOD's matrix is too large for METIS */
       
return (EMPTY) ;
@@ -283,34 +283,34 @@
     DEBUG
(for (j = 0 ; j < n ; j++) ASSERT (Anw [j] > 0)) ;
 
     
/* ---------------------------------------------------------------------- */
-    /* copy Int to METIS idxtype, if necessary */
+    /* copy Int to METIS idx_t, if necessary */
     
/* ---------------------------------------------------------------------- */
 
     DEBUG
(for (j = 0 ; j < nz ; j++) ASSERT (Aew [j] > 0)) ;
-    if (sizeof (Int) == sizeof (idxtype))
+    if (sizeof (Int) == sizeof (idx_t))
     
{
       
/* this is the typical case */
-       if (sizeof (Int) != sizeof (idxtype))

+       if (sizeof (Int) != sizeof (idx_t))
       
{
-           CHOLMOD(free) (nz, sizeof (idxtype), Mi,    Common) ;
-           CHOLMOD(free) (nz, sizeof (idxtype), Mew,   Common) ;
-           CHOLMOD(free) (n1, sizeof (idxtype), Mp,    Common) ;
-           CHOLMOD(free) (n,  sizeof (idxtype), Mnw,   Common) ;
-           CHOLMOD(free) (n,  sizeof (idxtype), Mpart, Common) ;
+           CHOLMOD(free) (nz, sizeof (idx_t), Mi,    Common) ;
+           CHOLMOD(free) (nz, sizeof (idx_t), Mew,   Common) ;
+           CHOLMOD(free) (n1, sizeof (idx_t), Mp,    Common) ;
+           CHOLMOD(free) (n,  sizeof (idx_t), Mnw,   Common) ;
+           CHOLMOD(free) (n,  sizeof (idx_t), Mpart, Common) ;
       
}
       
return (EMPTY) ;
     
}
@@ -370,27 +370,27 @@
 
#endif
 
     nn
= n ;
-    METIS_NodeComputeSeparator (&nn, Mp, Mi, Mnw, Mew, Opt, &csp, Mpart) ;
+    METIS_ComputeVertexSeparator (&nn, Mp, Mi, Mnw, Opt, &csp, Mpart) ;
     n
= nn ;
     csep
= csp ;
 
     PRINT1
(("METIS csep "ID"\n", csep)) ;
 
     
/* ---------------------------------------------------------------------- */
-    /* copy the results back from idxtype, if required */
+    /* copy the results back from idx_t, if required */
     
/* ---------------------------------------------------------------------- */
 
-    if (sizeof (Int) != sizeof (idxtype))
+    if (sizeof (Int) != sizeof (idx_t))
     
{

       
for (j = 0 ; j < n ; j++)

       
{
           
Partition [j] = Mpart [j] ;

       
}
-       CHOLMOD(free) (nz, sizeof (idxtype), Mi,    Common) ;
-       CHOLMOD(free) (nz, sizeof (idxtype), Mew,   Common) ;
-       CHOLMOD(free) (n1, sizeof (idxtype), Mp,    Common) ;
-       CHOLMOD(free) (n,  sizeof (idxtype), Mnw,   Common) ;
-       CHOLMOD(free) (n,  sizeof (idxtype), Mpart, Common) ;
+       CHOLMOD(free) (nz, sizeof (idx_t), Mi,    Common) ;
+       CHOLMOD(free) (nz, sizeof (idx_t), Mew,   Common) ;
+       CHOLMOD(free) (n1, sizeof (idx_t), Mp,    Common) ;
+       CHOLMOD(free) (n,  sizeof (idx_t), Mnw,   Common) ;
+       CHOLMOD(free) (n,  sizeof (idx_t), Mpart, Common) ;
     
}

 
     
/* ---------------------------------------------------------------------- */
@@ -508,7 +508,7 @@
 
{
     
double d ;
     
Int *Iperm, *Iwork, *Bp, *Bi ;
-    idxtype *Mp, *Mi, *Mperm, *Miperm ;
+    idx_t *Mp, *Mi, *Mperm, *Miperm ;
     cholmod_sparse
*B ;
     
Int i, j, n, nz, p, identity, uncol ;
     
int Opt [8], nn, zero = 0 ;
@@ -601,7 +601,7 @@

     
/* ---------------------------------------------------------------------- */
 
 
#ifdef LONG
-    if (sizeof (Int) > sizeof (idxtype) && MAX (n,nz) > INT_MAX / sizeof (int))
+    if (sizeof (Int) > sizeof (idx_t) && MAX (n,nz) > INT_MAX / sizeof (int))
     
{

       
/* CHOLMOD's matrix is too large for METIS */

        CHOLMOD
(free_sparse) (&B, Common) ;
@@ -630,29 +630,29 @@
     
/* allocate the METIS input arrays, if needed */
     
/* ---------------------------------------------------------------------- */

 
-    if (sizeof (Int) == sizeof (idxtype))
+    if (sizeof (Int) == sizeof (idx_t))
     
{

       
/* This is the typical case. */
-       Miperm = (idxtype *) Iperm ;
-       Mperm  = (idxtype *) Perm ;
-       Mp     = (idxtype *) Bp ;
-       Mi     = (idxtype *) Bi ;
+       Miperm = (idx_t *) Iperm ;
+       Mperm  = (idx_t *) Perm ;
+       Mp     = (idx_t *) Bp ;
+       Mi     = (idx_t *) Bi ;
     
}
     
else
     
{
-       /* allocate graph for METIS only if Int and idxtype differ */
-       Miperm = CHOLMOD(malloc) (n,  sizeof (idxtype), Common) ;
-       Mperm  = CHOLMOD(malloc) (n,  sizeof (idxtype), Common) ;

-       Mp     = CHOLMOD(malloc) (n1, sizeof (idxtype), Common) ;
-       Mi     = CHOLMOD(malloc) (nz, sizeof (idxtype), Common) ;
+       /* allocate graph for METIS only if Int and idx_t differ */
+       Miperm = CHOLMOD(malloc) (n,  sizeof (idx_t), Common) ;
+       Mperm  = CHOLMOD(malloc) (n,  sizeof (idx_t), Common) ;

+       Mp     = CHOLMOD(malloc) (n1, sizeof (idx_t), Common) ;
+       Mi     = CHOLMOD(malloc) (nz, sizeof (idx_t), Common) ;

       
if (Common->status < CHOLMOD_OK)
       
{
           
/* out of memory */
            CHOLMOD
(free_sparse) (&B, Common) ;
-           CHOLMOD(free) (n,  sizeof (idxtype), Miperm, Common) ;
-           CHOLMOD(free) (n,  sizeof (idxtype), Mperm, Common) ;

-           CHOLMOD(free) (n1, sizeof (idxtype), Mp, Common) ;
-           CHOLMOD(free) (nz, sizeof (idxtype), Mi, Common) ;
+           CHOLMOD(free) (n,  sizeof (idx_t), Miperm, Common) ;
+           CHOLMOD(free) (n,  sizeof (idx_t), Mperm, Common) ;

+           CHOLMOD(free) (n1, sizeof (idx_t), Mp, Common) ;
+           CHOLMOD(free) (nz, sizeof (idx_t), Mi, Common) ;

           
return (FALSE) ;
       
}
       
for (j = 0 ; j <= n ; j++)
@@ -741,16 +741,16 @@
     
/* free the METIS input arrays */
     
/* ---------------------------------------------------------------------- */
 
-    if (sizeof (Int) != sizeof (idxtype))
+    if (sizeof (Int) != sizeof (idx_t))
     
{
       
for (i = 0 ; i < n ; i++)
       
{
           
Perm [i] = (Int) (Mperm [i]) ;
       
}
-       CHOLMOD(free) (n,   sizeof (idxtype), Miperm, Common) ;
-       CHOLMOD(free) (n,   sizeof (idxtype), Mperm, Common) ;
-       CHOLMOD(free) (n+1, sizeof (idxtype), Mp, Common) ;

-       CHOLMOD(free) (nz,  sizeof (idxtype), Mi, Common) ;
+       CHOLMOD(free) (n,   sizeof (idx_t), Miperm, Common) ;
+       CHOLMOD(free) (n,   sizeof (idx_t), Mperm, Common) ;
+       CHOLMOD(free) (n+1, sizeof (idx_t), Mp, Common) ;

+       CHOLMOD(free) (nz,  sizeof (idx_t), Mi, Common) ;
     
}

 
     CHOLMOD
(free_sparse) (&B, Common) ;
Only in .: metis.patch



3. Download Eigen.
4. Download Ceres 1.8.0.
5. Adapt the CMakeLists.txt in Ceres:

# Ceres Solver - A fast non-linear least squares minimizer
# Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
#
# 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: ke...@google.com (Keir Mierle)

CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)
CMAKE_POLICY(VERSION 2.8)

IF (COMMAND cmake_policy)
  CMAKE_POLICY(SET CMP0003 NEW)
ENDIF (COMMAND cmake_policy)

PROJECT(CERES C CXX)

# Set up the git hook to make Gerrit Change-Id: lines in commit messages.
SET (LOCAL_GIT_DIRECTORY)
IF (EXISTS ${CMAKE_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 (EXISTS ${CMAKE_SOURCE_DIR}/.git)
  # TODO(keir) Add proper Windows support
ENDIF (EXISTS ${CMAKE_SOURCE_DIR}/.git)

IF (EXISTS ${LOCAL_GIT_DIRECTORY})
  IF (NOT EXISTS ${LOCAL_GIT_DIRECTORY}/hooks/commit-msg)
    # Download the hook only if it is not already present
         ${CMAKE_BINARY_DIR}/commit-msg)

    # Make the downloaded file executable, since it is not by default.
    FILE(COPY ${CMAKE_BINARY_DIR}/commit-msg
         DESTINATION ${LOCAL_GIT_DIRECTORY}/hooks/
         FILE_PERMISSIONS
           OWNER_READ OWNER_WRITE OWNER_EXECUTE
           GROUP_READ GROUP_WRITE GROUP_EXECUTE
           WORLD_READ WORLD_EXECUTE)
  ENDIF (NOT EXISTS ${LOCAL_GIT_DIRECTORY}/hooks/commit-msg)
ENDIF (EXISTS ${LOCAL_GIT_DIRECTORY})

# Make CMake aware of the cmake folder for local FindXXX scripts.
SET (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")

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 postfixes for generated libraries based on buildtype.
SET(CMAKE_RELEASE_POSTFIX "")
SET(CMAKE_DEBUG_POSTFIX "-debug")

# Important: Always bump the second number (e.g. 1.3.x to 1.4.0) for any
# release that changes the ABI. The ABI changes for almost any modification to
# include/ceres (e.g. the public API). If you are unsure about whether
# something is an ABI change, please ask on the list.
#
# For versions without ABI changes, bump the smallest number in CERES_VERSION,
# but leave the CERES_ABI_VERSION unchanged.
SET(CERES_VERSION_MAJOR 1)
SET(CERES_VERSION_MINOR 8)
SET(CERES_VERSION_PATCH 0)
SET(CERES_VERSION
    ${CERES_VERSION_MAJOR}.${CERES_VERSION_MINOR}.${CERES_VERSION_PATCH})
SET(CERES_ABI_VERSION 1.8.0)

ENABLE_TESTING()

OPTION(MINIGLOG "Use a stripped down version of glog." OFF)
OPTION(GFLAGS "Enable Google Flags." ON)
OPTION(SUITESPARSE "Enable SuiteSparse." ON)
OPTION(CXSPARSE "Enable CXSparse." ON)
OPTION(LAPACK "Enable use of LAPACK." ON)
# Template specializations for the Schur complement based solvers. If
# compile time, binary size or compiler performance is an issue, you
# may consider disabling this.
OPTION(SCHUR_SPECIALIZATIONS "Enable fixed-size schur specializations." ON)
OPTION(CUSTOM_BLAS
       "Use handcoded BLAS routines (usually faster) instead of Eigen."
       ON)
# Multithreading using OpenMP
OPTION(OPENMP "Enable threaded solving in Ceres (requires OpenMP)" ON)
# TODO(sameeragarwal): Replace this with a positive option instead?

# Line search minimizer is useful for large scale problems or when
# sparse linear algebra libraries are not available. If compile time,
# binary size or compiler performance is an issue, consider disabling
# this.
OPTION(LINE_SEARCH_MINIMIZER "Enable the line search minimizer." ON)
OPTION(BUILD_TESTING "Enable tests" ON)
OPTION(BUILD_DOCUMENTATION "Build User's Guide (html)" OFF)
OPTION(BUILD_EXAMPLES "Build examples" ON)
OPTION(BUILD_SHARED_LIBS "Build Ceres as a shared library." OFF)
IF (MSVC)
  OPTION(MSVC_USE_STATIC_CRT
    "MS Visual Studio: Use static C-Run Time Library in place of shared." OFF)
ENDIF (MSVC)

# Prior to October 2013, Ceres used some non-CMake standardised variables to
# hold user-specified (as opposed to FindPackage found) include directory and
# library paths for Ceres dependencies.  These were were of the form:
# <DEPENDENCY>_LIB / <DEPENDENCY>_INCLUDE.  Since then, Ceres now has
# FindPackage() scripts for all of its dependencies which obey the standard
# CMake variables: <DEPENDENCY>_LIBRARIES & <DEPENDENCY>_INCLUDE_DIRS.  In order
# to ensure backwards compatibility, we use convert any legacy variables to
# _directory_ hints for the FindPackage() scripts.
MACRO(HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT
    LEGACY_VAR DIRECTORY_HINT_VAR)
  IF (DEFINED ${LEGACY_VAR})
    # Get the dependency name (all caps) from the hint directory variable
    # for the warning message.
    STRING(REGEX MATCH "^[^_]*" DEPENDENCY_NAME ${DIRECTORY_HINT_VAR})
    MESSAGE(WARNING "You are defining a legacy variable ${LEGACY_VAR} "
      "to specify the include directory for ${DEPENDENCY_NAME}.  This is "
      "deprecated and support for it will be removed in a future release. "
      "Please use either the search directory hints variable: "
      "${DIRECTORY_HINT_VAR} or ${DEPENDENCY_NAME}_INCLUDE_DIR to specify "
      "exactly the directory used (no search performed), see: "
      "for more information.")
    LIST(APPEND ${DIRECTORY_HINT_VAR} ${${LEGACY_VAR}})
  ENDIF (DEFINED ${LEGACY_VAR})
ENDMACRO(HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT)

MACRO(HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT
    LEGACY_VAR DIRECTORY_HINT_VAR)
  IF (DEFINED ${LEGACY_VAR})
    # Get the dependency name (all caps) from the hint directory variable
    # for the warning message.
    STRING(REGEX MATCH "^[^_]*" DEPENDENCY_NAME ${DIRECTORY_HINT_VAR})
    MESSAGE(WARNING "You are defining a legacy variable ${LEGACY_VAR} "
      "to specify the library for ${DEPENDENCY_NAME}.  This is "
      "deprecated and support for it will be removed in a future release. "
      "Please use either the search directory hints variable: "
      "${DIRECTORY_HINT_VAR} or ${DEPENDENCY_NAME}_LIBRARY to specify "
      "exactly the library used (no search performed), see: "
      "for more information.")
    IF (EXISTS ${${LEGACY_VAR}} AND
        NOT IS_DIRECTORY ${${LEGACY_VAR}})
      # User specified an explicit (library) file using the legacy variable
      # interface, hints to FindPackage() scripts are directories so add the
      # parent directory of the specified file.
      GET_FILENAME_COMPONENT(DIR_HINT ${${LEGACY_VAR}} PATH)
      LIST(APPEND ${DIRECTORY_HINT_VAR} ${DIR_HINT})
    ELSEIF (EXISTS ${${LEGACY_VAR}} AND
            IS_DIRECTORY ${${LEGACY_VAR}})
      # User specified a directory hint using the legacy variable, use it.
      LIST(APPEND ${DIRECTORY_HINT_VAR} ${${LEGACY_VAR}})
    ENDIF()
  ENDIF (DEFINED ${LEGACY_VAR})
ENDMACRO(HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT)

# Eigen.
HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(EIGEN_INCLUDE EIGEN_INCLUDE_DIR_HINTS)
FIND_PACKAGE(Eigen REQUIRED)
IF (EIGEN_FOUND)
  MESSAGE("-- Found Eigen version ${EIGEN_VERSION}: ${EIGEN_INCLUDE_DIRS}")
ENDIF (EIGEN_FOUND)

# LAPACK (& BLAS).
IF (LAPACK)
  FIND_PACKAGE(LAPACK QUIET)
  IF (LAPACK_FOUND)
    MESSAGE("-- Found LAPACK library: ${LAPACK_LIBRARIES}")
  ELSE (LAPACK_FOUND)
    MESSAGE("-- Did not find LAPACK library, disabling LAPACK support.")
  ENDIF (LAPACK_FOUND)

  FIND_PACKAGE(BLAS QUIET)
  IF (BLAS_FOUND)
    MESSAGE("-- Found BLAS library: ${BLAS_LIBRARIES}")
  ELSE (BLAS_FOUND)
    MESSAGE("-- Did not find BLAS library, disabling LAPACK support.")
  ENDIF (BLAS_FOUND)

  IF (NOT (LAPACK_FOUND AND BLAS_FOUND))
    # Retain the help string associated with the LAPACK option
    # 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)
  ENDIF (NOT (LAPACK_FOUND AND BLAS_FOUND))
ELSE (LAPACK)
  MESSAGE("-- Building without LAPACK.")
  ADD_DEFINITIONS(-DCERES_NO_LAPACK)
ENDIF (LAPACK)

# SuiteSparse.

SET(SUITESPARSE ON)

IF (SUITESPARSE)
  # By default, if SuiteSparse and all dependencies are found, Ceres is
  # built with SuiteSparse support.

  # Check for SuiteSparse and dependencies.
  FIND_PACKAGE(SuiteSparse)
  IF (SUITESPARSE_FOUND)
    # On Ubuntu the system install of SuiteSparse (v3.4.0) up to at least
    # Ubuntu 13.10 cannot be used to link shared libraries.
    IF (BUILD_SHARED_LIBS AND
        SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION)
      MESSAGE(FATAL_ERROR "You are attempting to build Ceres as a shared "
        "library on Ubuntu using a system package install of SuiteSparse "
        "3.4.0. This package is broken and does not support the "
        "construction of shared libraries (you can still build Ceres as "
        "a static library).  If you wish to build a shared version of Ceres "
        "you should uninstall the system install of SuiteSparse "
        "(libsuitesparse-dev) and perform a source install of SuiteSparse "
        "(we recommend that you use the latest version), "
        "/ceres-solver/dev/building.html for more information.")
    ENDIF (BUILD_SHARED_LIBS AND
      SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION)

    # By default, if all of SuiteSparse's dependencies are found, Ceres is
    # built with SuiteSparse support.
    MESSAGE("-- Found SuiteSparse ${SUITESPARSE_VERSION}, "
            "building with SuiteSparse.")
  ELSE (SUITESPARSE_FOUND)
    # Disable use of SuiteSparse if it cannot be found and continue.
    MESSAGE("-- Did not find all SuiteSparse dependencies, disabling "
      "SuiteSparse support.")
    # Retain the help string associated with the SUITESPARSE option
    # 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)
  ENDIF (SUITESPARSE_FOUND)
ELSE (SUITESPARSE)
  MESSAGE("-- Building without SuiteSparse.")
  ADD_DEFINITIONS(-DCERES_NO_SUITESPARSE)
ENDIF (SUITESPARSE)

# CXSparse.
IF (CXSPARSE)
  # Don't search with REQUIRED as we can continue without CXSparse.
  FIND_PACKAGE(CXSparse)
  IF (CXSPARSE_FOUND)
    # By default, if CXSparse and all dependencies are found, Ceres is
    # built with CXSparse support.
    MESSAGE("-- Found CXSparse version: ${CXSPARSE_VERSION}, "
      "building with CXSparse.")
  ELSE (CXSPARSE_FOUND)
    # Disable use of CXSparse if it cannot be found and continue.
    MESSAGE("-- Did not find CXSparse, Building without CXSparse.")
    # Retain the help string associated with the CXSPARSE option
    # 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)
  ENDIF (CXSPARSE_FOUND)
ELSE (CXSPARSE)
  MESSAGE("-- Building without CXSparse.")
  ADD_DEFINITIONS(-DCERES_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
  # CXSPARSE instead of setting them.
  MARK_AS_ADVANCED(FORCE CXSPARSE_INCLUDE_DIR
                         CXSPARSE_LIBRARY)
ENDIF (CXSPARSE)

# GFlags.
IF (GFLAGS)
  HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(GFLAGS_INCLUDE GFLAGS_INCLUDE_DIR_HINTS)
  HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT(GFLAGS_LIB GFLAGS_LIBRARY_DIR_HINTS)

  # Don't search with REQUIRED as we can continue without gflags.
  FIND_PACKAGE(Gflags)
  IF (GFLAGS_FOUND)
    MESSAGE("-- Found Google Flags header in: ${GFLAGS_INCLUDE_DIRS}")
  ELSE (GFLAGS_FOUND)
    MESSAGE("-- Did not find Google Flags (gflags), Building without gflags "
      "- no tests or tools will be built!")
    # Retain the help string associated with the GFLAGS option
    # 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
  # GFLAGS instead of setting them.
  MARK_AS_ADVANCED(FORCE GFLAGS_INCLUDE_DIR
                         GFLAGS_LIBRARY)
ENDIF (GFLAGS)

# MiniGLog.
IF (MINIGLOG)
  SET(GLOG_LIBRARIES miniglog)
  MESSAGE("-- Using minimal Glog substitute (library): ${GLOG_LIBRARIES}")
  SET(GLOG_INCLUDE_DIRS internal/ceres/miniglog)
  MESSAGE("-- Using minimal Glog substitute (include): ${GLOG_INCLUDE_DIRS}")

  # Mark as advanced (remove from default GUI view) the glog search
  # variables in case user disables MINIGLOG, FindGlog did not find it, so
  # made search variables visible in GUI for user to set, but then user enables
  # MINIGLOG instead of setting them.
  MARK_AS_ADVANCED(FORCE GLOG_INCLUDE_DIR
                         GLOG_LIBRARY)
ELSE (MINIGLOG)
  HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(GLOG_INCLUDE GLOG_INCLUDE_DIR_HINTS)
  HANDLE_LEGACY_LIBRARY_DEPENDENCY_HINT(GLOG_LIB GLOG_LIBRARY_DIR_HINTS)

  # Don't search with REQUIRED so that configuration continues if not found and
  # we can output an error messages explaining MINIGLOG option.
  FIND_PACKAGE(Glog)
  IF (GLOG_FOUND)
    MESSAGE("-- Found Google Log header in: ${GLOG_INCLUDE_DIRS}")
  ELSE (GLOG_FOUND)
    MESSAGE(FATAL_ERROR "Can't find Google Log. Please set GLOG_INCLUDE_DIR & "
      "GLOG_LIBRARY or enable MINIGLOG option to use minimal glog "
      "implementation.")
  ENDIF (GLOG_FOUND)
ENDIF (MINIGLOG)

IF (NOT SCHUR_SPECIALIZATIONS)
  ADD_DEFINITIONS(-DCERES_RESTRICT_SCHUR_SPECIALIZATION)
  MESSAGE("-- Disabling Schur specializations (faster compiles)")
ENDIF (NOT SCHUR_SPECIALIZATIONS)

IF (NOT LINE_SEARCH_MINIMIZER)
  ADD_DEFINITIONS(-DCERES_NO_LINE_SEARCH_MINIMIZER)
  MESSAGE("-- Disabling line search minimizer")
ENDIF (NOT LINE_SEARCH_MINIMIZER)

IF (NOT CUSTOM_BLAS)
  ADD_DEFINITIONS(-DCERES_NO_CUSTOM_BLAS)
  MESSAGE("-- Disabling custom blas")
ENDIF (NOT CUSTOM_BLAS)

IF (OPENMP)
  # Clang does not (yet) support OpenMP.
  IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    # Retain the help string associated with the OPENMP option
    # when updating it to disable use of OPENMP.
    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)
  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)
      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)
        SET(STATIC_LIBRARY_FLAGS
          "${STATIC_LIBRARY_FLAGS} ${CMAKE_THREAD_LIBS_INIT}")
        SET(CMAKE_SHARED_LINKER_FLAGS
          "${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_THREAD_LIBS_INIT}")
        ADD_DEFINITIONS(-DCERES_HAVE_PTHREAD)
        ADD_DEFINITIONS(-DCERES_HAVE_RWLOCK)
      ENDIF (UNIX)
    ELSE (OPENMP_FOUND)
      MESSAGE("-- Failed to find OpenMP, disabling.")
      # Retain the help string associated with the OPENMP option
      # 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)
    ENDIF (OPENMP_FOUND)
  ENDIF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
ELSE (OPENMP)
  MESSAGE("-- Building without OpenMP (disabling multithreading).")
  ADD_DEFINITIONS(-DCERES_NO_THREADS)
ENDIF (OPENMP)

Include(CheckIncludeFileCXX)
CHECK_INCLUDE_FILE_CXX(unordered_map UNORDERED_MAP_IN_STD_NAMESPACE)
If (UNORDERED_MAP_IN_STD_NAMESPACE)
  ADD_DEFINITIONS(-DCERES_STD_UNORDERED_MAP)
ELSE (UNORDERED_MAP_IN_STD_NAMESPACE)
  CHECK_INCLUDE_FILE_CXX("tr1/unordered_map" UNORDERED_MAP_IN_TR1_NAMESPACE)
  IF (UNORDERED_MAP_IN_TR1_NAMESPACE)
    ADD_DEFINITIONS(-DCERES_TR1_UNORDERED_MAP)
  ELSE (UNORDERED_MAP_IN_TR1_NAMESPACE)
    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)
  ENDIF (UNORDERED_MAP_IN_TR1_NAMESPACE)
ENDIF (UNORDERED_MAP_IN_STD_NAMESPACE)

INCLUDE_DIRECTORIES(
  include
  internal
  internal/ceres
  ${GLOG_INCLUDE_DIRS}
  ${EIGEN_INCLUDE_DIRS})

IF (SUITESPARSE)
  INCLUDE_DIRECTORIES(${SUITESPARSE_INCLUDE_DIRS})
ENDIF (SUITESPARSE)

IF (CXSPARSE)
  INCLUDE_DIRECTORIES(${CXSPARSE_INCLUDE_DIRS})
ENDIF (CXSPARSE)

IF (GFLAGS)
  INCLUDE_DIRECTORIES(${GFLAGS_INCLUDE_DIRS})
ENDIF (GFLAGS)

IF (BUILD_SHARED_LIBS)
  MESSAGE("-- Building Ceres as a shared library.")
ELSE (BUILD_SHARED_LIBS)
  MESSAGE("-- Building Ceres as a static library.")
ENDIF (BUILD_SHARED_LIBS)

# Change the default build type from Debug to Release, while still
# supporting overriding the build type.
#
# The CACHE STRING logic here and elsewhere is needed to force CMake
# to pay attention to the value of these variables.
IF (NOT CMAKE_BUILD_TYPE)
  MESSAGE("-- No build type specified; defaulting to CMAKE_BUILD_TYPE=Release.")
  SET(CMAKE_BUILD_TYPE Release CACHE STRING
    "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
    FORCE)
ELSE (NOT CMAKE_BUILD_TYPE)
  IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
    MESSAGE("\n=================================================================================")
    MESSAGE("\n-- Build type: Debug. Performance will be terrible!")
    MESSAGE("-- Add -DCMAKE_BUILD_TYPE=Release to the CMake command line to get an optimized build.")
    MESSAGE("\n=================================================================================")
  ENDIF (CMAKE_BUILD_TYPE STREQUAL "Debug")
ENDIF (NOT CMAKE_BUILD_TYPE)

# Set the default Ceres flags to an empty string.
SET (CERES_CXX_FLAGS)

IF (CMAKE_BUILD_TYPE STREQUAL "Release")
  IF (CMAKE_COMPILER_IS_GNUCXX)
    # Linux
...

cDc

unread,
Apr 21, 2017, 9:30:09 AM4/21/17
to Ceres Solver
I see a lot of trouble for trying to add glog ang gflags libs, however my understanding is that for using CERES as a library none of them are necessary (needed only for tests and examples). Am I missing something?
Reply all
Reply to author
Forward
0 new messages