Skip to content

Commit 9bb1b9c

Browse files
authored
Merge pull request #4609 from intelfx/BVLC-work-buildsystem
[cmake] Improvements to the build system
2 parents 475d619 + 6ed799c commit 9bb1b9c

File tree

11 files changed

+109
-150
lines changed

11 files changed

+109
-150
lines changed

CMakeLists.txt

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ caffe_option(USE_OPENCV "Build with OpenCV support" ON)
3939
caffe_option(USE_LEVELDB "Build with levelDB" ON)
4040
caffe_option(USE_LMDB "Build with lmdb" ON)
4141
caffe_option(ALLOW_LMDB_NOLOCK "Allow MDB_NOLOCK when reading LMDB files (only if necessary)" OFF)
42+
caffe_option(USE_OPENMP "Link with OpenMP (when your BLAS wants OpenMP and you get linker errors)" OFF)
4243

4344
# ---[ Dependencies
4445
include(cmake/Dependencies.cmake)
@@ -55,8 +56,6 @@ if(USE_libstdcpp)
5556
message("-- Warning: forcing libstdc++ (controlled by USE_libstdcpp option in cmake)")
5657
endif()
5758

58-
add_definitions(-DGTEST_USE_OWN_TR1_TUPLE)
59-
6059
# ---[ Warnings
6160
caffe_warnings_disable(CMAKE_CXX_FLAGS -Wno-sign-compare -Wno-uninitialized)
6261

