Autodetect gflags namespace.

- At version 2.1, gflags changed from using the google namespace, to
  using gflags by default.  However, it can be configured at build time
  to be something else (which would be google for legacy compatibility
  unless you were evil).
- Ceres previously assumed that gflags was in the google namespace.
- Now, FindGFlags.cmake extracts the namespace when gflags.h is found
  and saves it in GFLAGS_NAMESPACE.
- When building the tests and examples that require gflags,
  CERES_GFLAGS_NAMESPACE is defined to be the detected namespace, and
  all tests/examples now use CERES_GFLAGS_NAMESPACE:: instead of
  google:: when calling gflags functions.

Change-Id: Ia333df7a7e2f08ba9f26bbd339c3a785b88f04c4
This commit is contained in:
Alex Stewart
2014-11-26 20:46:36 +00:00
parent 9ad59a760a
commit cbe694505e
13 changed files with 71 additions and 13 deletions
+2 -1
View File
@@ -378,7 +378,8 @@ IF (GFLAGS)
# 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}")
MESSAGE("-- Found Google Flags header in: ${GFLAGS_INCLUDE_DIRS}, "
"in namespace: ${GFLAGS_NAMESPACE}")
ELSE (GFLAGS_FOUND)
MESSAGE("-- Did not find Google Flags (gflags), Building without gflags "
"- no tests or tools will be built!")
+49 -2
View File
@@ -36,6 +36,11 @@
# GFLAGS_FOUND: TRUE iff gflags is found.
# GFLAGS_INCLUDE_DIRS: Include directories for gflags.
# GFLAGS_LIBRARIES: Libraries required to link gflags.
# GFLAGS_NAMESPACE: The namespace in which gflags is defined. In versions of
# gflags < 2.1, this was google, for versions >= 2.1 it is
# by default gflags, although can be configured when building
# gflags to be something else (i.e. google for legacy
# compatibility).
#
# The following variables control the behaviour of this module:
#
@@ -67,6 +72,7 @@ MACRO(GFLAGS_REPORT_NOT_FOUND REASON_MSG)
UNSET(GFLAGS_FOUND)
UNSET(GFLAGS_INCLUDE_DIRS)
UNSET(GFLAGS_LIBRARIES)
UNSET(GFLAGS_NAMESPACE)
# Make results of search visible in the CMake GUI if gflags has not
# been found so that user does not have to toggle to advanced view.
MARK_AS_ADVANCED(CLEAR GFLAGS_INCLUDE_DIR
@@ -128,6 +134,46 @@ ENDIF (NOT GFLAGS_LIBRARY OR
# if called.
SET(GFLAGS_FOUND TRUE)
# Identify what namespace gflags was built with.
IF (GFLAGS_INCLUDE_DIR)
# First try the (older) google namespace.
INCLUDE(CheckCXXSourceCompiles)
# Setup include path & link library for gflags for CHECK_CXX_SOURCE_COMPILES
SET(CMAKE_REQUIRED_INCLUDES ${GFLAGS_INCLUDE_DIR})
SET(CMAKE_REQUIRED_LIBRARIES ${GFLAGS_LIBRARY})
CHECK_CXX_SOURCE_COMPILES(
"#include <gflags/gflags.h>
int main(int argc, char * argv[]) {
google::ParseCommandLineFlags(&argc, &argv, true);
return 0;
}"
GFLAGS_IN_GOOGLE_NAMESPACE)
IF (GFLAGS_IN_GOOGLE_NAMESPACE)
SET(GFLAGS_NAMESPACE google)
ELSE (GFLAGS_IN_GOOGLE_NAMESPACE)
# Try (newer) gflags namespace instead.
#
# Setup include path & link library for gflags for CHECK_CXX_SOURCE_COMPILES
SET(CMAKE_REQUIRED_INCLUDES ${GFLAGS_INCLUDE_DIR})
SET(CMAKE_REQUIRED_LIBRARIES ${GFLAGS_LIBRARY})
CHECK_CXX_SOURCE_COMPILES(
"#include <gflags/gflags.h>
int main(int argc, char * argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
return 0;
}"
GFLAGS_IN_GFLAGS_NAMESPACE)
IF (GFLAGS_IN_GFLAGS_NAMESPACE)
SET(GFLAGS_NAMESPACE gflags)
ENDIF (GFLAGS_IN_GFLAGS_NAMESPACE)
ENDIF (GFLAGS_IN_GOOGLE_NAMESPACE)
IF (NOT GFLAGS_NAMESPACE)
GFLAGS_REPORT_NOT_FOUND(
"Failed to determine gflags namespace, it is not google or gflags.")
ENDIF (NOT GFLAGS_NAMESPACE)
ENDIF (GFLAGS_INCLUDE_DIR)
# gflags does not seem to provide any record of the version in its
# source tree, thus cannot extract version.
@@ -162,11 +208,12 @@ ENDIF (GFLAGS_FOUND)
# Handle REQUIRED / QUIET optional arguments.
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Gflags DEFAULT_MSG
GFLAGS_INCLUDE_DIRS GFLAGS_LIBRARIES)
GFLAGS_INCLUDE_DIRS GFLAGS_LIBRARIES GFLAGS_NAMESPACE)
# Only mark internal variables as advanced if we found gflags, otherwise
# leave them visible in the standard GUI for the user to set manually.
IF (GFLAGS_FOUND)
MARK_AS_ADVANCED(FORCE GFLAGS_INCLUDE_DIR
GFLAGS_LIBRARY)
GFLAGS_LIBRARY
GFLAGS_NAMESPACE)
ENDIF (GFLAGS_FOUND)
+5
View File
@@ -70,6 +70,11 @@ ADD_EXECUTABLE(simple_bundle_adjuster
TARGET_LINK_LIBRARIES(simple_bundle_adjuster ceres)
IF (GFLAGS)
# The CERES_GFLAGS_NAMESPACE compile definition is NOT stored in
# CERES_COMPILE_OPTIONS (and thus config.h) as Ceres itself does not
# require gflags, only the tests and examples do.
ADD_DEFINITIONS(-DCERES_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
ADD_EXECUTABLE(powell powell.cc)
TARGET_LINK_LIBRARIES(powell ceres ${GFLAGS_LIBRARIES})
+1 -1
View File
@@ -333,7 +333,7 @@ void SolveProblem(const char* filename) {
} // namespace ceres
int main(int argc, char** argv) {
google::ParseCommandLineFlags(&argc, &argv, true);
CERES_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
if (FLAGS_input.empty()) {
LOG(ERROR) << "Usage: bundle_adjustment_example --input=bal_problem";
+1 -1
View File
@@ -107,7 +107,7 @@ class DistanceFromCircleCost {
};
int main(int argc, char** argv) {
google::ParseCommandLineFlags(&argc, &argv, true);
CERES_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
double x, y, r;
+2 -2
View File
@@ -176,8 +176,8 @@ int main(int argc, char** argv) {
usage("This program denoises an image using Ceres. Sample usage:\n");
usage += argv[0];
usage += " --input=<noisy image PGM file> --foe_file=<FoE file name>";
google::SetUsageMessage(usage);
google::ParseCommandLineFlags(&argc, &argv, true);
CERES_GFLAGS_NAMESPACE::SetUsageMessage(usage);
CERES_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
if (FLAGS_input.empty()) {
+1 -1
View File
@@ -779,7 +779,7 @@ void EuclideanBundleCommonIntrinsics(const vector<Marker> &all_markers,
} // namespace
int main(int argc, char **argv) {
google::ParseCommandLineFlags(&argc, &argv, true);
CERES_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
if (FLAGS_input.empty()) {
+1 -1
View File
@@ -337,7 +337,7 @@ template<typename TestProblem> string UnconstrainedSolve() {
} // namespace ceres
int main(int argc, char** argv) {
google::ParseCommandLineFlags(&argc, &argv, true);
CERES_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
using ceres::examples::UnconstrainedSolve;
+1 -1
View File
@@ -566,7 +566,7 @@ void SolveNISTProblems() {
} // namespace ceres
int main(int argc, char** argv) {
google::ParseCommandLineFlags(&argc, &argv, true);
CERES_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
ceres::examples::SolveNISTProblems();
return 0;
+1 -1
View File
@@ -99,7 +99,7 @@ DEFINE_string(minimizer, "trust_region",
"Minimizer type to use, choices are: line_search & trust_region");
int main(int argc, char** argv) {
google::ParseCommandLineFlags(&argc, &argv, true);
CERES_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
double x1 = 3.0;
+1 -1
View File
@@ -271,7 +271,7 @@ void PrintState(const vector<double>& odometry_readings,
int main(int argc, char** argv) {
google::InitGoogleLogging(argv[0]);
google::ParseCommandLineFlags(&argc, &argv, true);
CERES_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
// Make sure that the arguments parsed are all positive.
CHECK_GT(FLAGS_corridor_length, 0.0);
CHECK_GT(FLAGS_pose_separation, 0.0);
+5
View File
@@ -205,6 +205,11 @@ INSTALL(TARGETS ceres
ARCHIVE DESTINATION lib${LIB_SUFFIX})
IF (BUILD_TESTING AND GFLAGS)
# The CERES_GFLAGS_NAMESPACE compile definition is NOT stored in
# CERES_COMPILE_OPTIONS (and thus config.h) as Ceres itself does not
# require gflags, only the tests and examples do.
ADD_DEFINITIONS(-DCERES_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
ADD_LIBRARY(gtest gmock_gtest_all.cc gmock_main.cc)
ADD_LIBRARY(test_util
evaluator_test_utils.cc
+1 -1
View File
@@ -63,6 +63,6 @@ int main(int argc, char** argv) {
// gflags, InitGoogleTest() (called by InitGoogleMock()) must be called
// before ParseCommandLineFlags() to handle & remove them before gflags
// parses the remaining flags.
google::ParseCommandLineFlags(&argc, &argv, true);
CERES_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
return RUN_ALL_TESTS();
}