فهرست منبع

using data/mappings for processing

Jack Humbert 3 سال پیش
والد
کامیت
92005dee35
8فایلهای تغییر یافته به همراه226 افزوده شده و 54 حذف شده
  1. 3 12
      CMakeLists.txt
  2. 2 1
      cmake/Findchibios.cmake
  3. 64 0
      cmake/ParseHeader.cmake
  4. 49 23
      cmake/ParseMakefile.cmake
  5. 67 6
      cmake/ProcessKeyboard.cmake
  6. 15 11
      cmake/ResolveKeyboard.cmake
  7. 25 0
      cmake/Utils.cmake
  8. 1 1
      data/mappings/info_config.hjson

+ 3 - 12
CMakeLists.txt

@@ -1,5 +1,7 @@
 cmake_minimum_required(VERSION 3.20)
 
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "")
+
 list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 
 include(UpdateSubmodule)
@@ -34,9 +36,9 @@ else()
     endif()
 
     resolve_keyboard(${QMK_KEYBOARD_FOLDER} QMK_KEYBOARD_FOLDER_ABS)
-    process_keyboard()
     cmake_path(IS_PREFIX QMK_KEYBOARDS_FOLDER "${QMK_KEYBOARD_FOLDER_ABS}" IS_KEYBOARDS_FOLDER)
     resolve_config_h(${QMK_KEYBOARD_FOLDER_ABS} QMK_KEYBOARD_CONFIG_H)
+    process_keyboard()
     resolve_keyboard_h(${QMK_KEYBOARD_FOLDER_ABS} QMK_KEYBOARD_H)
     resolve_keymap_c(${QMK_KEYBOARD_FOLDER_ABS} ${QMK_KEYMAP_FOLDER} QMK_KEYMAP_C)
 
@@ -50,12 +52,6 @@ else()
         HOMEPAGE_URL ${URL}
         VERSION ${DEVICE_VER})
 
-    string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" VERSION_MATCH ${DEVICE_VER})
-    set(VERSION_MAJOR ${CMAKE_MATCH_1})
-    set(VERSION_MINOR ${CMAKE_MATCH_2})
-    set(VERSION_PATCH ${CMAKE_MATCH_3})
-    math(EXPR VERSION_C_EVAL "${VERSION_MAJOR} * 10000 + ${VERSION_MINOR} * 100 + ${VERSION_PATCH}" OUTPUT_FORMAT HEXADECIMAL)
-
     # add_compile_options(
     # -include ${QMK_KEYBOARD_CONFIG_H}
     # )
@@ -65,11 +61,6 @@ else()
         KEYMAP_C="${QMK_KEYMAP_C}"
         MATRIX_ROWS=8
         MATRIX_COLS=6
-        VENDOR_ID=${VENDOR_ID}
-        PRODUCT_ID=${PRODUCT_ID}
-        DEVICE_VER=${VERSION_C_EVAL}
-        MANUFACTURER="${MANUFACTURER}"
-        PRODUCT="${KEYBOARD_NAME}"
     )
 
     if(DEFINED DIODE_DIRECTION)

+ 2 - 1
cmake/Findchibios.cmake

@@ -72,7 +72,8 @@ find_file(STARTUP_MK startup_${MCU_STARTUP}.mk
 )
 get_filename_component(STARTUP_DIR ${STARTUP_MK} DIRECTORY)
 ParseMakefile(${STARTUP_MK})
-target_sources(qmk PUBLIC ${STARTUPSRC} ${STARTUPASM})
+target_sources(qmk PUBLIC ${STARTUPSRC})
+target_sources(qmk PUBLIC ${STARTUPASM})
 target_include_directories(qmk PUBLIC ${STARTUPINC})
 
 # board paths - we should just standardize these

+ 64 - 0
cmake/ParseHeader.cmake

