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)