@@ -65,8 +64,26 @@ configure_file(cmake/Templates/caffe_config.h.in "${PROJECT_BINARY_DIR}/caffe_co
6564

6665
# ---[ Includes
6766
set(Caffe_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
68-
include_directories(${Caffe_INCLUDE_DIR} ${PROJECT_BINARY_DIR})
69-
include_directories(BEFORE src) # This is needed for gtest.
67+
set(Caffe_SRC_DIR ${PROJECT_SOURCE_DIR}/src)
68+
include_directories(${PROJECT_BINARY_DIR})
69+
70+
# ---[ Includes & defines for CUDA
71+
72+
# cuda_compile() does not have per-call dependencies or include pathes
73+
# (cuda_compile() has per-call flags, but we set them here too for clarity)
74+
#
75+
# list(REMOVE_ITEM ...) invocations remove PRIVATE and PUBLIC keywords from collected definitions and include pathes
76+
if(HAVE_CUDA)
77+
# pass include pathes to cuda_include_directories()
78+
set(Caffe_ALL_INCLUDE_DIRS ${Caffe_INCLUDE_DIRS})
79+
list(REMOVE_ITEM Caffe_ALL_INCLUDE_DIRS PRIVATE PUBLIC)
80+
cuda_include_directories(${Caffe_INCLUDE_DIR} ${Caffe_SRC_DIR} ${Caffe_ALL_INCLUDE_DIRS})
81+
82+
# add definitions to nvcc flags directly
83+
set(Caffe_ALL_DEFINITIONS ${Caffe_DEFINITIONS})
84+
list(REMOVE_ITEM Caffe_ALL_DEFINITIONS PRIVATE PUBLIC)
85+
list(APPEND CUDA_NVCC_FLAGS ${Caffe_ALL_DEFINITIONS})
86+
endif()
7087

7188
# ---[ Subdirectories
7289
add_subdirectory(src/gtest)

cmake/ConfigGen.cmake

Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,4 @@
11

2-
################################################################################################
3-
# Helper function to fetch caffe includes which will be passed to dependent projects
4-
# Usage:
5-
# caffe_get_current_includes(<includes_list_variable>)
6-
function(caffe_get_current_includes includes_variable)
7-
get_property(current_includes DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
8-
caffe_convert_absolute_paths(current_includes)
9-
10-
# remove at most one ${PROJECT_BINARY_DIR} include added for caffe_config.h
11-
list(FIND current_includes ${PROJECT_BINARY_DIR} __index)
12-
list(REMOVE_AT current_includes ${__index})
13-
14-
# removing numpy includes (since not required for client libs)
15-
set(__toremove "")
16-
foreach(__i ${current_includes})
17-
if(${__i} MATCHES "python")
18-
list(APPEND __toremove ${__i})
19-
endif()
20-
endforeach()
21-
if(__toremove)
22-
list(REMOVE_ITEM current_includes ${__toremove})
23-
endif()
24-
25-
caffe_list_unique(current_includes)
26-
set(${includes_variable} ${current_includes} PARENT_SCOPE)
27-
endfunction()
28-
292
################################################################################################
303
# Helper function to get all list items that begin with given prefix
314
# Usage:
@@ -47,39 +20,15 @@ endfunction()
4720
function(caffe_generate_export_configs)
4821
set(install_cmake_suffix "share/Caffe")
4922

50-
# ---[ Configure build-tree CaffeConfig.cmake file ]---
51-
caffe_get_current_includes(Caffe_INCLUDE_DIRS)
52-
53-
set(Caffe_DEFINITIONS "")
5423
if(NOT HAVE_CUDA)
5524
set(HAVE_CUDA FALSE)
56-
list(APPEND Caffe_DEFINITIONS -DCPU_ONLY)
57-
endif()
58-
59-
if(USE_OPENCV)
60-
list(APPEND Caffe_DEFINITIONS -DUSE_OPENCV)
61-
endif()
62-
63-
if(USE_LMDB)
64-
list(APPEND Caffe_DEFINITIONS -DUSE_LMDB)
65-
if (ALLOW_LMDB_NOLOCK)
66-
list(APPEND Caffe_DEFINITIONS -DALLOW_LMDB_NOLOCK)
67-
endif()
68-
endif()
69-
70-
if(USE_LEVELDB)
71-
list(APPEND Caffe_DEFINITIONS -DUSE_LEVELDB)
7225
endif()
7326

7427
if(NOT HAVE_CUDNN)
7528
set(HAVE_CUDNN FALSE)
76-
else()
77-
list(APPEND DEFINITIONS -DUSE_CUDNN)
7829
endif()
7930

80-
if(BLAS STREQUAL "MKL" OR BLAS STREQUAL "mkl")
81-
list(APPEND Caffe_DEFINITIONS -DUSE_MKL)
82-
endif()
31+
# ---[ Configure build-tree CaffeConfig.cmake file ]---
8332

8433
configure_file("cmake/Templates/CaffeConfig.cmake.in" "${PROJECT_BINARY_DIR}/CaffeConfig.cmake" @ONLY)
8534

@@ -89,18 +38,6 @@ function(caffe_generate_export_configs)
8938

9039
# ---[ Configure install-tree CaffeConfig.cmake file ]---
9140

92-
# remove source and build dir includes
93-
caffe_get_items_with_prefix(${PROJECT_SOURCE_DIR} Caffe_INCLUDE_DIRS __insource)
94-
caffe_get_items_with_prefix(${PROJECT_BINARY_DIR} Caffe_INCLUDE_DIRS __inbinary)
95-
list(REMOVE_ITEM Caffe_INCLUDE_DIRS ${__insource} ${__inbinary})
96-
97-
# add `install` include folder
98-
set(lines
99-
"get_filename_component(__caffe_include \"\${Caffe_CMAKE_DIR}/../../include\" ABSOLUTE)\n"
100-
"list(APPEND Caffe_INCLUDE_DIRS \${__caffe_include})\n"
101-
"unset(__caffe_include)\n")
102-
string(REPLACE ";" "" Caffe_INSTALL_INCLUDE_DIR_APPEND_COMMAND ${lines})
103-
10441
configure_file("cmake/Templates/CaffeConfig.cmake.in" "${PROJECT_BINARY_DIR}/cmake/CaffeConfig.cmake" @ONLY)
10542

10643
# Install the CaffeConfig.cmake and export set to use with install-tree

cmake/Cuda.cmake

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -240,17 +240,17 @@ endif()
240240

241241
set(HAVE_CUDA TRUE)
242242
message(STATUS "CUDA detected: " ${CUDA_VERSION})
243-
include_directories(SYSTEM ${CUDA_INCLUDE_DIRS})
244-
list(APPEND Caffe_LINKER_LIBS ${CUDA_CUDART_LIBRARY}
245-
${CUDA_curand_LIBRARY} ${CUDA_CUBLAS_LIBRARIES})
243+
list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${CUDA_INCLUDE_DIRS})
244+
list(APPEND Caffe_LINKER_LIBS PUBLIC ${CUDA_CUDART_LIBRARY}
245+
${CUDA_curand_LIBRARY} ${CUDA_CUBLAS_LIBRARIES})
246246

247247
# cudnn detection
248248
if(USE_CUDNN)
249249
detect_cuDNN()
250250
if(HAVE_CUDNN)
251-
add_definitions(-DUSE_CUDNN)
252-
include_directories(SYSTEM ${CUDNN_INCLUDE})
253-
list(APPEND Caffe_LINKER_LIBS ${CUDNN_LIBRARY})
251+
list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_CUDNN)
252+
list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${CUDNN_INCLUDE})
253+
list(APPEND Caffe_LINKER_LIBS PUBLIC ${CUDNN_LIBRARY})
254254
endif()
255255
endif()
256256

