aboutsummaryrefslogtreecommitdiff
path: root/cmake
diff options
context:
space:
mode:
authorJosh Rahm <rahm@google.com>2022-07-18 19:37:18 +0000
committerJosh Rahm <rahm@google.com>2022-07-18 19:37:18 +0000
commit308e1940dcd64aa6c344c403d4f9e0dda58d9c5c (patch)
tree35fe43e01755e0f312650667004487a44d6b7941 /cmake
parent96a00c7c588b2f38a2424aeeb4ea3581d370bf2d (diff)
parente8c94697bcbe23a5c7b07c292b90a6b70aadfa87 (diff)
downloadrneovim-308e1940dcd64aa6c344c403d4f9e0dda58d9c5c.tar.gz
rneovim-308e1940dcd64aa6c344c403d4f9e0dda58d9c5c.tar.bz2
rneovim-308e1940dcd64aa6c344c403d4f9e0dda58d9c5c.zip
Merge remote-tracking branch 'upstream/master' into rahm
Diffstat (limited to 'cmake')
-rw-r--r--cmake/FindLibIntl.cmake13
-rw-r--r--cmake/FindLua.cmake197
-rw-r--r--cmake/FindWinpty.cmake10
-rw-r--r--cmake/GenerateVersion.cmake48
-rw-r--r--cmake/RunTests.cmake5
-rw-r--r--cmake/UninstallHelper.cmake13
-rw-r--r--cmake/UninstallHelper.cmake.in21
-rw-r--r--cmake/Util.cmake145
8 files changed, 222 insertions, 230 deletions
diff --git a/cmake/FindLibIntl.cmake b/cmake/FindLibIntl.cmake
index 09eafb786a..8cc5cb7dd2 100644
--- a/cmake/FindLibIntl.cmake
+++ b/cmake/FindLibIntl.cmake
@@ -41,6 +41,16 @@ endif()
if (MSVC)
list(APPEND CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARY})
endif()
+
+# On macOS, if libintl is a static library then we also need
+# to link libiconv and CoreFoundation.
+get_filename_component(LibIntl_EXT "${LibIntl_LIBRARY}" EXT)
+if (APPLE AND (LibIntl_EXT STREQUAL ".a"))
+ set(LibIntl_STATIC TRUE)
+ find_library(CoreFoundation_FRAMEWORK CoreFoundation)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "${ICONV_LIBRARY}" "${CoreFoundation_FRAMEWORK}")
+endif()
+
check_c_source_compiles("
#include <libintl.h>
@@ -54,6 +64,9 @@ int main(int argc, char** argv) {
if (MSVC)
list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARY})
endif()
+if (LibIntl_STATIC)
+ list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "${ICONV_LIBRARY}" "${CoreFoundation_FRAMEWORK}")
+endif()
if (LibIntl_INCLUDE_DIR)
list(REMOVE_ITEM CMAKE_REQUIRED_INCLUDES "${LibIntl_INCLUDE_DIR}")
endif()
diff --git a/cmake/FindLua.cmake b/cmake/FindLua.cmake
deleted file mode 100644
index 7ba13e1f56..0000000000
--- a/cmake/FindLua.cmake
+++ /dev/null
@@ -1,197 +0,0 @@
-# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
-# file Copyright.txt or https://cmake.org/licensing for details.
-
-#.rst:
-# FindLua
-# -------
-#
-#
-#
-# Locate Lua library This module defines
-#
-# ::
-#
-# LUA_FOUND - if false, do not try to link to Lua
-# LUA_LIBRARIES - both lua and lualib
-# LUA_INCLUDE_DIR - where to find lua.h
-# LUA_VERSION_STRING - the version of Lua found
-# LUA_VERSION_MAJOR - the major version of Lua
-# LUA_VERSION_MINOR - the minor version of Lua
-# LUA_VERSION_PATCH - the patch version of Lua
-#
-#
-#
-# Note that the expected include convention is
-#
-# ::
-#
-# #include "lua.h"
-#
-# and not
-#
-# ::
-#
-# #include <lua/lua.h>
-#
-# This is because, the lua location is not standardized and may exist in
-# locations other than lua/
-
-unset(_lua_include_subdirs)
-unset(_lua_library_names)
-unset(_lua_append_versions)
-
-# this is a function only to have all the variables inside go away automatically
-function(_lua_set_version_vars)
- set(LUA_VERSIONS5 5.4 5.3 5.2 5.1 5.0)
-
- if (Lua_FIND_VERSION_EXACT)
- if (Lua_FIND_VERSION_COUNT GREATER 1)
- set(_lua_append_versions ${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR})
- endif ()
- elseif (Lua_FIND_VERSION)
- # once there is a different major version supported this should become a loop
- if (NOT Lua_FIND_VERSION_MAJOR GREATER 5)
- if (Lua_FIND_VERSION_COUNT EQUAL 1)
- set(_lua_append_versions ${LUA_VERSIONS5})
- else ()
- foreach (subver IN LISTS LUA_VERSIONS5)
- if (NOT subver VERSION_LESS ${Lua_FIND_VERSION})
- list(APPEND _lua_append_versions ${subver})
- endif ()
- endforeach ()
- endif ()
- endif ()
- else ()
- # once there is a different major version supported this should become a loop
- set(_lua_append_versions ${LUA_VERSIONS5})
- endif ()
-
- list(APPEND _lua_include_subdirs "include/lua" "include")
-
- foreach (ver IN LISTS _lua_append_versions)
- string(REGEX MATCH "^([0-9]+)\\.([0-9]+)$" _ver "${ver}")
- list(APPEND _lua_include_subdirs
- include/lua${CMAKE_MATCH_1}${CMAKE_MATCH_2}
- include/lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
- include/lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
- )
- endforeach ()
-
- set(_lua_include_subdirs "${_lua_include_subdirs}" PARENT_SCOPE)
- set(_lua_append_versions "${_lua_append_versions}" PARENT_SCOPE)
-endfunction(_lua_set_version_vars)
-
-function(_lua_check_header_version _hdr_file)
- # At least 5.[012] have different ways to express the version
- # so all of them need to be tested. Lua 5.2 defines LUA_VERSION
- # and LUA_RELEASE as joined by the C preprocessor, so avoid those.
- file(STRINGS "${_hdr_file}" lua_version_strings
- REGEX "^#define[ \t]+LUA_(RELEASE[ \t]+\"Lua [0-9]|VERSION([ \t]+\"Lua [0-9]|_[MR])).*")
-
- string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MAJOR ";${lua_version_strings};")
- if (LUA_VERSION_MAJOR MATCHES "^[0-9]+$")
- string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MINOR ";${lua_version_strings};")
- string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_PATCH ";${lua_version_strings};")
- set(LUA_VERSION_STRING "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}")
- else ()
- string(REGEX REPLACE ".*;#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
- if (NOT LUA_VERSION_STRING MATCHES "^[0-9.]+$")
- string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
- endif ()
- string(REGEX REPLACE "^([0-9]+)\\.[0-9.]*$" "\\1" LUA_VERSION_MAJOR "${LUA_VERSION_STRING}")
- string(REGEX REPLACE "^[0-9]+\\.([0-9]+)[0-9.]*$" "\\1" LUA_VERSION_MINOR "${LUA_VERSION_STRING}")
- string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]).*" "\\1" LUA_VERSION_PATCH "${LUA_VERSION_STRING}")
- endif ()
- foreach (ver IN LISTS _lua_append_versions)
- if (ver STREQUAL "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}")
- set(LUA_VERSION_MAJOR ${LUA_VERSION_MAJOR} PARENT_SCOPE)
- set(LUA_VERSION_MINOR ${LUA_VERSION_MINOR} PARENT_SCOPE)
- set(LUA_VERSION_PATCH ${LUA_VERSION_PATCH} PARENT_SCOPE)
- set(LUA_VERSION_STRING ${LUA_VERSION_STRING} PARENT_SCOPE)
- return()
- endif ()
- endforeach ()
-endfunction(_lua_check_header_version)
-
-_lua_set_version_vars()
-
-if (LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
- _lua_check_header_version("${LUA_INCLUDE_DIR}/lua.h")
-endif ()
-
-if (NOT LUA_VERSION_STRING)
- foreach (subdir IN LISTS _lua_include_subdirs)
- unset(LUA_INCLUDE_PREFIX CACHE)
- find_path(LUA_INCLUDE_PREFIX ${subdir}/lua.h
- HINTS
- ENV LUA_DIR
- PATHS
- ~/Library/Frameworks
- /Library/Frameworks
- /sw # Fink
- /opt/local # DarwinPorts
- /opt/csw # Blastwave
- /opt
- )
- if (LUA_INCLUDE_PREFIX)
- _lua_check_header_version("${LUA_INCLUDE_PREFIX}/${subdir}/lua.h")
- if (LUA_VERSION_STRING)
- set(LUA_INCLUDE_DIR "${LUA_INCLUDE_PREFIX}/${subdir}")
- break()
- endif ()
- endif ()
- endforeach ()
-endif ()
-unset(_lua_include_subdirs)
-unset(_lua_append_versions)
-
-if (LUA_VERSION_STRING)
- set(_lua_library_names
- lua${LUA_VERSION_MAJOR}${LUA_VERSION_MINOR}
- lua${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}
- lua-${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}
- lua.${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}
- )
-endif ()
-
-find_library(LUA_LIBRARY
- NAMES ${_lua_library_names} lua
- HINTS
- ENV LUA_DIR
- PATH_SUFFIXES lib
- PATHS
- ~/Library/Frameworks
- /Library/Frameworks
- /sw
- /opt/local
- /opt/csw
- /opt
-)
-unset(_lua_library_names)
-
-if (LUA_LIBRARY)
- # include the math library for Unix
- if (UNIX AND NOT APPLE AND NOT BEOS)
- find_library(LUA_MATH_LIBRARY m)
- set(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}")
-
- # include dl library for statically-linked Lua library
- get_filename_component(LUA_LIB_EXT ${LUA_LIBRARY} EXT)
- if(LUA_LIB_EXT STREQUAL CMAKE_STATIC_LIBRARY_SUFFIX)
- list(APPEND LUA_LIBRARIES ${CMAKE_DL_LIBS})
- endif()
-
- # For Windows and Mac, don't need to explicitly include the math library
- else ()
- set(LUA_LIBRARIES "${LUA_LIBRARY}")
- endif ()
-endif ()
-
-include(FindPackageHandleStandardArgs)
-# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if
-# all listed variables are TRUE
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua
- REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
- VERSION_VAR LUA_VERSION_STRING)
-
-mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY LUA_MATH_LIBRARY)
diff --git a/cmake/FindWinpty.cmake b/cmake/FindWinpty.cmake
deleted file mode 100644
index 8feafc58a8..0000000000
--- a/cmake/FindWinpty.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-include(LibFindMacros)
-
-find_path(WINPTY_INCLUDE_DIR winpty.h)
-set(WINPTY_INCLUDE_DIRS ${WINPTY_INCLUDE_DIR})
-
-find_library(WINPTY_LIBRARY winpty)
-find_program(WINPTY_AGENT_EXE winpty-agent.exe)
-set(WINPTY_LIBRARIES ${WINPTY_LIBRARY})
-
-find_package_handle_standard_args(Winpty DEFAULT_MSG WINPTY_LIBRARY WINPTY_INCLUDE_DIR)
diff --git a/cmake/GenerateVersion.cmake b/cmake/GenerateVersion.cmake
new file mode 100644
index 0000000000..b9313f2498
--- /dev/null
+++ b/cmake/GenerateVersion.cmake
@@ -0,0 +1,48 @@
+# Handle generating version from Git.
+set(use_git_version 0)
+if(NVIM_VERSION_MEDIUM)
+ message(STATUS "USING NVIM_VERSION_MEDIUM: ${NVIM_VERSION_MEDIUM}")
+ return()
+endif()
+
+find_program(GIT_EXECUTABLE git)
+if(NOT GIT_EXECUTABLE)
+ message(AUTHOR_WARNING "Skipping version-string generation (cannot find git)")
+ file(WRITE "${OUTPUT}" "")
+ return()
+endif()
+
+execute_process(
+ COMMAND git describe --first-parent --tags --always --dirty
+ OUTPUT_VARIABLE GIT_TAG
+ ERROR_VARIABLE ERR
+ RESULT_VARIABLE RES
+)
+
+if("${RES}" EQUAL 1)
+ if(EXISTS ${OUTPUT})
+ message(STATUS "Unable to extract version-string from git: keeping the last known version")
+ else()
+ # this will only be executed once since the file will get generated afterwards
+ message(AUTHOR_WARNING "Git tag extraction failed with: " "${ERR}")
+ file(WRITE "${OUTPUT}" "")
+ endif()
+ return()
+endif()
+
+string(STRIP "${GIT_TAG}" GIT_TAG)
+string(REGEX REPLACE "^v[0-9]+.[0-9]+.[0-9]+-" "" NVIM_VERSION_GIT "${GIT_TAG}")
+set(NVIM_VERSION_MEDIUM
+ "v${NVIM_VERSION_MAJOR}.${NVIM_VERSION_MINOR}.${NVIM_VERSION_PATCH}-dev-${NVIM_VERSION_GIT}"
+)
+set(NVIM_VERSION_STRING "#define NVIM_VERSION_MEDIUM \"${NVIM_VERSION_MEDIUM}\"\n")
+string(SHA1 CURRENT_VERSION_HASH "${NVIM_VERSION_STRING}")
+
+if(EXISTS ${OUTPUT})
+ file(SHA1 "${OUTPUT}" NVIM_VERSION_HASH)
+endif()
+
+if(NOT "${NVIM_VERSION_HASH}" STREQUAL "${CURRENT_VERSION_HASH}")
+ message(STATUS "Updating NVIM_VERSION_MEDIUM: ${NVIM_VERSION_MEDIUM}")
+ file(WRITE "${OUTPUT}" "${NVIM_VERSION_STRING}")
+endif()
diff --git a/cmake/RunTests.cmake b/cmake/RunTests.cmake
index 3adbcbbfc5..e07c6dd174 100644
--- a/cmake/RunTests.cmake
+++ b/cmake/RunTests.cmake
@@ -11,6 +11,7 @@ set(ENV{NVIM_RPLUGIN_MANIFEST} ${BUILD_DIR}/Xtest_rplugin_manifest)
set(ENV{XDG_CONFIG_HOME} ${BUILD_DIR}/Xtest_xdg/config)
set(ENV{XDG_DATA_HOME} ${BUILD_DIR}/Xtest_xdg/share)
unset(ENV{XDG_DATA_DIRS})
+unset(ENV{NVIM}) # Clear $NVIM in case tests are running from Nvim. #11009
if(NOT DEFINED ENV{NVIM_LOG_FILE})
set(ENV{NVIM_LOG_FILE} ${BUILD_DIR}/.nvimlog)
@@ -50,8 +51,8 @@ if(DEFINED ENV{TEST_FILTER_OUT} AND NOT "$ENV{TEST_FILTER_OUT}" STREQUAL "")
list(APPEND BUSTED_ARGS --filter-out $ENV{TEST_FILTER_OUT})
endif()
-# TMPDIR: use relative test path (for parallel test runs / isolation).
-set(ENV{TMPDIR} "${BUILD_DIR}/Xtest_tmpdir/${TEST_PATH}")
+# TMPDIR: for helpers.tmpname() and Nvim tempname().
+set(ENV{TMPDIR} "${BUILD_DIR}/Xtest_tmpdir")
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory $ENV{TMPDIR})
# HISTFILE: do not write into user's ~/.bash_history
diff --git a/cmake/UninstallHelper.cmake b/cmake/UninstallHelper.cmake
new file mode 100644
index 0000000000..9a3d30af59
--- /dev/null
+++ b/cmake/UninstallHelper.cmake
@@ -0,0 +1,13 @@
+if(NOT EXISTS "${CMAKE_BINARY_DIR}/install_manifest.txt")
+ message(FATAL_ERROR "Cannot find install manifest: ${CMAKE_BINARY_DIR}/install_manifest.txt")
+endif()
+
+file(STRINGS "${CMAKE_BINARY_DIR}/install_manifest.txt" files)
+foreach(file ${files})
+ message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
+ if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
+ file(REMOVE $ENV{DESTDIR}${file})
+ else()
+ message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
+ endif()
+endforeach()
diff --git a/cmake/UninstallHelper.cmake.in b/cmake/UninstallHelper.cmake.in
deleted file mode 100644
index c2d34d4796..0000000000
--- a/cmake/UninstallHelper.cmake.in
+++ /dev/null
@@ -1,21 +0,0 @@
-if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
- message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
-endif()
-
-file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
-string(REGEX REPLACE "\n" ";" files "${files}")
-foreach(file ${files})
- message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
- if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
- exec_program(
- "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
- OUTPUT_VARIABLE rm_out
- RETURN_VALUE rm_retval
- )
- if(NOT "${rm_retval}" STREQUAL 0)
- message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
- endif()
- else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
- message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
- endif()
-endforeach()
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()