CMakeLists.txt 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. # CMAKE REFERENCE
  2. # intro: https://codingnest.com/basic-cmake/
  3. # best practices (3.0+): https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1
  4. # Version should match the tested CMAKE_URL in .travis.yml.
  5. cmake_minimum_required(VERSION 2.8.12)
  6. project(nvim C)
  7. # Point CMake at any custom modules we may ship
  8. list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
  9. # We don't support building in-tree.
  10. include(PreventInTreeBuilds)
  11. set_property(GLOBAL PROPERTY USE_FOLDERS ON)
  12. # Prefer our bundled versions of dependencies.
  13. if(DEFINED ENV{DEPS_BUILD_DIR})
  14. set(DEPS_PREFIX "$ENV{DEPS_BUILD_DIR}/usr" CACHE PATH "Path prefix for finding dependencies")
  15. else()
  16. set(DEPS_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/.deps/usr" CACHE PATH "Path prefix for finding dependencies")
  17. # When running from within CLion or Visual Studio,
  18. # build bundled dependencies automatically.
  19. if(NOT EXISTS ${DEPS_PREFIX}
  20. AND (DEFINED ENV{CLION_IDE}
  21. OR DEFINED ENV{VisualStudioEdition}))
  22. message(STATUS "Building dependencies...")
  23. set(DEPS_BUILD_DIR ${PROJECT_BINARY_DIR}/.deps)
  24. file(MAKE_DIRECTORY ${DEPS_BUILD_DIR})
  25. execute_process(
  26. COMMAND ${CMAKE_COMMAND} -G ${CMAKE_GENERATOR}
  27. -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
  28. -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
  29. -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
  30. -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
  31. -DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG}
  32. -DCMAKE_C_FLAGS_MINSIZEREL=${CMAKE_C_FLAGS_MINSIZEREL}
  33. -DCMAKE_C_FLAGS_RELWITHDEBINFO=${CMAKE_C_FLAGS_RELWITHDEBINFO}
  34. -DCMAKE_C_FLAGS_RELEASE=${CMAKE_C_FLAGS_RELEASE}
  35. -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
  36. ${PROJECT_SOURCE_DIR}/third-party
  37. WORKING_DIRECTORY ${DEPS_BUILD_DIR})
  38. execute_process(
  39. COMMAND ${CMAKE_COMMAND} --build ${DEPS_BUILD_DIR}
  40. --config ${CMAKE_BUILD_TYPE})
  41. set(DEPS_PREFIX ${DEPS_BUILD_DIR}/usr)
  42. endif()
  43. endif()
  44. if(CMAKE_CROSSCOMPILING AND NOT UNIX)
  45. list(INSERT CMAKE_FIND_ROOT_PATH 0 ${DEPS_PREFIX})
  46. list(INSERT CMAKE_PREFIX_PATH 0 ${DEPS_PREFIX}/../host/bin)
  47. else()
  48. list(INSERT CMAKE_PREFIX_PATH 0 ${DEPS_PREFIX})
  49. set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${DEPS_PREFIX}/lib/pkgconfig")
  50. endif()
  51. # used for check_c_compiler_flag
  52. include(CheckCCompilerFlag)
  53. if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
  54. # CMake tries to treat /sw and /opt/local as extension of the system path, but
  55. # that doesn't really work out very well. Once you have a dependency that
  56. # resides there and have to add it as an include directory, then any other
  57. # dependency that could be satisfied from there must be--otherwise you can end
  58. # up with conflicting versions. So, let's make them more of a priority having
  59. # them be included as one of the first places to look for dependencies.
  60. list(APPEND CMAKE_PREFIX_PATH /sw /opt/local)
  61. # Work around some old, broken detection by CMake for knowing when to use the
  62. # isystem flag. Apple's compilers have supported this for quite some time
  63. # now.
  64. if(CMAKE_COMPILER_IS_GNUCC)
  65. set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-isystem ")
  66. endif()
  67. endif()
  68. if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Darwin")
  69. # Enable fixing case-insensitive filenames for Windows and Mac.
  70. set(USE_FNAME_CASE TRUE)
  71. endif()
  72. option(ENABLE_LIBINTL "enable libintl" ON)
  73. option(ENABLE_LIBICONV "enable libiconv" ON)
  74. if (MINGW)
  75. # Disable LTO by default as it may not compile
  76. # See https://github.com/Alexpux/MINGW-packages/issues/3516
  77. # and https://github.com/neovim/neovim/pull/8654#issuecomment-402316672
  78. option(ENABLE_LTO "enable link time optimization" OFF)
  79. else()
  80. option(ENABLE_LTO "enable link time optimization" ON)
  81. endif()
  82. message(STATUS "CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}")
  83. # Build type.
  84. if(NOT CMAKE_BUILD_TYPE)
  85. message(STATUS "CMAKE_BUILD_TYPE not specified, default is 'Debug'")
  86. set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build" FORCE)
  87. else()
  88. message(STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
  89. endif()
  90. if(CMAKE_BUILD_TYPE MATCHES Debug)
  91. set(DEBUG 1)
  92. else()
  93. set(DEBUG 0)
  94. endif()
  95. # Set available build types for CMake GUIs.
  96. # Other build types can still be set by -DCMAKE_BUILD_TYPE=...
  97. set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
  98. STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
  99. # If not in a git repo (e.g., a tarball) these tokens define the complete
  100. # version string, else they are combined with the result of `git describe`.
  101. set(NVIM_VERSION_MAJOR 0)
  102. set(NVIM_VERSION_MINOR 4)
  103. set(NVIM_VERSION_PATCH 5)
  104. set(NVIM_VERSION_PRERELEASE "-dev") # for package maintainers
  105. # API level
  106. set(NVIM_API_LEVEL 6) # Bump this after any API change.
  107. set(NVIM_API_LEVEL_COMPAT 0) # Adjust this after a _breaking_ API change.
  108. set(NVIM_API_PRERELEASE false)
  109. file(TO_CMAKE_PATH ${CMAKE_CURRENT_LIST_DIR}/.git FORCED_GIT_DIR)
  110. include(GetGitRevisionDescription)
  111. get_git_head_revision(GIT_REFSPEC NVIM_VERSION_COMMIT)
  112. if(NVIM_VERSION_COMMIT) # is a git repo
  113. git_describe(NVIM_VERSION_MEDIUM)
  114. # `git describe` annotates the most recent tagged release; for pre-release
  115. # builds we must replace that with the unreleased version.
  116. string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.[0-9]+"
  117. "v${NVIM_VERSION_MAJOR}.${NVIM_VERSION_MINOR}.${NVIM_VERSION_PATCH}"
  118. NVIM_VERSION_MEDIUM
  119. ${NVIM_VERSION_MEDIUM})
  120. endif()
  121. set(NVIM_VERSION_BUILD_TYPE "${CMAKE_BUILD_TYPE}")
  122. # NVIM_VERSION_CFLAGS set further below.
  123. set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
  124. # Minimize logging for release-type builds.
  125. if(NOT CMAKE_C_FLAGS_RELEASE MATCHES DMIN_LOG_LEVEL)
  126. set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DMIN_LOG_LEVEL=3")
  127. endif()
  128. if(NOT CMAKE_C_FLAGS_MINSIZEREL MATCHES DMIN_LOG_LEVEL)
  129. set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} -DMIN_LOG_LEVEL=3")
  130. endif()
  131. if(NOT CMAKE_C_FLAGS_RELWITHDEBINFO MATCHES DMIN_LOG_LEVEL)
  132. set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DMIN_LOG_LEVEL=3")
  133. endif()
  134. # Log level (MIN_LOG_LEVEL in log.h)
  135. if("${MIN_LOG_LEVEL}" MATCHES "^$")
  136. message(STATUS "MIN_LOG_LEVEL not specified, default is 1 (INFO)")
  137. else()
  138. if(NOT MIN_LOG_LEVEL MATCHES "^[0-3]$")
  139. message(FATAL_ERROR "invalid MIN_LOG_LEVEL: " ${MIN_LOG_LEVEL})
  140. endif()
  141. message(STATUS "MIN_LOG_LEVEL=${MIN_LOG_LEVEL}")
  142. endif()
  143. # Default to -O2 on release builds.
  144. if(CMAKE_C_FLAGS_RELEASE MATCHES "-O3")
  145. message(STATUS "Replacing -O3 in CMAKE_C_FLAGS_RELEASE with -O2")
  146. string(REPLACE "-O3" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
  147. endif()
  148. if(CMAKE_COMPILER_IS_GNUCC)
  149. check_c_compiler_flag(-Og HAS_OG_FLAG)
  150. else()
  151. set(HAS_OG_FLAG 0)
  152. endif()
  153. #
  154. # Build-type: RelWithDebInfo
  155. #
  156. if(HAS_OG_FLAG)
  157. set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -Og -g")
  158. endif()
  159. # We _want_ assertions in RelWithDebInfo build-type.
  160. if(CMAKE_C_FLAGS_RELWITHDEBINFO MATCHES DNDEBUG)
  161. string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
  162. endif()
  163. # gcc 4.0+ sets _FORTIFY_SOURCE=2 automatically. This currently
  164. # does not work with Neovim due to some uses of dynamically-sized structures.
  165. # https://github.com/neovim/neovim/issues/223
  166. include(CheckCSourceCompiles)
  167. # Include the build type's default flags in the check for _FORTIFY_SOURCE,
  168. # otherwise we may incorrectly identify the level as acceptable and find out
  169. # later that it was not when optimizations were enabled. CFLAGS is applied
  170. # even though you don't see it in CMAKE_REQUIRED_FLAGS.
  171. set(INIT_FLAGS_NAME CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE})
  172. string(TOUPPER ${INIT_FLAGS_NAME} INIT_FLAGS_NAME)
  173. if(${INIT_FLAGS_NAME})
  174. set(CMAKE_REQUIRED_FLAGS "${${INIT_FLAGS_NAME}}")
  175. endif()
  176. # Include <string.h> because some toolchains define _FORTIFY_SOURCE=2 in
  177. # internal header files, which should in turn be #included by <string.h>.
  178. check_c_source_compiles("
  179. #include <string.h>
  180. #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 1
  181. #error \"_FORTIFY_SOURCE > 1\"
  182. #endif
  183. int
  184. main(void)
  185. {
  186. return 0;
  187. }
  188. " HAS_ACCEPTABLE_FORTIFY)
  189. if(NOT HAS_ACCEPTABLE_FORTIFY)
  190. message(STATUS "Unsupported _FORTIFY_SOURCE found, forcing _FORTIFY_SOURCE=1")
  191. # Extract possible prefix to _FORTIFY_SOURCE (e.g. -Wp,-D_FORTIFY_SOURCE).
  192. STRING(REGEX MATCH "[^\ ]+-D_FORTIFY_SOURCE" _FORTIFY_SOURCE_PREFIX "${CMAKE_C_FLAGS}")
  193. STRING(REPLACE "-D_FORTIFY_SOURCE" "" _FORTIFY_SOURCE_PREFIX "${_FORTIFY_SOURCE_PREFIX}" )
  194. if(NOT _FORTIFY_SOURCE_PREFIX STREQUAL "")
  195. message(STATUS "Detected _FORTIFY_SOURCE Prefix=${_FORTIFY_SOURCE_PREFIX}")
  196. endif()
  197. # -U in add_definitions doesn't end up in the correct spot, so we add it to
  198. # the flags variable instead.
  199. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_FORTIFY_SOURCE_PREFIX}-U_FORTIFY_SOURCE ${_FORTIFY_SOURCE_PREFIX}-D_FORTIFY_SOURCE=1")
  200. endif()
  201. # Remove --sort-common from linker flags, as this seems to cause bugs (see #2641, #3374).
  202. # TODO: Figure out the root cause.
  203. if(CMAKE_EXE_LINKER_FLAGS MATCHES "--sort-common" OR
  204. CMAKE_SHARED_LINKER_FLAGS MATCHES "--sort-common" OR
  205. CMAKE_MODULE_LINKER_FLAGS MATCHES "--sort-common")
  206. message(STATUS "Removing --sort-common from linker flags")
  207. string(REGEX REPLACE ",--sort-common(=[^,]+)?" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
  208. string(REGEX REPLACE ",--sort-common(=[^,]+)?" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
  209. string(REGEX REPLACE ",--sort-common(=[^,]+)?" "" CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}")
  210. # If no linker flags remain for a -Wl argument, remove it.
  211. # '-Wl$' will match LDFLAGS="-Wl,--sort-common",
  212. # '-Wl ' will match LDFLAGS="-Wl,--sort-common -Wl,..."
  213. string(REGEX REPLACE "-Wl($| )" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
  214. string(REGEX REPLACE "-Wl($| )" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
  215. string(REGEX REPLACE "-Wl($| )" "" CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}")
  216. endif()
  217. check_c_source_compiles("
  218. #include <execinfo.h>
  219. int main(void)
  220. {
  221. void *trace[1];
  222. backtrace(trace, 1);
  223. return 0;
  224. }
  225. " HAVE_EXECINFO_BACKTRACE)
  226. check_c_source_compiles("
  227. int main(void)
  228. {
  229. int a = 42;
  230. __builtin_add_overflow(a, a, &a);
  231. __builtin_sub_overflow(a, a, &a);
  232. return 0;
  233. }
  234. " HAVE_BUILTIN_ADD_OVERFLOW)
  235. if(MSVC)
  236. # XXX: /W4 gives too many warnings. #3241
  237. add_compile_options(/W3)
  238. add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
  239. add_definitions(-DWIN32)
  240. else()
  241. add_compile_options(-Wall -Wextra -pedantic -Wno-unused-parameter
  242. -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion
  243. -Wmissing-prototypes)
  244. check_c_compiler_flag(-Wimplicit-fallthrough HAS_WIMPLICIT_FALLTHROUGH_FLAG)
  245. if(HAS_WIMPLICIT_FALLTHROUGH_FLAG)
  246. add_compile_options(-Wimplicit-fallthrough)
  247. endif()
  248. # On FreeBSD 64 math.h uses unguarded C11 extension, which taints clang
  249. # 3.4.1 used there.
  250. if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" AND CMAKE_C_COMPILER_ID MATCHES "Clang")
  251. add_compile_options(-Wno-c11-extensions)
  252. endif()
  253. endif()
  254. if(MINGW)
  255. # Use POSIX compatible stdio in Mingw
  256. add_definitions(-D__USE_MINGW_ANSI_STDIO)
  257. endif()
  258. if(WIN32)
  259. # Windows Vista is the minimum supported version
  260. add_definitions(-D_WIN32_WINNT=0x0600)
  261. endif()
  262. # OpenBSD's GCC (4.2.1) doesn't have -Wvla
  263. check_c_compiler_flag(-Wvla HAS_WVLA_FLAG)
  264. if(HAS_WVLA_FLAG)
  265. add_compile_options(-Wvla)
  266. endif()
  267. if(UNIX)
  268. # -fstack-protector breaks non Unix builds even in Mingw-w64
  269. check_c_compiler_flag(-fstack-protector-strong HAS_FSTACK_PROTECTOR_STRONG_FLAG)
  270. check_c_compiler_flag(-fstack-protector HAS_FSTACK_PROTECTOR_FLAG)
  271. if(HAS_FSTACK_PROTECTOR_STRONG_FLAG)
  272. add_compile_options(-fstack-protector-strong)
  273. elseif(HAS_FSTACK_PROTECTOR_FLAG)
  274. add_compile_options(-fstack-protector --param ssp-buffer-size=4)
  275. endif()
  276. endif()
  277. check_c_compiler_flag(-fno-common HAVE_FNO_COMMON)
  278. if (HAVE_FNO_COMMON)
  279. add_compile_options(-fno-common)
  280. endif()
  281. check_c_compiler_flag(-fdiagnostics-color=auto HAS_DIAG_COLOR_FLAG)
  282. if(HAS_DIAG_COLOR_FLAG)
  283. if(CMAKE_GENERATOR MATCHES "Ninja")
  284. add_compile_options(-fdiagnostics-color=always)
  285. else()
  286. add_compile_options(-fdiagnostics-color=auto)
  287. endif()
  288. endif()
  289. option(TRAVIS_CI_BUILD "Travis/QuickBuild CI, extra flags will be set" OFF)
  290. if(TRAVIS_CI_BUILD)
  291. message(STATUS "Travis/QuickBuild CI build enabled")
  292. add_compile_options(-Werror)
  293. if(DEFINED ENV{BUILD_32BIT})
  294. # Get some test coverage for unsigned char
  295. add_compile_options(-funsigned-char)
  296. endif()
  297. endif()
  298. option(LOG_LIST_ACTIONS "Add list actions logging" OFF)
  299. add_definitions(-DINCLUDE_GENERATED_DECLARATIONS)
  300. if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
  301. if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
  302. set(NO_UNDEFINED "-Wl,--no-undefined -lsocket")
  303. elseif(NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin")
  304. set(NO_UNDEFINED "-Wl,--no-undefined")
  305. endif()
  306. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${NO_UNDEFINED}")
  307. set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${NO_UNDEFINED}")
  308. # For O_CLOEXEC, O_DIRECTORY, and O_NOFOLLOW flags on older systems
  309. # (pre POSIX.1-2008: glibc 2.11 and earlier). #4042
  310. # For ptsname(). #6743
  311. add_definitions(-D_GNU_SOURCE)
  312. endif()
  313. if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
  314. # Required for luajit.
  315. set(CMAKE_EXE_LINKER_FLAGS
  316. "${CMAKE_EXE_LINKER_FLAGS} -pagezero_size 10000 -image_base 100000000")
  317. set(CMAKE_SHARED_LINKER_FLAGS
  318. "${CMAKE_SHARED_LINKER_FLAGS} -image_base 100000000")
  319. set(CMAKE_MODULE_LINKER_FLAGS
  320. "${CMAKE_MODULE_LINKER_FLAGS} -image_base 100000000")
  321. endif()
  322. include_directories("${PROJECT_BINARY_DIR}/config")
  323. include_directories("${PROJECT_SOURCE_DIR}/src")
  324. find_package(LibUV 1.28.0 REQUIRED)
  325. include_directories(SYSTEM ${LIBUV_INCLUDE_DIRS})
  326. find_package(Msgpack 1.0.0 REQUIRED)
  327. include_directories(SYSTEM ${MSGPACK_INCLUDE_DIRS})
  328. find_package(LibLUV 1.30.0 REQUIRED)
  329. include_directories(SYSTEM ${LIBLUV_INCLUDE_DIRS})
  330. # Note: The test lib requires LuaJIT; it will be skipped if LuaJIT is missing.
  331. option(PREFER_LUA "Prefer Lua over LuaJIT in the nvim executable." OFF)
  332. if(PREFER_LUA)
  333. find_package(Lua 5.1 REQUIRED)
  334. set(LUA_PREFERRED_INCLUDE_DIRS ${LUA_INCLUDE_DIR})
  335. set(LUA_PREFERRED_LIBRARIES ${LUA_LIBRARIES})
  336. # Passive (not REQUIRED): if LUAJIT_FOUND is not set, nvim-test is skipped.
  337. find_package(LuaJit)
  338. else()
  339. find_package(LuaJit REQUIRED)
  340. set(LUA_PREFERRED_INCLUDE_DIRS ${LUAJIT_INCLUDE_DIRS})
  341. set(LUA_PREFERRED_LIBRARIES ${LUAJIT_LIBRARIES})
  342. endif()
  343. list(APPEND CMAKE_REQUIRED_INCLUDES "${MSGPACK_INCLUDE_DIRS}")
  344. check_c_source_compiles("
  345. #include <msgpack.h>
  346. int
  347. main(void)
  348. {
  349. return MSGPACK_OBJECT_FLOAT32;
  350. }
  351. " MSGPACK_HAS_FLOAT32)
  352. list(REMOVE_ITEM CMAKE_REQUIRED_INCLUDES "${MSGPACK_INCLUDE_DIRS}")
  353. if(MSGPACK_HAS_FLOAT32)
  354. add_definitions(-DNVIM_MSGPACK_HAS_FLOAT32)
  355. endif()
  356. option(FEAT_TUI "Enable the Terminal UI" ON)
  357. if(FEAT_TUI)
  358. find_package(UNIBILIUM 2.0 REQUIRED)
  359. include_directories(SYSTEM ${UNIBILIUM_INCLUDE_DIRS})
  360. list(APPEND CMAKE_REQUIRED_INCLUDES "${UNIBILIUM_INCLUDE_DIRS}")
  361. list(APPEND CMAKE_REQUIRED_LIBRARIES "${UNIBILIUM_LIBRARIES}")
  362. check_c_source_compiles("
  363. #include <unibilium.h>
  364. int
  365. main(void)
  366. {
  367. return unibi_num_from_var(unibi_var_from_num(0));
  368. }
  369. " UNIBI_HAS_VAR_FROM)
  370. list(REMOVE_ITEM CMAKE_REQUIRED_INCLUDES "${UNIBILIUM_INCLUDE_DIRS}")
  371. list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "${UNIBILIUM_LIBRARIES}")
  372. if(UNIBI_HAS_VAR_FROM)
  373. add_definitions(-DNVIM_UNIBI_HAS_VAR_FROM)
  374. endif()
  375. find_package(LibTermkey 0.18 REQUIRED)
  376. include_directories(SYSTEM ${LIBTERMKEY_INCLUDE_DIRS})
  377. endif()
  378. find_package(LIBVTERM 0.1 REQUIRED)
  379. include_directories(SYSTEM ${LIBVTERM_INCLUDE_DIRS})
  380. if(WIN32)
  381. find_package(Winpty 0.4.3 REQUIRED)
  382. include_directories(SYSTEM ${WINPTY_INCLUDE_DIRS})
  383. endif()
  384. option(CLANG_ASAN_UBSAN "Enable Clang address & undefined behavior sanitizer for nvim binary." OFF)
  385. option(CLANG_MSAN "Enable Clang memory sanitizer for nvim binary." OFF)
  386. option(CLANG_TSAN "Enable Clang thread sanitizer for nvim binary." OFF)
  387. if((CLANG_ASAN_UBSAN AND CLANG_MSAN)
  388. OR (CLANG_ASAN_UBSAN AND CLANG_TSAN)
  389. OR (CLANG_MSAN AND CLANG_TSAN))
  390. message(FATAL_ERROR "Sanitizers cannot be enabled simultaneously")
  391. endif()
  392. if((CLANG_ASAN_UBSAN OR CLANG_MSAN OR CLANG_TSAN) AND NOT CMAKE_C_COMPILER_ID MATCHES "Clang")
  393. message(FATAL_ERROR "Sanitizers are only supported for Clang")
  394. endif()
  395. if(ENABLE_LIBICONV)
  396. find_package(Iconv REQUIRED)
  397. include_directories(SYSTEM ${Iconv_INCLUDE_DIRS})
  398. endif()
  399. if(ENABLE_LIBINTL)
  400. # LibIntl (not Intl) selects our FindLibIntl.cmake script. #8464
  401. find_package(LibIntl REQUIRED)
  402. include_directories(SYSTEM ${LibIntl_INCLUDE_DIRS})
  403. endif()
  404. # Determine platform's threading library. Set CMAKE_THREAD_PREFER_PTHREAD
  405. # explicitly to indicate a strong preference for pthread.
  406. set(CMAKE_THREAD_PREFER_PTHREAD ON)
  407. find_package(Threads REQUIRED)
  408. # Place targets in bin/ or lib/ for all build configurations
  409. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
  410. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
  411. set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
  412. foreach(CFGNAME ${CMAKE_CONFIGURATION_TYPES})
  413. string(TOUPPER ${CFGNAME} CFGNAME)
  414. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFGNAME} ${CMAKE_BINARY_DIR}/bin)
  415. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFGNAME} ${CMAKE_BINARY_DIR}/lib)
  416. set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFGNAME} ${CMAKE_BINARY_DIR}/lib)
  417. endforeach()
  418. # Find Lua interpreter
  419. include(LuaHelpers)
  420. set(LUA_DEPENDENCIES lpeg mpack bit)
  421. if(NOT LUA_PRG)
  422. foreach(CURRENT_LUA_PRG luajit lua5.1 lua5.2 lua)
  423. # If LUA_PRG is set find_program() will not search
  424. unset(LUA_PRG CACHE)
  425. unset(LUA_PRG_WORKS)
  426. find_program(LUA_PRG ${CURRENT_LUA_PRG})
  427. if(LUA_PRG)
  428. check_lua_deps(${LUA_PRG} "${LUA_DEPENDENCIES}" LUA_PRG_WORKS)
  429. if(LUA_PRG_WORKS)
  430. break()
  431. endif()
  432. endif()
  433. endforeach()
  434. else()
  435. check_lua_deps(${LUA_PRG} "${LUA_DEPENDENCIES}" LUA_PRG_WORKS)
  436. endif()
  437. if(NOT LUA_PRG_WORKS)
  438. message(FATAL_ERROR "Failed to find a Lua 5.1-compatible interpreter")
  439. endif()
  440. message(STATUS "Using Lua interpreter: ${LUA_PRG}")
  441. # Setup busted.
  442. find_program(BUSTED_PRG NAMES busted busted.bat)
  443. find_program(BUSTED_LUA_PRG busted-lua)
  444. if(NOT BUSTED_OUTPUT_TYPE)
  445. set(BUSTED_OUTPUT_TYPE "nvim")
  446. endif()
  447. find_program(LUACHECK_PRG luacheck)
  448. find_program(FLAKE8_PRG flake8)
  449. find_program(GPERF_PRG gperf)
  450. include(InstallHelpers)
  451. file(GLOB MANPAGES
  452. RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
  453. man/nvim.1)
  454. install_helper(
  455. FILES ${MANPAGES}
  456. DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
  457. #
  458. # Go down the tree.
  459. #
  460. add_subdirectory(src/nvim)
  461. get_directory_property(NVIM_VERSION_CFLAGS DIRECTORY src/nvim DEFINITION NVIM_VERSION_CFLAGS)
  462. add_subdirectory(test/includes)
  463. add_subdirectory(config)
  464. add_subdirectory(test/functional/fixtures) # compile test programs
  465. add_subdirectory(runtime)
  466. get_directory_property(GENERATED_HELP_TAGS DIRECTORY runtime DEFINITION GENERATED_HELP_TAGS)
  467. if(WIN32)
  468. install_helper(
  469. FILES ${DEPS_PREFIX}/share/nvim-qt/runtime/plugin/nvim_gui_shim.vim
  470. DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/nvim-qt/runtime/plugin)
  471. endif()
  472. # Setup some test-related bits. We do this after going down the tree because we
  473. # need some of the targets.
  474. if(BUSTED_PRG)
  475. get_property(TEST_INCLUDE_DIRS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  476. PROPERTY INCLUDE_DIRECTORIES)
  477. # When running tests from 'ninja' we need to use the
  478. # console pool: to do so we need to use the USES_TERMINAL
  479. # option, but this is only available in CMake 3.2
  480. set(TEST_TARGET_ARGS)
  481. if(NOT (${CMAKE_VERSION} VERSION_LESS 3.2.0))
  482. list(APPEND TEST_TARGET_ARGS "USES_TERMINAL")
  483. endif()
  484. set(UNITTEST_PREREQS nvim-test unittest-headers)
  485. set(FUNCTIONALTEST_PREREQS nvim printargs-test shell-test streams-test ${GENERATED_HELP_TAGS})
  486. if(NOT WIN32)
  487. list(APPEND FUNCTIONALTEST_PREREQS tty-test)
  488. endif()
  489. set(BENCHMARK_PREREQS nvim tty-test)
  490. # Useful for automated build systems, if they want to manually run the tests.
  491. add_custom_target(unittest-prereqs
  492. DEPENDS ${UNITTEST_PREREQS})
  493. set_target_properties(unittest-prereqs PROPERTIES FOLDER test)
  494. add_custom_target(functionaltest-prereqs
  495. DEPENDS ${FUNCTIONALTEST_PREREQS})
  496. add_custom_target(benchmark-prereqs
  497. DEPENDS ${BENCHMARK_PREREQS})
  498. check_lua_module(${LUA_PRG} "ffi" LUA_HAS_FFI)
  499. if(LUA_HAS_FFI)
  500. add_custom_target(unittest
  501. COMMAND ${CMAKE_COMMAND}
  502. -DBUSTED_PRG=${BUSTED_PRG}
  503. -DLUA_PRG=${LUA_PRG}
  504. -DWORKING_DIR=${CMAKE_CURRENT_SOURCE_DIR}
  505. -DBUSTED_OUTPUT_TYPE=${BUSTED_OUTPUT_TYPE}
  506. -DTEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test
  507. -DBUILD_DIR=${CMAKE_BINARY_DIR}
  508. -DTEST_TYPE=unit
  509. -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake
  510. DEPENDS ${UNITTEST_PREREQS}
  511. ${TEST_TARGET_ARGS})
  512. set_target_properties(unittest PROPERTIES FOLDER test)
  513. else()
  514. message(WARNING "disabling unit tests: no Luajit FFI in ${LUA_PRG}")
  515. endif()
  516. if(LUA_HAS_FFI)
  517. set(TEST_LIBNVIM_PATH $<TARGET_FILE:nvim-test>)
  518. else()
  519. set(TEST_LIBNVIM_PATH "")
  520. endif()
  521. configure_file(
  522. ${CMAKE_SOURCE_DIR}/test/config/paths.lua.in
  523. ${CMAKE_BINARY_DIR}/test/config/paths.lua.gen)
  524. file(GENERATE
  525. OUTPUT ${CMAKE_BINARY_DIR}/test/config/paths.lua
  526. INPUT ${CMAKE_BINARY_DIR}/test/config/paths.lua.gen)
  527. add_custom_target(functionaltest
  528. COMMAND ${CMAKE_COMMAND}
  529. -DBUSTED_PRG=${BUSTED_PRG}
  530. -DLUA_PRG=${LUA_PRG}
  531. -DNVIM_PRG=$<TARGET_FILE:nvim>
  532. -DWORKING_DIR=${CMAKE_CURRENT_SOURCE_DIR}
  533. -DBUSTED_OUTPUT_TYPE=${BUSTED_OUTPUT_TYPE}
  534. -DTEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test
  535. -DBUILD_DIR=${CMAKE_BINARY_DIR}
  536. -DTEST_TYPE=functional
  537. -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake
  538. DEPENDS ${FUNCTIONALTEST_PREREQS}
  539. ${TEST_TARGET_ARGS})
  540. set_target_properties(functionaltest functionaltest-prereqs
  541. PROPERTIES FOLDER test)
  542. add_custom_target(benchmark
  543. COMMAND ${CMAKE_COMMAND}
  544. -DBUSTED_PRG=${BUSTED_PRG}
  545. -DLUA_PRG=${LUA_PRG}
  546. -DNVIM_PRG=$<TARGET_FILE:nvim>
  547. -DWORKING_DIR=${CMAKE_CURRENT_SOURCE_DIR}
  548. -DBUSTED_OUTPUT_TYPE=${BUSTED_OUTPUT_TYPE}
  549. -DTEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test
  550. -DBUILD_DIR=${CMAKE_BINARY_DIR}
  551. -DTEST_TYPE=benchmark
  552. -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake
  553. DEPENDS ${BENCHMARK_PREREQS}
  554. ${TEST_TARGET_ARGS})
  555. set_target_properties(benchmark benchmark-prereqs PROPERTIES FOLDER test)
  556. endif()
  557. if(BUSTED_LUA_PRG)
  558. add_custom_target(functionaltest-lua
  559. COMMAND ${CMAKE_COMMAND}
  560. -DBUSTED_PRG=${BUSTED_LUA_PRG}
  561. -DLUA_PRG=${LUA_PRG}
  562. -DNVIM_PRG=$<TARGET_FILE:nvim>
  563. -DWORKING_DIR=${CMAKE_CURRENT_SOURCE_DIR}
  564. -DBUSTED_OUTPUT_TYPE=${BUSTED_OUTPUT_TYPE}
  565. -DTEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test
  566. -DBUILD_DIR=${CMAKE_BINARY_DIR}
  567. -DTEST_TYPE=functional
  568. -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake
  569. DEPENDS ${FUNCTIONALTEST_PREREQS}
  570. ${TEST_TARGET_ARGS})
  571. set_target_properties(functionaltest-lua PROPERTIES FOLDER test)
  572. endif()
  573. if(LUACHECK_PRG)
  574. add_custom_target(lualint
  575. COMMAND ${LUACHECK_PRG} -q runtime/ src/ test/
  576. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
  577. else()
  578. add_custom_target(lualint false
  579. COMMENT "lualint: LUACHECK_PRG not defined")
  580. endif()
  581. set(CPACK_PACKAGE_NAME "Neovim")
  582. set(CPACK_PACKAGE_VENDOR "neovim.io")
  583. set(CPACK_PACKAGE_VERSION ${NVIM_VERSION_MEDIUM})
  584. set(CPACK_PACKAGE_INSTALL_DIRECTORY "Neovim")
  585. # Set toplevel directory/installer name as Neovim
  586. set(CPACK_PACKAGE_FILE_NAME "Neovim")
  587. set(CPACK_TOPLEVEL_TAG "Neovim")
  588. set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
  589. set(CPACK_NSIS_MODIFY_PATH ON)
  590. set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
  591. include(CPack)