cmake/Dependencies.cmake

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,76 @@
1-
# This list is required for static linking and exported to CaffeConfig.cmake
1+
# These lists are later turned into target properties on main caffe library target
22
set(Caffe_LINKER_LIBS "")
3+
set(Caffe_INCLUDE_DIRS "")
4+
set(Caffe_DEFINITIONS "")
5+
set(Caffe_COMPILE_OPTIONS "")
36

47
# ---[ Boost
58
find_package(Boost 1.46 REQUIRED COMPONENTS system thread filesystem)
6-
include_directories(SYSTEM ${Boost_INCLUDE_DIR})
7-
list(APPEND Caffe_LINKER_LIBS ${Boost_LIBRARIES})
9+
list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${Boost_INCLUDE_DIRS})
10+
list(APPEND Caffe_LINKER_LIBS PUBLIC ${Boost_LIBRARIES})
811

912
# ---[ Threads
1013
find_package(Threads REQUIRED)
11-
list(APPEND Caffe_LINKER_LIBS ${CMAKE_THREAD_LIBS_INIT})
14+
list(APPEND Caffe_LINKER_LIBS PRIVATE ${CMAKE_THREAD_LIBS_INIT})
15+
16+
# ---[ OpenMP
17+
if(USE_OPENMP)
18+
# Ideally, this should be provided by the BLAS library IMPORTED target. However,
19+
# nobody does this, so we need to link to OpenMP explicitly and have the maintainer
20+
# to flick the switch manually as needed.
21+
#
22+
# Moreover, OpenMP package does not provide an IMPORTED target as well, and the
23+
# suggested way of linking to OpenMP is to append to CMAKE_{C,CXX}_FLAGS.
24+
# However, this naïve method will force any user of Caffe to add the same kludge
25+
# into their buildsystem again, so we put these options into per-target PUBLIC
26+
# compile options and link flags, so that they will be exported properly.
27+
find_package(OpenMP REQUIRED)
28+
list(APPEND Caffe_LINKER_LIBS PRIVATE ${OpenMP_CXX_FLAGS})
29+
list(APPEND Caffe_COMPILE_OPTIONS PRIVATE ${OpenMP_CXX_FLAGS})
30+
endif()
1231

1332
# ---[ Google-glog
1433
include("cmake/External/glog.cmake")
15-
include_directories(SYSTEM ${GLOG_INCLUDE_DIRS})
16-
list(APPEND Caffe_LINKER_LIBS ${GLOG_LIBRARIES})
34+
list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${GLOG_INCLUDE_DIRS})
35+
list(APPEND Caffe_LINKER_LIBS PUBLIC ${GLOG_LIBRARIES})
1736

1837
# ---[ Google-gflags
1938
include("cmake/External/gflags.cmake")
20-
include_directories(SYSTEM ${GFLAGS_INCLUDE_DIRS})
21-
list(APPEND Caffe_LINKER_LIBS ${GFLAGS_LIBRARIES})
39+
list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${GFLAGS_INCLUDE_DIRS})
40+
list(APPEND Caffe_LINKER_LIBS PUBLIC ${GFLAGS_LIBRARIES})
2241

2342
# ---[ Google-protobuf
2443
include(cmake/ProtoBuf.cmake)
2544

2645
# ---[ HDF5
2746
find_package(HDF5 COMPONENTS HL REQUIRED)
28-
include_directories(SYSTEM ${HDF5_INCLUDE_DIRS} ${HDF5_HL_INCLUDE_DIR})
29-
list(APPEND Caffe_LINKER_LIBS ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES})
47+
list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${HDF5_INCLUDE_DIRS})
48+
list(APPEND Caffe_LINKER_LIBS PUBLIC ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES})
3049

3150
# ---[ LMDB
3251
if(USE_LMDB)
3352
find_package(LMDB REQUIRED)
34-
include_directories(SYSTEM ${LMDB_INCLUDE_DIR})
35-
list(APPEND Caffe_LINKER_LIBS ${LMDB_LIBRARIES})
36-
add_definitions(-DUSE_LMDB)
53+
list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${LMDB_INCLUDE_DIR})
54+
list(APPEND Caffe_LINKER_LIBS PUBLIC ${LMDB_LIBRARIES})
55+
list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_LMDB)
3756
if(ALLOW_LMDB_NOLOCK)
38-
add_definitions(-DALLOW_LMDB_NOLOCK)
57+
list(APPEND Caffe_DEFINITIONS PRIVATE -DALLOW_LMDB_NOLOCK)
3958
endif()
4059
endif()
4160

