作者: 谢瑞阳 10225101483 徐翔宇 10225101535
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

493 lines
15 KiB

leveldb: Fix PosixWritableFile::Sync() on Apple systems. Apple doesn't follow POSIX specifications for fsync(). Instead, fsync() guarantees to flush the buffer cache to the device, which means the data will survive kernel panics, but may not survive power outages. Applications that need stronger guarantees (like databases) need to use fcntl(F_FULLFSYNC). This CL switches PosixWritableFile::Sync() to get the stronger guarantees on Apple systems. The improved implementation follows the same principles as SQLite [1] and node.js [2]. Research for the fcntl() to fsync() fallback strategy: Apple's released source code at https://opensource.apple.com/ shows at least three different error codes being returned when a filesystem does not support F_FULLFSYNC. fcntl() is implemented in xnu-4903.221.2 in bsd/kern/kern_descrip.c, where it delegates to fcntl_nocancel(). The documentation for fcntl_nocancel() mentions error codes for some operations, but does not include F_FULLFSYNC. The F_FULLSYNC branch in fcntl_nocancel() calls VNOP_IOCTL(_, F_FULLSYNC, NULL, 0, _), whose return value sets the error code. VNOP_IOCTL() is implemented in bsd/vfs/kpi_vfs.c and calls the ioctl function in the vnode's operation vector. The per-filesystem function names follow the pattern _vnop_ioctl() for all the instances in opensource code: {hfs,msdosfs,nfs,ntfs,smbfs,webdav,zfs}_vnop_ioctl(). hfs-407.30.1, msdosfs-229.200.3, and nfs in xnu-4903.221.2 handle F_FULLFSYNC. ntfs-94.200.1 and smb-759.40.1 do not handle F_FULLFSYNC, and the default branch returns ENOSUP. webdav-380.200.1 also does not handle F_FULLFSYNC, but the default branch returns EINVAL. zfs-59 also does not handle F_FULLSYNC, and its default branch returns ENOTTY. From a different angle, Apple's ntfs-94.200.1 includes utility code that uses fcntl(F_FULLFSYNC) and falls back to fsync() just like we do, supporting the hypothesis that there is no good way to detect lack of F_FULLFSYNC support. Also, Apple's fcntl() man page [3] does not mention a way to detect lack of F_FULLFSYNC support. [1] https://www.sqlite.org/src/doc/trunk/src/os_unix.c [2] https://github.com/libuv/libuv/blob/master/src/unix/fs.c [3] https://developer.apple.com/library/archive/documentatiVon/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html Tested: https://travis-ci.org/pwnall/leveldb/builds/477318498 TAP global presubmit ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=228593729
6 years ago
  1. # Copyright 2017 The LevelDB Authors. All rights reserved.
  2. # Use of this source code is governed by a BSD-style license that can be
  3. # found in the LICENSE file. See the AUTHORS file for names of contributors.
  4. cmake_minimum_required(VERSION 3.9)
  5. # Keep the version below in sync with the one in db.h
  6. project(leveldb VERSION 1.22.0 LANGUAGES C CXX)
  7. # C standard can be overridden when this is used as a sub-project.
  8. if(NOT CMAKE_C_STANDARD)
  9. # This project can use C11, but will gracefully decay down to C89.
  10. set(CMAKE_C_STANDARD 11)
  11. set(CMAKE_C_STANDARD_REQUIRED OFF)
  12. set(CMAKE_C_EXTENSIONS OFF)
  13. endif(NOT CMAKE_C_STANDARD)
  14. # C++ standard can be overridden when this is used as a sub-project.
  15. if(NOT CMAKE_CXX_STANDARD)
  16. # This project requires C++11.
  17. set(CMAKE_CXX_STANDARD 11)
  18. set(CMAKE_CXX_STANDARD_REQUIRED ON)
  19. set(CMAKE_CXX_EXTENSIONS OFF)
  20. endif(NOT CMAKE_CXX_STANDARD)
  21. if (WIN32)
  22. set(LEVELDB_PLATFORM_NAME LEVELDB_PLATFORM_WINDOWS)
  23. # TODO(cmumford): Make UNICODE configurable for Windows.
  24. add_definitions(-D_UNICODE -DUNICODE)
  25. else (WIN32)
  26. set(LEVELDB_PLATFORM_NAME LEVELDB_PLATFORM_POSIX)
  27. endif (WIN32)
  28. option(LEVELDB_BUILD_TESTS "Build LevelDB's unit tests" ON)
  29. option(LEVELDB_BUILD_BENCHMARKS "Build LevelDB's benchmarks" ON)
  30. option(LEVELDB_INSTALL "Install LevelDB's header and library" ON)
  31. include(TestBigEndian)
  32. test_big_endian(LEVELDB_IS_BIG_ENDIAN)
  33. include(CheckIncludeFile)
  34. check_include_file("unistd.h" HAVE_UNISTD_H)
  35. include(CheckLibraryExists)
  36. check_library_exists(crc32c crc32c_value "" HAVE_CRC32C)
  37. check_library_exists(snappy snappy_compress "" HAVE_SNAPPY)
  38. check_library_exists(tcmalloc malloc "" HAVE_TCMALLOC)
  39. include(CheckCXXSymbolExists)
  40. # Using check_cxx_symbol_exists() instead of check_c_symbol_exists() because
  41. # we're including the header from C++, and feature detection should use the same
  42. # compiler language that the project will use later. Principles aside, some
  43. # versions of do not expose fdatasync() in <unistd.h> in standard C mode
  44. # (-std=c11), but do expose the function in standard C++ mode (-std=c++11).
  45. check_cxx_symbol_exists(fdatasync "unistd.h" HAVE_FDATASYNC)
  46. check_cxx_symbol_exists(F_FULLFSYNC "fcntl.h" HAVE_FULLFSYNC)
  47. check_cxx_symbol_exists(O_CLOEXEC "fcntl.h" HAVE_O_CLOEXEC)
  48. if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  49. # Disable C++ exceptions.
  50. string(REGEX REPLACE "/EH[a-z]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
  51. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHs-c-")
  52. add_definitions(-D_HAS_EXCEPTIONS=0)
  53. # Disable RTTI.
  54. string(REGEX REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
  55. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-")
  56. else(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  57. # Enable strict prototype warnings for C code in clang and gcc.
  58. if(NOT CMAKE_C_FLAGS MATCHES "-Wstrict-prototypes")
  59. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-prototypes")
  60. endif(NOT CMAKE_C_FLAGS MATCHES "-Wstrict-prototypes")
  61. # Disable C++ exceptions.
  62. string(REGEX REPLACE "-fexceptions" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
  63. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
  64. # Disable RTTI.
  65. string(REGEX REPLACE "-frtti" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
  66. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
  67. endif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  68. # Test whether -Wthread-safety is available. See
  69. # https://clang.llvm.org/docs/ThreadSafetyAnalysis.html
  70. include(CheckCXXCompilerFlag)
  71. check_cxx_compiler_flag(-Wthread-safety HAVE_CLANG_THREAD_SAFETY)
  72. # Used by googletest.
  73. check_cxx_compiler_flag(-Wno-missing-field-initializers
  74. LEVELDB_HAVE_NO_MISSING_FIELD_INITIALIZERS)
  75. include(CheckCXXSourceCompiles)
  76. # Test whether C++17 __has_include is available.
  77. check_cxx_source_compiles("
  78. #if defined(__has_include) && __has_include(<string>)
  79. #include <string>
  80. #endif
  81. int main() { std::string str; return 0; }
  82. " HAVE_CXX17_HAS_INCLUDE)
  83. set(LEVELDB_PUBLIC_INCLUDE_DIR "include/leveldb")
  84. set(LEVELDB_PORT_CONFIG_DIR "include/port")
  85. configure_file(
  86. "port/port_config.h.in"
  87. "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
  88. )
  89. include_directories(
  90. "${PROJECT_BINARY_DIR}/include"
  91. "."
  92. )
  93. if(BUILD_SHARED_LIBS)
  94. # Only export LEVELDB_EXPORT symbols from the shared library.
  95. add_compile_options(-fvisibility=hidden)
  96. endif(BUILD_SHARED_LIBS)
  97. # Must be included before CMAKE_INSTALL_INCLUDEDIR is used.
  98. include(GNUInstallDirs)
  99. add_library(leveldb "")
  100. target_sources(leveldb
  101. PRIVATE
  102. "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
  103. "db/builder.cc"
  104. "db/builder.h"
  105. "db/c.cc"
  106. "db/db_impl.cc"
  107. "db/db_impl.h"
  108. "db/db_iter.cc"
  109. "db/db_iter.h"
  110. "db/dbformat.cc"
  111. "db/dbformat.h"
  112. "db/dumpfile.cc"
  113. "db/filename.cc"
  114. "db/filename.h"
  115. "db/log_format.h"
  116. "db/log_reader.cc"
  117. "db/log_reader.h"
  118. "db/log_writer.cc"
  119. "db/log_writer.h"
  120. "db/memtable.cc"
  121. "db/memtable.h"
  122. "db/repair.cc"
  123. "db/skiplist.h"
  124. "db/snapshot.h"
  125. "db/table_cache.cc"
  126. "db/table_cache.h"
  127. "db/version_edit.cc"
  128. "db/version_edit.h"
  129. "db/version_set.cc"
  130. "db/version_set.h"
  131. "db/write_batch_internal.h"
  132. "db/write_batch.cc"
  133. "port/port_stdcxx.h"
  134. "port/port.h"
  135. "port/thread_annotations.h"
  136. "table/block_builder.cc"
  137. "table/block_builder.h"
  138. "table/block.cc"
  139. "table/block.h"
  140. "table/filter_block.cc"
  141. "table/filter_block.h"
  142. "table/format.cc"
  143. "table/format.h"
  144. "table/iterator_wrapper.h"
  145. "table/iterator.cc"
  146. "table/merger.cc"
  147. "table/merger.h"
  148. "table/table_builder.cc"
  149. "table/table.cc"
  150. "table/two_level_iterator.cc"
  151. "table/two_level_iterator.h"
  152. "util/arena.cc"
  153. "util/arena.h"
  154. "util/bloom.cc"
  155. "util/cache.cc"
  156. "util/coding.cc"
  157. "util/coding.h"
  158. "util/comparator.cc"
  159. "util/crc32c.cc"
  160. "util/crc32c.h"
  161. "util/env.cc"
  162. "util/filter_policy.cc"
  163. "util/hash.cc"
  164. "util/hash.h"
  165. "util/logging.cc"
  166. "util/logging.h"
  167. "util/mutexlock.h"
  168. "util/no_destructor.h"
  169. "util/options.cc"
  170. "util/random.h"
  171. "util/status.cc"
  172. # Only CMake 3.3+ supports PUBLIC sources in targets exported by "install".
  173. $<$<VERSION_GREATER:CMAKE_VERSION,3.2>:PUBLIC>
  174. "${LEVELDB_PUBLIC_INCLUDE_DIR}/c.h"
  175. "${LEVELDB_PUBLIC_INCLUDE_DIR}/cache.h"
  176. "${LEVELDB_PUBLIC_INCLUDE_DIR}/comparator.h"
  177. "${LEVELDB_PUBLIC_INCLUDE_DIR}/db.h"
  178. "${LEVELDB_PUBLIC_INCLUDE_DIR}/dumpfile.h"
  179. "${LEVELDB_PUBLIC_INCLUDE_DIR}/env.h"
  180. "${LEVELDB_PUBLIC_INCLUDE_DIR}/export.h"
  181. "${LEVELDB_PUBLIC_INCLUDE_DIR}/filter_policy.h"
  182. "${LEVELDB_PUBLIC_INCLUDE_DIR}/iterator.h"
  183. "${LEVELDB_PUBLIC_INCLUDE_DIR}/options.h"
  184. "${LEVELDB_PUBLIC_INCLUDE_DIR}/slice.h"
  185. "${LEVELDB_PUBLIC_INCLUDE_DIR}/status.h"
  186. "${LEVELDB_PUBLIC_INCLUDE_DIR}/table_builder.h"
  187. "${LEVELDB_PUBLIC_INCLUDE_DIR}/table.h"
  188. "${LEVELDB_PUBLIC_INCLUDE_DIR}/write_batch.h"
  189. )
  190. if (WIN32)
  191. target_sources(leveldb
  192. PRIVATE
  193. "util/env_windows.cc"
  194. "util/windows_logger.h"
  195. )
  196. else (WIN32)
  197. target_sources(leveldb
  198. PRIVATE
  199. "util/env_posix.cc"
  200. "util/posix_logger.h"
  201. )
  202. endif (WIN32)
  203. # MemEnv is not part of the interface and could be pulled to a separate library.
  204. target_sources(leveldb
  205. PRIVATE
  206. "helpers/memenv/memenv.cc"
  207. "helpers/memenv/memenv.h"
  208. )
  209. target_include_directories(leveldb
  210. PUBLIC
  211. $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
  212. $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
  213. )
  214. set_target_properties(leveldb
  215. PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR})
  216. target_compile_definitions(leveldb
  217. PRIVATE
  218. # Used by include/export.h when building shared libraries.
  219. LEVELDB_COMPILE_LIBRARY
  220. # Used by port/port.h.
  221. ${LEVELDB_PLATFORM_NAME}=1
  222. )
  223. if (NOT HAVE_CXX17_HAS_INCLUDE)
  224. target_compile_definitions(leveldb
  225. PRIVATE
  226. LEVELDB_HAS_PORT_CONFIG_H=1
  227. )
  228. endif(NOT HAVE_CXX17_HAS_INCLUDE)
  229. if(BUILD_SHARED_LIBS)
  230. target_compile_definitions(leveldb
  231. PUBLIC
  232. # Used by include/export.h.
  233. LEVELDB_SHARED_LIBRARY
  234. )
  235. endif(BUILD_SHARED_LIBS)
  236. if(HAVE_CLANG_THREAD_SAFETY)
  237. target_compile_options(leveldb
  238. PUBLIC
  239. -Werror -Wthread-safety)
  240. endif(HAVE_CLANG_THREAD_SAFETY)
  241. if(HAVE_CRC32C)
  242. target_link_libraries(leveldb crc32c)
  243. endif(HAVE_CRC32C)
  244. if(HAVE_SNAPPY)
  245. target_link_libraries(leveldb snappy)
  246. endif(HAVE_SNAPPY)
  247. if(HAVE_TCMALLOC)
  248. target_link_libraries(leveldb tcmalloc)
  249. endif(HAVE_TCMALLOC)
  250. # Needed by port_stdcxx.h
  251. find_package(Threads REQUIRED)
  252. target_link_libraries(leveldb Threads::Threads)
  253. add_executable(leveldbutil
  254. "db/leveldbutil.cc"
  255. )
  256. target_link_libraries(leveldbutil leveldb)
  257. if(LEVELDB_BUILD_TESTS)
  258. enable_testing()
  259. # Prevent overriding the parent project's compiler/linker settings on Windows.
  260. set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
  261. set(install_gtest OFF)
  262. set(install_gmock OFF)
  263. set(build_gmock ON)
  264. # This project is tested using GoogleTest.
  265. add_subdirectory("third_party/googletest")
  266. # GoogleTest triggers a missing field initializers warning.
  267. if(LEVELDB_HAVE_NO_MISSING_FIELD_INITIALIZERS)
  268. set_property(TARGET gtest
  269. APPEND PROPERTY COMPILE_OPTIONS -Wno-missing-field-initializers)
  270. set_property(TARGET gmock
  271. APPEND PROPERTY COMPILE_OPTIONS -Wno-missing-field-initializers)
  272. endif(LEVELDB_HAVE_NO_MISSING_FIELD_INITIALIZERS)
  273. function(leveldb_test test_file)
  274. get_filename_component(test_target_name "${test_file}" NAME_WE)
  275. add_executable("${test_target_name}" "")
  276. target_sources("${test_target_name}"
  277. PRIVATE
  278. "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
  279. "util/testutil.cc"
  280. "util/testutil.h"
  281. "${test_file}"
  282. )
  283. target_link_libraries("${test_target_name}" leveldb gmock gtest)
  284. target_compile_definitions("${test_target_name}"
  285. PRIVATE
  286. ${LEVELDB_PLATFORM_NAME}=1
  287. )
  288. if (NOT HAVE_CXX17_HAS_INCLUDE)
  289. target_compile_definitions("${test_target_name}"
  290. PRIVATE
  291. LEVELDB_HAS_PORT_CONFIG_H=1
  292. )
  293. endif(NOT HAVE_CXX17_HAS_INCLUDE)
  294. add_test(NAME "${test_target_name}" COMMAND "${test_target_name}")
  295. endfunction(leveldb_test)
  296. leveldb_test("db/c_test.c")
  297. leveldb_test("db/fault_injection_test.cc")
  298. leveldb_test("issues/issue178_test.cc")
  299. leveldb_test("issues/issue200_test.cc")
  300. leveldb_test("issues/issue320_test.cc")
  301. leveldb_test("util/env_test.cc")
  302. leveldb_test("util/status_test.cc")
  303. leveldb_test("util/no_destructor_test.cc")
  304. if(NOT BUILD_SHARED_LIBS)
  305. leveldb_test("db/autocompact_test.cc")
  306. leveldb_test("db/corruption_test.cc")
  307. leveldb_test("db/db_test.cc")
  308. leveldb_test("db/dbformat_test.cc")
  309. leveldb_test("db/filename_test.cc")
  310. leveldb_test("db/log_test.cc")
  311. leveldb_test("db/recovery_test.cc")
  312. leveldb_test("db/skiplist_test.cc")
  313. leveldb_test("db/version_edit_test.cc")
  314. leveldb_test("db/version_set_test.cc")
  315. leveldb_test("db/write_batch_test.cc")
  316. leveldb_test("helpers/memenv/memenv_test.cc")
  317. leveldb_test("table/filter_block_test.cc")
  318. leveldb_test("table/table_test.cc")
  319. leveldb_test("util/arena_test.cc")
  320. leveldb_test("util/bloom_test.cc")
  321. leveldb_test("util/cache_test.cc")
  322. leveldb_test("util/coding_test.cc")
  323. leveldb_test("util/crc32c_test.cc")
  324. leveldb_test("util/hash_test.cc")
  325. leveldb_test("util/logging_test.cc")
  326. # TODO(costan): This test also uses
  327. # "util/env_{posix|windows}_test_helper.h"
  328. if (WIN32)
  329. leveldb_test("util/env_windows_test.cc")
  330. else (WIN32)
  331. leveldb_test("util/env_posix_test.cc")
  332. endif (WIN32)
  333. endif(NOT BUILD_SHARED_LIBS)
  334. endif(LEVELDB_BUILD_TESTS)
  335. if(LEVELDB_BUILD_BENCHMARKS)
  336. function(leveldb_benchmark bench_file)
  337. get_filename_component(bench_target_name "${bench_file}" NAME_WE)
  338. add_executable("${bench_target_name}" "")
  339. target_sources("${bench_target_name}"
  340. PRIVATE
  341. "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
  342. "util/histogram.cc"
  343. "util/histogram.h"
  344. "util/testutil.cc"
  345. "util/testutil.h"
  346. "${bench_file}"
  347. )
  348. target_link_libraries("${bench_target_name}" leveldb gmock gtest)
  349. target_compile_definitions("${bench_target_name}"
  350. PRIVATE
  351. ${LEVELDB_PLATFORM_NAME}=1
  352. )
  353. if (NOT HAVE_CXX17_HAS_INCLUDE)
  354. target_compile_definitions("${bench_target_name}"
  355. PRIVATE
  356. LEVELDB_HAS_PORT_CONFIG_H=1
  357. )
  358. endif(NOT HAVE_CXX17_HAS_INCLUDE)
  359. endfunction(leveldb_benchmark)
  360. if(NOT BUILD_SHARED_LIBS)
  361. leveldb_benchmark("benchmarks/db_bench.cc")
  362. endif(NOT BUILD_SHARED_LIBS)
  363. check_library_exists(sqlite3 sqlite3_open "" HAVE_SQLITE3)
  364. if(HAVE_SQLITE3)
  365. leveldb_benchmark("benchmarks/db_bench_sqlite3.cc")
  366. target_link_libraries(db_bench_sqlite3 sqlite3)
  367. endif(HAVE_SQLITE3)
  368. # check_library_exists is insufficient here because the library names have
  369. # different manglings when compiled with clang or gcc, at least when installed
  370. # with Homebrew on Mac.
  371. set(OLD_CMAKE_REQURED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
  372. list(APPEND CMAKE_REQUIRED_LIBRARIES kyotocabinet)
  373. check_cxx_source_compiles("
  374. #include <kcpolydb.h>
  375. int main() {
  376. kyotocabinet::TreeDB* db = new kyotocabinet::TreeDB();
  377. delete db;
  378. return 0;
  379. }
  380. " HAVE_KYOTOCABINET)
  381. set(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQURED_LIBRARIES})
  382. if(HAVE_KYOTOCABINET)
  383. leveldb_benchmark("benchmarks/db_bench_tree_db.cc")
  384. target_link_libraries(db_bench_tree_db kyotocabinet)
  385. endif(HAVE_KYOTOCABINET)
  386. endif(LEVELDB_BUILD_BENCHMARKS)
  387. if(LEVELDB_INSTALL)
  388. install(TARGETS leveldb
  389. EXPORT leveldbTargets
  390. RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  391. LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  392. ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  393. )
  394. install(
  395. FILES
  396. "${LEVELDB_PUBLIC_INCLUDE_DIR}/c.h"
  397. "${LEVELDB_PUBLIC_INCLUDE_DIR}/cache.h"
  398. "${LEVELDB_PUBLIC_INCLUDE_DIR}/comparator.h"
  399. "${LEVELDB_PUBLIC_INCLUDE_DIR}/db.h"
  400. "${LEVELDB_PUBLIC_INCLUDE_DIR}/dumpfile.h"
  401. "${LEVELDB_PUBLIC_INCLUDE_DIR}/env.h"
  402. "${LEVELDB_PUBLIC_INCLUDE_DIR}/export.h"
  403. "${LEVELDB_PUBLIC_INCLUDE_DIR}/filter_policy.h"
  404. "${LEVELDB_PUBLIC_INCLUDE_DIR}/iterator.h"
  405. "${LEVELDB_PUBLIC_INCLUDE_DIR}/options.h"
  406. "${LEVELDB_PUBLIC_INCLUDE_DIR}/slice.h"
  407. "${LEVELDB_PUBLIC_INCLUDE_DIR}/status.h"
  408. "${LEVELDB_PUBLIC_INCLUDE_DIR}/table_builder.h"
  409. "${LEVELDB_PUBLIC_INCLUDE_DIR}/table.h"
  410. "${LEVELDB_PUBLIC_INCLUDE_DIR}/write_batch.h"
  411. DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/leveldb"
  412. )
  413. include(CMakePackageConfigHelpers)
  414. configure_package_config_file(
  415. "cmake/${PROJECT_NAME}Config.cmake.in"
  416. "${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake"
  417. INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
  418. )
  419. write_basic_package_version_file(
  420. "${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}ConfigVersion.cmake"
  421. COMPATIBILITY SameMajorVersion
  422. )
  423. install(
  424. EXPORT leveldbTargets
  425. NAMESPACE leveldb::
  426. DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
  427. )
  428. install(
  429. FILES
  430. "${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake"
  431. "${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}ConfigVersion.cmake"
  432. DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
  433. )
  434. endif(LEVELDB_INSTALL)