Google Ceres Solver – Compilation with VC2012

A while back Google released their nonlinear least-squares minimizer, Ceres, to the public as open source. The tech is really good and very difficult to build by yourself, so I really applaud them for doing so.

Regrettably, it has been an incredible pain to get it to work under Windows. Mostly the glog dependency just didn’t play nice with my compiler.

In the end I got it to work with Visual Studio 2012 Express, and these are the exact steps I did to get there. This is probably helpful for those who are having trouble.

Downloads
1. Get the Ceres Solver source code (tar.gz) from http://code.google.com/p/ceres-solver (v1.4.0 at time of writing)
2. Get the Google Commandline Flags source code from http://code.google.com/p/gflags (v2.0 at time of writing)
3. Get the Google Logger source code from http://code.google.com/p/google-glog (v0.3.2 at time of writing)
4. Get a forked version from CXSparse from https://github.com/PetterS/CXSparse (v3.1.1 at time of writing)
5. Get the Eigen3 library from http://eigen.tuxfamily.org (v3.1.2 at time of writing)
6. Get CMake from http://www.cmake.org/ (v2.8.10 at time of writing)

Installation
1. Install CMake (if you haven’t already)

Folder structure
1. Create a base folder ‘ceres’
2. Extract the Ceres Solver source to its own subfolder ‘ceres/ceres-solver’
3. Extract the gflags source to its own subfolder ‘ceres/gflags’
4. Extract the glog source to its own subfolder ‘ceres/glog’
5. Extract the CXSparse source to its own subfolder ‘ceres/cxsparse’
6. Extract the Eigen source to its own subfolder ‘ceres/eigen’

gflags
1. Open the solution ‘ceres/gflags/gflags.sln’
2. Auto-migrate the solution to MSVC2012, enable one-way upgrades for all projects
3. Toggle ‘release’ mode compilation
4. Compile the project (expect 49 warnings, 0 errors)

glog
1. Open the solution ‘ceres/glog/google-glog.sln’
2. Auto-migrate the solution to MSVC2012, enable one-way upgrades for all projects
3. Open the ‘port.h’ file and comment line that says ‘#define hash hash_compare’ (line 97); or wrap it in a #if (_MSC_VER < 1700) 4. Open the 'logging.cc' file and replace the line '_asm int 3' (line 1262) with '__debugbreak();' (for 64 bit compilation compatibiltiy) 5. Toggle 'release' mode compilation 6. Compile the project (expect 5 warnings) CXSparse
1. Open the solution ‘ceres/cxsparse/Project/CXSparse/CXSparse.sln’
2. Update compiler and libraries
3. Toggle ‘release’ mode compilation
4. Compile the project (expect 6 warnings)

At this point we’re ready to start creating the solution for Ceres Solver… start CMake-Gui. In this part, make sure to use the complete, absolute paths to all includes and libraries.
CMake
1. Set ‘Where is the source code’ to the ‘ceres/ceres-solver’ folder
2. Set ‘Where to build the binaries’ to ‘ceres/build’
3. Click ‘configure’, ‘create new directory’ and specify ‘Visual Studio 11’ as the generator for this project
4. Set the ‘CXSPARSE_INCLUDE’ value to earlier extracted ‘ceres/cxsparse/Include’
5. Set the ‘CXSPARSE_LIB’ value to the earlier compiled ‘ceres/cxsparse/Lib/CXSparse.lib’
6. Set the ‘GFLAGS_LIB’ value to the earlier compiled ‘ceres/gflags/Release/libgflags.lib’
7. Click ‘configure’
8. Set the ‘GFLAGS_INCLUDE’ value to the earlier extracted ‘ceres/gflags/src/windows’
9. Click ‘configure’
10. Set the ‘GLOG_LIB’ value to the earlier compiled ‘ceres/glog/Release/libglog.lib’
11. Click ‘configure’
12. Set the ‘GLOG_INCLUDE’ value to the earlier extracted ‘ceres/glog/src/windows’
13. Click ‘configure’
14. Set the ‘EIGEN_INCLUDE’ value to the earlier extracted ‘ceres/eigen’
15. Uncheck the ‘BUILD_TESTING’ setting (tests just give lots of compilation errors at this point)
16. Click ‘configure’
17. Click ‘generate’

Now we are ready to compile Ceres Solver.
1. Open ‘ceres/build/CERES.sln’
2. Right click on the ‘ceres’ project and go to the project properties
3. Toggle ‘All Configurations’
4. In the ‘C/C++ / Preprocessor / Preprocessor Definitions’ add ‘GLOG_NO_ABBREVIATED_SEVERITIES’
5. Compile the project
6. Copy ‘ceres/gflags/Release/libgflags.dll’ to ‘ceres/build/bin/Release’
7. Copy ‘ceres/glog/Release/libglog.dll’ to ‘ceres/build/bin/Release’
8. Run Powell.exe to test the library

Aaand it’s working! Using the library in your own projects is a matter of adding the include folders ‘ceres/ceres-solver/include’, ‘ceres/glog/src/windows’, ‘ceres/gflags/src/windows’ and ‘ceres/eigen’, linking to ‘ceres/build/lib/release/ceres.lib’ and adding the ‘libglog.dll’ and ‘libgflags.dll’ binaries.

