diff --git a/docs/module/ECMConfiguredInstall.rst b/docs/module/ECMConfiguredInstall.rst new file mode 100644 --- /dev/null +++ b/docs/module/ECMConfiguredInstall.rst @@ -0,0 +1 @@ +.. ecm-module:: ../../modules/ECMConfiguredInstall.cmake diff --git a/modules/ECMConfiguredInstall.cmake b/modules/ECMConfiguredInstall.cmake new file mode 100644 --- /dev/null +++ b/modules/ECMConfiguredInstall.cmake @@ -0,0 +1,81 @@ +#.rst: +# ECMConfiguredInstall +# -------------------- +# +# Take a list of files, runs configure_file and installs it in the given location. +# +# Any suffix of ".in" in the passed file names wil be stripped from the file name at the installed location. +# :: +# ecm_install_configured_files(TEMPLATES [ [...]] DESTINATION [COPYONLY] [ESCAPE_QUOTES] [@ONLY] [COMPONENT ]) +# +# Example usage: +# +# .. code-block:: cmake +# +# ecm_install_configured_files(TEMPLATES foo.txt.in DESTINATION ${KDE_INSTALL_DATADIR} @ONLY) +# +# This wil install the file as foo.txt with any cmake variable replacements made into the data directory. + +# Copyright 2020 David Edmundson +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +function(ecm_install_configured_files) + set(options COPYONLY ESCAPE_QUOTES @ONLY) + set(oneValueArgs DESTINATION COMPONENT) + set(multiValueArgs TEMPLATES) + + cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" + "${multiValueArgs}" ${ARGN}) + + foreach(_template ${ARGS_TEMPLATES}) + # convert absolute paths + get_filename_component(_name ${_template} NAME) + + string(REGEX REPLACE ".in$" "" _name ${_name}) + + set(_out_file ${CMAKE_CURRENT_BINARY_DIR}/${_name}) + + set(_configure_args "") + if (ARGS_COPY_ONLY) + string(APPEND _configure_args COPY_ONLY) + endif() + if (ARGS_ESCAPE_QUOTES) + string(APPEND _configure_args ESCAPE_QUOTES) + endif() + if (ARGS_@ONLY) + string(APPEND _configure_args @ONLY) + endif() + + configure_file(${_template} ${_out_file} ${_configure_args}) + + if (DEFINED ARGS_COMPONENT) + set(_component COMPONENT ${ARGS_COMPONENT}) + else() + set(_component) + endif() + + install(FILES ${_out_file} DESTINATION ${ARGS_DESTINATION} ${_component}) + endforeach() +endfunction() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -222,3 +222,13 @@ if (TARGET Qt5::Quick) add_test_macro(ECMQMLModules dummy) endif() + +set(ECMConfiguredInstallTest_EXTRA_OPTIONS + --build-target install + --build-options + "-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/ECMConfiguredInstallTest/InstallDirectory" +) +add_test_macro(ECMConfiguredInstallTest + ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/ECMConfiguredInstallTest/check_tree.cmake" +) + diff --git a/tests/ECMConfiguredInstallTest/CMakeLists.txt b/tests/ECMConfiguredInstallTest/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/tests/ECMConfiguredInstallTest/CMakeLists.txt @@ -0,0 +1,21 @@ +project(ECMConfiguredInstallTest) +cmake_minimum_required(VERSION 3.5) +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../modules) + +# make sure the test install dir is clean +file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}") +include(ECMConfiguredInstall) + +# run test + +set(FOO myFoo) +set(BAR myBar) + +ecm_install_configured_files(TEMPLATES configured.txt DESTINATION ${CMAKE_INSTALL_PREFIX}/test1) + +ecm_install_configured_files(TEMPLATES configured_atOnly.txt.in DESTINATION ${CMAKE_INSTALL_PREFIX}/test2 @ONLY) + +ecm_install_configured_files(TEMPLATES multi1.txt.in ${CMAKE_CURRENT_SOURCE_DIR}/multi2.txt.in DESTINATION ${CMAKE_INSTALL_PREFIX}/test3 ESCAPE_QUOTES) + +# this will be run by CTest +configure_file(check_tree.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/check_tree.cmake" @ONLY) diff --git a/tests/ECMConfiguredInstallTest/check_tree.cmake.in b/tests/ECMConfiguredInstallTest/check_tree.cmake.in new file mode 100644 --- /dev/null +++ b/tests/ECMConfiguredInstallTest/check_tree.cmake.in @@ -0,0 +1,37 @@ +set(EXPECTED "@CMAKE_CURRENT_SOURCE_DIR@/expected") +set(ACTUAL "@CMAKE_INSTALL_PREFIX@") + +execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files ${ACTUAL}/test1/configured.txt + ${EXPECTED}/configured.txt + RESULT_VARIABLE test1_result +) + +If (NOT test1_result EQUAL 0) + message(FATAL_ERROR "Configured files differ!") +endif() + +execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files ${ACTUAL}/test2/configured_atOnly.txt + ${EXPECTED}/configured_atOnly.txt + RESULT_VARIABLE test2_result +) + +If (NOT test2_result EQUAL 0) + message(FATAL_ERROR "Configured files differ!") +endif() + +execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files ${ACTUAL}/test3/multi1.txt + ${EXPECTED}/multi1.txt + RESULT_VARIABLE test31_result +) +execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files ${ACTUAL}/test3/multi2.txt + ${EXPECTED}/multi2.txt + RESULT_VARIABLE test32_result +) + +If (NOT test31_result EQUAL 0) + message(FATAL_ERROR "Configured files differ!") +endif() + +If (NOT test32_result EQUAL 0) + message(FATAL_ERROR "Configured files differ!") +endif() diff --git a/tests/ECMConfiguredInstallTest/configured.txt b/tests/ECMConfiguredInstallTest/configured.txt new file mode 100644 --- /dev/null +++ b/tests/ECMConfiguredInstallTest/configured.txt @@ -0,0 +1,3 @@ +[General] +Foo=@FOO@ +Bar=${BAR} diff --git a/tests/ECMConfiguredInstallTest/configured_atOnly.txt.in b/tests/ECMConfiguredInstallTest/configured_atOnly.txt.in new file mode 100644 --- /dev/null +++ b/tests/ECMConfiguredInstallTest/configured_atOnly.txt.in @@ -0,0 +1,3 @@ +[General] +Foo=@FOO@ +Bar=${BAR} diff --git a/tests/ECMConfiguredInstallTest/expected/configured.txt b/tests/ECMConfiguredInstallTest/expected/configured.txt new file mode 100644 --- /dev/null +++ b/tests/ECMConfiguredInstallTest/expected/configured.txt @@ -0,0 +1,3 @@ +[General] +Foo=myFoo +Bar=myBar diff --git a/tests/ECMConfiguredInstallTest/expected/configured_atOnly.txt b/tests/ECMConfiguredInstallTest/expected/configured_atOnly.txt new file mode 100644 --- /dev/null +++ b/tests/ECMConfiguredInstallTest/expected/configured_atOnly.txt @@ -0,0 +1,3 @@ +[General] +Foo=myFoo +Bar=${BAR} diff --git a/tests/ECMConfiguredInstallTest/expected/multi1.txt b/tests/ECMConfiguredInstallTest/expected/multi1.txt new file mode 100644 --- /dev/null +++ b/tests/ECMConfiguredInstallTest/expected/multi1.txt @@ -0,0 +1,2 @@ +TestMulti1 +Foo=myFoo diff --git a/tests/ECMConfiguredInstallTest/expected/multi2.txt b/tests/ECMConfiguredInstallTest/expected/multi2.txt new file mode 100644 --- /dev/null +++ b/tests/ECMConfiguredInstallTest/expected/multi2.txt @@ -0,0 +1,2 @@ +TestMulti2 +Foo=myFoo diff --git a/tests/ECMConfiguredInstallTest/multi1.txt.in b/tests/ECMConfiguredInstallTest/multi1.txt.in new file mode 100644 --- /dev/null +++ b/tests/ECMConfiguredInstallTest/multi1.txt.in @@ -0,0 +1,2 @@ +TestMulti1 +Foo=@FOO@ diff --git a/tests/ECMConfiguredInstallTest/multi2.txt.in b/tests/ECMConfiguredInstallTest/multi2.txt.in new file mode 100644 --- /dev/null +++ b/tests/ECMConfiguredInstallTest/multi2.txt.in @@ -0,0 +1,2 @@ +TestMulti2 +Foo=@FOO@