#=========================== begin_copyright_notice ============================ # # Copyright (C) 2021 Intel Corporation # # SPDX-License-Identifier: MIT # #============================ end_copyright_notice ============================= #=============================== Resource files ================================ include_guard(DIRECTORY) # Registers configuration for resource files for specific idenitifer. # # The configuration of resource files can be fetched using igc_rc_get_resource() function. # # Current version of CMake does not allow to modify sources list after calling add_*() # functions, so resources still need to be added by using igc_rc_get_resource() to get # list of resource files and adding it to add_*(). # # igc_rc_register_resource( # resourceId # [RESOURCES [importedId [importedId [...]]]] # [FILE rcFile [rcFile [...]] # [[APPEND] INCLUDE_DIRECTORIES [incudeDir [includeDir [...]]]] # [[APPEND] DEFINES [define [define [...]]]] # [[APPEND] FLAGS [flag [flag [...]]]]] # ) # # @param resourceId Identifier of resource file or of group of resource files. # @param importedId Identifiers of additional resources that should be added with currently registered # resource. # @param rcFile Resource files which are be connected to specified resource identifier. # @param incudeDir Additional for resource files. # @param define Additional defines for resource files. # @param flag Additional flags for resource files. function(igc_rc_register_resource resourceId) if(NOT ("${resourceId}" MATCHES "[a-zA-Z0-9_]+")) message(FATAL_ERROR "The resource identifier \"${resourceId}\" is invalid.") endif() set(_rcPropPrefix "IGC_PROPERTY__RC_RESOURCES_R${resourceId}_") set(_rcIdxPropName "${_rcPropPrefix}INDEX") # Preserve resource index to support multiple registration calls. get_property(_rcIdxSet GLOBAL PROPERTY "${_rcIdxPropName}" SET) if(_rcIdxSet) get_property(_rcIdx GLOBAL PROPERTY "${_rcIdxPropName}") else() set(_rcIdx 0) endif() set(_rcFilesPropName "${_rcPropPrefix}G${_rcIdx}_FILES") set(_includeDirsPropName "${_rcPropPrefix}G${_rcIdx}_INCDIRS") set(_definesPropName "${_rcPropPrefix}G${_rcIdx}_DEFINES") set(_flagsPropName "${_rcPropPrefix}G${_rcIdx}_FLAGS") set(_importResIdsPropName "${_rcPropPrefix}G${_rcIdx}_IMPORTED_RES_IDS") set(_appendIncludeDirsPropName "${_includeDirsPropName}_APPEND") set(_appendDefinesPropName "${_definesPropName}_APPEND") set(_appendFlagsPropName "${_flagsPropName}_APPEND") set(_importResIds) set(_rcFiles) set(_includeDirs) set(_defines) set(_flags) set(_appendIncludeDirs NO) set(_appendDefines NO) set(_appendFlags NO) set(_parseState 1) foreach(_resArg ${ARGN}) string(REPLACE ";" "\;" _resArg "${_resArg}") # [WA#1] Must escape ; again if occurred in item. # States: [0] [1] *1( "RESOURCES" [100] * [100] ) *1( "FILE" [2] [3] * [3] # *1( *1( "APPEND" [4] ) "INCLUDE_DIRECTORIES" [5] * [5] ) *1( *1( "APPEND" [6] ) "DEFINES" [7] * [7] ) # *1( *1( "APPEND" [8] ) "FLAGS" [9] * [9] ) ) # Transitions: 0 -> 1 // by explict parameters # 1 (FILE) -> 2 -> 3 # 1 (RESOURCES) -> 100 # 3 (APPEND) -> 4 {6,8} # 3 (INCLUDE_DIRECTORIES) -> 5 # 3 (DEFINES) -> 7 # 3 (FLAGS) -> 9 # 3 -> 3 # 4 (INCLUDE_DIRECTORIES) -> 5 # 4 (DEFINES) -> 7 # 4 (FLAGS) -> 9 # 5 (APPEND) -> 6 {8} # 5 (DEFINES) -> 7 # 5 (FLAGS) -> 9 # 5 -> 5 # 6 (DEFINES) -> 7 # 6 (FLAGS) -> 9 # 7 (APPEND) -> 8 # 7 (FLAGS) -> 9 # 7 -> 7 # 8 (FLAGS) -> 9 # 9 -> 9 # 100 (FILE) -> 2 -> 3 # 100 -> 100 # Stop States: 3, 5, 7, 9, 100 if(_parseState EQUAL 1) if(_resArg MATCHES "^FILE$") set(_parseState 2) elseif(_resArg MATCHES "^RESOURCES$") set(_parseState 100) else() message(FATAL_ERROR "Invalid parameter token near \"${_resArg}\".") endif() elseif(_parseState EQUAL 2) set(_rcFiles "${_resArg}") set(_parseState 3) elseif(_parseState EQUAL 3) if(_resArg MATCHES "^APPEND$") set(_parseState 4) elseif(_resArg MATCHES "^INCLUDE_DIRECTORIES$") set(_parseState 5) elseif(_resArg MATCHES "^DEFINES$") set(_parseState 7) elseif(_resArg MATCHES "^FLAGS$") set(_parseState 9) else() list(APPEND _rcFiles "${_resArg}") endif() elseif(_parseState EQUAL 4) if(_resArg MATCHES "^INCLUDE_DIRECTORIES$") set(_appendIncludeDirs YES) set(_parseState 5) elseif(_resArg MATCHES "^DEFINES$") set(_appendDefines YES) set(_parseState 7) elseif(_resArg MATCHES "^FLAGS$") set(_appendFlags YES) set(_parseState 9) else() message(FATAL_ERROR "Invalid parameter token near \"${_resArg}\".") endif() elseif(_parseState EQUAL 5) if(_resArg MATCHES "^APPEND$") set(_parseState 6) elseif(_resArg MATCHES "^DEFINES$") set(_parseState 7) elseif(_resArg MATCHES "^FLAGS$") set(_parseState 9) else() list(APPEND _includeDirs "${_resArg}") endif() elseif(_parseState EQUAL 6) if(_resArg MATCHES "^DEFINES$") set(_appendDefines YES) set(_parseState 7) elseif(_resArg MATCHES "^FLAGS$") set(_appendFlags YES) set(_parseState 9) else() message(FATAL_ERROR "Invalid parameter token near \"${_resArg}\".") endif() elseif(_parseState EQUAL 7) if(_resArg MATCHES "^APPEND$") set(_parseState 8) elseif(_resArg MATCHES "^FLAGS$") set(_parseState 9) else() list(APPEND _defines "${_resArg}") endif() elseif(_parseState EQUAL 8) if(_resArg MATCHES "^FLAGS$") set(_appendFlags YES) set(_parseState 9) else() message(FATAL_ERROR "Invalid parameter token near \"${_resArg}\".") endif() elseif(_parseState EQUAL 9) list(APPEND _flags "${_resArg}") elseif(_parseState EQUAL 100) if(_resArg MATCHES "^FILE$") set(_parseState 2) else() list(APPEND _importResIds "${_resArg}") endif() else() message(FATAL_ERROR "Invalid parameter token near \"${_resArg}\".") endif() endforeach() if(NOT ((_parseState EQUAL 3) OR (_parseState EQUAL 5) OR (_parseState EQUAL 7) OR (_parseState EQUAL 9) OR (_parseState EQUAL 100))) message(FATAL_ERROR "Invalid number of parameters.") endif() if(DEFINED _rcFiles) list(REMOVE_DUPLICATES _rcFiles) endif() if(DEFINED _importResIds) list(REMOVE_DUPLICATES _importResIds) endif() set_property(GLOBAL PROPERTY "${_rcFilesPropName}" "${_rcFiles}") set_property(GLOBAL PROPERTY "${_includeDirsPropName}" "${_includeDirs}") set_property(GLOBAL PROPERTY "${_definesPropName}" "${_defines}") set_property(GLOBAL PROPERTY "${_flagsPropName}" "${_flags}") set_property(GLOBAL PROPERTY "${_importResIdsPropName}" "${_importResIds}") set_property(GLOBAL PROPERTY "${_appendIncludeDirsPropName}" "${_appendIncludeDirs}") set_property(GLOBAL PROPERTY "${_appendDefinesPropName}" "${_appendDefines}") set_property(GLOBAL PROPERTY "${_appendFlagsPropName}" "${_appendFlags}") math(EXPR _rcIdx "${_rcIdx} + 1") set_property(GLOBAL PROPERTY "${_rcIdxPropName}" "${_rcIdx}") endfunction() # Preconfigures and returns names of resource files connected to specified resource identifier. # # Preconfiguration sets additional definitions, include directories, etc. for each resource file. # The returned files can be used only in current directory targets. # # @param rcFilesVarName Name of variable placeholder where names of resource files will be returned. # @param resourceId Idenfifier of resource file or of group of resource files. function(igc_rc_get_resource rcFilesVarName resourceId) if(NOT ("${resourceId}" MATCHES "[a-zA-Z0-9_]+")) message(FATAL_ERROR "The resource identifier \"${resourceId}\" is invalid.") endif() set(_rcPropPrefix "IGC_PROPERTY__RC_RESOURCES_R${resourceId}_") set(_rcIdxPropName "${_rcPropPrefix}INDEX") # Preserve resource index to support multiple registration calls. get_property(_rcIdxSet GLOBAL PROPERTY "${_rcIdxPropName}" SET) if(_rcIdxSet) get_property(_rcIdx GLOBAL PROPERTY "${_rcIdxPropName}") else() message(AUTHOR_WARNING "Resource connected to \"${resourceId}\" not found.") set(_rcIdx 0) endif() set(_targetRcFiles) if(_rcIdx GREATER 0) math(EXPR _rcIdxM1 "${_rcIdx} - 1") foreach(_idx RANGE 0 "${_rcIdxM1}") set(_rcFilesPropName "${_rcPropPrefix}G${_idx}_FILES") set(_includeDirsPropName "${_rcPropPrefix}G${_idx}_INCDIRS") set(_definesPropName "${_rcPropPrefix}G${_idx}_DEFINES") set(_flagsPropName "${_rcPropPrefix}G${_idx}_FLAGS") set(_importResIdsPropName "${_rcPropPrefix}G${_idx}_IMPORTED_RES_IDS") set(_appendIncludeDirsPropName "${_includeDirsPropName}_APPEND") set(_appendDefinesPropName "${_definesPropName}_APPEND") set(_appendFlagsPropName "${_flagsPropName}_APPEND") get_property(_rcFiles GLOBAL PROPERTY "${_rcFilesPropName}") get_property(_includeDirs GLOBAL PROPERTY "${_includeDirsPropName}") get_property(_defines GLOBAL PROPERTY "${_definesPropName}") get_property(_flags GLOBAL PROPERTY "${_flagsPropName}") get_property(_importResIds GLOBAL PROPERTY "${_importResIdsPropName}") get_property(_appendIncludeDirs GLOBAL PROPERTY "${_appendIncludeDirsPropName}") get_property(_appendDefines GLOBAL PROPERTY "${_appendDefinesPropName}") get_property(_appendFlags GLOBAL PROPERTY "${_appendFlagsPropName}") set(_includeDirFlags) foreach(_includeDir ${_includeDirs}) string(REPLACE ";" "\;" _includeDir "${_includeDir}") # [WA#1] Must escape ; again if occurred in item. if(DEFINED _includeDirFlags) set(_includeDirFlags "${_includeDirFlags} /I\"${_includeDir}\"") else() set(_includeDirFlags "/I\"${_includeDir}\"") endif() endforeach() set(_flagFlags) foreach(_flag ${_flags}) string(REPLACE ";" "\;" _flag "${_flag}") # [WA#1] Must escape ; again if occurred in item. if(DEFINED _flagFlags) set(_flagFlags "${_flagFlags} ${_flag}") else() set(_flagFlags "${_flag}") endif() endforeach() if(DEFINED _flagFlags) set(_allFlags "${_flagFlags} ${_includeDirFlags}") else() set(_allFlags "${_includeDirFlags}") endif() foreach(_rcFile ${_rcFiles}) string(REPLACE ";" "\;" _rcFile "${_rcFile}") # [WA#1] Must escape ; again if occurred in item. if(_appendDefines) set_property(SOURCE "${_rcFile}" APPEND PROPERTY COMPILE_DEFINITIONS "${_defines}") else() set_property(SOURCE "${_rcFile}" PROPERTY COMPILE_DEFINITIONS "${_defines}") endif() # NOTE: Currently there is no include dirs (per source), so appending options are limited. if(_appendFlags OR _appendIncludeDirs) set_property(SOURCE "${_rcFile}" APPEND PROPERTY COMPILE_FLAGS "${_allFlags}") else() set_property(SOURCE "${_rcFile}" PROPERTY COMPILE_FLAGS "${_allFlags}") endif() list(APPEND _targetRcFiles "${_rcFile}") endforeach() foreach(_importResId ${_importResIds}) string(REPLACE ";" "\;" _importResId "${_importResId}") # [WA#1] Must escape ; again if occurred in item. set(_importedResources) igc_rc_get_resource(_importedResources "${_importResId}") list(APPEND _targetRcFiles "${_importedResources}") endforeach() endforeach() endif() if(DEFINED _targetRcFiles) list(REMOVE_DUPLICATES _targetRcFiles) endif() set("${rcFilesVarName}" "${_targetRcFiles}" PARENT_SCOPE) endfunction()