Build gflags and glog through CMake if not found in the system
authorNuno Subtil <nsubtil@nvidia.com>
Thu, 2 Apr 2015 02:10:55 +0000 (19:10 -0700)
committerNuno Subtil <nsubtil@nvidia.com>
Thu, 2 Apr 2015 02:15:42 +0000 (19:15 -0700)
This adds functionality to fetch gflags and glog from GitHub and build
them during the Caffe build. This happens only if a system-wide
installed version is not found (i.e., when find_package() fails).

If built as part of the Caffe build, gflags and glog are compiled as
position-independent static libraries. This avoids doing a system-wide
install of these libraries during the Caffe install target.

CMakeLists.txt
cmake/Dependencies.cmake
cmake/External/gflags.cmake [new file with mode: 0644]
cmake/External/glog.cmake [new file with mode: 0644]
cmake/Targets.cmake

index 74fa70c..f22aa57 100644 (file)
@@ -6,6 +6,8 @@ project(Caffe C CXX)
 # ---[ Using cmake scripts and modules
 list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/Modules)
 
+include(ExternalProject)
+
 include(cmake/Utils.cmake)
 include(cmake/Targets.cmake)
 include(cmake/Misc.cmake)
index f328e82..7cae5c9 100644 (file)
@@ -11,12 +11,12 @@ find_package(Threads REQUIRED)
 list(APPEND Caffe_LINKER_LIBS ${CMAKE_THREAD_LIBS_INIT})
 
 # ---[ Google-glog
-find_package(Glog REQUIRED)
+include("cmake/External/glog.cmake")
 include_directories(SYSTEM ${GLOG_INCLUDE_DIRS})
 list(APPEND Caffe_LINKER_LIBS ${GLOG_LIBRARIES})
 
 # ---[ Google-gflags
-find_package(GFlags REQUIRED)
+include("cmake/External/gflags.cmake")
 include_directories(SYSTEM ${GFLAGS_INCLUDE_DIRS})
 list(APPEND Caffe_LINKER_LIBS ${GFLAGS_LIBRARIES})
 
