CMakeLists.txt 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. #
  2. # Licensed to the Apache Software Foundation (ASF) under one
  3. # or more contributor license agreements. See the NOTICE file
  4. # distributed with this work for additional information
  5. # regarding copyright ownership. The ASF licenses this file
  6. # to you under the Apache License, Version 2.0 (the
  7. # "License"); you may not use this file except in compliance
  8. # with the License. You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing, software
  13. # distributed under the License is distributed on an "AS IS" BASIS,
  14. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. # See the License for the specific language governing permissions and
  16. # limitations under the License.
  17. #
  18. # If cmake variable HDFSPP_LIBRARY_ONLY is set, then tests, examples, and
  19. # tools will not be built. This allows for faster builds of the libhdfspp
  20. # library alone, avoids looking for a JDK, valgrind, and gmock, and
  21. # prevents the generation of multiple binaries that might not be relevant
  22. # to other projects during normal use.
  23. # Example of cmake invocation with HDFSPP_LIBRARY_ONLY enabled:
  24. # cmake -DHDFSPP_LIBRARY_ONLY=1
  25. project (libhdfspp)
  26. cmake_minimum_required(VERSION 2.8)
  27. enable_testing()
  28. include (CTest)
  29. SET(BUILD_SHARED_HDFSPP TRUE CACHE STRING "BUILD_SHARED_HDFSPP defaulting to 'TRUE'")
  30. SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH})
  31. # If there's a better way to inform FindCyrusSASL.cmake, let's make this cleaner:
  32. SET(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${CYRUS_SASL_DIR};${GSASL_DIR}")
  33. find_package(Doxygen)
  34. find_package(OpenSSL REQUIRED)
  35. find_package(Protobuf REQUIRED)
  36. find_package(CyrusSASL)
  37. find_package(GSasl)
  38. find_package(Threads)
  39. include(CheckCXXSourceCompiles)
  40. # Check if thread_local is supported
  41. unset (THREAD_LOCAL_SUPPORTED CACHE)
  42. set (CMAKE_REQUIRED_DEFINITIONS "-std=c++11")
  43. set (CMAKE_REQUIRED_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
  44. check_cxx_source_compiles(
  45. "#include <thread>
  46. int main(void) {
  47. thread_local int s;
  48. return 0;
  49. }"
  50. THREAD_LOCAL_SUPPORTED)
  51. if (NOT THREAD_LOCAL_SUPPORTED)
  52. message(FATAL_ERROR
  53. "FATAL ERROR: The required feature thread_local storage is not supported by your compiler. \
  54. Known compilers that support this feature: GCC, Visual Studio, Clang (community version), \
  55. Clang (version for iOS 9 and later).")
  56. endif (NOT THREAD_LOCAL_SUPPORTED)
  57. # Check if PROTOC library was compiled with the compatible compiler by trying
  58. # to compile some dummy code
  59. unset (PROTOC_IS_COMPATIBLE CACHE)
  60. set (CMAKE_REQUIRED_INCLUDES ${PROTOBUF_INCLUDE_DIRS})
  61. set (CMAKE_REQUIRED_LIBRARIES ${PROTOBUF_LIBRARY} ${PROTOBUF_PROTOC_LIBRARY})
  62. check_cxx_source_compiles(
  63. "#include <google/protobuf/io/printer.h>
  64. #include <string>
  65. int main(void) {
  66. ::google::protobuf::io::ZeroCopyOutputStream *out = NULL;
  67. ::google::protobuf::io::Printer printer(out, '$');
  68. printer.PrintRaw(std::string(\"test\"));
  69. return 0;
  70. }"
  71. PROTOC_IS_COMPATIBLE)
  72. if (NOT PROTOC_IS_COMPATIBLE)
  73. message(WARNING
  74. "WARNING: the Protocol Buffers Library and the Libhdfs++ Library must both be compiled \
  75. with the same (or compatible) compiler. Normally only the same major versions of the same \
  76. compiler are compatible with each other.")
  77. endif (NOT PROTOC_IS_COMPATIBLE)
  78. find_program(MEMORYCHECK_COMMAND valgrind HINTS ${VALGRIND_DIR} )
  79. set(MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes --leak-check=full --error-exitcode=1")
  80. message(STATUS "valgrind location: ${MEMORYCHECK_COMMAND}")
  81. if (REQUIRE_VALGRIND AND MEMORYCHECK_COMMAND MATCHES "MEMORYCHECK_COMMAND-NOTFOUND" )
  82. message(FATAL_ERROR "valgrind was required but not found. "
  83. "The path can be included via a -DVALGRIND_DIR=... flag passed to CMake.")
  84. endif (REQUIRE_VALGRIND AND MEMORYCHECK_COMMAND MATCHES "MEMORYCHECK_COMMAND-NOTFOUND" )
  85. # Find the SASL library to use. If you don't want to require a sasl library,
  86. # define -DNO_SASL=1 in your cmake call
  87. # Prefer Cyrus SASL, but use GSASL if it is found
  88. # Note that the packages can be disabled by setting CMAKE_DISABLE_FIND_PACKAGE_GSasl or
  89. # CMAKE_DISABLE_FIND_PACKAGE_CyrusSASL, respectively (case sensitive)
  90. set (SASL_LIBRARIES)
  91. set (SASL_INCLUDE_DIR)
  92. if (NOT NO_SASL)
  93. if (CYRUS_SASL_FOUND)
  94. message(STATUS "Using Cyrus SASL; link with ${CYRUS_SASL_SHARED_LIB}")
  95. set (SASL_INCLUDE_DIR ${CYRUS_SASL_INCLUDE_DIR})
  96. set (SASL_LIBRARIES ${CYRUS_SASL_SHARED_LIB})
  97. set (CMAKE_USING_CYRUS_SASL 1)
  98. add_definitions(-DUSE_SASL -DUSE_CYRUS_SASL)
  99. else (CYRUS_SASL_FOUND)
  100. if (REQUIRE_CYRUS_SASL)
  101. message(FATAL_ERROR "Cyrus SASL was required but not found. "
  102. "The path can be included via a -DCYRUS_SASL_DIR=... flag passed to CMake.")
  103. endif (REQUIRE_CYRUS_SASL)
  104. # If we didn't pick Cyrus, use GSASL instead
  105. if (GSASL_FOUND)
  106. message(STATUS "Using GSASL; link with ${GSASL_LIBRARIES}")
  107. set (SASL_INCLUDE_DIR ${GSASL_INCLUDE_DIR})
  108. set (SASL_LIBRARIES ${GSASL_LIBRARIES})
  109. set (CMAKE_USING_GSASL 1)
  110. add_definitions(-DUSE_SASL -DUSE_GSASL)
  111. else (GSASL_FOUND)
  112. if (REQUIRE_GSASL)
  113. message(FATAL_ERROR "GSASL was required but not found. "
  114. "The path can be included via a -DGSASL_DIR=... flag passed to CMake.")
  115. endif (REQUIRE_GSASL)
  116. # No SASL was found, but NO_SASL was not defined
  117. message(FATAL_ERROR "Cound not find a SASL library (GSASL (gsasl) or Cyrus SASL (libsasl2). "
  118. "Install/configure one of them or define NO_SASL=1 in your cmake call")
  119. endif (GSASL_FOUND)
  120. endif (CYRUS_SASL_FOUND)
  121. else (NOT NO_SASL)
  122. message(STATUS "Compiling with NO SASL SUPPORT")
  123. endif (NOT NO_SASL)
  124. add_definitions(-DASIO_STANDALONE -DASIO_CPP11_DATE_TIME)
  125. # Disable optimizations if compiling debug
  126. set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
  127. set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
  128. if(UNIX)
  129. set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -std=c++11 -g -fPIC -fno-strict-aliasing")
  130. set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -fPIC -fno-strict-aliasing")
  131. endif()
  132. if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  133. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
  134. add_definitions(-DASIO_HAS_STD_ADDRESSOF -DASIO_HAS_STD_ARRAY -DASIO_HAS_STD_ATOMIC -DASIO_HAS_CSTDINT -DASIO_HAS_STD_SHARED_PTR -DASIO_HAS_STD_TYPE_TRAITS -DASIO_HAS_VARIADIC_TEMPLATES -DASIO_HAS_STD_FUNCTION -DASIO_HAS_STD_CHRONO -DASIO_HAS_STD_SYSTEM_ERROR)
  135. endif ()
  136. # Mac OS 10.7 and later deprecates most of the methods in OpenSSL.
  137. # Add -Wno-deprecated-declarations to avoid the warnings.
  138. if(APPLE)
  139. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -Wno-deprecated-declarations -Wno-unused-local-typedef")
  140. endif()
  141. if(DOXYGEN_FOUND)
  142. configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/doc/Doxyfile @ONLY)
  143. add_custom_target(doc ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doc/Doxyfile
  144. WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
  145. COMMENT "Generating API documentation with Doxygen" VERBATIM)
  146. endif(DOXYGEN_FOUND)
  147. # Copy files from the hadoop tree into the output/extern directory if
  148. # they've changed
  149. function (copy_on_demand input_src_glob input_dest_dir)
  150. get_filename_component(src_glob ${input_src_glob} REALPATH)
  151. get_filename_component(dest_dir ${input_dest_dir} REALPATH)
  152. get_filename_component(src_dir ${src_glob} PATH)
  153. message(STATUS "Syncing ${src_glob} to ${dest_dir}")
  154. file(GLOB_RECURSE src_files ${src_glob})
  155. foreach(src_path ${src_files})
  156. file(RELATIVE_PATH relative_src ${src_dir} ${src_path})
  157. set(dest_path "${dest_dir}/${relative_src}")
  158. add_custom_command(TARGET copy_hadoop_files
  159. COMMAND ${CMAKE_COMMAND} -E copy_if_different "${src_path}" "${dest_path}"
  160. )
  161. endforeach()
  162. endfunction()
  163. # If we're building in the hadoop tree, pull the Hadoop files that
  164. # libhdfspp depends on. This allows us to ensure that
  165. # the distribution will have a consistent set of headers and
  166. # .proto files
  167. if(HADOOP_BUILD)
  168. set(HADOOP_IMPORT_DIR ${PROJECT_BINARY_DIR}/extern)
  169. get_filename_component(HADOOP_IMPORT_DIR ${HADOOP_IMPORT_DIR} REALPATH)
  170. add_custom_target(copy_hadoop_files ALL)
  171. # Gather the Hadoop files and resources that libhdfs++ needs to build
  172. copy_on_demand(../libhdfs/include/*.h* ${HADOOP_IMPORT_DIR}/include)
  173. copy_on_demand(${CMAKE_CURRENT_LIST_DIR}/../../../../../hadoop-hdfs-client/src/main/proto/*.proto ${HADOOP_IMPORT_DIR}/proto/hdfs)
  174. copy_on_demand(${CMAKE_CURRENT_LIST_DIR}/../../../../../../hadoop-common-project/hadoop-common/src/main/proto/*.proto ${HADOOP_IMPORT_DIR}/proto/hadoop)
  175. copy_on_demand(${CMAKE_CURRENT_LIST_DIR}/../../../../../../hadoop-common-project/hadoop-common/src/test/proto/*.proto ${HADOOP_IMPORT_DIR}/proto/hadoop_test)
  176. else(HADOOP_BUILD)
  177. set(HADOOP_IMPORT_DIR ${CMAKE_CURRENT_LIST_DIR}/extern)
  178. endif(HADOOP_BUILD)
  179. # Paths to find the imported files
  180. set(PROTO_HDFS_DIR ${HADOOP_IMPORT_DIR}/proto/hdfs)
  181. set(PROTO_HADOOP_DIR ${HADOOP_IMPORT_DIR}/proto/hadoop)
  182. set(PROTO_HADOOP_TEST_DIR ${HADOOP_IMPORT_DIR}/proto/hadoop_test)
  183. include_directories(
  184. include
  185. lib
  186. ${HADOOP_IMPORT_DIR}/include
  187. )
  188. include_directories( SYSTEM
  189. ${PROJECT_BINARY_DIR}/lib/proto
  190. third_party/asio-1.10.2/include
  191. third_party/rapidxml-1.13
  192. third_party/gmock-1.7.0
  193. third_party/tr2
  194. third_party/protobuf
  195. third_party/uriparser2
  196. ${OPENSSL_INCLUDE_DIR}
  197. ${SASL_INCLUDE_DIR}
  198. ${PROTOBUF_INCLUDE_DIRS}
  199. )
  200. add_subdirectory(third_party/gmock-1.7.0)
  201. add_subdirectory(third_party/uriparser2)
  202. add_subdirectory(lib)
  203. if(NOT HDFSPP_LIBRARY_ONLY)
  204. add_subdirectory(tests)
  205. add_subdirectory(examples)
  206. add_subdirectory(tools)
  207. endif()
  208. # create an empty file; hadoop_add_dual_library wraps add_library which
  209. # requires at least one file as an argument
  210. set(EMPTY_FILE_CC ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/empty.cc)
  211. file(WRITE ${EMPTY_FILE_CC} "")
  212. # Build the output libraries
  213. if(NEED_LINK_DL)
  214. set(LIB_DL dl)
  215. endif()
  216. set(LIBHDFSPP_VERSION "0.1.0")
  217. set(LIBHDFSPP_ALL_OBJECTS $<TARGET_OBJECTS:bindings_c_obj> $<TARGET_OBJECTS:fs_obj> $<TARGET_OBJECTS:rpc_obj> $<TARGET_OBJECTS:reader_obj> $<TARGET_OBJECTS:proto_obj> $<TARGET_OBJECTS:connection_obj> $<TARGET_OBJECTS:common_obj> $<TARGET_OBJECTS:uriparser2_obj>)
  218. if (HADOOP_BUILD)
  219. hadoop_add_dual_library(hdfspp ${EMPTY_FILE_CC} ${LIBHDFSPP_ALL_OBJECTS})
  220. hadoop_target_link_dual_libraries(hdfspp
  221. ${LIB_DL}
  222. ${PROTOBUF_LIBRARY}
  223. ${OPENSSL_LIBRARIES}
  224. ${SASL_LIBRARIES}
  225. ${CMAKE_THREAD_LIBS_INIT}
  226. )
  227. set_target_properties(hdfspp PROPERTIES SOVERSION ${LIBHDFSPP_VERSION})
  228. else (HADOOP_BUILD)
  229. add_library(hdfspp_static STATIC ${EMPTY_FILE_CC} ${LIBHDFSPP_ALL_OBJECTS})
  230. target_link_libraries(hdfspp_static
  231. ${LIB_DL}
  232. ${PROTOBUF_LIBRARY}
  233. ${OPENSSL_LIBRARIES}
  234. ${SASL_LIBRARIES}
  235. ${CMAKE_THREAD_LIBS_INIT}
  236. )
  237. if(BUILD_SHARED_HDFSPP)
  238. add_library(hdfspp SHARED ${EMPTY_FILE_CC} ${LIBHDFSPP_ALL_OBJECTS})
  239. set_target_properties(hdfspp PROPERTIES SOVERSION ${LIBHDFSPP_VERSION})
  240. endif(BUILD_SHARED_HDFSPP)
  241. endif (HADOOP_BUILD)
  242. # Set up make install targets
  243. # Can be installed to a particular location via "make DESTDIR=... install"
  244. file(GLOB_RECURSE LIBHDFSPP_HEADER_FILES "${CMAKE_CURRENT_LIST_DIR}/include/*.h*")
  245. file(GLOB_RECURSE LIBHDFS_HEADER_FILES "${HADOOP_IMPORT_DIR}/include/*.h*")
  246. install(FILES ${LIBHDFSPP_HEADER_FILES} DESTINATION include/hdfspp)
  247. install(FILES ${LIBHDFS_HEADER_FILES} DESTINATION include/hdfs)
  248. install(TARGETS hdfspp_static ARCHIVE DESTINATION lib)
  249. if(BUILD_SHARED_HDFSPP)
  250. install(TARGETS hdfspp LIBRARY DESTINATION lib)
  251. endif(BUILD_SHARED_HDFSPP)
  252. add_custom_target(
  253. InstallToBuildDirectory
  254. COMMAND "${CMAKE_MAKE_PROGRAM}" install DESTDIR=${PROJECT_BINARY_DIR}/output
  255. )
  256. set(LIBHDFSPP_DIR ${PROJECT_BINARY_DIR}/output)