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.

244 lines
8.8 KiB

  1. cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
  2. project(mergerfs LANGUAGES CXX)
  3. include(CMakeDependentOption)
  4. include(GNUInstallDirs)
  5. if(NOT DEFINED ENABLE_XATTR)
  6. set(ENABLE_XATTR "AUTO")
  7. endif()
  8. # we could have used option(ENABLE_XATTR) here, but it doesn't allow for AUTO behavior
  9. set(ENABLE_XATTR "${ENABLE_XATTR}" CACHE STRING "Build with xattr support (AUTO, YES, NO)")
  10. CMAKE_DEPENDENT_OPTION(WITH_XATTR "Include dir with xattr headers"
  11. OFF "ENABLE_XATTR"
  12. OFF)
  13. option(WITH_INTERNAL_FUSE "Use bundled (YES) or system (NO) libfuse" "YES")
  14. if(NOT DEFINED CMAKE_BUILD_TYPE)
  15. set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING)
  16. endif()
  17. file(GLOB mergerfs_sources src/*.cpp src/*.icpp src/*.hpp src/*.h)
  18. set(version_hpp "${CMAKE_CURRENT_BINARY_DIR}/version.hpp")
  19. list(APPEND mergerfs_sources ${version_hpp})
  20. add_executable(mergerfs ${mergerfs_sources})
  21. target_include_directories(mergerfs PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
  22. set(GIT2DEBCL "${CMAKE_CURRENT_SOURCE_DIR}/tools/git2debcl")
  23. find_program(PANDOC pandoc)
  24. if(NOT PANDOC)
  25. message(WARNING "pandoc does not appear available: manpage won't be buildable")
  26. endif()
  27. if(NOT DEFINED ${MERGERFS_VERSION})
  28. set(git_toplevel_dir)
  29. find_program(GIT git)
  30. if(GIT)
  31. execute_process(
  32. COMMAND ${GIT} rev-parse --show-toplevel
  33. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  34. OUTPUT_VARIABLE git_toplevel_dir
  35. OUTPUT_STRIP_TRAILING_WHITESPACE
  36. )
  37. if(git_toplevel_dir)
  38. file(TO_CMAKE_PATH "${git_toplevel_dir}" git_toplevel_dir)
  39. endif()
  40. endif()
  41. if(git_toplevel_dir STREQUAL CMAKE_CURRENT_SOURCE_DIR)
  42. # we're in a git worktree, and not in a super-project git tree
  43. execute_process(
  44. COMMAND ${GIT} describe --always --tags --dirty
  45. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  46. OUTPUT_VARIABLE MERGERFS_VERSION
  47. OUTPUT_STRIP_TRAILING_WHITESPACE
  48. )
  49. elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION")
  50. file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" MERGERFS_VERSION)
  51. else()
  52. message(FATAL_ERROR "mergerfs version can't be determined. Use release tarball or run from within mergerfs git repository")
  53. endif()
  54. endif()
  55. # XXX: might get stale
  56. # after MERGERFS_VERSION is defined
  57. configure_file(src/version.hpp.in "${version_hpp}" @ONLY)
  58. if(ENABLE_XATTR) # including "AUTO"
  59. if(WITH_XATTR)
  60. find_path(XATTR_INCLUDE_DIR attr/xattr.h PATHS "${WITH_XATTR}")
  61. else()
  62. find_path(XATTR_INCLUDE_DIR attr/xattr.h)
  63. endif()
  64. if(NOT XATTR_INCLUDE_DIR)
  65. if(ENABLE_XATTR EQUAL "AUTO")
  66. set(msg_level "WARNING")
  67. else()
  68. # xattr is explicitly requested, but is not available
  69. set(msg_level "FATAL_ERROR")
  70. endif()
  71. message("${msg_level}" "xattr not available: disabling")
  72. endif()
  73. else()
  74. set(XATTR_INCLUDE_DIR NO)
  75. endif()
  76. if(XATTR_INCLUDE_DIR)
  77. target_include_directories(mergerfs PRIVATE "${XATTR_INCLUDE_DIR}")
  78. else()
  79. target_compile_definitions(mergerfs PRIVATE "-DWITHOUT_XATTR")
  80. endif()
  81. if(WITH_INTERNAL_FUSE)
  82. include(ExternalProject)
  83. ExternalProject_Add(libfuse_internal
  84. URL "${CMAKE_CURRENT_SOURCE_DIR}/libfuse"
  85. CONFIGURE_COMMAND ${CMAKE_COMMAND} -E make_directory m4
  86. COMMAND autoreconf --force --install
  87. COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} --enable-lib --disable-util --disable-example
  88. BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}
  89. INSTALL_COMMAND true
  90. BUILD_IN_SOURCE 1
  91. )
  92. ExternalProject_Get_Property(libfuse_internal SOURCE_DIR)
  93. ExternalProject_Get_Property(libfuse_internal BINARY_DIR)
  94. add_library(libfuse STATIC IMPORTED)
  95. set_property(TARGET libfuse PROPERTY IMPORTED_LOCATION "${BINARY_DIR}/lib/.libs/libfuse.a")
  96. add_dependencies(mergerfs libfuse_internal)
  97. target_include_directories(mergerfs PRIVATE "${SOURCE_DIR}/include")
  98. target_compile_definitions(mergerfs PRIVATE "-D_FILE_OFFSET_BITS=64")
  99. target_link_libraries(mergerfs PRIVATE libfuse dl)
  100. set_property(TARGET mergerfs APPEND PROPERTY LINK_FLAGS "-pthread")
  101. else()
  102. set(EXTERNAL_FUSE_MIN_REQ 2.9.7)
  103. find_package(PkgConfig REQUIRED)
  104. pkg_search_module(FUSE REQUIRED "fuse >= ${EXTERNAL_FUSE_MIN_REQ}")
  105. target_include_directories(mergerfs PRIVATE "${FUSE_INCLUDE_DIRS}")
  106. target_compile_options(mergerfs PRIVATE "${FUSE_CFLAGS_OTHER}")
  107. target_link_libraries(mergerfs PRIVATE "${FUSE_LIBRARIES}")
  108. set_property(TARGET mergerfs APPEND PROPERTY LINK_FLAGS "${FUSE_LDFLAGS_OTHER}")
  109. link_directories("${FUSE_LIBRARY_DIRS}")
  110. endif()
  111. set(UGID_USE_RWLOCK 0)
  112. target_compile_definitions(mergerfs PRIVATE
  113. "-DFUSE_USE_VERSION=29"
  114. "-DUGID_USE_RWLOCK=${UGID_USE_RWLOCK}"
  115. )
  116. target_compile_options(mergerfs PRIVATE "-Wall" "-Wno-unused-result")
  117. add_custom_command(OUTPUT mount.mergerfs
  118. COMMAND ${CMAKE_COMMAND} -E create_symlink mergerfs mount.mergerfs
  119. DEPENDS mergerfs
  120. VERBATIM
  121. )
  122. add_custom_target(create-mount.mergerfs ALL
  123. DEPENDS mount.mergerfs
  124. )
  125. install(TARGETS mergerfs DESTINATION "${CMAKE_INSTALL_BINDIR}")
  126. install(FILES "${CMAKE_CURRENT_BINARY_DIR}/mount.mergerfs" DESTINATION "${CMAKE_INSTALL_BINDIR}")
  127. set(manpage "${CMAKE_CURRENT_SOURCE_DIR}/man/mergerfs.1")
  128. if(PANDOC)
  129. set(manpage "${CMAKE_CURRENT_BINARY_DIR}/mergerfs.1")
  130. add_custom_command(OUTPUT "${manpage}"
  131. COMMAND ${PANDOC} -s -t man -o "${manpage}" "${CMAKE_CURRENT_SOURCE_DIR}/README.md"
  132. DEPENDS README.md
  133. VERBATIM
  134. )
  135. endif()
  136. install(
  137. FILES "${manpage}"
  138. DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
  139. )
  140. add_custom_target(man ALL DEPENDS "${manpage}")
  141. if(GIT)
  142. add_custom_target(changelog
  143. COMMAND ${GIT2DEBCL} --name ${PROJECT_NAME} > ${CMAKE_CURRENT_BINARY_DIR}/changelog
  144. BYPRODUCTS changelog
  145. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  146. )
  147. add_custom_target(authors
  148. COMMAND ${GIT} log --format='%aN <%aE>' | sort -fu > ${CMAKE_CURRENT_BINARY_DIR}/AUTHORS
  149. BYPRODUCTS AUTHORS
  150. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  151. )
  152. endif()
  153. if(EXISTS /usr/bin/apt-get)
  154. add_custom_target(install-build-pkgs
  155. COMMAND apt-get -qy update
  156. COMMAND apt-get -qy --no-install-suggests --no-install-recommends --force-yes install build-essential git g++ debhelper libattr1-dev python automake libtool lsb-release
  157. )
  158. elseif(EXISTS /usr/bin/dnf)
  159. add_custom_target(install-build-pkgs
  160. COMMAND dnf -y update
  161. COMMAND dnf -y install git rpm-build libattr-devel gcc-c++ make which python automake libtool gettext-devel
  162. )
  163. elseif(EXISTS /usr/bin/yum)
  164. add_custom_target(install-build-pkgs
  165. COMMAND yum -y update
  166. COMMAND yum -y install git rpm-build libattr-devel gcc-c++ make which python automake libtool gettext-devel
  167. )
  168. endif()
  169. set(CPACK_GENERATOR "DEB;RPM")
  170. set(CPACK_PACKAGE_NAME "${PROJECT_NAME}")
  171. set(CPACK_PACKAGE_VERSION "${MERGERFS_VERSION}")
  172. set(CPACK_PACKAGE_CONTACT "Antonio SJ Musumeci <trapexit@spawn.link>")
  173. set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "another FUSE union filesystem")
  174. set(package_long_description
  175. "mergerfs is similar to mhddfs, unionfs, and aufs.
  176. Like mhddfs in that it too uses FUSE.
  177. Like aufs in that it provides multiple policies for how to handle behavior."
  178. )
  179. set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
  180. set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
  181. set(CPACK_DEBIAN_PACKAGE_DEPENDS "\\$\{shlibs\:Depends}, \\$\{misc\:Depends}, fuse [linux-any] | fuse4bsd [kfreebsd-any]")
  182. set(CPACK_DEBIAN_PACKAGE_BUILDS_DEPENDS "debhelper (>= 8.0.0), libattr1-dev")
  183. set(CPACK_DEBIAN_PACKAGE_SECTION "utils")
  184. set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
  185. set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://github.com/trapexit/mergerfs")
  186. set(CPACK_DEBIAN_PACKAGE_DESCRIPTION
  187. "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}
  188. ${package_long_description}"
  189. )
  190. set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS "ON")
  191. set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION "ON")
  192. set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
  193. "${CMAKE_CURRENT_SOURCE_DIR}/debian/docs;${CMAKE_CURRENT_SOURCE_DIR}/debian/copyright;${CMAKE_CURRENT_BINARY_DIR}/changelog"
  194. )
  195. set(CPACK_RPM_PACKAGE_RELEASE "1%{?dist}")
  196. set(CPACK_RPM_PACKAGE_LICENSE "ISC")
  197. set(CPACK_RPM_PACKAGE_GROUP "Applications/System")
  198. set(CPACK_RPM_PACKAGE_URL "http://github.com/trapexit/mergerfs")
  199. set(CPACK_RPM_PACKAGE_REQUIRES "fuse")
  200. set(CPACK_RPM_PACKAGE_SUMMARY "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
  201. set(CPACK_RPM_PACKAGE_DESCRIPTION "${package_long_description}")
  202. # TODO: CPACK_RPM_CHANGELOG_FILE
  203. set(CPACK_SOURCE_GENERATOR "TGZ")
  204. set(CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${MERGERFS_VERSION}")
  205. set(CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/.git/")
  206. # CPACK_SOURCE_INSTALLED_DIRECTORIES
  207. # custom_target instead of cpack source generator?
  208. include(CPack)