4261
# ---[ LevelDB
4362
if(USE_LEVELDB)
4463
find_package(LevelDB REQUIRED)
45-
include_directories(SYSTEM ${LevelDB_INCLUDE})
46-
list(APPEND Caffe_LINKER_LIBS ${LevelDB_LIBRARIES})
47-
add_definitions(-DUSE_LEVELDB)
64+
list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${LevelDB_INCLUDES})
65+
list(APPEND Caffe_LINKER_LIBS PUBLIC ${LevelDB_LIBRARIES})
66+
list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_LEVELDB)
4867
endif()
4968

5069
# ---[ Snappy
5170
if(USE_LEVELDB)
5271
find_package(Snappy REQUIRED)
53-
include_directories(SYSTEM ${Snappy_INCLUDE_DIR})
54-
list(APPEND Caffe_LINKER_LIBS ${Snappy_LIBRARIES})
72+
list(APPEND Caffe_INCLUDE_DIRS PRIVATE ${Snappy_INCLUDE_DIR})
73+
list(APPEND Caffe_LINKER_LIBS PRIVATE ${Snappy_LIBRARIES})
5574
endif()
5675

5776
# ---[ CUDA
@@ -63,8 +82,7 @@ if(NOT HAVE_CUDA)
6382
message(WARNING "-- CUDA is not detected by cmake. Building without it...")
6483
endif()
6584

66-
# TODO: remove this not cross platform define in future. Use caffe_config.h instead.
67-
add_definitions(-DCPU_ONLY)
85+
list(APPEND Caffe_DEFINITIONS PUBLIC -DCPU_ONLY)
6886
endif()
6987

7088
if(USE_NCCL)
@@ -80,10 +98,10 @@ if(USE_OPENCV)
8098
if(NOT OpenCV_FOUND) # if not OpenCV 3.x, then imgcodecs are not found
8199
find_package(OpenCV REQUIRED COMPONENTS core highgui imgproc)
82100
endif()
83-
include_directories(SYSTEM ${OpenCV_INCLUDE_DIRS})
84-
list(APPEND Caffe_LINKER_LIBS ${OpenCV_LIBS})
101+
list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${OpenCV_INCLUDE_DIRS})
102+
list(APPEND Caffe_LINKER_LIBS PUBLIC ${OpenCV_LIBS})
85103
message(STATUS "OpenCV found (${OpenCV_CONFIG_PATH})")
86-
add_definitions(-DUSE_OPENCV)
104+
list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_OPENCV)
87105
endif()
88106

89107
# ---[ BLAS
@@ -93,26 +111,26 @@ if(NOT APPLE)
93111

94112
if(BLAS STREQUAL "Atlas" OR BLAS STREQUAL "atlas")
95113
find_package(Atlas REQUIRED)
96-
include_directories(SYSTEM ${Atlas_INCLUDE_DIR})
97-
list(APPEND Caffe_LINKER_LIBS ${Atlas_LIBRARIES})
114+
list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${Atlas_INCLUDE_DIR})
115+
list(APPEND Caffe_LINKER_LIBS PUBLIC ${Atlas_LIBRARIES})
98116
elseif(BLAS STREQUAL "Open" OR BLAS STREQUAL "open")
99117
find_package(OpenBLAS REQUIRED)
100-
include_directories(SYSTEM ${OpenBLAS_INCLUDE_DIR})
101-
list(APPEND Caffe_LINKER_LIBS ${OpenBLAS_LIB})
118+
list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${OpenBLAS_INCLUDE_DIR})
119+
list(APPEND Caffe_LINKER_LIBS PUBLIC ${OpenBLAS_LIB})
102120
elseif(BLAS STREQUAL "MKL" OR BLAS STREQUAL "mkl")
103121
find_package(MKL REQUIRED)
104-
include_directories(SYSTEM ${MKL_INCLUDE_DIR})
105-
list(APPEND Caffe_LINKER_LIBS ${MKL_LIBRARIES})
106-
add_definitions(-DUSE_MKL)
122+
list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${MKL_INCLUDE_DIR})
123+
list(APPEND Caffe_LINKER_LIBS PUBLIC ${MKL_LIBRARIES})
124+
list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_MKL)
107125
endif()
108126
elseif(APPLE)
109127
find_package(vecLib REQUIRED)
110-
include_directories(SYSTEM ${vecLib_INCLUDE_DIR})
111-
list(APPEND Caffe_LINKER_LIBS ${vecLib_LINKER_LIBS})
128+
list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${vecLib_INCLUDE_DIR})
129+
list(APPEND Caffe_LINKER_LIBS PUBLIC ${vecLib_LINKER_LIBS})
112130

