Compile miniglog into Ceres if enabled on all platforms.
- Previously if miniglog was being used (on a non-Android system), we
compiled it into a separate library, against which Ceres then linked.
- This was unsatisfactory as it required miniglog being built as a
static library when building Ceres as a Windows DLL, because miniglog
did not use the dllexport/dllimport statements, whilst for other
platforms when building Ceres as a shared library, miniglog needed to
be compiled as a shared library.
- We now compile miniglog into Ceres on all platforms, not just on
Android.
- miniglog now uses the CERES_EXPORT macro to support Windows DLLs.
This means that miniglog now depends on Ceres' internal/port.h (and
thus internal/config.h) which define the CERES_EXPORT macro and
control its behaviour respectively.
- miniglog now also uses localtime_s, not localtime on Windows.
Change-Id: Ia55b9af8b4e6decf067eab92f0a5c2d14358a1e9
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fba40ce..8606286 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -142,11 +142,11 @@
# to config the cmake. The PLATFORM can be one of OS, SIMULATOR and SIMULATOR64.
# Check the documentation in iOS.cmake to find more options.
#
-# After building, you will get libceres.a and libminiglog.a
-# You need to add these two libraries into your xcode project.
+# After building, you will get a single library: libceres.a, which
+# you need to add to your Xcode project.
#
# If you use the lapack and blas, then you also need to add Accelerate.framework
-# to your xcode project's linking dependency.
+# to your Xcode project's linking dependency.
IF (IOS)
MESSAGE(STATUS "Building Ceres for iOS platform: ${IOS_PLATFORM}")
@@ -361,10 +361,9 @@
# MiniGLog.
IF (MINIGLOG)
- SET(GLOG_LIBRARIES miniglog)
- MESSAGE("-- Using minimal Glog substitute (library): ${GLOG_LIBRARIES}")
+ MESSAGE("-- Compiling minimal glog substitute into Ceres.")
SET(GLOG_INCLUDE_DIRS internal/ceres/miniglog)
- MESSAGE("-- Using minimal Glog substitute (include): ${GLOG_INCLUDE_DIRS}")
+ 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
diff --git a/docs/source/building.rst b/docs/source/building.rst
index eb0cd5b..2c187b9 100644
--- a/docs/source/building.rst
+++ b/docs/source/building.rst
@@ -368,13 +368,13 @@
``SIMULATOR64`` (``x86_64``) separately and use ``LIPO`` to merge them into
one static library. See ``cmake/iOS.cmake`` for more options.
-After building, you will get ``libceres.a`` and ``libminiglog.a``
-You need to add these two libraries into your XCode project.
+After building, you will get a ``libceres.a`` library, which you will need to
+add to your Xcode project.
The default CMake configuration builds a bare bones version of Ceres
-Solver that only depends on Eigen and MINIGLOG, this should be
-sufficient for solving small to moderate sized problems (No
-``SPARSE_SCHUR``, ``SPARSE_NORMAL_CHOLESKY`` linear solvers and no
+Solver that only depends on Eigen (``MINIGLOG`` is compiled into Ceres if it is
+used), this should be sufficient for solving small to moderate sized problems
+(No ``SPARSE_SCHUR``, ``SPARSE_NORMAL_CHOLESKY`` linear solvers and no
``CLUSTER_JACOBI`` and ``CLUSTER_TRIDIAGONAL`` preconditioners).
If you decide to use ``LAPACK`` and ``BLAS``, then you also need to add
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index 89757b3..4d4f873 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -136,24 +136,10 @@
FILE(GLOB CERES_INTERNAL_SCHUR_FILES generated/*_d_d_d.cc)
ENDIF (SCHUR_SPECIALIZATIONS)
-# Primarily for Android, but optionally for others, use the minimal internal
-# Glog implementation.
-IF (MINIGLOG)
- IF (MSVC)
- # Miniglog needs to be built statically with Visual Studio since it
- # doesn't export any symbols with dllexport/dllimport.
- ADD_LIBRARY(miniglog STATIC miniglog/glog/logging.cc)
- ELSE()
- ADD_LIBRARY(miniglog miniglog/glog/logging.cc)
- ENDIF()
- INSTALL(TARGETS miniglog
- EXPORT CeresExport
- RUNTIME DESTINATION bin
- LIBRARY DESTINATION lib${LIB_SUFFIX}
- ARCHIVE DESTINATION lib${LIB_SUFFIX})
-ENDIF (MINIGLOG)
-
-SET(CERES_LIBRARY_PUBLIC_DEPENDENCIES ${GLOG_LIBRARIES})
+# Build the list of dependencies for Ceres based on the current configuration.
+IF (NOT MINIGLOG AND GLOG_FOUND)
+ LIST(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES ${GLOG_LIBRARIES})
+ENDIF (NOT MINIGLOG AND GLOG_FOUND)
IF (SUITESPARSE AND SUITESPARSE_FOUND)
LIST(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES ${SUITESPARSE_LIBRARIES})
@@ -180,6 +166,12 @@
${CERES_INTERNAL_HDRS}
${CERES_INTERNAL_SCHUR_FILES})
+# Primarily for Android, but optionally for others, compile the minimal
+# glog implementation into Ceres.
+IF (MINIGLOG)
+ LIST(APPEND CERES_LIBRARY_SOURCE miniglog/glog/logging.cc)
+ENDIF (MINIGLOG)
+
ADD_LIBRARY(ceres ${CERES_LIBRARY_SOURCE})
SET_TARGET_PROPERTIES(ceres PROPERTIES
VERSION ${CERES_VERSION}
@@ -215,8 +207,15 @@
numeric_diff_test_utils.cc
test_util.cc)
- TARGET_LINK_LIBRARIES(gtest ${GFLAGS_LIBRARIES} ${GLOG_LIBRARIES})
- TARGET_LINK_LIBRARIES(test_util ceres gtest ${GLOG_LIBRARIES})
+ IF (MINIGLOG)
+ # When using miniglog, it is compiled into Ceres, thus Ceres becomes
+ # the library against which other libraries should link for logging.
+ TARGET_LINK_LIBRARIES(gtest ${GFLAGS_LIBRARIES} ceres)
+ TARGET_LINK_LIBRARIES(test_util ceres gtest)
+ ELSE (MINIGLOG)
+ TARGET_LINK_LIBRARIES(gtest ${GFLAGS_LIBRARIES} ${GLOG_LIBRARIES})
+ TARGET_LINK_LIBRARIES(test_util ceres gtest ${GLOG_LIBRARIES})
+ ENDIF (MINIGLOG)
MACRO (CERES_TEST NAME)
ADD_EXECUTABLE(${NAME}_test ${NAME}_test.cc)
diff --git a/internal/ceres/miniglog/glog/logging.h b/internal/ceres/miniglog/glog/logging.h
index e43d05e..e9c0dff 100644
--- a/internal/ceres/miniglog/glog/logging.h
+++ b/internal/ceres/miniglog/glog/logging.h
@@ -105,6 +105,10 @@
#include <string>
#include <vector>
+// For appropriate definition of CERES_EXPORT macro.
+#include "ceres/internal/port.h"
+#include "ceres/internal/disable_warnings.h"
+
// Log severity level constants.
const int FATAL = -3;
const int ERROR = -2;
@@ -125,7 +129,7 @@
// added, all log output is also sent to each sink through the send function.
// In this implementation, WaitTillSent() is called immediately after the send.
// This implementation is not thread safe.
-class LogSink {
+class CERES_EXPORT LogSink {
public:
virtual ~LogSink() {}
virtual void send(LogSeverity severity,
@@ -139,7 +143,7 @@
};
// Global set of log sinks. The actual object is defined in logging.cc.
-extern std::set<LogSink *> log_sinks_global;
+extern CERES_EXPORT std::set<LogSink *> log_sinks_global;
inline void InitGoogleLogging(char *argv) {
// Do nothing; this is ignored.
@@ -164,7 +168,7 @@
// defined, output is directed to std::cerr. This class should not
// be directly instantiated in code, rather it should be invoked through the
// use of the log macros LG, LOG, or VLOG.
-class MessageLogger {
+class CERES_EXPORT MessageLogger {
public:
MessageLogger(const char *file, int line, const char *tag, int severity)
: file_(file), line_(line), tag_(tag), severity_(severity) {
@@ -223,10 +227,18 @@
private:
void LogToSinks(int severity) {
time_t rawtime;
- struct tm* timeinfo;
-
time (&rawtime);
+
+ struct tm* timeinfo;
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
+ // On Windows, use secure localtime_s not localtime.
+ struct tm windows_timeinfo;
+ timeinfo = &windows_timeinfo;
+ localtime_s(timeinfo, &rawtime);
+#else
timeinfo = localtime(&rawtime);
+#endif
+
std::set<google::LogSink*>::iterator iter;
// Send the log message to all sinks.
for (iter = google::log_sinks_global.begin();
@@ -271,7 +283,7 @@
// This class is used to explicitly ignore values in the conditional
// logging macros. This avoids compiler warnings like "value computed
// is not used" and "statement has no effect".
-class LoggerVoidify {
+class CERES_EXPORT LoggerVoidify {
public:
LoggerVoidify() { }
// This has to be an operator with a precedence lower than << but
@@ -409,4 +421,6 @@
CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val))
#endif // NDEBUG
+#include "ceres/internal/reenable_warnings.h"
+
#endif // CERCES_INTERNAL_MINIGLOG_GLOG_LOGGING_H_