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.
 
 
 
 
 
 

677 lines
23 KiB

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