@@ -0,0 +1,64 @@
+# Simple CMake utility to read variables from MK files
+# - Gets contents from given file (name or path)
+# - Parses the assignment statements
+# - Makes the same assignments in the PARENT_SCOPE
+
+if(POLICY CMP0007)
+    cmake_policy(SET CMP0007 NEW)
+endif()
+
+function(ParseHeader HeaderFile Prefix)
+    _ParseHeader(${HeaderFile} ${Prefix})
+endfunction()
+
+macro(_ParseHeader HeaderFile Prefix)
+    message(CHECK_START "Parsing Header")
+    list(APPEND CMAKE_MESSAGE_INDENT "  ")
+    message(STATUS "Reading \"${HeaderFile}\"")
+
+    file(READ "${HeaderFile}" FileContents)
+    string(REGEX REPLACE "/\\*.*\\*/" "" FileContents ${FileContents})
+    # replace the \ newlines with spaces
+    string(REGEX REPLACE "\\\\\r?\n *" " " FileContents ${FileContents})
+    # turn each line into an item in a list
+    string(REGEX REPLACE "\r?\n" ";" FileLines ${FileContents})
+    list(REMOVE_ITEM FileLines "")
+
+    foreach(line ${FileLines})
+        # remove comments from the ends of each line
+        string(REGEX REPLACE "//.*" "" line ${line})
+
+        # remove now-empty lines
+        if("${line}" STREQUAL "")
+            continue()
+        endif()
+
+        # try to process includes, if the file exists
+        if(line MATCHES "^#include \"(.+)\"")
+            set(INCLUDED_HEADER ${CMAKE_MATCH_1})
+            if(EXISTS ${INCLUDED_HEADER})
+                _ParseHeader("${INCLUDED_HEADER}" ${Prefix})
+            else()
+                message(STATUS "Could not read ${INCLUDED_HEADER}")
+            endif()
+            continue()
+        endif()
+        
+        # array
+        if(line MATCHES "#define ([A-Za-z0-9_]+) {(.*)}")
+            set(VARIABLE_NAME ${CMAKE_MATCH_1})
+            set(VARIABLE_VALUE ${CMAKE_MATCH_2})
+            set(${Prefix}${VARIABLE_NAME} ${VARIABLE_VALUE})
+        endif()
+
+        # regular variable
+        if(line MATCHES "#define ([A-Za-z0-9_]+) (.*)")
+            set(VARIABLE_NAME ${CMAKE_MATCH_1})
+            set(VARIABLE_VALUE ${CMAKE_MATCH_2})
+            set(${Prefix}${VARIABLE_NAME} ${VARIABLE_VALUE})
+        endif()
+    endforeach()
+
+    list(POP_BACK CMAKE_MESSAGE_INDENT)
+    message(CHECK_PASS "Complete")
+endmacro()

+ 49 - 23
cmake/ParseMakefile.cmake

@@ -8,65 +8,91 @@ if(POLICY CMP0007)
 endif()
 
 function(ParseMakefile MKFile)
-    _ParseMakefile(${MKFile})
+    _ParseMakefile(${MKFile} ${ARGN})
 endfunction()
 
 macro(_ParseMakefile MKFile)
-    message(VERBOSE "Parsing ${MKFile}")
+    message(CHECK_START "Parsing Makefile")
+    list(APPEND CMAKE_MESSAGE_INDENT "  ")
+    message(STATUS "Reading \"${MKFile}\"")
+
     file(READ "${MKFile}" FileContents)
+    # replace the \ newlines with spaces
     string(REGEX REPLACE "\\\\\r?\n *" " " FileContents ${FileContents})
-    string(REGEX REPLACE "(\r?\n)+" ";" FileLines ${FileContents})
+    # turn each line into an item in a list
+    string(REGEX REPLACE "\r?\n" ";" FileLines ${FileContents})
     list(REMOVE_ITEM FileLines "")
 
     foreach(line ${FileLines})
-        # if(line MATCHES "\\$\\((.+)\\)")
-        # set(MAKE_VARIABLE "${CMAKE_MATCH_1}")
-        # string(REPLACE "$(${MAKE_VARIABLE})" "${${MAKE_VARIABLE}}" line ${line})
-        # endif()
-        # message(STATUS "From: ${line}")
+        # remove comments from the ends of each line
         string(REGEX REPLACE "#.*" "" line ${line})
 
+        # remove now-empty lines
         if("${line}" STREQUAL "")
             continue()
         endif()
 
-        string(REGEX REPLACE "\\$\\(([^\\(\\)]+)\\)" "${CHIBIOS}" line ${line})
+        # try to process includes, if the file exists
+        if(line MATCHES "^-?include (.+)$")
+            set(MAKE_CHILD ${CMAKE_MATCH_1})
+            if(EXISTS ${MAKE_CHILD})
+                _ParseMakefile("${MAKE_CHILD}" ${ARGN})
+            else()
+                message(STATUS "Could not read ${MAKE_CHILD}")
+            endif()
+            continue()
+        endif()
 