113131
if(VECLIB_FOUND)
114132
if(NOT vecLib_INCLUDE_DIR MATCHES "^/System/Library/Frameworks/vecLib.framework.*")
115-
add_definitions(-DUSE_ACCELERATE)
133+
list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_ACCELERATE)
116134
endif()
117135
endif()
118136
endif()
@@ -156,9 +174,9 @@ if(BUILD_python)
156174
if(PYTHONLIBS_FOUND AND NUMPY_FOUND AND Boost_PYTHON_FOUND)
157175
set(HAVE_PYTHON TRUE)
158176
if(BUILD_python_layer)
159-
add_definitions(-DWITH_PYTHON_LAYER)
160-
include_directories(SYSTEM ${PYTHON_INCLUDE_DIRS} ${NUMPY_INCLUDE_DIR} ${Boost_INCLUDE_DIRS})
161-
list(APPEND Caffe_LINKER_LIBS ${PYTHON_LIBRARIES} ${Boost_LIBRARIES})
177+
list(APPEND Caffe_DEFINITIONS PRIVATE -DWITH_PYTHON_LAYER)
178+
list(APPEND Caffe_INCLUDE_DIRS PRIVATE ${PYTHON_INCLUDE_DIRS} ${NUMPY_INCLUDE_DIR} PUBLIC ${Boost_INCLUDE_DIRS})
179+
list(APPEND Caffe_LINKER_LIBS PRIVATE ${PYTHON_LIBRARIES} PUBLIC ${Boost_LIBRARIES})
162180
endif()
163181
endif()
164182
endif()

cmake/ProtoBuf.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
# the standard cmake script with version and python generation support
33

44
find_package( Protobuf REQUIRED )
5-
include_directories(SYSTEM ${PROTOBUF_INCLUDE_DIR})
6-
list(APPEND Caffe_LINKER_LIBS ${PROTOBUF_LIBRARIES})
5+
list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${PROTOBUF_INCLUDE_DIR})
6+
list(APPEND Caffe_LINKER_LIBS PUBLIC ${PROTOBUF_LIBRARIES})
77

88
# As of Ubuntu 14.04 protoc is no longer a part of libprotobuf-dev package
99
# and should be installed separately as in: sudo apt-get install protobuf-compiler

cmake/Templates/CaffeConfig.cmake.in

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
# After successful configuration the following variables
1010
# will be defined:
1111
#
12-
# Caffe_INCLUDE_DIRS - Caffe include directories
13-
# Caffe_LIBRARIES - libraries to link against
14-
# Caffe_DEFINITIONS - a list of definitions to pass to compiler
12+
# Caffe_LIBRARIES - IMPORTED targets to link against
13+
# (There is no Caffe_INCLUDE_DIRS and Caffe_DEFINITIONS
14+
# because they are specified in the IMPORTED target interface.)
1515
#
1616
# Caffe_HAVE_CUDA - signals about CUDA support
1717
# Caffe_HAVE_CUDNN - signals about cuDNN support
@@ -27,7 +27,7 @@ if(@USE_OPENCV@)
2727

2828
if(EXISTS ${Caffe_OpenCV_CONFIG_PATH} AND NOT TARGET opencv_core)
2929
message(STATUS "Caffe: using OpenCV config from ${Caffe_OpenCV_CONFIG_PATH}")
30-
include(${Caffe_OpenCV_CONFIG_PATH}/OpenCVModules.cmake)
30+
include(${Caffe_OpenCV_CONFIG_PATH}/OpenCVConfig.cmake)
3131
endif()
3232

3333
else()
@@ -39,21 +39,16 @@ endif()
3939

4040
# Compute paths
4141
get_filename_component(Caffe_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
42-
set(Caffe_INCLUDE_DIRS "@Caffe_INCLUDE_DIRS@")
43-
44-
@Caffe_INSTALL_INCLUDE_DIR_APPEND_COMMAND@
4542

4643
# Our library dependencies
4744
if(NOT TARGET caffe AND NOT caffe_BINARY_DIR)
4845
include("${Caffe_CMAKE_DIR}/CaffeTargets.cmake")
4946
endif()
5047

5148
# List of IMPORTED libs created by CaffeTargets.cmake
49+
# These targets already specify all needed definitions and include pathes
5250
set(Caffe_LIBRARIES caffe)
5351

54-
# Definitions
55-
set(Caffe_DEFINITIONS "@Caffe_DEFINITIONS@")
56-
5752
# Cuda support variables
5853
set(Caffe_CPU_ONLY @CPU_ONLY@)
5954
set(Caffe_HAVE_CUDA @HAVE_CUDA@)

0 commit comments

Comments
 (0)