Improvements to the build system #4609

Merged
merged 6 commits into from Feb 17, 2017
View
@@ -38,6 +38,7 @@ caffe_option(USE_OPENCV "Build with OpenCV support" ON)
caffe_option(USE_LEVELDB "Build with levelDB" ON)
caffe_option(USE_LMDB "Build with lmdb" ON)
caffe_option(ALLOW_LMDB_NOLOCK "Allow MDB_NOLOCK when reading LMDB files (only if necessary)" OFF)
+caffe_option(USE_OPENMP "Link with OpenMP (when your BLAS wants OpenMP and you get linker errors)" OFF)
# ---[ Dependencies
include(cmake/Dependencies.cmake)
@@ -54,8 +55,6 @@ if(USE_libstdcpp)
message("-- Warning: forcing libstdc++ (controlled by USE_libstdcpp option in cmake)")
endif()
-add_definitions(-DGTEST_USE_OWN_TR1_TUPLE)
-
# ---[ Warnings
caffe_warnings_disable(CMAKE_CXX_FLAGS -Wno-sign-compare -Wno-uninitialized)
@@ -64,8 +63,26 @@ configure_file(cmake/Templates/caffe_config.h.in "${PROJECT_BINARY_DIR}/caffe_co
# ---[ Includes
set(Caffe_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
-include_directories(${Caffe_INCLUDE_DIR} ${PROJECT_BINARY_DIR})
-include_directories(BEFORE src) # This is needed for gtest.
+set(Caffe_SRC_DIR ${PROJECT_SOURCE_DIR}/src)
+include_directories(${PROJECT_BINARY_DIR})
+
+# ---[ Includes & defines for CUDA
+
+# cuda_compile() does not have per-call dependencies or include pathes
+# (cuda_compile() has per-call flags, but we set them here too for clarity)
+#
+# list(REMOVE_ITEM ...) invocations remove PRIVATE and PUBLIC keywords from collected definitions and include pathes
+if(HAVE_CUDA)
+ # pass include pathes to cuda_include_directories()
+ set(Caffe_ALL_INCLUDE_DIRS ${Caffe_INCLUDE_DIRS})
+ list(REMOVE_ITEM Caffe_ALL_INCLUDE_DIRS PRIVATE PUBLIC)
+ cuda_include_directories(${Caffe_INCLUDE_DIR} ${Caffe_SRC_DIR} ${Caffe_ALL_INCLUDE_DIRS})
+
+ # add definitions to nvcc flags directly
+ set(Caffe_ALL_DEFINITIONS ${Caffe_DEFINITIONS})
+ list(REMOVE_ITEM Caffe_ALL_DEFINITIONS PRIVATE PUBLIC)
+ list(APPEND CUDA_NVCC_FLAGS ${Caffe_ALL_DEFINITIONS})
+endif()
# ---[ Subdirectories
add_subdirectory(src/gtest)
View
@@ -1,32 +1,5 @@
################################################################################################
-# Helper function to fetch caffe includes which will be passed to dependent projects
-# Usage:
-# caffe_get_current_includes(<includes_list_variable>)
-function(caffe_get_current_includes includes_variable)
- get_property(current_includes DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
- caffe_convert_absolute_paths(current_includes)
-
- # remove at most one ${PROJECT_BINARY_DIR} include added for caffe_config.h
- list(FIND current_includes ${PROJECT_BINARY_DIR} __index)
- list(REMOVE_AT current_includes ${__index})
-
- # removing numpy includes (since not required for client libs)
- set(__toremove "")
- foreach(__i ${current_includes})
- if(${__i} MATCHES "python")
- list(APPEND __toremove ${__i})
- endif()
- endforeach()
- if(__toremove)
- list(REMOVE_ITEM current_includes ${__toremove})
- endif()
-
- caffe_list_unique(current_includes)
- set(${includes_variable} ${current_includes} PARENT_SCOPE)
-endfunction()
-
-################################################################################################
# Helper function to get all list items that begin with given prefix
# Usage:
# caffe_get_items_with_prefix(<prefix> <list_variable> <output_variable>)
@@ -47,39 +20,15 @@ endfunction()
function(caffe_generate_export_configs)
set(install_cmake_suffix "share/Caffe")
- # ---[ Configure build-tree CaffeConfig.cmake file ]---
- caffe_get_current_includes(Caffe_INCLUDE_DIRS)
-
- set(Caffe_DEFINITIONS "")
if(NOT HAVE_CUDA)
set(HAVE_CUDA FALSE)
- list(APPEND Caffe_DEFINITIONS -DCPU_ONLY)
- endif()
-
- if(USE_OPENCV)
- list(APPEND Caffe_DEFINITIONS -DUSE_OPENCV)
- endif()
-
- if(USE_LMDB)
- list(APPEND Caffe_DEFINITIONS -DUSE_LMDB)
- if (ALLOW_LMDB_NOLOCK)
- list(APPEND Caffe_DEFINITIONS -DALLOW_LMDB_NOLOCK)
- endif()
- endif()
-
- if(USE_LEVELDB)
- list(APPEND Caffe_DEFINITIONS -DUSE_LEVELDB)
endif()
if(NOT HAVE_CUDNN)
set(HAVE_CUDNN FALSE)
- else()
- list(APPEND DEFINITIONS -DUSE_CUDNN)
endif()
- if(BLAS STREQUAL "MKL" OR BLAS STREQUAL "mkl")
- list(APPEND Caffe_DEFINITIONS -DUSE_MKL)
- endif()
+ # ---[ Configure build-tree CaffeConfig.cmake file ]---
configure_file("cmake/Templates/CaffeConfig.cmake.in" "${PROJECT_BINARY_DIR}/CaffeConfig.cmake" @ONLY)
@@ -89,18 +38,6 @@ function(caffe_generate_export_configs)
# ---[ Configure install-tree CaffeConfig.cmake file ]---
- # remove source and build dir includes
- caffe_get_items_with_prefix(${PROJECT_SOURCE_DIR} Caffe_INCLUDE_DIRS __insource)
- caffe_get_items_with_prefix(${PROJECT_BINARY_DIR} Caffe_INCLUDE_DIRS __inbinary)
- list(REMOVE_ITEM Caffe_INCLUDE_DIRS ${__insource} ${__inbinary})
-
- # add `install` include folder
- set(lines
- "get_filename_component(__caffe_include \"\${Caffe_CMAKE_DIR}/../../include\" ABSOLUTE)\n"
- "list(APPEND Caffe_INCLUDE_DIRS \${__caffe_include})\n"
- "unset(__caffe_include)\n")
- string(REPLACE ";" "" Caffe_INSTALL_INCLUDE_DIR_APPEND_COMMAND ${lines})
-
configure_file("cmake/Templates/CaffeConfig.cmake.in" "${PROJECT_BINARY_DIR}/cmake/CaffeConfig.cmake" @ONLY)
# Install the CaffeConfig.cmake and export set to use with install-tree
View
@@ -238,17 +238,17 @@ endif()
set(HAVE_CUDA TRUE)
message(STATUS "CUDA detected: " ${CUDA_VERSION})
-include_directories(SYSTEM ${CUDA_INCLUDE_DIRS})
-list(APPEND Caffe_LINKER_LIBS ${CUDA_CUDART_LIBRARY}
- ${CUDA_curand_LIBRARY} ${CUDA_CUBLAS_LIBRARIES})
+list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${CUDA_INCLUDE_DIRS})
+list(APPEND Caffe_LINKER_LIBS PUBLIC ${CUDA_CUDART_LIBRARY}
+ ${CUDA_curand_LIBRARY} ${CUDA_CUBLAS_LIBRARIES})
# cudnn detection
if(USE_CUDNN)
detect_cuDNN()
if(HAVE_CUDNN)
- add_definitions(-DUSE_CUDNN)
- include_directories(SYSTEM ${CUDNN_INCLUDE})
- list(APPEND Caffe_LINKER_LIBS ${CUDNN_LIBRARY})
+ list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_CUDNN)
+ list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${CUDNN_INCLUDE})
+ list(APPEND Caffe_LINKER_LIBS PUBLIC ${CUDNN_LIBRARY})
endif()
endif()
View
@@ -1,57 +1,76 @@
-# This list is required for static linking and exported to CaffeConfig.cmake
+# These lists are later turned into target properties on main caffe library target
set(Caffe_LINKER_LIBS "")
+set(Caffe_INCLUDE_DIRS "")
+set(Caffe_DEFINITIONS "")
+set(Caffe_COMPILE_OPTIONS "")
# ---[ Boost
find_package(Boost 1.46 REQUIRED COMPONENTS system thread filesystem)
-include_directories(SYSTEM ${Boost_INCLUDE_DIR})
-list(APPEND Caffe_LINKER_LIBS ${Boost_LIBRARIES})
+list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${Boost_INCLUDE_DIRS})
+list(APPEND Caffe_LINKER_LIBS PUBLIC ${Boost_LIBRARIES})
# ---[ Threads
find_package(Threads REQUIRED)
-list(APPEND Caffe_LINKER_LIBS ${CMAKE_THREAD_LIBS_INIT})
+list(APPEND Caffe_LINKER_LIBS PRIVATE ${CMAKE_THREAD_LIBS_INIT})
+
+# ---[ OpenMP
+if(USE_OPENMP)
+ # Ideally, this should be provided by the BLAS library IMPORTED target. However,
+ # nobody does this, so we need to link to OpenMP explicitly and have the maintainer
+ # to flick the switch manually as needed.
+ #
+ # Moreover, OpenMP package does not provide an IMPORTED target as well, and the
+ # suggested way of linking to OpenMP is to append to CMAKE_{C,CXX}_FLAGS.
+ # However, this naïve method will force any user of Caffe to add the same kludge
+ # into their buildsystem again, so we put these options into per-target PUBLIC
+ # compile options and link flags, so that they will be exported properly.
+ find_package(OpenMP REQUIRED)
+ list(APPEND Caffe_LINKER_LIBS PRIVATE ${OpenMP_CXX_FLAGS})
+ list(APPEND Caffe_COMPILE_OPTIONS PRIVATE ${OpenMP_CXX_FLAGS})
+endif()
# ---[ Google-glog
include("cmake/External/glog.cmake")
-include_directories(SYSTEM ${GLOG_INCLUDE_DIRS})
-list(APPEND Caffe_LINKER_LIBS ${GLOG_LIBRARIES})
+list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${GLOG_INCLUDE_DIRS})
+list(APPEND Caffe_LINKER_LIBS PUBLIC ${GLOG_LIBRARIES})
# ---[ Google-gflags
include("cmake/External/gflags.cmake")
-include_directories(SYSTEM ${GFLAGS_INCLUDE_DIRS})
-list(APPEND Caffe_LINKER_LIBS ${GFLAGS_LIBRARIES})
+list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${GFLAGS_INCLUDE_DIRS})
+list(APPEND Caffe_LINKER_LIBS PUBLIC ${GFLAGS_LIBRARIES})
# ---[ Google-protobuf
include(cmake/ProtoBuf.cmake)
# ---[ HDF5
find_package(HDF5 COMPONENTS HL REQUIRED)
-include_directories(SYSTEM ${HDF5_INCLUDE_DIRS} ${HDF5_HL_INCLUDE_DIR})
-list(APPEND Caffe_LINKER_LIBS ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES})
+list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${HDF5_INCLUDE_DIRS})
+list(APPEND Caffe_LINKER_LIBS PUBLIC ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES})
# ---[ LMDB
if(USE_LMDB)
find_package(LMDB REQUIRED)
- include_directories(SYSTEM ${LMDB_INCLUDE_DIR})
- list(APPEND Caffe_LINKER_LIBS ${LMDB_LIBRARIES})
- add_definitions(-DUSE_LMDB)
+ list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${LMDB_INCLUDE_DIR})
+ list(APPEND Caffe_LINKER_LIBS PUBLIC ${LMDB_LIBRARIES})
+ list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_LMDB)
if(ALLOW_LMDB_NOLOCK)
- add_definitions(-DALLOW_LMDB_NOLOCK)
+ list(APPEND Caffe_DEFINITIONS PRIVATE -DALLOW_LMDB_NOLOCK)
endif()
endif()
# ---[ LevelDB
if(USE_LEVELDB)
find_package(LevelDB REQUIRED)
- include_directories(SYSTEM ${LevelDB_INCLUDE})
- list(APPEND Caffe_LINKER_LIBS ${LevelDB_LIBRARIES})
- add_definitions(-DUSE_LEVELDB)
+ list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${LevelDB_INCLUDES})
+ list(APPEND Caffe_LINKER_LIBS PUBLIC ${LevelDB_LIBRARIES})
+ list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_LEVELDB)
endif()
# ---[ Snappy
if(USE_LEVELDB)
find_package(Snappy REQUIRED)
- include_directories(SYSTEM ${Snappy_INCLUDE_DIR})
- list(APPEND Caffe_LINKER_LIBS ${Snappy_LIBRARIES})
+ list(APPEND Caffe_INCLUDE_DIRS PRIVATE ${Snappy_INCLUDE_DIR})
+ list(APPEND Caffe_LINKER_LIBS PRIVATE ${Snappy_LIBRARIES})
endif()
# ---[ CUDA
@@ -63,8 +82,7 @@ if(NOT HAVE_CUDA)
message(WARNING "-- CUDA is not detected by cmake. Building without it...")
endif()
- # TODO: remove this not cross platform define in future. Use caffe_config.h instead.
- add_definitions(-DCPU_ONLY)
+ list(APPEND Caffe_DEFINITIONS PUBLIC -DCPU_ONLY)
endif()
# ---[ OpenCV
@@ -73,10 +91,10 @@ if(USE_OPENCV)
if(NOT OpenCV_FOUND) # if not OpenCV 3.x, then imgcodecs are not found
find_package(OpenCV REQUIRED COMPONENTS core highgui imgproc)
endif()
- include_directories(SYSTEM ${OpenCV_INCLUDE_DIRS})
- list(APPEND Caffe_LINKER_LIBS ${OpenCV_LIBS})
+ list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${OpenCV_INCLUDE_DIRS})
+ list(APPEND Caffe_LINKER_LIBS PUBLIC ${OpenCV_LIBS})
message(STATUS "OpenCV found (${OpenCV_CONFIG_PATH})")
- add_definitions(-DUSE_OPENCV)
+ list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_OPENCV)
endif()
# ---[ BLAS
@@ -86,26 +104,26 @@ if(NOT APPLE)
if(BLAS STREQUAL "Atlas" OR BLAS STREQUAL "atlas")
find_package(Atlas REQUIRED)
- include_directories(SYSTEM ${Atlas_INCLUDE_DIR})
- list(APPEND Caffe_LINKER_LIBS ${Atlas_LIBRARIES})
+ list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${Atlas_INCLUDE_DIR})
+ list(APPEND Caffe_LINKER_LIBS PUBLIC ${Atlas_LIBRARIES})
elseif(BLAS STREQUAL "Open" OR BLAS STREQUAL "open")
find_package(OpenBLAS REQUIRED)
- include_directories(SYSTEM ${OpenBLAS_INCLUDE_DIR})
- list(APPEND Caffe_LINKER_LIBS ${OpenBLAS_LIB})
+ list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${OpenBLAS_INCLUDE_DIR})
+ list(APPEND Caffe_LINKER_LIBS PUBLIC ${OpenBLAS_LIB})
elseif(BLAS STREQUAL "MKL" OR BLAS STREQUAL "mkl")
find_package(MKL REQUIRED)
- include_directories(SYSTEM ${MKL_INCLUDE_DIR})
- list(APPEND Caffe_LINKER_LIBS ${MKL_LIBRARIES})
- add_definitions(-DUSE_MKL)
+ list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${MKL_INCLUDE_DIR})
+ list(APPEND Caffe_LINKER_LIBS PUBLIC ${MKL_LIBRARIES})
+ list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_MKL)
endif()
elseif(APPLE)
find_package(vecLib REQUIRED)
- include_directories(SYSTEM ${vecLib_INCLUDE_DIR})
- list(APPEND Caffe_LINKER_LIBS ${vecLib_LINKER_LIBS})
+ list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${vecLib_INCLUDE_DIR})
+ list(APPEND Caffe_LINKER_LIBS PUBLIC ${vecLib_LINKER_LIBS})
if(VECLIB_FOUND)
if(NOT vecLib_INCLUDE_DIR MATCHES "^/System/Library/Frameworks/vecLib.framework.*")
- add_definitions(-DUSE_ACCELERATE)
+ list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_ACCELERATE)
endif()
endif()
endif()
@@ -149,9 +167,9 @@ if(BUILD_python)
if(PYTHONLIBS_FOUND AND NUMPY_FOUND AND Boost_PYTHON_FOUND)
set(HAVE_PYTHON TRUE)
if(BUILD_python_layer)
- add_definitions(-DWITH_PYTHON_LAYER)
- include_directories(SYSTEM ${PYTHON_INCLUDE_DIRS} ${NUMPY_INCLUDE_DIR} ${Boost_INCLUDE_DIRS})
- list(APPEND Caffe_LINKER_LIBS ${PYTHON_LIBRARIES} ${Boost_LIBRARIES})
+ list(APPEND Caffe_DEFINITIONS PRIVATE -DWITH_PYTHON_LAYER)
+ list(APPEND Caffe_INCLUDE_DIRS PRIVATE ${PYTHON_INCLUDE_DIRS} ${NUMPY_INCLUDE_DIR} PUBLIC ${Boost_INCLUDE_DIRS})
+ list(APPEND Caffe_LINKER_LIBS PRIVATE ${PYTHON_LIBRARIES} PUBLIC ${Boost_LIBRARIES})
endif()
endif()
endif()
View
@@ -2,8 +2,8 @@
# the standard cmake script with version and python generation support
find_package( Protobuf REQUIRED )
-include_directories(SYSTEM ${PROTOBUF_INCLUDE_DIR})
-list(APPEND Caffe_LINKER_LIBS ${PROTOBUF_LIBRARIES})
+list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${PROTOBUF_INCLUDE_DIR})
+list(APPEND Caffe_LINKER_LIBS PUBLIC ${PROTOBUF_LIBRARIES})
# As of Ubuntu 14.04 protoc is no longer a part of libprotobuf-dev package
# and should be installed separately as in: sudo apt-get install protobuf-compiler
@@ -9,9 +9,9 @@
# After successful configuration the following variables
# will be defined:
#
-# Caffe_INCLUDE_DIRS - Caffe include directories
-# Caffe_LIBRARIES - libraries to link against
-# Caffe_DEFINITIONS - a list of definitions to pass to compiler
+# Caffe_LIBRARIES - IMPORTED targets to link against
+# (There is no Caffe_INCLUDE_DIRS and Caffe_DEFINITIONS
+# because they are specified in the IMPORTED target interface.)
#
# Caffe_HAVE_CUDA - signals about CUDA support
# Caffe_HAVE_CUDNN - signals about cuDNN support
@@ -27,7 +27,7 @@ if(@USE_OPENCV@)
if(EXISTS ${Caffe_OpenCV_CONFIG_PATH} AND NOT TARGET opencv_core)
message(STATUS "Caffe: using OpenCV config from ${Caffe_OpenCV_CONFIG_PATH}")
- include(${Caffe_OpenCV_CONFIG_PATH}/OpenCVModules.cmake)
+ include(${Caffe_OpenCV_CONFIG_PATH}/OpenCVConfig.cmake)
endif()
else()
@@ -39,21 +39,16 @@ endif()
# Compute paths
get_filename_component(Caffe_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
-set(Caffe_INCLUDE_DIRS "@Caffe_INCLUDE_DIRS@")
-
-@Caffe_INSTALL_INCLUDE_DIR_APPEND_COMMAND@
# Our library dependencies
if(NOT TARGET caffe AND NOT caffe_BINARY_DIR)
include("${Caffe_CMAKE_DIR}/CaffeTargets.cmake")
endif()
# List of IMPORTED libs created by CaffeTargets.cmake
+# These targets already specify all needed definitions and include pathes
set(Caffe_LIBRARIES caffe)
-# Definitions
-set(Caffe_DEFINITIONS "@Caffe_DEFINITIONS@")
-
# Cuda support variables
set(Caffe_CPU_ONLY @CPU_ONLY@)
set(Caffe_HAVE_CUDA @HAVE_CUDA@)
Oops, something went wrong.