-        # message(STATUS "To  : ${line}")
-        # if(line MATCHES "^include (.+)$")
-        # set(MAKE_CHILD ${CMAKE_MATCH_1})
-        # message(STATUS "Reading ${MAKE_CHILD}")
-        # _ParseMakefile("${MAKE_CHILD}")
-        # else()
+        # turn the assignment into a list with the first item being the variable name
         string(REPLACE "=" ";" line_split ${line})
         list(LENGTH line_split count)
 
         if(count LESS 2)
-            message(VERBOSE "Skipping ${line}")
+            message(STATUS "Skipping ${line}")
             continue()
         endif()
 
         list(GET line_split -1 value)
         string(STRIP ${value} value)
-        separate_arguments(value)
+        # separate_arguments(value)
+        # string(REPLACE " " ";" value ${value})
         list(REMOVE_AT line_split -1)
 
         foreach(var_name ${line_split})
             string(STRIP ${var_name} var_name)
+            # replace $(?) with the variable ? from cmake
+            if(value MATCHES "\\$\\(([^\\(\\)]+)\\)")
+                set(MAKE_VARIABLE "${CMAKE_MATCH_1}")
+                string(REPLACE "$(${MAKE_VARIABLE})" "${${MAKE_VARIABLE}}" value ${value})
+            endif()
+
+            # look for +, assuming it used to be +=
             if(${var_name} MATCHES "([^ \\+]+) *\\+")
-                message(VERBOSE "Appending '${CMAKE_MATCH_1}' with '${value}'")
-                set(${CMAKE_MATCH_1} ${${CMAKE_MATCH_1}} ${value} PARENT_SCOPE)
+                message(STATUS "Appending \"${CMAKE_MATCH_1}\" with \"${value}\"")
+                # read parent variable in local & append
+                set(LOCAL_${CMAKE_MATCH_1} ${CMAKE_MATCH_1})
+                # APPEND accepts spaces between values
+                list(APPEND LOCAL_${CMAKE_MATCH_1} ${value})
+                set(${CMAKE_MATCH_1} ${LOCAL_${CMAKE_MATCH_1}})
+                set(${CMAKE_MATCH_1} ${LOCAL_${CMAKE_MATCH_1}} PARENT_SCOPE)
             else()
+                # set needs ; between elements to be considered a list
+                string(REGEX REPLACE " +" ";" value ${value})
+                # try to find variable in cache and FORCE wtih INTERNAL if it exists
                 if(DEFINED CACHE${${var_name}})
-                    message(VERBOSE "Caching '${var_name}' to '${value}'")
+                    message(STATUS "Caching \"${var_name}\" to \"${value}\"")
+                    # set locally so replacement still work
+                    set(${var_name} ${value})
                     set(${var_name} ${value} CACHE INTERNAL "")
                 else()
-                    message(VERBOSE "Setting '${var_name}' to '${value}'")
+                    message(STATUS "Setting \"${var_name}\" to \"${value}\"")
+                    set(${var_name} ${value})
                     set(${var_name} ${value} PARENT_SCOPE)
                 endif()
             endif()
         endforeach()
-
-        # endif()
     endforeach()
+
+    list(POP_BACK CMAKE_MESSAGE_INDENT)
+    message(CHECK_PASS "Complete")
 endmacro()

+ 67 - 6
cmake/ProcessKeyboard.cmake

@@ -1,17 +1,78 @@
 include(ParseMakefile)
+include(Utils)
 
 macro(process_keyboard)
+    message(CHECK_START "Processing keyboard")
+    list(APPEND CMAKE_MESSAGE_INDENT "  ")
+
     validate_json(${QMK_KEYBOARD_FOLDER_ABS}/info.json keyboard QMK_KEYBOARD_INFO_JSON_STRING)
 
