1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
|
# Finds Google Protocol Buffers library and compilers and extends
# the standard cmake script with version and python generation support
macro(custom_protobuf_find)
message(STATUS "Use custom protobuf build.")
option(protobuf_BUILD_TESTS "" OFF)
option(protobuf_BUILD_EXAMPLES "" OFF)
option(protobuf_WITH_ZLIB "" OFF)
if(APPLE)
# Protobuf generated files triggers a deprecated atomic operation warning
# so we turn it off here.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
endif()
if(${CAFFE2_LINK_LOCAL_PROTOBUF})
# If we are going to link protobuf locally, we will need to turn off
# shared libs build for protobuf.
option(protobuf_BUILD_SHARED_LIBS "" OFF)
else()
# If we are building Caffe2 as shared libs, we will also build protobuf as
# shared libs.
option(protobuf_BUILD_SHARED_LIBS "" ${BUILD_SHARED_LIBS})
endif()
# We will make sure that protobuf and caffe2 uses the same msvc runtime.
option(protobuf_MSVC_STATIC_RUNTIME "" ${CAFFE2_USE_MSVC_STATIC_RUNTIME})
if(${CAFFE2_LINK_LOCAL_PROTOBUF})
set(__caffe2_CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ${CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS})
set(__caffe2_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS OFF)
set(BUILD_SHARED_LIBS OFF)
if(${COMPILER_SUPPORTS_HIDDEN_VISIBILITY})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
endif()
if(${COMPILER_SUPPORTS_HIDDEN_INLINE_VISIBILITY})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden")
endif()
endif()
set(__caffe2_CMAKE_POSITION_INDEPENDENT_CODE ${CMAKE_POSITION_INDEPENDENT_CODE})
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(MSVC)
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL)
if(${flag_var} MATCHES "/Z[iI7]")
string(REGEX REPLACE "/Z[iI7]" "" ${flag_var} "${${flag_var}}")
endif()
endforeach(flag_var)
if(MSVC_Z7_OVERRIDE)
foreach(flag_var
CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/Z[iI]")
string(REGEX REPLACE "/Z[iI]" "/Z7" ${flag_var} "${${flag_var}}")
endif()
endforeach(flag_var)
endif(MSVC_Z7_OVERRIDE)
endif(MSVC)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../third_party/protobuf/cmake)
set(CMAKE_POSITION_INDEPENDENT_CODE ${__caffe2_CMAKE_POSITION_INDEPENDENT_CODE})
if(${CAFFE2_LINK_LOCAL_PROTOBUF})
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ${__caffe2_CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS})
set(BUILD_SHARED_LIBS ON)
set(CMAKE_CXX_FLAGS ${__caffe2_CMAKE_CXX_FLAGS})
endif()
# Protobuf "namespaced" target is only added post protobuf 3.5.1. As a
# result, for older versions, we will manually add alias.
if(NOT TARGET protobuf::libprotobuf)
add_library(protobuf::libprotobuf ALIAS libprotobuf)
add_library(protobuf::libprotobuf-lite ALIAS libprotobuf-lite)
# There is link error when cross compiling protoc on mobile:
# https://github.com/protocolbuffers/protobuf/issues/2719
# And protoc is very unlikely needed for mobile builds.
if(NOT (ANDROID OR IOS))
add_executable(protobuf::protoc ALIAS protoc)
endif()
endif()
endmacro()
# Main entry for protobuf. If we are building on Android, iOS or we have hard
# coded BUILD_CUSTOM_PROTOBUF, we will hard code the use of custom protobuf
# in the submodule.
if(ANDROID OR IOS)
if(NOT BUILD_CUSTOM_PROTOBUF)
message(WARNING
"For Android and iOS cross compilation, I am automatically using "
"custom protobuf under third party. Note that this behavior may "
"change in the future, and you will need to specify "
"-DBUILD_CUSTOM_PROTOBUF=ON explicitly.")
endif()
# There is link error when cross compiling protoc on mobile:
# https://github.com/protocolbuffers/protobuf/issues/2719
# And protoc is very unlikely needed for mobile builds.
set(__caffe2_protobuf_BUILD_PROTOC_BINARIES ${protobuf_BUILD_PROTOC_BINARIES})
set(protobuf_BUILD_PROTOC_BINARIES OFF CACHE BOOL "" FORCE)
custom_protobuf_find()
set(protobuf_BUILD_PROTOC_BINARIES ${__caffe2_protobuf_BUILD_PROTOC_BINARIES} CACHE BOOL "" FORCE)
elseif(BUILD_CUSTOM_PROTOBUF)
message(STATUS "Building using own protobuf under third_party per request.")
custom_protobuf_find()
else()
include(cmake/public/protobuf.cmake)
endif()
if((NOT TARGET protobuf::libprotobuf) AND (NOT TARGET protobuf::libprotobuf-lite))
message(WARNING
"Protobuf cannot be found. Caffe2 will automatically switch to use "
"own protobuf under third_party. Note that this behavior may change in "
"the future, and you will need to specify -DBUILD_CUSTOM_PROTOBUF=ON "
"explicitly.")
custom_protobuf_find()
# TODO(jiayq): enable this in the future, when Jenkins Mac support is
# properly set up with protobuf installs.
# message(FATAL_ERROR
# "Protobuf cannot be found. Caffe2 will have to build with libprotobuf. "
# "Please set the proper paths so that I can find protobuf correctly.")
endif()
get_target_property(__tmp protobuf::libprotobuf INTERFACE_INCLUDE_DIRECTORIES)
message(STATUS "Caffe2 protobuf include directory: " ${__tmp})
include_directories(BEFORE SYSTEM ${__tmp})
# If Protobuf_VERSION is known (true in most cases, false if we are building
# local protobuf), then we will add a protobuf version check in
# Caffe2Config.cmake.in.
if(DEFINED ${Protobuf_VERSION})
set(CAFFE2_KNOWN_PROTOBUF_VERSION TRUE)
else()
set(CAFFE2_KNOWN_PROTOBUF_VERSION FALSE)
set(Protobuf_VERSION "Protobuf_VERSION_NOTFOUND")
endif()
# Figure out which protoc to use.
# If CAFFE2_CUSTOM_PROTOC_EXECUTABLE is set, we assume the user knows
# what they're doing and we blindly use the specified protoc. This
# is typically the case when cross-compiling where protoc must be
# compiled for the host architecture and libprotobuf must be
# compiled for the target architecture.
# If CAFFE2_CUSTOM_PROTOC_EXECUTABLE is NOT set, we use the protoc
# target that is built as part of including the protobuf project.
if(EXISTS "${CAFFE2_CUSTOM_PROTOC_EXECUTABLE}")
set(CAFFE2_PROTOC_EXECUTABLE ${CAFFE2_CUSTOM_PROTOC_EXECUTABLE})
else()
set(CAFFE2_PROTOC_EXECUTABLE protobuf::protoc)
endif()
################################################################################################
# Modification of standard 'protobuf_generate_cpp()' with output dir parameter and python support
# Usage:
# caffe2_protobuf_generate_cpp_py(<srcs_var> <hdrs_var> <python_var> <proto_files>)
function(caffe2_protobuf_generate_cpp_py srcs_var hdrs_var python_var)
if(NOT ARGN)
message(SEND_ERROR "Error: caffe_protobuf_generate_cpp_py() called without any proto files")
return()
endif()
set(${srcs_var})
set(${hdrs_var})
set(${python_var})
foreach(fil ${ARGN})
get_filename_component(abs_fil ${fil} ABSOLUTE)
get_filename_component(fil_we ${fil} NAME_WE)
list(APPEND ${srcs_var} "${CMAKE_CURRENT_BINARY_DIR}/${fil_we}.pb.cc")
list(APPEND ${hdrs_var} "${CMAKE_CURRENT_BINARY_DIR}/${fil_we}.pb.h")
list(APPEND ${python_var} "${CMAKE_CURRENT_BINARY_DIR}/${fil_we}_pb2.py")
# Add TORCH_API prefix to protobuf classes and methods in all cases
set(DLLEXPORT_STR "dllexport_decl=TORCH_API:")
# Note: the following depends on PROTOBUF_PROTOC_EXECUTABLE. This
# is done to make sure protoc is built before attempting to
# generate sources if we're using protoc from the third_party
# directory and are building it as part of the Caffe2 build. If
# points to an existing path, it is a no-op.
if(${CAFFE2_LINK_LOCAL_PROTOBUF})
# We need to rewrite the pb.h files to route GetEmptyStringAlreadyInited
# through our wrapper in proto_utils so the memory location test
# is correct.
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${fil_we}.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${fil_we}.pb.h"
"${CMAKE_CURRENT_BINARY_DIR}/${fil_we}_pb2.py"
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}"
COMMAND ${CAFFE2_PROTOC_EXECUTABLE} -I${PROJECT_SOURCE_DIR} --cpp_out=${DLLEXPORT_STR}${PROJECT_BINARY_DIR} ${abs_fil}
COMMAND ${CAFFE2_PROTOC_EXECUTABLE} -I${PROJECT_SOURCE_DIR} --python_out "${PROJECT_BINARY_DIR}" ${abs_fil}
# If we remove all reference to these pb.h files from external
# libraries and binaries this rewrite can be removed.
COMMAND ${CMAKE_COMMAND} -DFILENAME=${CMAKE_CURRENT_BINARY_DIR}/${fil_we}.pb.h -DNAMESPACES=caffe\;caffe2\;onnx\;torch -P ${PROJECT_SOURCE_DIR}/cmake/ProtoBufPatch.cmake
DEPENDS ${CAFFE2_PROTOC_EXECUTABLE} ${abs_fil}
COMMENT "Running C++/Python protocol buffer compiler on ${fil}" VERBATIM )
else()
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${fil_we}.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${fil_we}.pb.h"
"${CMAKE_CURRENT_BINARY_DIR}/${fil_we}_pb2.py"
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}"
COMMAND ${CAFFE2_PROTOC_EXECUTABLE} -I${PROJECT_SOURCE_DIR} --cpp_out=${DLLEXPORT_STR}${PROJECT_BINARY_DIR} ${abs_fil}
COMMAND ${CAFFE2_PROTOC_EXECUTABLE} -I${PROJECT_SOURCE_DIR} --python_out "${PROJECT_BINARY_DIR}" ${abs_fil}
COMMAND ${CMAKE_COMMAND} -DFILENAME=${CMAKE_CURRENT_BINARY_DIR}/${fil_we}.pb.h -DNAMESPACES=caffe\;caffe2\;onnx\;torch -DSYSTEM_PROTOBUF=YES -P ${PROJECT_SOURCE_DIR}/cmake/ProtoBufPatch.cmake
DEPENDS ${CAFFE2_PROTOC_EXECUTABLE} ${abs_fil}
COMMENT "Running C++/Python protocol buffer compiler on ${fil}" VERBATIM )
endif()
endforeach()
set_source_files_properties(${${srcs_var}} ${${hdrs_var}} ${${python_var}} PROPERTIES GENERATED TRUE)
set(${srcs_var} ${${srcs_var}} PARENT_SCOPE)
set(${hdrs_var} ${${hdrs_var}} PARENT_SCOPE)
set(${python_var} ${${python_var}} PARENT_SCOPE)
endfunction()
|