1# #################################################################################################
2# ALibTools.cmake - CMake Tools for projects using ALib
4# Copyright 2015-2024 A-Worx GmbH, Germany
5# Published under 'Boost Software License' (a free software license, see LICENSE.txt)
8# This CMake file is included by "ALib.cmake" automatically and is not intended for manual
9# inclusion. Its contents was separated into a separated cmake file solely for clarity.
10# #################################################################################################
12# -------------------------------------------------------------------------------------------------
13# Collects resource files and add copy commands to a new target.
14# Then sets a dependency of the main target to this new resource target.
16# This methods may be used when resource files like texts, json data or images have to be copied
17# to the target build directory. The use is simple and done as follows:
19# 1. Create a LIST variable that holds one or more directory names with file wildcards, used for
20# "globbing" the resource files, for example:
22# list( append MY_PROJECT_RESOURCE_FILES ../../resources/res_*.img )
24# 2. After the executable (or library) is defined with cmake (add_executable or add_library),
25# insert the following invocation of this method:
27# AddResourceTarget( my_resources_target my_target ${MY_PROJECT_RESOURCE_FILES})
29# with the first parameter being an arbitrary name for the resource target to create.
31# add_dependencies ( my_target_unity my_resources_target )
32# -------------------------------------------------------------------------------------------------
33FUNCTION( AddResourceTarget resourceProjectName targetName resourceFileFilters)
35 #message(STATUS "### AddResourceTarget() ###")
36 #message(STATUS "resourceProjectName : ${resourceProjectName}")
37 #message(STATUS "targetName : ${targetName}")
38 #message(STATUS "resourceFilter : ${resourceFilter}")
40 FOREACH(_resourceFileFilter IN LISTS resourceFileFilters)
41 file( GLOB_RECURSE resourceList ${_resourceFileFilter} )
43 #message(STATUS "resourceList : ${resourceList}")
45 FOREACH(_resourceFile IN LISTS resourceList)
47 #get filename and create destination file
48 get_filename_component( _destFile ${_resourceFile} NAME)
49 set ( _destFile ${CMAKE_CURRENT_BINARY_DIR}/${_destFile} )
50 list ( APPEND _destFileList ${_destFile} )
53 add_custom_command( OUTPUT "${_destFile}"
54 COMMAND ${CMAKE_COMMAND} -E copy "${_resourceFile}" "${_destFile}"
55 COMMENT "Copying resource to ${_destFile}" )
58 # create the copy target
59 add_custom_target(${resourceProjectName} ALL DEPENDS "${_destFileList}")
61 # add a dependency to the main target
62 add_dependencies ( ${targetName} ${resourceProjectName} )
64ENDFUNCTION(AddResourceTarget)
66# -------------------------------------------------------------------------------------------------
67# Removes duplicates from a given LIST and collects those found in second list. The list of
68# found duplicates may contain duplicates as well, if entries had been trippled before.
69# In other words, the sum of entries of the modified input list and entries in the result list
70# is the same as the number of original entries.
72# Note that both input parameters have to give the name of variables:
73# - "sourceListName" denotes the name of an existing variable in the calling scope which is
75# - "duplicateListName" denotes the name of an new variable that is created in the calling scope.
76# In the case it previously existed already, it will be overwritten.
78# ===============================================================================================
79# Recipe for modifying existing variables of the, and creating new ones in the parent scope
80# -------------------------------------------------------------------------------------------------
81# CMake is not easy to understand for humans. Therefore, two recepies should be given here, as
82# it took us a while to understand that (or rather: to make it work).
84# 1. How to create a variable in the parent scope:
85# - Have a function parameter that specifies the name (!) of the variable.
86# - Use an own local variable to create the result value.
87# - At the end, before the function returns, assign the local variable into the gloabl
88# scope using parameter PARENT_SCOPE of the SET command.
92# FUNCTION( SetHello resultVarName )
93# SET( resultVar "Hello World" )
94# SET( ${resultVarName} ${resultVar} PARENT_SCOPE)
95# ENDFUNCTION( SetHello )
97# 2. How to modify an existing variable from the parent scope:
98# - Have a function parameter that specifies the name (!) of the existing variable.
99# - Copy the contents of the existing variable into a local one. This has to be done with
100# a nested ${} operator! (Yes, when you think about it...)
101# - Do modifications only with the local copy (e.g. add or remove list entries)
102# - At the end, before the function returns, assign the local variable into the gloabl
103# scope using parameter PARENT_SCOPE of the SET command.
107# FUNCTION( AddHello existingVarName )
108# SET( localVar ${${existingVarName}} )
109# SET( localVar "Hello World")
110# SET( ${existingVarName} ${localVar} PARENT_SCOPE)
111# ENDFUNCTION( AddHello )
113# -------------------------------------------------------------------------------------------------
114FUNCTION( CollectAndRemoveDuplicates sourceListVariableName duplicateListVariableName )
115 #message(STATUS "****************** CollectAndRemoveDuplicates START ***********************" )
117 # copy source list to local list
118 SET( sourceList ${${sourceListVariableName}} )
120 # copy list to duplicates
121 SET( duplicates ${sourceList} )
124 LIST( LENGTH sourceList cntSource )
125 IF( ${cntSource} GREATER 0 )
127 # remove duplicates from source
128 LIST( REMOVE_DUPLICATES sourceList )
130 # remove each in source from duplicates
131 FOREACH( entry IN LISTS sourceList )
132 LIST(FIND duplicates ${entry} idx )
133 IF( ${idx} EQUAL -1 )
134 message( ERROR " Internal script error in CollectAndRemoveDuplicates: Item not found in original list." )
136 LIST(REMOVE_AT duplicates ${idx})
140 # Transfer local variables back to parent scope
141 SET( ${sourceListVariableName} ${sourceList} PARENT_SCOPE)
142 SET( ${duplicateListVariableName} ${duplicates} PARENT_SCOPE)
144 #message(STATUS "****************** CollectAndRemoveDuplicates END ************************" )
145ENDFUNCTION(CollectAndRemoveDuplicates)
148FUNCTION( DumpList listVariableName )
150 LIST( LENGTH ${listVariableName} length )
151 message(STATUS "Entries in list '${listVariableName}': ${length}" )
153 MATH(EXPR maxIdx "${length} - 1" )
154 FOREACH( idx RANGE 0 ${maxIdx} )
155 list(GET ${listVariableName} ${idx} entry )
156 message( STATUS " ${idx}: ${entry}" )
159ENDFUNCTION( DumpList )
162# --------------------------------------------------------------------------------------------------
163# ALibDumpCMakeVariables() Writes out all currently defined CMake variables
164# --------------------------------------------------------------------------------------------------
165FUNCTION (ALibDumpCMakeVariables)
167 message(STATUS "------------------------------ Dumping CMake Variables: ------------------------------")
168 get_cmake_property(_variableNames VARIABLES)
169 list (SORT _variableNames)
170 foreach (_variableName ${_variableNames})
171 if( "${_variableName}" STREQUAL "temp"
172 OR "${_variableName}" STREQUAL "_gccStdout"
173 OR "${_variableName}" STREQUAL "_defineLines"
174 OR "${_variableName}" STREQUAL "_dummy"
175 OR "${_variableName}" STREQUAL "OUTPUT"
176 OR "${_variableName}" STREQUAL "CMAKE_C_COMPILER_ID_TOOL_MATCH_REGEX"
177 OR "${_variableName}" STREQUAL "CMAKE_CXX_COMPILER_ID_TOOL_MATCH_REGEX"
178 OR "${_variableName}" STREQUAL "CMAKE_C_COMPILER_ID_PLATFORM_CONTENT"
179 OR "${_variableName}" STREQUAL "CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT"
180 OR "${_variableName}" STREQUAL "CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS"
181 OR "${_variableName}" STREQUAL "CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS"
182 OR "${_variableName}" STREQUAL "PTHREAD_C_CXX_TEST_SOURCE"
183 OR "${_variableName}" STREQUAL "Qt5Gui_PLUGINS" )
184 message(STATUS "${_variableName}=[...] (omitted)")
188 message(STATUS "${_variableName}=${${_variableName}}")
190 message(STATUS "------------------------------ Dumping CMake Variables (END) ------------------------------")