neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

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)