+    # process rules from info.json
+    file(READ ${CMAKE_SOURCE_DIR}/data/mappings/info_rules.hjson JSON_STRING)
+    string(JSON MAPPING_LENGTH LENGTH ${JSON_STRING})
+    math(EXPR MAX "${MAPPING_LENGTH} - 1")
+    foreach(IDX RANGE ${MAX})
+        string(JSON RULE_KEY MEMBER ${JSON_STRING} ${IDX})
+        # string(JSON INFO_KEY GET ${JSON_STRING} ${RULE_KEY} info_key)
+        json_get_with_default(INFO_KEY ${JSON_STRING} _ ${RULE_KEY} info_key)
+        string(REPLACE "." " " INFO_KEYS ${INFO_KEY})
+        string(JSON RULE_VALUE ERROR_VARIABLE RULE_KEY_NOT_FOUND GET ${QMK_KEYBOARD_INFO_JSON_STRING} ${INFO_KEYS})
+        if(${RULE_KEY_NOT_FOUND} STREQUAL "NOTFOUND")
+            json_get_with_default(VALUE_TYPE ${JSON_STRING} raw ${RULE_KEY} value_type)
+            if(${VALUE_TYPE} STREQUAL "list")
+                string(JSON NUM_VALUES LENGTH ${RULE_VALUE})
+                math(EXPR MAX "${NUM_VALUES} - 1")
+                foreach(IDX RANGE ${MAX})
+                    string(JSON VALUE GET ${RULE_VALUE} ${IDX})
+                    list(APPEND ${RULE_KEY} ${VALUE})
+                endforeach()
+                message(STATUS "Found rule '${INFO_KEY}': '${${RULE_KEY}}' assigned to '${RULE_KEY}'")
+            else()
+                set(${RULE_KEY} ${RULE_VALUE})
+                message(STATUS "Found rule '${INFO_KEY}': '${RULE_VALUE}' assigned to '${RULE_KEY}'")
+            endif()
+        endif()
+    endforeach()
+
+    # process definitions from info.json
+    file(READ ${CMAKE_SOURCE_DIR}/data/mappings/info_config.hjson JSON_STRING)
+    string(JSON MAPPING_LENGTH LENGTH ${JSON_STRING})
+    math(EXPR MAX "${MAPPING_LENGTH} - 1")
+    foreach(IDX RANGE ${MAX})
+        string(JSON CONFIG_KEY MEMBER ${JSON_STRING} ${IDX})
+        json_get_with_default(INFO_KEY ${JSON_STRING} _ ${CONFIG_KEY} info_key)
+        string(REPLACE "." ";" INFO_KEYS ${INFO_KEY})
+        # string(JSON CONFIG_VALUE ERROR_VARIABLE CONFIG_KEY_NOT_FOUND GET ${QMK_KEYBOARD_INFO_JSON_STRING} ${INFO_KEYS})
+        json_get_with_default(CONFIG_VALUE ${QMK_KEYBOARD_INFO_JSON_STRING} NOTFOUND ${INFO_KEYS})
+        if(NOT CONFIG_VALUE STREQUAL "NOTFOUND")
+            set(${CONFIG_KEY} ${CONFIG_VALUE})
+            json_get_with_default(VALUE_TYPE ${JSON_STRING} raw ${CONFIG_KEY} value_type)
+            if(${VALUE_TYPE} STREQUAL "str")
+                add_compile_definitions(${CONFIG_KEY}="${CONFIG_VALUE}")
+                message(STATUS "Found definition '${INFO_KEY}': '\"${CONFIG_VALUE}\"' assigned to '${CONFIG_KEY}'")
+            elseif(${VALUE_TYPE} STREQUAL "bcd_version")
+                string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" VERSION_MATCH ${CONFIG_VALUE})
+                set(VERSION_MAJOR ${CMAKE_MATCH_1})
+                set(VERSION_MINOR ${CMAKE_MATCH_2})
+                set(VERSION_PATCH ${CMAKE_MATCH_3})
+                math(EXPR BCD_VERSION "${VERSION_MAJOR} * 10000 + ${VERSION_MINOR} * 100 + ${VERSION_PATCH}" OUTPUT_FORMAT HEXADECIMAL)
+                add_compile_definitions(${CONFIG_KEY}=${BCD_VERSION})
+                message(STATUS "Found definition '${INFO_KEY}': '${BCD_VERSION}' assigned to '${CONFIG_KEY}'")
+            else()
+                add_compile_definitions(${CONFIG_KEY}=${CONFIG_VALUE})
+                message(STATUS "Found definition '${INFO_KEY}': '${CONFIG_VALUE}' assigned to '${CONFIG_KEY}'")
+            endif()
+        endif()
+    endforeach()
+
     string(JSON KEYBOARD_NAME GET ${QMK_KEYBOARD_INFO_JSON_STRING} keyboard_name)
     string(JSON MANUFACTURER GET ${QMK_KEYBOARD_INFO_JSON_STRING} manufacturer)
     string(JSON URL GET ${QMK_KEYBOARD_INFO_JSON_STRING} url)
     string(JSON QMK_MCU GET ${QMK_KEYBOARD_INFO_JSON_STRING} processor)
