Adding option for static/shared CRT in MSVC & Windows fixes.
- MSVC users can now choose whether to use the static or shared
C-Run Time (CRT) libraries explicitly.
- FindPackage() scripts now check that the lowercase libraries match
the expected library names, as Windows uses CamelCase for some
library names (other OSs don't).
Change-Id: Icbba5e9bf80181a5437e5009bdda1c12934bc6f3
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6f267b2..ad7e220 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -116,6 +116,10 @@
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
@@ -538,6 +542,29 @@
# 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)
diff --git a/cmake/FindCXSparse.cmake b/cmake/FindCXSparse.cmake
index cebddb5..45b2f02 100644
--- a/cmake/FindCXSparse.cmake
+++ b/cmake/FindCXSparse.cmake
@@ -167,16 +167,19 @@
# Catch the case when the caller has set CXSPARSE_LIBRARY in the cache / GUI and
# thus FIND_LIBRARY was not called, but specified library is invalid, otherwise
# we would report CXSparse as found.
-# TODO: This regex for CXSparse library is pretty primitive, could it be better?
+# TODO: This regex for CXSparse library is pretty primitive, we use lowercase
+# for comparison to handle Windows using CamelCase library names, could
+# this check be better?
+STRING(TOLOWER "${CXSPARSE_LIBRARY}" LOWERCASE_CXSPARSE_LIBRARY)
IF (CXSPARSE_LIBRARY AND
EXISTS ${CXSPARSE_LIBRARY} AND
- NOT ${CXSPARSE_LIBRARY} MATCHES ".*cxsparse[^/]*")
+ NOT "${LOWERCASE_CXSPARSE_LIBRARY}" MATCHES ".*cxsparse[^/]*")
CXSPARSE_REPORT_NOT_FOUND(
"Caller defined CXSPARSE_LIBRARY: "
"${CXSPARSE_LIBRARY} does not match CXSparse.")
ENDIF (CXSPARSE_LIBRARY AND
EXISTS ${CXSPARSE_LIBRARY} AND
- NOT ${CXSPARSE_LIBRARY} MATCHES ".*cxsparse[^/]*")
+ NOT "${LOWERCASE_CXSPARSE_LIBRARY}" MATCHES ".*cxsparse[^/]*")
# Set standard CMake FindPackage variables if found.
IF (CXSPARSE_FOUND)
diff --git a/cmake/FindGflags.cmake b/cmake/FindGflags.cmake
index 17fc70a..1091862 100644
--- a/cmake/FindGflags.cmake
+++ b/cmake/FindGflags.cmake
@@ -138,14 +138,17 @@
" ${GFLAGS_INCLUDE_DIR} does not contain gflags/gflags.h header.")
ENDIF (GFLAGS_INCLUDE_DIR AND
NOT EXISTS ${GFLAGS_INCLUDE_DIR}/gflags/gflags.h)
-# TODO: This regex for gflags library is pretty primitive, could it be better?
+# TODO: This regex for gflags library is pretty primitive, we use lowercase
+# for comparison to handle Windows using CamelCase library names, could
+# this check be better?
+STRING(TOLOWER "${GFLAGS_LIBRARY}" LOWERCASE_GFLAGS_LIBRARY)
IF (GFLAGS_LIBRARY AND
- NOT ${GFLAGS_LIBRARY} MATCHES ".*gflags[^/]*")
+ NOT "${LOWERCASE_GFLAGS_LIBRARY}" MATCHES ".*gflags[^/]*")
GFLAGS_REPORT_NOT_FOUND(
"Caller defined GFLAGS_LIBRARY: "
"${GFLAGS_LIBRARY} does not match gflags.")
ENDIF (GFLAGS_LIBRARY AND
- NOT ${GFLAGS_LIBRARY} MATCHES ".*gflags[^/]*")
+ NOT "${LOWERCASE_GFLAGS_LIBRARY}" MATCHES ".*gflags[^/]*")
# Set standard CMake FindPackage variables if found.
IF (GFLAGS_FOUND)
diff --git a/cmake/FindGlog.cmake b/cmake/FindGlog.cmake
index 30b95e2..b94cff3 100644
--- a/cmake/FindGlog.cmake
+++ b/cmake/FindGlog.cmake
@@ -138,14 +138,17 @@
" ${GLOG_INCLUDE_DIR} does not contain glog/logging.h header.")
ENDIF (GLOG_INCLUDE_DIR AND
NOT EXISTS ${GLOG_INCLUDE_DIR}/glog/logging.h)
-# TODO: This regex for glog library is pretty primitive, could it be better?
+# TODO: This regex for glog library is pretty primitive, we use lowercase
+# for comparison to handle Windows using CamelCase library names, could
+# this check be better?
+STRING(TOLOWER "${GLOG_LIBRARY}" LOWERCASE_GLOG_LIBRARY)
IF (GLOG_LIBRARY AND
- NOT ${GLOG_LIBRARY} MATCHES ".*glog[^/]*")
+ NOT "${LOWERCASE_GLOG_LIBRARY}" MATCHES ".*glog[^/]*")
GLOG_REPORT_NOT_FOUND(
"Caller defined GLOG_LIBRARY: "
"${GLOG_LIBRARY} does not match glog.")
ENDIF (GLOG_LIBRARY AND
- NOT ${GLOG_LIBRARY} MATCHES ".*glog[^/]*")
+ NOT "${LOWERCASE_GLOG_LIBRARY}" MATCHES ".*glog[^/]*")
# Set standard CMake FindPackage variables if found.
IF (GLOG_FOUND)