CMakeLists.txt 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. cmake_minimum_required(VERSION 2.8.5)
  2. if(POLICY CMP0042)
  3. # CMP0042 is only known to CMake 3.0 and above
  4. cmake_policy(SET CMP0042 OLD)
  5. endif(POLICY CMP0042)
  6. PROJECT(ledger)
  7. set(Ledger_VERSION_MAJOR 3)
  8. set(Ledger_VERSION_MINOR 1)
  9. set(Ledger_VERSION_PATCH 1)
  10. set(Ledger_VERSION_PRERELEASE "")
  11. set(Ledger_VERSION_DATE 20150915)
  12. set(Ledger_TEST_TIMEZONE "America/Chicago")
  13. # Point CMake at any custom modules we may ship
  14. list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
  15. enable_testing()
  16. add_definitions(-std=c++11)
  17. if (CYGWIN)
  18. add_definitions(-U__STRICT_ANSI__)
  19. endif()
  20. ########################################################################
  21. option(USE_PYTHON "Build support for the Python scripting bridge" OFF)
  22. option(USE_DOXYGEN "Build reference documentation using Doxygen" OFF)
  23. option(DISABLE_ASSERTS "Build without any internal consistency checks" OFF)
  24. option(BUILD_DEBUG "Build support for runtime debugging" OFF)
  25. option(BUILD_LIBRARY "Build and install Ledger as a library" ON)
  26. option(BUILD_DOCS "Build and install documentation" OFF)
  27. option(BUILD_WEB_DOCS "Build version of documentation suitable for viewing online" OFF)
  28. option(BUILD_EMACSLISP "Build and install ledger-mode for Emacs" OFF)
  29. if (BUILD_DEBUG)
  30. set(CMAKE_BUILD_TYPE Debug)
  31. set(DEBUG_MODE 1)
  32. else()
  33. set(CMAKE_BUILD_TYPE Release)
  34. set(DEBUG_MODE 0)
  35. endif()
  36. if (DISABLE_ASSERTS)
  37. set(NO_ASSERTS 1)
  38. else()
  39. set(NO_ASSERTS 0)
  40. endif()
  41. if (CLANG_GCOV)
  42. set(PROFILE_LIBS profile_rt)
  43. set(CMAKE_REQUIRED_LIBRARIES ${PROFILE_LIBS})
  44. endif()
  45. ########################################################################
  46. set(Python_ADDITIONAL_VERSIONS 2.7 2.6)
  47. find_package(PythonInterp) # Used for running tests
  48. if (USE_PYTHON)
  49. if (NOT BUILD_LIBRARY)
  50. message(ERROR "Building the python module requires BUILD_LIBRARY=ON.")
  51. endif()
  52. find_package(PythonLibs)
  53. if (PYTHONLIBS_FOUND)
  54. set(BOOST_PYTHON python)
  55. set(HAVE_BOOST_PYTHON 1)
  56. include_directories(SYSTEM ${PYTHON_INCLUDE_DIRS})
  57. else()
  58. set(HAVE_BOOST_PYTHON 0)
  59. message("Could not find a Python library to use with Boost.Python")
  60. endif()
  61. else()
  62. set(HAVE_BOOST_PYTHON 0)
  63. endif()
  64. # Set BOOST_ROOT to help CMake to find the right Boost version
  65. find_package(Boost 1.49.0
  66. REQUIRED date_time filesystem system iostreams regex unit_test_framework
  67. ${BOOST_PYTHON})
  68. include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
  69. link_directories(${Boost_LIBRARY_DIRS})
  70. ########################################################################
  71. include(CheckIncludeFiles)
  72. include(CheckLibraryExists)
  73. include(CheckFunctionExists)
  74. include(CheckCSourceCompiles)
  75. include(CheckCXXSourceRuns)
  76. include(CMakePushCheckState)
  77. check_function_exists(access HAVE_ACCESS)
  78. check_function_exists(realpath HAVE_REALPATH)
  79. check_function_exists(getpwuid HAVE_GETPWUID)
  80. check_function_exists(getpwnam HAVE_GETPWNAM)
  81. check_function_exists(ioctl HAVE_IOCTL)
  82. check_function_exists(isatty HAVE_ISATTY)
  83. check_c_source_compiles("
  84. #include <sys/types.h>
  85. #include <sys/wait.h>
  86. #include <unistd.h>
  87. #include <stdlib.h>
  88. #include <string.h>
  89. #include <stdio.h>
  90. int main() {
  91. int status, pfd[2];
  92. status = pipe(pfd);
  93. status = fork();
  94. if (status < 0) {
  95. ;
  96. } else if (status == 0) {
  97. char *arg0 = NULL;
  98. status = dup2(pfd[0], STDIN_FILENO);
  99. close(pfd[1]);
  100. close(pfd[0]);
  101. execlp(\"\", arg0, (char *)0);
  102. perror(\"execl\");
  103. exit(1);
  104. } else {
  105. close(pfd[0]);
  106. }
  107. return 0;
  108. }" UNIX_PIPES_COMPILES)
  109. if (UNIX_PIPES_COMPILES)
  110. set(HAVE_UNIX_PIPES 1)
  111. else()
  112. set(HAVE_UNIX_PIPES 0)
  113. endif()
  114. cmake_push_check_state()
  115. set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH} ${Boost_INCLUDE_DIRS})
  116. set(CMAKE_REQUIRED_LIBRARIES ${Boost_LIBRARIES} icuuc ${PROFILE_LIBS})
  117. check_cxx_source_runs("
  118. #include <boost/regex/icu.hpp>
  119. using namespace boost;
  120. int main() {
  121. std::string text = \"Активы\";
  122. u32regex r = make_u32regex(\"активы\", regex::perl | regex::icase);
  123. return u32regex_search(text, r) ? 0 : 1;
  124. }" BOOST_REGEX_UNICODE_RUNS)
  125. if (BOOST_REGEX_UNICODE_RUNS)
  126. set(HAVE_BOOST_REGEX_UNICODE 1)
  127. else()
  128. set(HAVE_BOOST_REGEX_UNICODE 0)
  129. endif()
  130. cmake_pop_check_state()
  131. # Check if fix for https://github.com/boostorg/python/issues/39 is needed
  132. if (HAVE_BOOST_PYTHON)
  133. cmake_push_check_state()
  134. set(CMAKE_REQUIRED_INCLUDES
  135. ${CMAKE_INCLUDE_PATH} ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
  136. set(CMAKE_REQUIRED_LIBRARIES
  137. ${Boost_LIBRARIES} ${PYTHON_LIBRARIES} ${PROFILE_LIBS})
  138. check_cxx_source_runs("
  139. #include <boost/python.hpp>
  140. struct X { int y; };
  141. int main()
  142. {
  143. boost::python::make_setter(&X::y);
  144. }" BOOST_MAKE_SETTER_RUNS)
  145. if (BOOST_MAKE_SETTER_RUNS)
  146. set(HAVE_BOOST_159_ISSUE_39 0)
  147. else()
  148. set(HAVE_BOOST_159_ISSUE_39 1)
  149. endif()
  150. cmake_pop_check_state()
  151. endif()
  152. ########################################################################
  153. include_directories(${CMAKE_INCLUDE_PATH})
  154. macro(find_opt_library_and_header _header_var _header _lib_var _lib _have_var)
  155. if (${_have_var})
  156. find_path(${_header_var} ${_header})
  157. if (NOT ${_header_var})
  158. set(${_have_var} 0)
  159. else()
  160. find_library(${_lib_var} ${_lib})
  161. if (NOT ${_lib_var})
  162. set(${_have_var} 0)
  163. else()
  164. include_directories(SYSTEM "${${_header_var}}")
  165. set(${_have_var} 1)
  166. endif()
  167. endif()
  168. else()
  169. set(${_have_var} 0)
  170. endif()
  171. endmacro(find_opt_library_and_header _header_var _header _lib_var _lib _have_var)
  172. macro(find_req_library_and_header _header_var _header _lib_var _lib)
  173. find_path(${_header_var} ${_header})
  174. if (NOT ${_header_var})
  175. message(SEND_ERROR "Could not find ${_header} on your system")
  176. else()
  177. include_directories(SYSTEM "${${_header_var}}")
  178. find_library(${_lib_var} ${_lib})
  179. if (NOT ${_lib_var})
  180. message(SEND_ERROR "Could not find library ${_lib} on your system")
  181. endif()
  182. endif()
  183. endmacro(find_req_library_and_header _header_var _header _lib_var _lib)
  184. find_req_library_and_header(GMP_PATH gmp.h GMP_LIB gmp)
  185. find_req_library_and_header(MPFR_PATH mpfr.h MPFR_LIB mpfr)
  186. check_library_exists(edit readline "" HAVE_EDIT)
  187. find_opt_library_and_header(EDIT_PATH histedit.h EDIT_LIB edit HAVE_EDIT)
  188. #find_package(Gettext) # Used for running tests
  189. #if (GETTEXT_FOUND)
  190. # set(HAVE_GETTEXT 1)
  191. #else()
  192. set(HAVE_GETTEXT 0)
  193. #endif()
  194. #find_path(INTL_PATH libintl.h)
  195. #find_library(INTL_LIB intl)
  196. #include_directories(SYSTEM "${INTL_PATH}")
  197. ########################################################################
  198. macro(add_ledger_library_dependencies _target)
  199. target_link_libraries(${_target} ${MPFR_LIB})
  200. target_link_libraries(${_target} ${GMP_LIB})
  201. if (HAVE_EDIT)
  202. target_link_libraries(${_target} ${EDIT_LIB})
  203. endif()
  204. if (HAVE_GETTEXT)
  205. target_link_libraries(${_target} ${INTL_LIB})
  206. endif()
  207. if (HAVE_BOOST_PYTHON)
  208. if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
  209. # Don't link directly to a Python framework on OS X, to avoid segfaults
  210. # when the module is imported from a different interpreter
  211. target_link_libraries(${_target} ${Boost_LIBRARIES})
  212. set_target_properties(${_target} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
  213. else()
  214. target_link_libraries(${_target} ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
  215. endif()
  216. else()
  217. target_link_libraries(${_target} ${Boost_LIBRARIES})
  218. endif()
  219. if (HAVE_BOOST_REGEX_UNICODE)
  220. target_link_libraries(${_target} icuuc)
  221. endif()
  222. target_link_libraries(${_target} ${PROFILE_LIBS})
  223. endmacro(add_ledger_library_dependencies _target)
  224. ########################################################################
  225. include(FindUtfcpp)
  226. if (UTFCPP_FOUND)
  227. include_directories("${UTFCPP_INCLUDE_DIR}")
  228. else()
  229. message(FATAL_ERROR "Missing required header file: utf8.h\n"
  230. "Define UTFCPP_PATH or install utfcpp locally into the source tree below lib/utfcpp/."
  231. )
  232. endif()
  233. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
  234. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
  235. # add the binary tree to the search path for include files so that we will
  236. # find system.hh
  237. include_directories("${PROJECT_BINARY_DIR}")
  238. configure_file(
  239. ${PROJECT_SOURCE_DIR}/src/system.hh.in
  240. ${PROJECT_BINARY_DIR}/system.hh)
  241. if (CMAKE_CXX_COMPILER MATCHES "clang")
  242. set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem ")
  243. elseif(CMAKE_CXX_COMPILER MATCHES "g\\+\\+")
  244. set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem ")
  245. endif()
  246. add_subdirectory(src)
  247. add_subdirectory(doc)
  248. if (BUILD_EMACSLISP)
  249. add_subdirectory(lisp)
  250. endif()
  251. add_subdirectory(test)
  252. ########################################################################
  253. # build a CPack driven installer package
  254. include (InstallRequiredSystemLibraries)
  255. set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.md")
  256. set (CPACK_PACKAGE_VERSION_MAJOR "${Ledger_VERSION_MAJOR}")
  257. set (CPACK_PACKAGE_VERSION_MINOR "${Ledger_VERSION_MINOR}")
  258. set (CPACK_PACKAGE_VERSION_PATCH "${Ledger_VERSION_PATCH}${Ledger_VERSION_PRERELEASE}")
  259. set (CPACK_GENERATOR "TBZ2")
  260. set (CPACK_SOURCE_GENERATOR "TBZ2")
  261. set (CPACK_SOURCE_PACKAGE_FILE_NAME
  262. "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
  263. set (CPACK_SOURCE_IGNORE_FILES "/.git*;/.dir-locals.el;~$;/doc/website/;/doc/wiki/;/lib/*.sh;/lib/Makefile;/tools/;${CPACK_SOURCE_IGNORE_FILES}")
  264. include (CPack)
  265. ### CMakeLists.txt ends here