-    string(JSON VENDOR_ID GET ${QMK_KEYBOARD_INFO_JSON_STRING} usb vid)
-    string(JSON PRODUCT_ID GET ${QMK_KEYBOARD_INFO_JSON_STRING} usb pid)
-    string(JSON DEVICE_VER GET ${QMK_KEYBOARD_INFO_JSON_STRING} usb device_version)
-    string(JSON DIODE_DIRECTION ERROR_VARIABLE _ GET ${QMK_KEYBOARD_INFO_JSON_STRING} diode_direction)
-    string(JSON BOOTLOADER ERROR_VARIABLE _ GET ${QMK_KEYBOARD_INFO_JSON_STRING} bootloader)
 
-    ParseMakefile(${QMK_KEYBOARD_FOLDER_ABS}/rules.mk)  
+    list(POP_BACK CMAKE_MESSAGE_INDENT)
+    message(CHECK_PASS "info.json validated and loaded")
+
+
+    ParseMakefile(${QMK_KEYBOARD_FOLDER_ABS}/rules.mk)
 endmacro()

+ 15 - 11
cmake/ResolveKeyboard.cmake

@@ -1,3 +1,5 @@
+include(Utils)
+
 function(resolve_keyboard KEYBOARD KEYBOAD_FOLDER_ABS_STR)
     message(VERBOSE "Resolving ${KEYBOARD}")
     if(EXISTS "${CMAKE_SOURCE_DIR}/keyboards/${KEYBOARD}")
@@ -42,17 +44,19 @@ function(resolve_keyboard KEYBOARD KEYBOAD_FOLDER_ABS_STR)
 endfunction()
 
 function(resolve_config_h KEYBOARD_FOLDER_ABS CONFIG_H_STR)
+    set(${CONFIG_H_STR} PARENT_SCOPE)
     if(${IS_KEYBOARDS_FOLDER})
         file(RELATIVE_PATH RELATIVE_KEYBOARD_FOLDER ${QMK_KEYBOARDS_FOLDER} ${KEYBOARD_FOLDER_ABS})
         # get the deepest config.h
         while(NOT ${RELATIVE_KEYBOARD_FOLDER} STREQUAL "")  
             if(EXISTS "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/config.h")
-                set(${CONFIG_H_STR} "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/config.h" PARENT_SCOPE)
-                return()
+                parent_list(PREPEND ${CONFIG_H_STR} "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/config.h")
+                # set(${CONFIG_H_STR} "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/config.h" PARENT_SCOPE)
+                # return()
             endif()
             get_filename_component(RELATIVE_KEYBOARD_FOLDER ${RELATIVE_KEYBOARD_FOLDER} DIRECTORY)
         endwhile()
-        message(FATAL_ERROR "Could not find config.h in ${KEYBOARD_FOLDER_ABS}")
+        # message(FATAL_ERROR "Could not find config.h in ${KEYBOARD_FOLDER_ABS}")
     else()
         if(EXISTS "${KEYBOARD_FOLDER_ABS}/config.h")
             set(${CONFIG_H_STR} "${KEYBOARD_FOLDER_ABS}/config.h" PARENT_SCOPE)
@@ -112,26 +116,26 @@ function(resolve_keymap_c KEYBOARD_FOLDER_ABS KEYMAP_FOLDER KEYMAP_C_STR)
         endif()
     endif()
 
-    string(JSON COMMUNITY_LAYOUTS ERROR_VARIABLE NO_COMMUNITY_LAYOUTS GET ${QMK_KEYBOARD_INFO_JSON_STRING} community_layouts)
+    # string(JSON COMMUNITY_LAYOUTS ERROR_VARIABLE NO_COMMUNITY_LAYOUTS GET ${QMK_KEYBOARD_INFO_JSON_STRING} community_layouts)
 
