aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt65
-rw-r--r--cmake/DefCmdTarget.cmake19
-rw-r--r--cmake/RunUncrustify.cmake16
-rw-r--r--cmake/Util.cmake145
-rwxr-xr-xsrc/nvim/CMakeLists.txt19
5 files changed, 190 insertions, 74 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5fd99b59f9..22b9a6a5ee 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,6 +21,9 @@ list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
# We don't support building in-tree.
include(PreventInTreeBuilds)
+include(Util)
+
+set(TOUCHES_DIR ${PROJECT_BINARY_DIR}/touches)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
@@ -611,34 +614,44 @@ find_program(STYLUA_PRG stylua)
find_program(FLAKE8_PRG flake8)
find_program(UNCRUSTIFY_PRG uncrustify)
find_program(SHELLCHECK_PRG shellcheck)
-include(DefCmdTarget)
-def_cmd_target(lintlua ${LUACHECK_PRG} LUACHECK_PRG true)
-if(LUACHECK_PRG)
- add_custom_command(TARGET lintlua
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
- COMMAND ${LUACHECK_PRG} -q runtime/ scripts/ src/ test/)
-endif()
-if(STYLUA_PRG)
- add_custom_command(TARGET lintlua
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
- COMMAND ${STYLUA_PRG} --color=always --check runtime/)
-else()
- add_custom_command(TARGET lintlua COMMAND ${CMAKE_COMMAND} -E echo "STYLUA_PRG not found")
-endif()
-def_cmd_target(lintpy ${FLAKE8_PRG} FLAKE8_PRG false)
-if(FLAKE8_PRG)
- add_custom_command(TARGET lintpy
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
- COMMAND ${FLAKE8_PRG} contrib/ scripts/ src/ test/)
-endif()
-def_cmd_target(lintsh ${SHELLCHECK_PRG} SHELLCHECK_PRG false)
-if(SHELLCHECK_PRG)
- add_custom_command(TARGET lintsh
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
- COMMAND ${SHELLCHECK_PRG} scripts/vim-patch.sh)
-endif()
+
+add_glob_targets(
+ REQUIRED
+ TARGET lintlua-luacheck
+ COMMAND ${LUACHECK_PRG}
+ FLAGS -q
+ GLOB_DIRS runtime/ scripts/ src/ test/
+ GLOB_PAT *.lua
+ TOUCH_STRATEGY SINGLE
+ )
+
+add_glob_targets(
+ TARGET lintlua-stylua
+ COMMAND ${STYLUA_PRG}
+ FLAGS --color=always --check
+ GLOB_DIRS runtime/
+ GLOB_PAT *.lua
+ TOUCH_STRATEGY SINGLE
+ )
+
+add_custom_target(lintlua)
+add_dependencies(lintlua lintlua-luacheck lintlua-stylua)
include(InstallHelpers)
+add_glob_targets(
+ TARGET lintpy
+ COMMAND ${FLAKE8_PRG}
+ GLOB_DIRS contrib scripts src test
+ GLOB_PAT *.py
+ TOUCH_STRATEGY SINGLE
+ )
+
+add_glob_targets(
+ TARGET lintsh
+ COMMAND ${SHELLCHECK_PRG}
+ FILES scripts/vim-patch.sh
+ TOUCH_STRATEGY SINGLE
+ )
install_helper(
FILES ${CMAKE_SOURCE_DIR}/src/man/nvim.1
diff --git a/cmake/DefCmdTarget.cmake b/cmake/DefCmdTarget.cmake
deleted file mode 100644
index 48e90cf5c8..0000000000
--- a/cmake/DefCmdTarget.cmake
+++ /dev/null
@@ -1,19 +0,0 @@
-# Defines a target named ${target}. If ${prg} is undefined the target prints
-# "not found".
-#
-# - Use add_custom_command(TARGET <target_name> ...) to append a command to the
-# target.
-function(def_cmd_target target prg prg_name prg_fatal)
- add_custom_target(${target})
-
- if(NOT prg)
- if(prg_fatal)
- add_custom_command(TARGET ${target}
- COMMAND ${CMAKE_COMMAND} -E echo "${target}: ${prg_name} not found"
- COMMAND false)
- else()
- add_custom_command(TARGET ${target}
- COMMAND ${CMAKE_COMMAND} -E echo "${target}: SKIP: ${prg_name} not found")
- endif()
- endif()
-endfunction()
diff --git a/cmake/RunUncrustify.cmake b/cmake/RunUncrustify.cmake
deleted file mode 100644
index 7f5e2a34f4..0000000000
--- a/cmake/RunUncrustify.cmake
+++ /dev/null
@@ -1,16 +0,0 @@
-# HACK: This script is invoked with "cmake -P …" as a workaround to silence uncrustify.
-
-# Split space-separated string into a cmake list, so that execute_process()
-# will pass each file as individual arg to uncrustify.
-string(REPLACE " " ";" NVIM_SOURCES ${NVIM_SOURCES})
-string(REPLACE " " ";" NVIM_HEADERS ${NVIM_HEADERS})
-
-execute_process(
- COMMAND ${UNCRUSTIFY_PRG} -c "${PROJECT_SOURCE_DIR}/src/uncrustify.cfg" -q --check ${NVIM_SOURCES} ${NVIM_HEADERS}
- OUTPUT_VARIABLE crusty_out
- ERROR_VARIABLE crusty_err
- RESULT_VARIABLE crusty_res)
-
-if(NOT crusty_res EQUAL 0)
- message(FATAL_ERROR "crusty: ${crusty_res} ${crusty_err}")
-endif()
diff --git a/cmake/Util.cmake b/cmake/Util.cmake
new file mode 100644
index 0000000000..b485f4606b
--- /dev/null
+++ b/cmake/Util.cmake
@@ -0,0 +1,145 @@
+# Defines a target that depends on FILES and the files found by globbing
+# when using GLOB_PAT and GLOB_DIRS. The target will rerun if any files it
+# depends on has changed. Which files the target will run the command on
+# depends on the value of TOUCH_STRATEGY.
+#
+# Options:
+# REQUIRED - Abort if COMMAND doesn't exist.
+#
+# Single value arguments:
+# TARGET - Name of the target
+# COMMAND - Path of the command to be run
+# GLOB_PAT - Glob pattern to use. Only used if GLOB_DIRS is specified
+# TOUCH_STRATEGY - Specify touch strategy, meaning decide how to group files
+# and connect them to a specific touch file.
+#
+# For example, let us say we have file A and B and that we create a touch file
+# for each of them, TA and TB. This would essentially make file A and B
+# independent of each other, meaning that if I change file A and run the
+# target, then the target will only run its commands for file A and ignore
+# file B.
+#
+# Another example: let's say we have file A and B, but now we create only a
+# single touch file T for both of them. This would mean that if I change
+# either file A or B, then the target will run its commands on both A and B.
+# Meaning that even if I only change file A, the target will still run
+# commands on both A and B.
+#
+# The more touch files we create for a target, the fewer commands we'll need
+# to rerun, and by extension, the more time we'll save. Unfortunately, the
+# more touch files we create the more intermediary targets will be created,
+# one for each touch file. This makes listing all targets with
+# `cmake --build build --target help` less useful since each touch file will
+# be listed. The tradeoff that needs to be done here is between performance
+# and "discoverability". As a general guideline: the more popular a target is
+# and the more time it takes to run it, the more granular you want your touch
+# files to be. Conversely, if a target rarely needs to be run or if it's fast,
+# then you should create fewer targets.
+#
+# Possible values for TOUCH_STRATEGY:
+# "SINGLE": create a single touch file for all files.
+# "PER_FILE": create a touch file for each file. Defaults to this if
+# TOUCH_STRATEGY isn't specified.
+# "PER_DIR": create a touch file for each directory.
+#
+# List arguments:
+# FLAGS - List of flags to use after COMMAND
+# FILES - List of files to use COMMAND on. It's possible to combine this
+# with GLOB_PAT and GLOB_DIRS; the files found by globbing will
+# simple be added to FILES
+# GLOB_DIRS - The directories to recursively search for files with extension
+# GLOB_PAT
+#
+function(add_glob_targets)
+ cmake_parse_arguments(ARG
+ "REQUIRED"
+ "TARGET;COMMAND;GLOB_PAT;TOUCH_STRATEGY"
+ "FLAGS;FILES;GLOB_DIRS"
+ ${ARGN}
+ )
+
+ if(NOT ARG_COMMAND)
+ add_custom_target(${ARG_TARGET})
+ if(ARG_REQUIRED)
+ add_custom_command(TARGET ${ARG_TARGET}
+ COMMAND ${CMAKE_COMMAND} -E echo "${ARG_TARGET}: ${ARG_COMMAND} not found"
+ COMMAND false)
+ else()
+ add_custom_command(TARGET ${ARG_TARGET}
+ COMMAND ${CMAKE_COMMAND} -E echo "${ARG_TARGET} SKIP: ${ARG_COMMAND} not found")
+ endif()
+ return()
+ endif()
+
+ foreach(gd ${ARG_GLOB_DIRS})
+ file(GLOB_RECURSE globfiles ${PROJECT_SOURCE_DIR}/${gd}/${ARG_GLOB_PAT})
+ list(APPEND ARG_FILES ${globfiles})
+ endforeach()
+
+ if(NOT ARG_TOUCH_STRATEGY)
+ set(ARG_TOUCH_STRATEGY PER_FILE)
+ endif()
+ set(POSSIBLE_TOUCH_STRATEGIES SINGLE PER_FILE PER_DIR)
+ if(NOT ARG_TOUCH_STRATEGY IN_LIST POSSIBLE_TOUCH_STRATEGIES)
+ message(FATAL_ERROR "Unrecognized value for TOUCH_STRATEGY: ${ARG_TOUCH_STRATEGY}")
+ endif()
+
+ if(ARG_TOUCH_STRATEGY STREQUAL SINGLE)
+ set(touch_file ${TOUCHES_DIR}/ran-${ARG_TARGET})
+ add_custom_command(
+ OUTPUT ${touch_file}
+ COMMAND ${CMAKE_COMMAND} -E touch ${touch_file}
+ COMMAND ${ARG_COMMAND} ${ARG_FLAGS} ${ARG_FILES}
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ DEPENDS ${ARG_FILES})
+ list(APPEND touch_list ${touch_file})
+ elseif(ARG_TOUCH_STRATEGY STREQUAL PER_FILE)
+ set(touch_dir ${TOUCHES_DIR}/${ARG_TARGET})
+ file(MAKE_DIRECTORY ${touch_dir})
+ foreach(f ${ARG_FILES})
+ string(REGEX REPLACE "^${PROJECT_SOURCE_DIR}/" "" tf ${f})
+ string(REGEX REPLACE "[/.]" "-" tf ${tf})
+ set(touch_file ${touch_dir}/ran-${tf})
+ add_custom_command(
+ OUTPUT ${touch_file}
+ COMMAND ${CMAKE_COMMAND} -E touch ${touch_file}
+ COMMAND ${ARG_COMMAND} ${ARG_FLAGS} ${f}
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ DEPENDS ${f})
+ list(APPEND touch_list ${touch_file})
+ endforeach()
+ elseif(ARG_TOUCH_STRATEGY STREQUAL PER_DIR)
+ set(touch_dirs)
+ foreach(f ${ARG_FILES})
+ get_filename_component(out ${f} DIRECTORY)
+ list(APPEND touch_dirs ${out})
+ endforeach()
+ list(REMOVE_DUPLICATES touch_dirs)
+
+ foreach(touch_dir ${touch_dirs})
+ set(relevant_files)
+ foreach(f ${ARG_FILES})
+ get_filename_component(out ${f} DIRECTORY)
+ if(${touch_dir} STREQUAL ${out})
+ list(APPEND relevant_files ${f})
+ endif()
+ endforeach()
+
+ set(td ${TOUCHES_DIR}/${ARG_TARGET})
+ file(MAKE_DIRECTORY ${td})
+ string(REGEX REPLACE "^${PROJECT_SOURCE_DIR}/" "" tf ${touch_dir})
+ string(REGEX REPLACE "[/.]" "-" tf ${tf})
+ set(touch_file ${td}/ran-${tf})
+
+ add_custom_command(
+ OUTPUT ${touch_file}
+ COMMAND ${CMAKE_COMMAND} -E touch ${touch_file}
+ COMMAND ${ARG_COMMAND} ${ARG_FLAGS} ${relevant_files}
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ DEPENDS ${relevant_files})
+ list(APPEND touch_list ${touch_file})
+ endforeach()
+ endif()
+
+ add_custom_target(${ARG_TARGET} DEPENDS ${touch_list})
+endfunction()
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index a6c4bafc78..a0b8f16a39 100755
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -1,7 +1,5 @@
option(USE_GCOV "Enable gcov support" OFF)
-include(DefCmdTarget)
-
if(USE_GCOV)
if(CLANG_TSAN)
# GCOV and TSAN results in false data race reports
@@ -24,7 +22,6 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -framework CoreServices")
endif()
-set(TOUCHES_DIR ${PROJECT_BINARY_DIR}/touches)
set(GENERATOR_DIR ${CMAKE_CURRENT_LIST_DIR}/generators)
set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto)
set(BINARY_LIB_DIR ${PROJECT_BINARY_DIR}/lib/nvim/)
@@ -800,16 +797,12 @@ foreach(sfile ${LINT_NVIM_SOURCES})
endforeach()
add_custom_target(lintc DEPENDS ${LINT_TARGETS})
-def_cmd_target(lintuncrustify ${UNCRUSTIFY_PRG} UNCRUSTIFY_PRG false)
-if(UNCRUSTIFY_PRG)
- add_custom_command(TARGET lintuncrustify
- COMMAND ${CMAKE_COMMAND}
- -D UNCRUSTIFY_PRG=${UNCRUSTIFY_PRG}
- -D PROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR}
- -D NVIM_SOURCES="${NVIM_SOURCES}"
- -D NVIM_HEADERS="${NVIM_HEADERS}"
- -P ${PROJECT_SOURCE_DIR}/cmake/RunUncrustify.cmake)
-endif()
+add_glob_targets(
+ TARGET lintuncrustify
+ COMMAND ${UNCRUSTIFY_PRG}
+ FLAGS -c "${PROJECT_SOURCE_DIR}/src/uncrustify.cfg" -q --check
+ FILES ${LINT_NVIM_SOURCES}
+ )
add_custom_target(
lintcfull