CMakeLists.txt (39117B)
1 add_library(main_lib INTERFACE) 2 3 # Internally we need to make a distinction between "nvim without runtime files" 4 # (nvim_bin) and "nvim with runtime files" (nvim). 5 add_executable(nvim_bin EXCLUDE_FROM_ALL) 6 7 set_target_properties(nvim_bin 8 PROPERTIES 9 EXPORT_COMPILE_COMMANDS ON 10 ENABLE_EXPORTS TRUE 11 OUTPUT_NAME nvim) 12 13 #------------------------------------------------------------------------------- 14 # Dependencies 15 #------------------------------------------------------------------------------- 16 17 add_library(nlua0 MODULE) 18 if(WIN32) 19 target_compile_definitions(nlua0 PUBLIC LUA_BUILD_AS_DLL LUA_LIB) 20 set_target_properties(nlua0 PROPERTIES ENABLE_EXPORTS TRUE) 21 elseif(APPLE) 22 target_link_options(nlua0 PRIVATE -undefined dynamic_lookup) 23 endif() 24 25 # TODO(dundargoc): unittest stops working if I create an pseudo-imported 26 # library "luv" as with the other dependencies. Figure out why and fix. 27 find_package(Luv 1.43.0 REQUIRED) 28 target_include_directories(main_lib SYSTEM BEFORE INTERFACE ${LUV_INCLUDE_DIR}) 29 target_link_libraries(main_lib INTERFACE ${LUV_LIBRARY}) 30 31 find_package(Iconv REQUIRED) 32 find_package(Libuv 1.28.0 REQUIRED) 33 find_package(Lpeg REQUIRED) 34 find_package(Treesitter 0.25.0 REQUIRED) 35 find_package(UTF8proc REQUIRED) 36 37 target_link_libraries(main_lib INTERFACE 38 iconv 39 lpeg 40 treesitter 41 utf8proc) 42 target_link_libraries(nlua0 PUBLIC lpeg) 43 44 if(ENABLE_LIBINTL) 45 find_package(Libintl REQUIRED) # Libintl (not Intl) selects our FindLibintl.cmake script. #8464 46 target_link_libraries(main_lib INTERFACE libintl) 47 endif() 48 49 if(ENABLE_UNIBILIUM) 50 find_package(Unibilium 2.0 REQUIRED) 51 target_compile_definitions(nvim_bin PRIVATE HAVE_UNIBILIUM) 52 target_link_libraries(main_lib INTERFACE unibilium) 53 endif() 54 55 if(ENABLE_WASMTIME) 56 find_package(Wasmtime 36.0.6 EXACT REQUIRED) 57 target_link_libraries(main_lib INTERFACE wasmtime) 58 target_compile_definitions(nvim_bin PRIVATE HAVE_WASMTIME) 59 endif() 60 61 # The unit test lib requires LuaJIT; it will be skipped if LuaJIT is missing. 62 option(PREFER_LUA "Prefer Lua over LuaJIT in the nvim executable." OFF) 63 if(PREFER_LUA) 64 find_package(Lua 5.1 EXACT REQUIRED) 65 target_include_directories(main_lib SYSTEM BEFORE INTERFACE ${LUA_INCLUDE_DIR}) 66 target_include_directories(nlua0 SYSTEM BEFORE PUBLIC ${LUA_INCLUDE_DIR}) 67 target_link_libraries(main_lib INTERFACE ${LUA_LIBRARIES}) 68 # Passive (not REQUIRED): if LUAJIT_FOUND is not set, fixtures for unittests is skipped. 69 find_package(Luajit) 70 else() 71 find_package(Luajit REQUIRED) 72 target_include_directories(main_lib SYSTEM BEFORE INTERFACE ${LUAJIT_INCLUDE_DIR}) 73 target_link_libraries(main_lib INTERFACE ${LUAJIT_LIBRARY}) 74 target_include_directories(nlua0 SYSTEM BEFORE PUBLIC ${LUAJIT_INCLUDE_DIR}) 75 if(WIN32 OR CYGWIN) 76 target_link_libraries(nlua0 PUBLIC ${LUAJIT_LIBRARY}) 77 endif() 78 endif() 79 80 #------------------------------------------------------------------------------- 81 # Compiler and linker options 82 #------------------------------------------------------------------------------- 83 84 if(NOT MSVC) 85 target_compile_options(main_lib INTERFACE -Wall -Wextra -pedantic -Wno-unused-parameter 86 -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wvla 87 -Wdouble-promotion 88 -Wmissing-noreturn 89 -Wmissing-format-attribute 90 -Wmissing-prototypes 91 -Wno-unused-function # because #35129 92 -fsigned-char) 93 94 # For O_CLOEXEC, O_DIRECTORY, and O_NOFOLLOW flags on older systems 95 # (pre POSIX.1-2008: glibc 2.11 and earlier). #4042 96 # For ptsname(). #6743 97 target_compile_definitions(main_lib INTERFACE _GNU_SOURCE) 98 endif() 99 100 # -fstack-protector breaks Mingw-w64 builds 101 if(NOT MINGW AND NOT CMAKE_SYSTEM_NAME STREQUAL "Haiku") 102 check_c_compiler_flag(-fstack-protector-strong HAS_FSTACK_PROTECTOR_STRONG_FLAG) 103 if(HAS_FSTACK_PROTECTOR_STRONG_FLAG) 104 target_compile_options(main_lib INTERFACE -fstack-protector-strong) 105 target_link_libraries(main_lib INTERFACE -fstack-protector-strong) 106 else() 107 check_c_compiler_flag(-fstack-protector HAS_FSTACK_PROTECTOR_FLAG) 108 if(HAS_FSTACK_PROTECTOR_FLAG) 109 target_compile_options(main_lib INTERFACE -fstack-protector --param ssp-buffer-size=4) 110 target_link_libraries(main_lib INTERFACE -fstack-protector --param ssp-buffer-size=4) 111 endif() 112 endif() 113 endif() 114 115 # Compiler specific options 116 if(MSVC) 117 target_compile_options(main_lib INTERFACE -W3) 118 119 # Disable warnings that give too many false positives. 120 target_compile_options(main_lib INTERFACE -wd4311 -wd4146 -wd4003 -wd4715) 121 target_compile_definitions(main_lib INTERFACE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_DEPRECATE) 122 123 target_sources(main_lib INTERFACE ${CMAKE_CURRENT_LIST_DIR}/os/nvim.manifest) 124 elseif(MINGW) 125 # Use POSIX compatible stdio in Mingw 126 target_compile_definitions(main_lib INTERFACE __USE_MINGW_ANSI_STDIO) 127 128 # wrapper for nvim.manifest 129 target_sources(main_lib INTERFACE ${CMAKE_CURRENT_LIST_DIR}/os/nvim.rc) 130 elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU") 131 target_compile_options(main_lib INTERFACE 132 -Wno-conversion 133 -fno-common 134 $<$<CONFIG:Release>:-Wno-unused-result> 135 $<$<CONFIG:RelWithDebInfo>:-Wno-unused-result> 136 $<$<CONFIG:MinSizeRel>:-Wno-unused-result>) 137 elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") 138 # On FreeBSD 64 math.h uses unguarded C11 extension, which taints clang 139 # 3.4.1 used there. 140 if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") 141 target_compile_options(main_lib INTERFACE -Wno-c11-extensions) 142 endif() 143 144 # workaround for clang-11 on macOS, supported on later versions 145 if(NOT APPLE) 146 target_link_libraries(nvim_bin PRIVATE -Wl,--no-undefined) 147 endif() 148 endif() 149 150 # Platform specific options 151 if(UNIX) 152 target_link_libraries(main_lib INTERFACE m) 153 if (CMAKE_SYSTEM_NAME STREQUAL "Haiku") 154 target_link_libraries(main_lib INTERFACE bsd) 155 target_link_libraries(nvim_bin PRIVATE -lnetwork) 156 elseif (NOT CMAKE_SYSTEM_NAME STREQUAL "SunOS") 157 target_link_libraries(main_lib INTERFACE util) 158 endif() 159 endif() 160 161 if(CMAKE_SYSTEM_NAME MATCHES "Windows") 162 target_compile_definitions(main_lib INTERFACE _WIN32_WINNT=0x0602 MSWIN WIN32_LEAN_AND_MEAN) 163 target_link_libraries(main_lib INTERFACE netapi32) 164 elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin") 165 target_link_libraries(nvim_bin PRIVATE "-framework CoreServices") 166 167 # Actually export symbols - symbols may not be visible even though 168 # ENABLE_EXPORTS is set. https://github.com/neovim/neovim/issues/25295 169 target_link_options(nvim_bin PRIVATE "-Wl,-export_dynamic") 170 elseif(CMAKE_SYSTEM_NAME MATCHES "OpenBSD") 171 target_link_libraries(main_lib INTERFACE pthread c++abi) 172 elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS") 173 target_link_libraries(nvim_bin PRIVATE -lsocket) 174 endif() 175 176 check_c_compiler_flag(-Wimplicit-fallthrough HAVE_WIMPLICIT_FALLTHROUGH_FLAG) 177 if(HAVE_WIMPLICIT_FALLTHROUGH_FLAG) 178 target_compile_options(main_lib INTERFACE -Wimplicit-fallthrough) 179 endif() 180 181 check_c_compiler_flag(-fdiagnostics-color=auto HAS_DIAG_COLOR_FLAG) 182 if(HAS_DIAG_COLOR_FLAG) 183 if(CMAKE_GENERATOR MATCHES "Ninja") 184 target_compile_options(main_lib INTERFACE -fdiagnostics-color=always) 185 else() 186 target_compile_options(main_lib INTERFACE -fdiagnostics-color=auto) 187 endif() 188 endif() 189 190 # Remove --sort-common from linker flags, as this seems to cause bugs (see #2641, #3374). 191 # TODO: Figure out the root cause. 192 if(CMAKE_EXE_LINKER_FLAGS MATCHES "--sort-common" OR 193 CMAKE_SHARED_LINKER_FLAGS MATCHES "--sort-common" OR 194 CMAKE_MODULE_LINKER_FLAGS MATCHES "--sort-common") 195 message(STATUS "Removing --sort-common from linker flags") 196 string(REGEX REPLACE ",--sort-common(=[^,]+)?" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") 197 string(REGEX REPLACE ",--sort-common(=[^,]+)?" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}") 198 string(REGEX REPLACE ",--sort-common(=[^,]+)?" "" CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}") 199 200 # If no linker flags remain for a -Wl argument, remove it. 201 # '-Wl$' will match LDFLAGS="-Wl,--sort-common", 202 # '-Wl ' will match LDFLAGS="-Wl,--sort-common -Wl,..." 203 string(REGEX REPLACE "-Wl($| )" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") 204 string(REGEX REPLACE "-Wl($| )" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}") 205 string(REGEX REPLACE "-Wl($| )" "" CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}") 206 endif() 207 208 #------------------------------------------------------------------------------- 209 # Cmake options 210 #------------------------------------------------------------------------------- 211 212 if(ENABLE_ASAN_UBSAN) 213 message(STATUS "Enabling address sanitizer and undefined behavior sanitizer for nvim.") 214 if(NOT MSVC) 215 if(CI_BUILD) 216 # Try to recover from all sanitize issues so we get reports about all failures 217 target_compile_options(nvim_bin PRIVATE -fsanitize-recover=all) 218 else() 219 target_compile_options(nvim_bin PRIVATE -fno-sanitize-recover=all) 220 endif() 221 target_compile_options(nvim_bin PRIVATE 222 -fno-omit-frame-pointer 223 -fno-optimize-sibling-calls 224 -fsanitize=undefined) 225 endif() 226 227 target_compile_options(nvim_bin PRIVATE -fsanitize=address) 228 target_link_libraries(nvim_bin PRIVATE -fsanitize=address -fsanitize=undefined) 229 target_compile_definitions(nvim_bin PRIVATE ENABLE_ASAN_UBSAN) 230 endif() 231 232 if(ENABLE_MSAN) 233 message(STATUS "Enabling memory sanitizer for nvim.") 234 target_compile_options(nvim_bin PRIVATE 235 -fsanitize=memory 236 -fsanitize-memory-track-origins 237 -fno-omit-frame-pointer 238 -fno-optimize-sibling-calls) 239 target_link_libraries(nvim_bin PRIVATE -fsanitize=memory -fsanitize-memory-track-origins) 240 endif() 241 242 if(ENABLE_TSAN) 243 message(STATUS "Enabling thread sanitizer for nvim.") 244 target_compile_options(nvim_bin PRIVATE -fsanitize=thread -fPIE) 245 target_link_libraries(nvim_bin PRIVATE -fsanitize=thread) 246 endif() 247 248 option(CI_BUILD "CI, extra flags will be set" OFF) 249 if(CI_BUILD) 250 message(STATUS "CI build enabled") 251 if(MSVC) 252 target_compile_options(main_lib INTERFACE -WX) 253 else() 254 target_compile_options(main_lib INTERFACE -Werror) 255 endif() 256 endif() 257 258 option(ENABLE_IWYU "Run include-what-you-use with the compiler." OFF) 259 if(ENABLE_IWYU) 260 find_program(IWYU_PRG NAMES include-what-you-use iwyu REQUIRED) 261 set(iwyu_flags "${IWYU_PRG};") 262 string(APPEND iwyu_flags "-Xiwyu;--no_default_mappings;") 263 string(APPEND iwyu_flags "-Xiwyu;--no_fwd_decls;") 264 string(APPEND iwyu_flags "-Xiwyu;--mapping_file=${PROJECT_SOURCE_DIR}/cmake.config/iwyu/mapping.imp") 265 266 set_target_properties(nvim_bin PROPERTIES C_INCLUDE_WHAT_YOU_USE "${iwyu_flags}") 267 target_compile_definitions(main_lib INTERFACE EXITFREE) 268 endif() 269 270 option(ENABLE_COMPILER_SUGGESTIONS "Enable -Wsuggest compiler warnings" OFF) 271 if(ENABLE_COMPILER_SUGGESTIONS) 272 target_compile_options(main_lib INTERFACE 273 -Wsuggest-attribute=cold 274 -Wsuggest-attribute=const 275 -Wsuggest-attribute=malloc 276 -Wsuggest-attribute=pure) 277 endif() 278 279 option(ENABLE_GCOV "Enable gcov support" OFF) 280 if(ENABLE_GCOV) 281 if(ENABLE_TSAN) 282 # GCOV and TSAN results in false data race reports 283 message(FATAL_ERROR "ENABLE_GCOV cannot be used with ENABLE_TSAN") 284 endif() 285 message(STATUS "Enabling gcov support") 286 target_compile_options(main_lib INTERFACE --coverage) 287 target_link_libraries(main_lib INTERFACE --coverage) 288 target_compile_definitions(main_lib INTERFACE USE_GCOV) 289 endif() 290 291 #------------------------------------------------------------------------------- 292 # Variables 293 #------------------------------------------------------------------------------- 294 295 set(EVAL_FUNCS_METADATA ${PROJECT_BINARY_DIR}/eval_funcs_metadata.mpack) 296 set(EXPORTED_FUNCS_METADATA ${PROJECT_BINARY_DIR}/exported_funcs_metadata.mpack) 297 set(UI_METADATA ${PROJECT_BINARY_DIR}/ui_metadata.mpack) 298 set(BINARY_LIB_DIR ${PROJECT_BINARY_DIR}/lib/nvim) 299 set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto) 300 set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include) 301 set(GENERATOR_DIR ${PROJECT_SOURCE_DIR}/src/gen) 302 set(GEN_EVAL_TOUCH ${TOUCHES_DIR}/gen_doc_eval) 303 set(LUAJIT_RUNTIME_DIR ${DEPS_PREFIX}/share/luajit-2.1/jit) 304 set(NVIM_RUNTIME_DIR ${PROJECT_SOURCE_DIR}/runtime) 305 306 # GENERATOR_DIR 307 set(API_DISPATCH_GENERATOR ${GENERATOR_DIR}/gen_api_dispatch.lua) 308 set(API_UI_EVENTS_GENERATOR ${GENERATOR_DIR}/gen_api_ui_events.lua) 309 set(API_METADATA_GENERATOR ${GENERATOR_DIR}/gen_api_metadata.lua) 310 set(CHAR_BLOB_GENERATOR ${GENERATOR_DIR}/gen_char_blob.lua) 311 set(EVENTS_GENERATOR ${GENERATOR_DIR}/gen_events.lua) 312 set(EX_CMDS_GENERATOR ${GENERATOR_DIR}/gen_ex_cmds.lua) 313 set(FUNCS_GENERATOR ${GENERATOR_DIR}/gen_eval.lua) 314 set(KEYCODES_GENERATOR ${GENERATOR_DIR}/gen_keycodes.lua) 315 set(GENERATOR_C_GRAMMAR ${GENERATOR_DIR}/c_grammar.lua) 316 set(GENERATOR_HASHY ${GENERATOR_DIR}/hashy.lua) 317 set(GENERATOR_PRELOAD ${GENERATOR_DIR}/preload_nlua.lua) 318 set(NVIM_LUA_PRELOAD ${GENERATOR_DIR}/preload.lua) 319 set(HEADER_GENERATOR ${GENERATOR_DIR}/gen_declarations.lua) 320 set(OPTIONS_GENERATOR ${GENERATOR_DIR}/gen_options.lua) 321 322 # GENERATED_DIR and GENERATED_INCLUDES_DIR 323 set(GENERATED_API_DISPATCH ${GENERATED_DIR}/api/private/dispatch_wrappers.generated.h) 324 set(GENERATED_EVENTS_ENUM ${GENERATED_INCLUDES_DIR}/auevents_enum.generated.h) 325 set(GENERATED_EVENTS_NAMES_MAP ${GENERATED_DIR}/auevents_name_map.generated.h) 326 set(GENERATED_EX_CMDS_DEFS ${GENERATED_DIR}/ex_cmds_defs.generated.h) 327 set(GENERATED_EX_CMDS_ENUM ${GENERATED_INCLUDES_DIR}/ex_cmds_enum.generated.h) 328 set(GENERATED_FUNCS ${GENERATED_DIR}/funcs.generated.h) 329 set(GENERATED_KEYCODE_NAMES ${GENERATED_DIR}/keycode_names.generated.h) 330 set(GENERATED_API_METADATA ${GENERATED_DIR}/api/private/api_metadata.generated.h) 331 set(GENERATED_KEYSETS_DEFS ${GENERATED_DIR}/keysets_defs.generated.h) 332 set(GENERATED_OPTIONS ${GENERATED_DIR}/options.generated.h) 333 set(GENERATED_OPTIONS_ENUM ${GENERATED_DIR}/options_enum.generated.h) 334 set(GENERATED_OPTIONS_MAP ${GENERATED_DIR}/options_map.generated.h) 335 set(GENERATED_OPTION_VARS ${GENERATED_DIR}/option_vars.generated.h) 336 set(GENERATED_UI_EVENTS_CALL ${GENERATED_DIR}/ui_events_call.generated.h) 337 set(GENERATED_UI_EVENTS_CLIENT ${GENERATED_DIR}/ui_events_client.generated.h) 338 set(GENERATED_UI_EVENTS_REMOTE ${GENERATED_DIR}/ui_events_remote.generated.h) 339 set(LUA_API_C_BINDINGS ${GENERATED_DIR}/lua_api_c_bindings.generated.h) 340 set(VIM_MODULE_FILE ${GENERATED_DIR}/lua/vim_module.generated.h) 341 342 # NVIM_RUNTIME_DIR 343 set(LUA_FILETYPE_MODULE_SOURCE ${NVIM_RUNTIME_DIR}/lua/vim/filetype.lua) 344 set(LUA_FS_MODULE_SOURCE ${NVIM_RUNTIME_DIR}/lua/vim/fs.lua) 345 set(LUA_F_MODULE_SOURCE ${NVIM_RUNTIME_DIR}/lua/vim/F.lua) 346 # Must be item 1 in `builtin_modules`, for `--luamod-dev`. 347 set(LUA_INIT_PACKAGES_MODULE_SOURCE ${NVIM_RUNTIME_DIR}/lua/vim/_init_packages.lua) 348 # Must be item 2 in `builtin_modules`, for `--luamod-dev`. 349 set(LUA_INSPECT_MODULE_SOURCE ${NVIM_RUNTIME_DIR}/lua/vim/inspect.lua) 350 set(LUA_KEYMAP_MODULE_SOURCE ${NVIM_RUNTIME_DIR}/lua/vim/keymap.lua) 351 set(LUA_LOADER_MODULE_SOURCE ${NVIM_RUNTIME_DIR}/lua/vim/loader.lua) 352 set(LUA_TEXT_MODULE_SOURCE ${NVIM_RUNTIME_DIR}/lua/vim/text.lua) 353 354 # Find all Lua modules in the _core/ directory. 355 file(GLOB LUA_CORE_MODULE_SOURCES ${NVIM_RUNTIME_DIR}/lua/vim/_core/*.lua) 356 set(LUA_CORE_COMMAND_ARGS) 357 foreach(core_source ${LUA_CORE_MODULE_SOURCES}) 358 get_filename_component(core_filename ${core_source} NAME_WE) 359 list(APPEND LUA_CORE_COMMAND_ARGS ${core_source} "vim._core.${core_filename}") 360 endforeach() 361 362 file(GLOB API_HEADERS CONFIGURE_DEPENDS api/*.h) 363 list(REMOVE_ITEM API_HEADERS ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h) 364 file(GLOB MSGPACK_RPC_HEADERS CONFIGURE_DEPENDS msgpack_rpc/*.h) 365 366 target_include_directories(main_lib INTERFACE 367 ${GENERATED_DIR} 368 ${GENERATED_INCLUDES_DIR} 369 "${PROJECT_BINARY_DIR}/cmake.config" 370 "${PROJECT_SOURCE_DIR}/src") 371 372 target_include_directories(nlua0 PUBLIC 373 "${PROJECT_SOURCE_DIR}/src" 374 "${PROJECT_BINARY_DIR}/cmake.config" 375 ${GENERATED_INCLUDES_DIR}) 376 377 file(MAKE_DIRECTORY ${TOUCHES_DIR} ${GENERATED_DIR} ${GENERATED_INCLUDES_DIR}) 378 379 file(GLOB NVIM_SOURCES CONFIGURE_DEPENDS *.c) 380 file(GLOB NVIM_HEADERS CONFIGURE_DEPENDS *.h) 381 file(GLOB EXTERNAL_SOURCES CONFIGURE_DEPENDS ../xdiff/*.c ../mpack/*.c ../cjson/*.c ../klib/*.c) 382 file(GLOB EXTERNAL_HEADERS CONFIGURE_DEPENDS ../xdiff/*.h ../mpack/*.h ../cjson/*.h ../klib/*.h) 383 384 file(GLOB NLUA0_SOURCES CONFIGURE_DEPENDS ../mpack/*.c) 385 386 if(PREFER_LUA) 387 # luajit not used, use a vendored copy of the bit module 388 list(APPEND EXTERNAL_SOURCES ${PROJECT_SOURCE_DIR}/src/bit.c) 389 list(APPEND NLUA0_SOURCES ${PROJECT_SOURCE_DIR}/src/bit.c) 390 target_compile_definitions(main_lib INTERFACE NVIM_VENDOR_BIT) 391 endif() 392 393 # Inlined external projects, we don't maintain it. #9306 394 if(MSVC) 395 set_source_files_properties( 396 ${EXTERNAL_SOURCES} PROPERTIES COMPILE_OPTIONS "-wd4090;-wd4244;-wd4267") 397 else() 398 set_source_files_properties( 399 ${EXTERNAL_SOURCES} PROPERTIES COMPILE_OPTIONS "-Wno-conversion;-Wno-missing-noreturn;-Wno-missing-format-attribute;-Wno-double-promotion;-Wno-strict-prototypes;-Wno-misleading-indentation;-Wno-sign-compare;-Wno-implicit-fallthrough;-Wno-missing-prototypes;-Wno-missing-field-initializers") 400 endif() 401 402 list(APPEND NLUA0_SOURCES ${PROJECT_SOURCE_DIR}/src/nlua0.c) 403 404 foreach(subdir 405 os 406 api 407 api/private 408 msgpack_rpc 409 tui 410 tui/termkey 411 vterm 412 event 413 eval 414 lua 415 lib 416 viml 417 viml/parser 418 ) 419 420 file(MAKE_DIRECTORY ${GENERATED_DIR}/${subdir}) 421 file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/${subdir}) 422 file(GLOB sources CONFIGURE_DEPENDS ${subdir}/*.c) 423 file(GLOB headers CONFIGURE_DEPENDS ${subdir}/*.h) 424 list(APPEND NVIM_SOURCES ${sources}) 425 list(APPEND NVIM_HEADERS ${headers}) 426 endforeach() 427 428 # Sort file lists to ensure generated files are created in the same order from 429 # build to build. 430 list(SORT NVIM_SOURCES) 431 list(SORT NVIM_HEADERS) 432 433 list(APPEND UNCRUSTIFY_NVIM_SOURCES ${NVIM_SOURCES} ${NVIM_HEADERS}) 434 list(APPEND UNCRUSTIFY_NVIM_SOURCES 435 ${PROJECT_SOURCE_DIR}/src/tee/tee.c 436 ${PROJECT_SOURCE_DIR}/src/xxd/xxd.c 437 ) 438 439 foreach(sfile ${NVIM_SOURCES}) 440 get_filename_component(f ${sfile} NAME) 441 if(WIN32 AND ${f} MATCHES "^(pty_proc_unix.c)$") 442 list(REMOVE_ITEM NVIM_SOURCES ${sfile}) 443 endif() 444 if(NOT WIN32 AND ${f} MATCHES "^(pty_proc_win.c)$") 445 list(REMOVE_ITEM NVIM_SOURCES ${sfile}) 446 endif() 447 if(NOT WIN32 AND ${f} MATCHES "^(pty_conpty_win.c)$") 448 list(REMOVE_ITEM NVIM_SOURCES ${sfile}) 449 endif() 450 if(NOT WIN32 AND ${f} MATCHES "^(os_win_console.c)$") 451 list(REMOVE_ITEM NVIM_SOURCES ${sfile}) 452 endif() 453 endforeach() 454 455 foreach(hfile ${NVIM_HEADERS}) 456 get_filename_component(f ${hfile} NAME) 457 if(WIN32 AND ${f} MATCHES "^(unix_defs.h)$") 458 list(REMOVE_ITEM NVIM_HEADERS ${hfile}) 459 endif() 460 if(WIN32 AND ${f} MATCHES "^(pty_proc_unix.h)$") 461 list(REMOVE_ITEM NVIM_HEADERS ${hfile}) 462 endif() 463 if(NOT WIN32 AND ${f} MATCHES "^(win_defs.h)$") 464 list(REMOVE_ITEM NVIM_HEADERS ${hfile}) 465 endif() 466 endforeach() 467 468 list(APPEND LINT_NVIM_SOURCES ${NVIM_SOURCES} ${NVIM_HEADERS}) 469 list(APPEND LINT_NVIM_SOURCES 470 ${PROJECT_SOURCE_DIR}/src/tee/tee.c 471 ${PROJECT_SOURCE_DIR}/src/xxd/xxd.c 472 ) 473 474 # Log level (NVIM_LOG_DEBUG in log.h) 475 if(CI_BUILD) 476 # Don't debug log on CI, it gets too verbose in the main build log. 477 # TODO(bfredl): debug log level also exposes some errors with EXITFREE in ASAN build. 478 else() 479 # Minimize logging for release-type builds. 480 target_compile_definitions(nvim_bin PRIVATE $<$<CONFIG:Debug>:NVIM_LOG_DEBUG>) 481 endif() 482 483 if(ENABLE_ASAN_UBSAN OR ENABLE_MSAN OR ENABLE_TSAN) 484 target_compile_definitions(main_lib INTERFACE EXITFREE) 485 endif() 486 487 #------------------------------------------------------------------------------- 488 # Header generation 489 #------------------------------------------------------------------------------- 490 491 get_directory_property(targets BUILDSYSTEM_TARGETS) 492 foreach(target ${targets}) 493 get_target_property(prop ${target} INTERFACE_INCLUDE_DIRECTORIES) 494 if(NOT "${prop}" STREQUAL "prop-NOTFOUND") 495 message(STATUS "${target} props '${prop}'") 496 foreach(gen_include ${prop}) 497 list(APPEND TEST_INCLUDE_DIRS "${gen_include}") 498 endforeach() 499 endif() 500 endforeach() 501 502 list(REMOVE_DUPLICATES TEST_INCLUDE_DIRS) 503 504 set(NVIM_VERSION_GIT_H ${PROJECT_BINARY_DIR}/cmake.config/auto/versiondef_git.h) 505 add_custom_target(update_version_stamp 506 COMMAND ${CMAKE_COMMAND} 507 -D NVIM_VERSION_MAJOR=${NVIM_VERSION_MAJOR} 508 -D NVIM_VERSION_MINOR=${NVIM_VERSION_MINOR} 509 -D NVIM_VERSION_PATCH=${NVIM_VERSION_PATCH} 510 -D NVIM_VERSION_PRERELEASE=${NVIM_VERSION_PRERELEASE} 511 -D OUTPUT=${NVIM_VERSION_GIT_H} 512 -D NVIM_SOURCE_DIR=${CMAKE_SOURCE_DIR} 513 -P ${PROJECT_SOURCE_DIR}/cmake/GenerateVersion.cmake 514 BYPRODUCTS ${NVIM_VERSION_GIT_H}) 515 516 set(NVIM_VERSION_DEF_H ${PROJECT_BINARY_DIR}/cmake.config/auto/versiondef.h) 517 add_custom_command( 518 OUTPUT "${NVIM_VERSION_DEF_H}" 519 COMMAND "${CMAKE_COMMAND}" 520 -E copy 521 "${PROJECT_BINARY_DIR}/cmake.config/auto/versiondef-$<CONFIG>.h" 522 "${NVIM_VERSION_DEF_H}" 523 DEPENDS "${PROJECT_BINARY_DIR}/cmake.config/auto/versiondef-$<CONFIG>.h") 524 525 if(CMAKE_CROSSCOMPILING AND NLUA0_HOST_PRG) 526 set(LUA_GEN ${LUA_GEN_PRG} ${GENERATOR_PRELOAD} ${PROJECT_SOURCE_DIR} ${NLUA0_HOST_PRG} ${PROJECT_BINARY_DIR}) 527 set(LUA_GEN_DEPS ${GENERATOR_PRELOAD} ${NLUA0_HOST_PRG}) 528 else() 529 set(LUA_GEN ${LUA_GEN_PRG} ${GENERATOR_PRELOAD} ${PROJECT_SOURCE_DIR} $<TARGET_FILE:nlua0> ${PROJECT_BINARY_DIR}) 530 set(LUA_GEN_DEPS ${GENERATOR_PRELOAD} $<TARGET_FILE:nlua0>) 531 endif() 532 533 # Like LUA_GEN but includes also vim.fn, vim.api, vim.uv, etc 534 set(NVIM_LUA $<TARGET_FILE:nvim_bin> -u NONE -l ${NVIM_LUA_PRELOAD} ${PROJECT_SOURCE_DIR}) 535 536 # NVIM_GENERATED_FOR_HEADERS: generated headers to be included in headers 537 # NVIM_GENERATED_FOR_SOURCES: generated headers to be included in sources 538 # These lists must be mutually exclusive. 539 foreach(sfile ${NVIM_SOURCES} 540 ${NVIM_HEADERS} 541 ${GENERATED_API_DISPATCH} 542 "${GENERATED_UI_EVENTS_CALL}" 543 "${GENERATED_UI_EVENTS_REMOTE}" 544 "${GENERATED_UI_EVENTS_CLIENT}" 545 ) 546 get_filename_component(full_d ${sfile} DIRECTORY) 547 file(RELATIVE_PATH d "${CMAKE_CURRENT_LIST_DIR}" "${full_d}") 548 if(${d} MATCHES "^[.][.]|auto/") 549 file(RELATIVE_PATH d "${GENERATED_DIR}" "${full_d}") 550 endif() 551 get_filename_component(f ${sfile} NAME) 552 get_filename_component(r ${sfile} NAME_WE) 553 get_filename_component(ext ${sfile} EXT) 554 if(NOT ${d} EQUAL ".") 555 set(f "${d}/${f}") 556 set(r "${d}/${r}") 557 endif() 558 if ("${ext}" STREQUAL ".c.h") 559 continue() # .c.h files are sussy baka, skip 560 elseif(${sfile} IN_LIST NVIM_HEADERS) 561 set(gf_basename "${r}.h.inline.generated.h") 562 set(gf_c_h "${GENERATED_INCLUDES_DIR}/${r}.h.inline.generated.h") 563 set(gf_h_h "SKIP") 564 set(gf_h_h_out "") 565 else() 566 set(gf_basename "${r}.c.generated.h") 567 set(gf_c_h "${GENERATED_DIR}/${r}.c.generated.h") 568 set(gf_h_h "${GENERATED_INCLUDES_DIR}/${r}.h.generated.h") 569 set(gf_h_h_out "${gf_h_h}") 570 endif() 571 572 set(depends "${HEADER_GENERATOR}" "${sfile}" "${LUA_GEN_DEPS}" "${GENERATOR_C_GRAMMAR}") 573 if("${f}" STREQUAL "version.c") 574 # Ensure auto/versiondef_git.h exists after "make clean". 575 list(APPEND depends update_version_stamp "${NVIM_VERSION_GIT_H}" "${NVIM_VERSION_DEF_H}") 576 endif() 577 add_custom_command( 578 OUTPUT "${gf_c_h}" ${gf_h_h_out} 579 COMMAND ${LUA_GEN} "${HEADER_GENERATOR}" "${sfile}" "${gf_c_h}" "${gf_h_h}" "${gf_basename}" 580 DEPENDS ${depends}) 581 list(APPEND NVIM_GENERATED_FOR_SOURCES "${gf_c_h}") 582 if (NOT ${sfile} IN_LIST NVIM_HEADERS) 583 list(APPEND NVIM_GENERATED_FOR_HEADERS "${gf_h_h}") 584 if(${d} MATCHES "^api$" AND NOT ${f} MATCHES "^api/helpers.c$") 585 list(APPEND API_HEADERS ${gf_h_h}) 586 endif() 587 endif() 588 endforeach() 589 590 set(NVIM_VERSION_LUA ${PROJECT_BINARY_DIR}/nvim_version.lua) 591 configure_file(${GENERATOR_DIR}/nvim_version.lua.in ${NVIM_VERSION_LUA}) 592 593 add_custom_command( 594 OUTPUT ${GENERATED_API_DISPATCH} ${EXPORTED_FUNCS_METADATA} 595 ${EVAL_FUNCS_METADATA} ${LUA_API_C_BINDINGS} ${GENERATED_KEYSETS_DEFS} 596 COMMAND ${LUA_GEN} ${API_DISPATCH_GENERATOR} 597 ${GENERATED_API_DISPATCH} 598 ${EXPORTED_FUNCS_METADATA} ${EVAL_FUNCS_METADATA} 599 ${LUA_API_C_BINDINGS} 600 ${GENERATED_KEYSETS_DEFS} 601 ${CMAKE_CURRENT_LIST_DIR}/api/dispatch_deprecated.lua 602 ${API_HEADERS} 603 604 DEPENDS 605 ${LUA_GEN_DEPS} 606 ${API_HEADERS} 607 ${MSGPACK_RPC_HEADERS} 608 ${API_DISPATCH_GENERATOR} 609 ${GENERATOR_C_GRAMMAR} 610 ${GENERATOR_HASHY} 611 ${CMAKE_CURRENT_LIST_DIR}/api/dispatch_deprecated.lua 612 ) 613 614 add_custom_command( 615 OUTPUT ${GENERATED_API_METADATA} 616 COMMAND ${LUA_GEN} ${API_METADATA_GENERATOR} 617 ${EXPORTED_FUNCS_METADATA} 618 ${UI_METADATA} 619 ${CMAKE_CURRENT_LIST_DIR}/api/ui.h 620 ${NVIM_VERSION_GIT_H} ${NVIM_VERSION_LUA} 621 ${GENERATOR_DIR}/dump_bin_array.lua 622 ${GENERATED_API_METADATA} 623 624 DEPENDS 625 ${LUA_GEN_DEPS} 626 ${API_METADATA_GENERATOR} 627 ${GENERATOR_DIR}/dump_bin_array.lua 628 ${UI_METADATA} 629 ${EXPORTED_FUNCS_METADATA} 630 ${NVIM_VERSION_LUA} 631 ${NVIM_VERSION_GIT_H} 632 ) 633 634 add_custom_command( 635 OUTPUT ${VIM_MODULE_FILE} 636 COMMAND ${CMAKE_COMMAND} -E env 637 "LUAC_PRG=${LUAC_PRG}" 638 ${LUA_PRG} ${CHAR_BLOB_GENERATOR} -c ${VIM_MODULE_FILE} 639 # NB: vim._init_packages and vim.inspect must be be first and second ones 640 # respectively, otherwise --luamod-dev won't work properly. 641 ${LUA_INIT_PACKAGES_MODULE_SOURCE} "vim._init_packages" 642 ${LUA_INSPECT_MODULE_SOURCE} "vim.inspect" 643 ${LUA_FILETYPE_MODULE_SOURCE} "vim.filetype" 644 ${LUA_FS_MODULE_SOURCE} "vim.fs" 645 ${LUA_F_MODULE_SOURCE} "vim.F" 646 ${LUA_KEYMAP_MODULE_SOURCE} "vim.keymap" 647 ${LUA_LOADER_MODULE_SOURCE} "vim.loader" 648 ${LUA_TEXT_MODULE_SOURCE} "vim.text" 649 ${LUA_CORE_COMMAND_ARGS} 650 DEPENDS 651 ${CHAR_BLOB_GENERATOR} 652 ${LUA_INIT_PACKAGES_MODULE_SOURCE} 653 ${LUA_INSPECT_MODULE_SOURCE} 654 ${LUA_FILETYPE_MODULE_SOURCE} 655 ${LUA_FS_MODULE_SOURCE} 656 ${LUA_F_MODULE_SOURCE} 657 ${LUA_KEYMAP_MODULE_SOURCE} 658 ${LUA_LOADER_MODULE_SOURCE} 659 ${LUA_TEXT_MODULE_SOURCE} 660 ${LUA_CORE_MODULE_SOURCES} 661 VERBATIM 662 ) 663 664 add_custom_command( 665 OUTPUT ${GENERATED_UI_EVENTS_CALL} 666 ${GENERATED_UI_EVENTS_REMOTE} 667 ${UI_METADATA} 668 ${GENERATED_UI_EVENTS_CLIENT} 669 COMMAND ${LUA_GEN} ${API_UI_EVENTS_GENERATOR} 670 ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h 671 ${GENERATED_UI_EVENTS_CALL} 672 ${GENERATED_UI_EVENTS_REMOTE} 673 ${UI_METADATA} 674 ${GENERATED_UI_EVENTS_CLIENT} 675 DEPENDS 676 ${LUA_GEN_DEPS} 677 ${API_UI_EVENTS_GENERATOR} 678 ${GENERATOR_C_GRAMMAR} 679 ${GENERATOR_HASHY} 680 ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h 681 ) 682 683 add_custom_command(OUTPUT ${GENERATED_EX_CMDS_ENUM} ${GENERATED_EX_CMDS_DEFS} 684 COMMAND ${LUA_GEN} ${EX_CMDS_GENERATOR} ${GENERATED_EX_CMDS_ENUM} ${GENERATED_EX_CMDS_DEFS} ${CMAKE_CURRENT_LIST_DIR}/ex_cmds.lua 685 DEPENDS ${LUA_GEN_DEPS} ${EX_CMDS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/ex_cmds.lua 686 ) 687 688 add_custom_command(OUTPUT ${GENERATED_FUNCS} ${FUNCS_DATA} 689 COMMAND ${LUA_GEN} ${FUNCS_GENERATOR} ${GENERATED_FUNCS} ${EVAL_FUNCS_METADATA} ${FUNCS_DATA} ${CMAKE_CURRENT_LIST_DIR}/eval.lua 690 DEPENDS ${LUA_GEN_DEPS} ${FUNCS_GENERATOR} ${GENERATOR_HASHY} ${CMAKE_CURRENT_LIST_DIR}/eval.lua ${EVAL_FUNCS_METADATA} 691 ) 692 693 add_custom_command(OUTPUT ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP} 694 COMMAND ${LUA_GEN} ${EVENTS_GENERATOR} ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP} ${CMAKE_CURRENT_LIST_DIR}/auevents.lua 695 DEPENDS ${LUA_GEN_DEPS} ${EVENTS_GENERATOR} ${GENERATOR_HASHY} ${CMAKE_CURRENT_LIST_DIR}/auevents.lua 696 ) 697 698 add_custom_command(OUTPUT ${GENERATED_KEYCODE_NAMES} 699 COMMAND ${LUA_GEN} ${KEYCODES_GENERATOR} ${GENERATED_KEYCODE_NAMES} ${CMAKE_CURRENT_LIST_DIR}/keycodes.lua 700 DEPENDS ${LUA_GEN_DEPS} ${KEYCODES_GENERATOR} ${GENERATOR_HASHY} ${CMAKE_CURRENT_LIST_DIR}/keycodes.lua 701 ) 702 703 add_custom_command(OUTPUT ${GENERATED_OPTIONS} ${GENERATED_OPTIONS_ENUM} ${GENERATED_OPTIONS_MAP} ${GENERATED_OPTION_VARS} 704 COMMAND ${LUA_GEN} ${OPTIONS_GENERATOR} ${GENERATED_OPTIONS} ${GENERATED_OPTIONS_ENUM} ${GENERATED_OPTIONS_MAP} ${GENERATED_OPTION_VARS} ${CMAKE_CURRENT_LIST_DIR}/options.lua 705 DEPENDS ${LUA_GEN_DEPS} ${OPTIONS_GENERATOR} ${GENERATOR_HASHY} ${CMAKE_CURRENT_LIST_DIR}/options.lua 706 ) 707 708 list(APPEND NVIM_GENERATED_FOR_HEADERS 709 "${GENERATED_EX_CMDS_ENUM}" 710 "${GENERATED_EVENTS_ENUM}" 711 "${GENERATED_KEYSETS_DEFS}" 712 "${GENERATED_OPTIONS_ENUM}" 713 "${GENERATED_OPTION_VARS}" 714 ) 715 716 list(APPEND NVIM_GENERATED_FOR_SOURCES 717 "${GENERATED_API_DISPATCH}" 718 "${GENERATED_EX_CMDS_DEFS}" 719 "${GENERATED_EVENTS_NAMES_MAP}" 720 "${GENERATED_FUNCS}" 721 "${GENERATED_KEYCODE_NAMES}" 722 "${GENERATED_OPTIONS}" 723 "${GENERATED_OPTIONS_MAP}" 724 "${VIM_MODULE_FILE}" 725 "${GENERATED_API_METADATA}" 726 "${PROJECT_BINARY_DIR}/cmake.config/auto/pathdef.h" 727 ) 728 729 # NVIM_GENERATED_FOR_SOURCES and NVIM_GENERATED_FOR_HEADERS must be mutually exclusive. 730 foreach(hfile ${NVIM_GENERATED_FOR_HEADERS}) 731 list(FIND NVIM_GENERATED_FOR_SOURCES ${hfile} hfile_idx) 732 if(NOT ${hfile_idx} EQUAL -1) 733 message(FATAL_ERROR "File included in both NVIM_GENERATED_FOR_HEADERS and NVIM_GENERATED_FOR_SOURCES") 734 endif() 735 endforeach() 736 737 if(PREFER_LUA) 738 message(STATUS "luajit not used, skipping unit tests") 739 else() 740 file(GLOB UNIT_TEST_FIXTURES CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/test/unit/fixtures/*.c) 741 target_sources(nvim_bin PRIVATE ${UNIT_TEST_FIXTURES}) 742 target_compile_definitions(nvim_bin PRIVATE UNIT_TESTING) 743 endif() 744 745 target_sources(main_lib INTERFACE 746 ${NVIM_GENERATED_FOR_SOURCES} 747 ${NVIM_GENERATED_FOR_HEADERS} 748 ${NVIM_SOURCES} 749 ${NVIM_HEADERS} 750 ${EXTERNAL_SOURCES} 751 ${EXTERNAL_HEADERS}) 752 753 if(WIN32) 754 # add windows resource file pointing to the neovim icon 755 # this makes the icon appear for the neovim exe and associated filetypes 756 target_sources(nvim_bin PRIVATE ${NVIM_RUNTIME_DIR}/windows_icon.rc) 757 endif() 758 759 target_sources(nlua0 PUBLIC ${NLUA0_SOURCES}) 760 761 if(STATIC_BUILD) 762 target_link_options(nvim_bin PRIVATE -static-libgcc -static-libstdc++ -static) 763 endif() 764 target_link_libraries(nvim_bin PRIVATE main_lib PUBLIC libuv) 765 766 install_helper(TARGETS nvim_bin) 767 if(MSVC) 768 install(FILES $<TARGET_PDB_FILE:nvim_bin> DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) 769 endif() 770 771 if(ENABLE_LTO) 772 include(CheckIPOSupported) 773 check_ipo_supported(RESULT IPO_SUPPORTED) 774 if(IPO_SUPPORTED) 775 set_target_properties(nvim_bin PROPERTIES 776 INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE 777 INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE 778 INTERPROCEDURAL_OPTIMIZATION_MINSIZEREL TRUE) 779 endif() 780 endif() 781 782 add_custom_target(nvim_runtime_deps) 783 if(WIN32) 784 # Copy DLLs and third-party tools to bin/ and install them along with nvim 785 add_custom_command(TARGET nvim_runtime_deps 786 POST_BUILD 787 COMMAND ${CMAKE_COMMAND} -E ${COPY_DIRECTORY} ${PROJECT_BINARY_DIR}/windows_runtime_deps/ 788 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) 789 install(DIRECTORY ${PROJECT_BINARY_DIR}/windows_runtime_deps/ 790 DESTINATION ${CMAKE_INSTALL_BINDIR}) 791 792 add_custom_target(nvim_dll_deps DEPENDS nvim_bin 793 COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/windows_runtime_deps 794 COMMAND ${CMAKE_COMMAND} 795 -D CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} 796 -D BINARY="${PROJECT_BINARY_DIR}/bin/nvim${CMAKE_EXECUTABLE_SUFFIX}" 797 -D DST=${PROJECT_BINARY_DIR}/windows_runtime_deps 798 -D CI_BUILD=${CI_BUILD} 799 -P ${PROJECT_SOURCE_DIR}/cmake/WindowsDllCopy.cmake) 800 add_dependencies(nvim_runtime_deps nvim_dll_deps) 801 802 # A CMake script is used for copying the files to avoid the 803 # "command line is too long" error that occurs when Ninja tries running 804 # a command that exceeds the length limit (8191 characters) on Windows. 805 # See https://developercommunity.visualstudio.com/content/problem/212207/file-open-cmake-the-command-line-is-too-long.html 806 set(EXTERNAL_BLOBS_SCRIPT 807 "file(MAKE_DIRECTORY \"${PROJECT_BINARY_DIR}/windows_runtime_deps/platforms\")") 808 foreach(DEP_FILE IN ITEMS 809 win32yank.exe 810 ) 811 get_filename_component(DEP_FILE_DIR ${DEP_FILE} DIRECTORY) 812 set(EXTERNAL_BLOBS_SCRIPT "${EXTERNAL_BLOBS_SCRIPT}\n" 813 "file(COPY \"${DEPS_PREFIX}/bin/${DEP_FILE}\" 814 DESTINATION \"${PROJECT_BINARY_DIR}/windows_runtime_deps/${DEP_FILE_DIR}\")") 815 endforeach() 816 file(WRITE ${PROJECT_BINARY_DIR}/external_blobs.cmake ${EXTERNAL_BLOBS_SCRIPT}) 817 add_custom_target(external_blobs 818 COMMAND ${CMAKE_COMMAND} -P ${PROJECT_BINARY_DIR}/external_blobs.cmake) 819 add_dependencies(nvim_runtime_deps external_blobs) 820 endif() 821 822 file(MAKE_DIRECTORY ${BINARY_LIB_DIR}) 823 824 # install treesitter parser if bundled 825 if(EXISTS ${DEPS_PREFIX}/lib/nvim/parser) 826 add_custom_command( 827 TARGET nvim_runtime_deps 828 POST_BUILD 829 COMMAND ${CMAKE_COMMAND} -E ${COPY_DIRECTORY} ${DEPS_PREFIX}/lib/nvim/parser ${BINARY_LIB_DIR}/parser) 830 endif() 831 832 if(CYGWIN) 833 if(NOT PREFER_LUA) 834 add_custom_command( 835 TARGET nvim_runtime_deps 836 POST_BUILD 837 COMMAND ${CMAKE_COMMAND} -E copy ${DEPS_PREFIX}/bin/cyglua51.dll ${PROJECT_BINARY_DIR}/bin) 838 install(PROGRAMS ${PROJECT_BINARY_DIR}/bin/cyglua51.dll DESTINATION ${CMAKE_INSTALL_BINDIR}) 839 endif() 840 endif() 841 842 install(DIRECTORY ${BINARY_LIB_DIR} 843 DESTINATION ${CMAKE_INSTALL_LIBDIR} 844 USE_SOURCE_PERMISSIONS) 845 846 if(NOT PREFER_LUA) 847 # install luajit runtime files if bundled 848 if(EXISTS ${LUAJIT_RUNTIME_DIR}) 849 install(DIRECTORY ${LUAJIT_RUNTIME_DIR} 850 DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/nvim/runtime/lua 851 USE_SOURCE_PERMISSIONS) 852 endif() 853 endif() 854 855 add_library(libnvim STATIC EXCLUDE_FROM_ALL) 856 if(MSVC) 857 set(LIBNVIM_NAME libnvim) 858 else() 859 set(LIBNVIM_NAME nvim) 860 endif() 861 set_target_properties( 862 libnvim 863 PROPERTIES 864 OUTPUT_NAME ${LIBNVIM_NAME} 865 ) 866 target_compile_definitions(libnvim PRIVATE MAKE_LIB) 867 target_link_libraries(libnvim PRIVATE main_lib PUBLIC libuv) 868 869 #------------------------------------------------------------------------------- 870 # Lint 871 #------------------------------------------------------------------------------- 872 873 find_program(CLANG_TIDY_PRG clang-tidy) 874 mark_as_advanced(CLANG_TIDY_PRG) 875 set(EXCLUDE_CLANG_TIDY typval_encode.c.h ui_events.in.h xxd/xxd.c) 876 if(WIN32) 877 list(APPEND EXCLUDE_CLANG_TIDY 878 os/pty_proc_unix.h 879 os/unix_defs.h) 880 else() 881 list(APPEND EXCLUDE_CLANG_TIDY 882 os/win_defs.h 883 os/pty_proc_win.h 884 os/pty_conpty_win.h 885 os/os_win_console.h) 886 endif() 887 add_glob_target( 888 TARGET lintc-clang-tidy 889 COMMAND ${CLANG_TIDY_PRG} 890 FILES ${LINT_NVIM_SOURCES} 891 FLAGS --quiet 892 EXCLUDE ${EXCLUDE_CLANG_TIDY}) 893 894 # The checks we ignore are meant to be removed eventually, but we can only 895 # enable each warning after we fix all instances of that specific warning as to 896 # not break CI. 897 if(APPLE) 898 string(APPEND CLANG_ANALYZER_IGNORE "-clang-analyzer-core.NonNullParamChecker,") 899 endif() 900 add_glob_target( 901 TARGET clang-analyzer 902 COMMAND ${CLANG_TIDY_PRG} 903 FILES ${LINT_NVIM_SOURCES} 904 FLAGS --quiet 905 --checks=' 906 -*, 907 clang-analyzer-*, 908 -clang-analyzer-core.NullDereference, 909 -clang-analyzer-core.UndefinedBinaryOperatorResult, 910 -clang-analyzer-core.uninitialized.Assign, 911 -clang-analyzer-optin.core.EnumCastOutOfRange, 912 -clang-analyzer-optin.performance.Padding, 913 -clang-analyzer-security.insecureAPI.strcpy, 914 -clang-analyzer-unix.StdCLibraryFunctions, 915 -clang-analyzer-unix.Stream, 916 ${CLANG_ANALYZER_IGNORE} 917 ' 918 EXCLUDE ${EXCLUDE_CLANG_TIDY}) 919 920 add_custom_target(copy_compile_commands 921 COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/compile_commands.json ${PROJECT_SOURCE_DIR}/compile_commands.json) 922 add_dependencies(copy_compile_commands nvim_bin) 923 add_dependencies(lintc-clang-tidy copy_compile_commands) 924 add_dependencies(clang-analyzer copy_compile_commands) 925 926 if(CI_BUILD) 927 set(LINT_OUTPUT_FORMAT gh_action) 928 else() 929 set(LINT_OUTPUT_FORMAT vs7) 930 endif() 931 add_glob_target( 932 TARGET lintc-clint 933 COMMAND $<TARGET_FILE:nvim_bin> 934 FLAGS --clean -l ${PROJECT_SOURCE_DIR}/src/clint.lua --output=${LINT_OUTPUT_FORMAT} 935 FILES ${LINT_NVIM_SOURCES} 936 EXCLUDE 937 tui/terminfo_defs.h 938 xxd/xxd.c) 939 add_dependencies(lintc-clint nvim_bin) 940 941 set(UNCRUSTIFY_PRG ${DEPS_BIN_DIR}/uncrustify) 942 set(UNCRUSTIFY_CONFIG ${PROJECT_SOURCE_DIR}/src/uncrustify.cfg) 943 944 add_custom_target(uncrustify_update_config 945 ${UNCRUSTIFY_PRG} -c ${UNCRUSTIFY_CONFIG} --update-config-with-doc -o ${UNCRUSTIFY_CONFIG}) 946 947 add_glob_target( 948 TARGET lintc-uncrustify 949 COMMAND ${UNCRUSTIFY_PRG} 950 FLAGS -c ${UNCRUSTIFY_CONFIG} -q --check 951 FILES ${UNCRUSTIFY_NVIM_SOURCES}) 952 953 add_glob_target( 954 TARGET formatc 955 COMMAND ${UNCRUSTIFY_PRG} 956 FLAGS -c ${UNCRUSTIFY_CONFIG} --replace --no-backup 957 FILES ${UNCRUSTIFY_NVIM_SOURCES}) 958 959 # TODO(bfredl): there is a bug in "uncrustify --update-config-with-doc" which breaks 960 # our config (backslash escape in strings). Once fixed these two lines should be deleted 961 # and the following two commented lines be uncomennetd. 962 add_dependencies(lintc-uncrustify uncrustify) 963 add_dependencies(formatc uncrustify) 964 #add_dependencies(lintc-uncrustify uncrustify_update_config) 965 #add_dependencies(formatc uncrustify_update_config) 966 967 add_dependencies(uncrustify_update_config uncrustify) 968 969 add_custom_target(lintc) 970 add_dependencies(lintc lintc-clint lintc-uncrustify lintc-clang-tidy) 971 972 #------------------------------------------------------------------------------- 973 # Docs 974 #------------------------------------------------------------------------------- 975 976 add_subdirectory(po) 977 978 add_custom_target(generated-sources DEPENDS 979 ${NVIM_GENERATED_FOR_HEADERS} 980 ${NVIM_GENERATED_FOR_SOURCES} 981 ) 982 983 file(GLOB API_SOURCES CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/src/nvim/api/*.c) 984 985 file(GLOB LUA_SOURCES CONFIGURE_DEPENDS 986 ${NVIM_RUNTIME_DIR}/lua/vim/*.lua 987 ${NVIM_RUNTIME_DIR}/lua/vim/_meta/*.lua 988 ${NVIM_RUNTIME_DIR}/lua/vim/filetype/*.lua 989 ${NVIM_RUNTIME_DIR}/lua/vim/lsp/*.lua 990 ${NVIM_RUNTIME_DIR}/lua/vim/treesitter/*.lua 991 ) 992 993 add_target(doc-vim 994 COMMAND ${NVIM_LUA} src/gen/gen_vimdoc.lua 995 DEPENDS 996 nvim 997 ${API_SOURCES} 998 ${LUA_SOURCES} 999 ${PROJECT_SOURCE_DIR}/src/gen/gen_vimdoc.lua 1000 ${NVIM_RUNTIME_DIR}/doc/api.txt 1001 ${NVIM_RUNTIME_DIR}/doc/diagnostic.txt 1002 ${NVIM_RUNTIME_DIR}/doc/lsp.txt 1003 ${NVIM_RUNTIME_DIR}/doc/lua.txt 1004 ${NVIM_RUNTIME_DIR}/doc/treesitter.txt 1005 ) 1006 1007 add_target(doc-eval 1008 COMMAND ${NVIM_LUA} ${PROJECT_SOURCE_DIR}/src/gen/gen_eval_files.lua ${EVAL_FUNCS_METADATA} ${PROJECT_BINARY_DIR}/runtime/doc/tags 1009 DEPENDS 1010 nvim 1011 ${EVAL_FUNCS_METADATA} 1012 ${PROJECT_SOURCE_DIR}/src/gen/gen_eval_files.lua 1013 ${PROJECT_SOURCE_DIR}/src/nvim/eval.lua 1014 ${PROJECT_SOURCE_DIR}/src/nvim/options.lua 1015 ${PROJECT_SOURCE_DIR}/src/nvim/vvars.lua 1016 ${NVIM_RUNTIME_DIR}/doc/vimfn.txt 1017 ) 1018 1019 add_custom_target(doc) 1020 add_dependencies(doc doc-vim doc-eval) 1021 1022 add_target(lintdoc 1023 COMMAND ${NVIM_LUA} scripts/lintdoc.lua 1024 DEPENDS ${DOCFILES} 1025 CUSTOM_COMMAND_ARGS USES_TERMINAL) 1026 add_dependencies(lintdoc nvim) 1027 1028 add_target(lintdocurls 1029 COMMAND ${NVIM_LUA} scripts/lintdoc.lua true 1030 DEPENDS ${DOCFILES} 1031 CUSTOM_COMMAND_ARGS USES_TERMINAL) 1032 add_dependencies(lintdocurls nvim)