-    if(${NO_COMMUNITY_LAYOUTS} STREQUAL "NOTFOUND")
-        string(JSON NUM_LAYOUTS LENGTH ${COMMUNITY_LAYOUTS})
-        math(EXPR MAX "${NUM_LAYOUTS} - 1")
-        foreach(IDX RANGE ${MAX})
-            string(JSON LAYOUT GET ${COMMUNITY_LAYOUTS} ${IDX})
+    # if(${NO_COMMUNITY_LAYOUTS} STREQUAL "NOTFOUND")
+        # string(JSON NUM_LAYOUTS LENGTH ${COMMUNITY_LAYOUTS})
+        # math(EXPR MAX "${NUM_LAYOUTS} - 1")
+        foreach(LAYOUT ${LAYOUTS})
+        # foreach(IDX RANGE ${MAX})
+            # string(JSON LAYOUT GET ${COMMUNITY_LAYOUTS} ${IDX})
             if(EXISTS "${CMAKE_SOURCE_DIR}/layouts/community/${LAYOUT}/${KEYMAP_FOLDER}/keymap.c")
                 set(${KEYMAP_C_STR} "${CMAKE_SOURCE_DIR}/layouts/community/${LAYOUT}/${KEYMAP_FOLDER}/keymap.c" PARENT_SCOPE)
                 return()
             endif()
         endforeach()
-    endif()
+    # endif()
     message(FATAL_ERROR "Could not resolve keymap '${KEYMAP_FOLDER}'")
 endfunction()
 
 function(resolve_keyboard_includes KEYBOARD_FOLDER_ABS)
     if(${IS_KEYBOARDS_FOLDER})
         file(RELATIVE_PATH RELATIVE_KEYBOARD_FOLDER ${QMK_KEYBOARDS_FOLDER} ${KEYBOARD_FOLDER_ABS})
-        # get the deepest config.h
         while(NOT ${RELATIVE_KEYBOARD_FOLDER} STREQUAL "")  
             target_include_directories(qmk PUBLIC "${CMAKE_SOURCE_DIR}/keyboards/${RELATIVE_KEYBOARD_FOLDER}")
             get_filename_component(RELATIVE_KEYBOARD_FOLDER ${RELATIVE_KEYBOARD_FOLDER} DIRECTORY)

+ 25 - 0
cmake/Utils.cmake

@@ -0,0 +1,25 @@
+macro(json_get_with_default KEY_STR JSON_STR DEFAULT)
+    # message(STATUS "Getting ${ARGN} for ${KEY_STR}")
+    string(JSON ${KEY_STR} ERROR_VARIABLE JSON_ERROR GET ${JSON_STR} ${ARGN})
+    if(NOT ${JSON_ERROR} STREQUAL "NOTFOUND")
+        set(${KEY_STR} ${DEFAULT})
+    endif()
+endmacro()
+
+macro(json_get KEY_STR JSON_STR)
+    # message(STATUS "Getting ${ARGN} for ${KEY_STR}")
+    string(JSON ${KEY_STR} ERROR_VARIABLE JSON_ERROR GET ${JSON_STR} ${ARGN})
+    if(NOT ${JSON_ERROR} STREQUAL "NOTFOUND")
+        unset(${KEY_STR})
+    endif()
+endmacro()
+
+macro(parent_list ACTION LIST_STR)
+    set(ARGS ${ARGN})
+    string(REPLACE ";" " " ARGS ${ARGS})
+    set(LOCAL_LIST ${${LIST_STR}})
+    list(${ACTION} LOCAL_LIST ${ARGS})
+    # set in current scope too
+    set(${LIST_STR} ${LOCAL_LIST})
+    set(${LIST_STR} ${LOCAL_LIST} PARENT_SCOPE)
+endmacro()

+ 1 - 1
data/mappings/info_config.hjson

@@ -129,7 +129,7 @@
     "TAPPING_FORCE_HOLD": {"info_key": "tapping.force_hold", "value_type": "bool", "deprecated": true},
     "TAPPING_FORCE_HOLD_PER_KEY": {"info_key": "tapping.force_hold_per_key", "value_type": "bool", "deprecated": true},
     "IGNORE_MOD_TAP_INTERRUPT": {"info_key": "_deprecated.ignore_mod_tap_interrupt", "value_type": "bool", "deprecated": true},
-    "IGNORE_MOD_TAP_INTERRUPT_PER_KEY": {"info_key": "_invalid.ignore_mod_tap_interrupt_per_key", "invalid": true}
+    "IGNORE_MOD_TAP_INTERRUPT_PER_KEY": {"info_key": "_invalid.ignore_mod_tap_interrupt_per_key", "invalid": true},
 
     // USB params, need to mark as failure when specified in config.h, rather than deprecated
     "PRODUCT_ID": {"info_key": "usb.pid", "value_type": "hex", "deprecated": true, "replace_with": "`usb.pid` in info.json"},