Of course creating debug or 64 bit versions involves doing everything once more, with the relevant compilation flags active at each stage.

Hope this helps!
– GrandMaster

23 thoughts on “Google Ceres Solver – Compilation with VC2012

  1. Hi!

    Thanks for such detailed explanations!
    Only the one point does not work – I needed to set absolute paths to all libraries in the CMake-gui. Otherwise it could not find files.

    Alexander

  2. Thanks for the post — it’s great to see. I’ve added a link back from my page to yours. I’m hoping to include a CMake for SuiteSparse in the future, too.

    Tim

  3. Helllo!
    Thanks you very much,I cannot understand the sentences”Aaand it’s working! Using the library in your own projects is a matter of adding the include folders ‘ceres/ceres-solver/include’, ‘ceres/glog/src/windows’, ‘ceres/gflags/src/windows’ and ‘ceres/eigen’, linking to ‘ceres/build/lib/release/ceres.lib’ and adding the ‘libglog.dll’ and ‘libgflags.dll’ binaries.” I have try it,but faild. could you help me ,I am looking forward to your reply.

    yffeng

    1. At that point, ceres should have compiled to a .lib file. To make use of such a code library in your own project, you need to include the relevant headers and link the .lib file. This is a very common procedure and in MSVC it boils down to loading your project, selecting ‘Properties > Properties (Alt + F7)’, then navigating to ‘C/C++’ and in the ‘General’ section add the path to the header files (the aforementioned ‘ceres/ceres-solver/include’, ‘ceres/glog/src/windows’, ‘ceres/gflags/src/windows’ and ‘ceres/eigen’).

      After that, navigate to the ‘Linker > General’ section and add to the Additional Library Directories the path to the .lib file (‘ceres/ceres-solver/build/release’). Now, in the ‘Linker > Input’ section add ‘ceres.lib’ to the list of statically libraries. After this your project should compile (but not run).

      The final step is to include the dynamic libraries to the project output folder, just make a copy of ‘libglog.dll’ and ‘libgflags.dll’ to the folder where your projects’ .exe is located.

      Good luck!

  4. Thank you so much, I’ve been trying to get this working for hours! Just one question, where is this Powell.exe that you say you can test your build with?

    1. Forget it, I found powell.cc in the examples folder. Of course, it does not compile. I’ve added the include paths and the lib but I get a ton of unresolved external symbols.

  5. I was trying to install it on a WIN 7 64 bit platform with VS2010, but the error came out, saying:
    – C compiler is unknown
    – C** compiler is unknown

    when I ran the CMake.exe and click the command “Configure” or “Generate”. It seems like Cmake cannot find the VS2010’s compiler, where I actually I did select Visual Studio 10 as in your Step 3 of Cmake.

    Could you please help me on this?
    Many thanks in advance.

  6. Hello
    I went through the building step of the library and I managed to compile the library
    however when I try to use it with the powell example I get the following compilation error

    1>—— Build started: Project: test, Configuration: Release Win32 ——
    1> powell.cc
    1>C:\Software\ceres\glog\src\windows\glog/logging.h(1158): warning C4251: ‘google::LogMessage::LogStream::streambuf_’ : class ‘google::base_logging::LogStreamBuf’ needs to have dll-interface to be used by clients of class ‘google::LogMessage::LogStream’
    1> C:\Software\ceres\glog\src\windows\glog/logging.h(1088) : see declaration of ‘google::base_logging::LogStreamBuf’
    1>C:\Software\ceres\ceres-solver\include\ceres/internal/port.h(39): fatal error C1083: Cannot open include file: ‘ceres/internal/config.h’: No such file or directory
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

    Indeed this file does not exist.
    any help would really be appreciated
    best
    jac

  7. Copying config.h into that folder seemed to get rid of that error…
    Now I get the following error:
    error LNK2019: unresolved external symbol “__declspec(dllimport) void __cdecl google::InitGoogleLogging(char const *)” (__imp_?InitGoogleLogging@google@@YAXPBD@Z) referenced in function _main
    1>c:\users\richard\documents\visual studio 2013\Projects\Ceres-HelloWorld\Debug\Ceres-HelloWorld.exe : fatal error LNK1120: 1 unresolved externals

    1. This error would come up if you forgot to add a library to the linking stage. This would require adding the various .lib files to the project — a standard procedure when using compiled external librries. Right-click on the c++ project, go to properties > configuration properties > linker > general, and under ‘additional library directories’ add the paths to all of the folders containing the .lib files. Then, go to properties > configuration properties > linker > input, and under ‘additional depedencies’ add the file names of the relevant .lib files.

    1. It’s been over a decade since I worked with it, but what I remember is that glog was not really built for 64-bit Windows. This was back in 2012 and relatively straightforward to get it working.

      I still found it a pain, and for less experienced developers it was not really workable.

      Cross-platform support for libraries is always a bit iffy though; in my experience especially the lower-level libraries are pretty fragile and difficult to actually use.

Leave a Reply to GrandMaster Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.