diff --git a/cmake/External/gflags.cmake b/cmake/External/gflags.cmake
new file mode 100644 (file)
index 0000000..a50a092
--- /dev/null
@@ -0,0 +1,56 @@
+if (NOT __GFLAGS_INCLUDED) # guard against multiple includes
+  set(__GFLAGS_INCLUDED TRUE)
+
+  # use the system-wide gflags if present
+  find_package(GFlags)
+  if (GFLAGS_FOUND)
+    set(GFLAGS_EXTERNAL FALSE)
+  else()
+    # gflags will use pthreads if it's available in the system, so we must link with it
+    find_package(Threads)
+
+    # build directory
+    set(gflags_PREFIX ${CMAKE_BINARY_DIR}/external/gflags-prefix)
+    # install directory
+    set(gflags_INSTALL ${CMAKE_BINARY_DIR}/external/gflags-install)
+
+    # we build gflags statically, but want to link it into the caffe shared library
+    # this requires position-independent code
+    if (UNIX)
+        set(GFLAGS_EXTRA_COMPILER_FLAGS "-fPIC")
+    endif()
+
+    set(GFLAGS_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${GFLAGS_EXTRA_COMPILER_FLAGS})
+    set(GFLAGS_C_FLAGS ${CMAKE_C_FLAGS} ${GFLAGS_EXTRA_COMPILER_FLAGS})
+
+    ExternalProject_Add(gflags
+      PREFIX ${gflags_PREFIX}
+      GIT_REPOSITORY "https://github.com/gflags/gflags.git"
+      GIT_TAG "v2.1.2"
+      UPDATE_COMMAND ""
+      INSTALL_DIR ${gflags_INSTALL}
+      CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
+                 -DCMAKE_INSTALL_PREFIX=${gflags_INSTALL}
+                 -DBUILD_SHARED_LIBS=OFF
+                 -DBUILD_STATIC_LIBS=ON
+                 -DBUILD_PACKAGING=OFF
+                 -DBUILD_TESTING=OFF
+                 -DBUILD_NC_TESTS=OFF
+                 -BUILD_CONFIG_TESTS=OFF
+                 -DINSTALL_HEADERS=ON
+                 -DCMAKE_C_FLAGS=${GFLAGS_C_FLAGS}
+                 -DCMAKE_CXX_FLAGS=${GFLAGS_CXX_FLAGS}
+      LOG_DOWNLOAD 1
+      LOG_INSTALL 1
+      )
+  
+    set(GFLAGS_FOUND TRUE)
+    set(GFLAGS_INCLUDE_DIRS ${gflags_INSTALL}/include)
+    set(GFLAGS_LIBRARIES ${gflags_INSTALL}/lib/libgflags.a ${CMAKE_THREAD_LIBS_INIT})    
+    set(GFLAGS_LIBRARY_DIRS ${gflags_INSTALL}/lib)
+    set(GFLAGS_EXTERNAL TRUE)
+
+    list(APPEND external_project_dependencies gflags)
+  endif()
+
+endif()
diff --git a/cmake/External/glog.cmake b/cmake/External/glog.cmake
new file mode 100644 (file)
index 0000000..02b39dd
--- /dev/null
@@ -0,0 +1,56 @@
+# glog depends on gflags
+include("cmake/External/gflags.cmake")
+
+if (NOT __GLOG_INCLUDED)
+  set(__GLOG_INCLUDED TRUE)
+
+  # try the system-wide glog first
+  find_package(Glog)
+  if (GLOG_FOUND)
+      set(GLOG_EXTERNAL FALSE)
+  else()
+    # fetch and build glog from github
+
+    # build directory
+    set(glog_PREFIX ${CMAKE_BINARY_DIR}/external/glog-prefix)
+    # install directory
+    set(glog_INSTALL ${CMAKE_BINARY_DIR}/external/glog-install)
+
+    # we build glog statically, but want to link it into the caffe shared library
+    # this requires position-independent code
+    if (UNIX)
+      set(GLOG_EXTRA_COMPILER_FLAGS "-fPIC")
+    endif()
+
+    set(GLOG_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${GLOG_EXTRA_COMPILER_FLAGS})
+    set(GLOG_C_FLAGS ${CMAKE_C_FLAGS} ${GLOG_EXTRA_COMPILER_FLAGS})
+
+    # depend on gflags if we're also building it
+    if (GFLAGS_EXTERNAL)
+      set(GLOG_DEPENDS gflags)
+    endif()
+    
+    ExternalProject_Add(glog
+      DEPENDS ${GLOG_DEPENDS}
+      PREFIX ${glog_PREFIX}
+      GIT_REPOSITORY "https://github.com/google/glog"
+      GIT_TAG "v0.3.4"
+      UPDATE_COMMAND ""
+      INSTALL_DIR ${gflags_INSTALL}
+      CONFIGURE_COMMAND env "CFLAGS=${GLOG_C_FLAGS}" "CXXFLAGS=${GLOG_CXX_FLAGS}" ${glog_PREFIX}/src/glog/configure --prefix=${glog_INSTALL} --enable-shared=no --enable-static=yes --with-gflags=${GFLAGS_LIBRARY_DIRS}/..
+      LOG_DOWNLOAD 1
+      LOG_CONFIGURE 1
+      LOG_INSTALL 1
+      )
+
+    set(GLOG_FOUND TRUE)
+    set(GLOG_INCLUDE_DIRS ${glog_INSTALL}/include)
+    set(GLOG_LIBRARIES ${GFLAGS_LIBRARIES} ${glog_INSTALL}/lib/libglog.a)
+    set(GLOG_LIBRARY_DIRS ${glog_INSTALL}/lib)
+    set(GLOG_EXTERNAL TRUE)
+
+    list(APPEND external_project_dependencies glog)
+  endif()
+
+endif()
+
index e3ad872..ed0ff96 100644 (file)
@@ -110,6 +110,10 @@ function(caffe_default_properties target)
     ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib"
     LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib"
     RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
+  # make sure we build all external depepdencies first
+  if (DEFINED external_project_dependencies)
+    add_dependencies(${target} ${external_project_dependencies})
+  endif()
 endfunction()
 
 ################################################################################################