+
+
+# This function is a drop-in replacement for the following CMake command:
+#
+# install(FILES ... DESTINATION ... [OTHER_ARGS])
+#
+# The above command takes every single file and puts it in the destination directory, but relative
+# paths are not taken into consideration, i.e. files a/b/c/file.h and boo.h will be both installed
+# in dest.
+#
+# By replacing install() with install_relative(), boo.h will end in dest, and a/b/c/file.h will end
+# in dest/a/b/c/file.h, i.e. relative paths are taken into account.
+#
+# If an absolute path was specified for an input file, a fatal error will be raised: only relative
+# paths can be specified.
+#
+# Since it is a drop-in command, its syntax is identical to install():
+#
+# install_relative(FILES ... DESTINATION ... [OTHER_ARGS])
+#
+# where OTHER_ARGS is passed as-is to the underlying install() command
+function(install_relative)
+
+ set(_EXPECT_FILE TRUE)
+ set(_EXPECT_DEST FALSE)
+ set(_EXPECT_REST FALSE)
+
+ foreach(_ARG ${ARGN})
+
+ if(_EXPECT_FILE)
+
+ if(${_ARG} STREQUAL "FILES")
+ set(_EXPECT_FILE FALSE)
+ else()
+ message(FATAL_ERROR "You may only use install_relative() in place of install(FILES ...)")
+ endif()
+
+ elseif(_EXPECT_REST)
+ # Remaining arguments
+ list(APPEND _REST ${_ARG})
+ elseif(_EXPECT_DEST)
+ # Destination prefix
+ set(_DEST ${_ARG})
+ set(_EXPECT_DEST FALSE)
+ set(_EXPECT_REST TRUE)
+ elseif(_ARG STREQUAL "DESTINATION")
+ # From now on, copy the arguments ditto to the install() command
+ set(_EXPECT_DEST TRUE)
+ else()
+ # Append files to install
+ list(APPEND _FILES ${_ARG})
+ endif()
+
+ endforeach()
+
+ # Print out our results (debug)
+ #message(STATUS "[install_relative] FILES: ${_FILES}")
+ #message(STATUS "[install_relative] DEST: ${_DEST}")
+ #message(STATUS "[install_relative] REST: ${_REST}")
+
+ # Prepare a distinct install command for each file, depending on its path
+ foreach(_FILE ${_FILES})
+
+ get_filename_component(_FILEPREFIX ${_FILE} DIRECTORY)
+ #message(STATUS "[install_relative] ${_FILE} --> ${_FILEPREFIX}")
+
+ string(SUBSTRING ${_FILE} 0 1 _FILE_FIRST)
+ if(${_FILE_FIRST} STREQUAL "/")
+ # An absolute path was found: not supported, error
+ message(FATAL_ERROR "Absolute paths are not supported by install_relative(): ${_FILE}")
+ endif()
+
+ install(FILES ${_FILE} DESTINATION ${_DEST}/${_FILEPREFIX} ${_REST})
+
+ endforeach()
+
+endfunction()