kconfig: Prune kconfig files that don't match the ARCH or BOARD

When Kconfiglib was introduced it caused a significant performance
issue. This patch uses pruning to mitigate the performance issue.

The pruning exploits the fact that before the Kconfig database is
parsed we already know what ARCH and BOARD has been selected. So in
theory we could prune away all Kconfig sources that are not related to
the current ARCH or BOARD. In practice, it is only the Kconfig sources
in zephyr/arch/$ARCH and zephyr/board/$ARCH/ that are easy to prune.

Still, that is quite a few Kconfig sources. For qemu_x86 this patch
reduced the number of parsed Kconfig source files from 632 to
272. This pruning resulted in a incremental reconfiguration (time
cmake ..) speedup of 21% (0.56s to 0.46) and a clean build speedup of
4% (Using board qemu_x86 and sample hello_world).

Furthermore, it should be easier to maintain ARCH's and BOARD's
out-of-tree since the user now has a mechanism to redirect where
Kconfig sources are found. But this has not been explored.

Signed-off-by: Sebastian Bøe <sebastian.boe@nordicsemi.no>
diff --git a/Kconfig.zephyr b/Kconfig.zephyr
index 7a5bfee..c57c0d8 100644
--- a/Kconfig.zephyr
+++ b/Kconfig.zephyr
@@ -10,6 +10,14 @@
 	string
 	option env="KERNELVERSION"
 
+config ENV_VAR_SYM_BOARD_DIR
+	string
+	option env="ENV_VAR_BOARD_DIR"
+
+config ENV_VAR_SYM_ARCH
+	string
+	option env="ENV_VAR_ARCH"
+
 source "arch/Kconfig"
 
 source "kernel/Kconfig"
@@ -37,5 +45,5 @@
 # Board defaults should be parsed after SoC defaults
 # because board usually overrides SoC values.
 #
-source "arch/*/soc/*/Kconfig.defconfig"
-source "boards/*/*/Kconfig.defconfig"
+source "arch/$ENV_VAR_SYM_ARCH/soc/*/Kconfig.defconfig"
+source "$ENV_VAR_SYM_BOARD_DIR/Kconfig.defconfig"
diff --git a/arch/Kconfig b/arch/Kconfig
index 51a5886..4c49d84 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -298,6 +298,6 @@
 	  arch/<arch>/soc/<family>/<series>
 
 
-source "arch/*/Kconfig"
+source "arch/$ENV_VAR_SYM_ARCH/Kconfig"
 
 source "boards/Kconfig"
diff --git a/boards/Kconfig b/boards/Kconfig
index 08533c5..e4391da 100644
--- a/boards/Kconfig
+++ b/boards/Kconfig
@@ -16,10 +16,10 @@
 
 choice
 prompt "Board Selection"
-source "boards/*/*/Kconfig.board"
+source "$ENV_VAR_SYM_BOARD_DIR/Kconfig.board"
 endchoice
 
 
 menu "Board Options"
-source "boards/*/*/Kconfig"
+source "$ENV_VAR_SYM_BOARD_DIR/Kconfig"
 endmenu
diff --git a/cmake/kconfig.cmake b/cmake/kconfig.cmake
index 20fbf78..e1f2f1b 100644
--- a/cmake/kconfig.cmake
+++ b/cmake/kconfig.cmake
@@ -33,6 +33,11 @@
 set(COMMAND_FOR_oldconfig  ${KCONFIG_CONF} --oldconfig    ${KCONFIG_ROOT})
 set(COMMAND_FOR_xconfig    qconf                          ${KCONFIG_ROOT})
 
+# Set environment variables so that Kconfig can prune Kconfig source
+# files for other architectures
+set(ENV{ENV_VAR_ARCH}         ${ARCH})
+set(ENV{ENV_VAR_BOARD_DIR}    ${BOARD_DIR})
+
 foreach(kconfig_target ${kconfig_target_list})
   if (NOT WIN32)
     add_custom_target(
@@ -41,6 +46,8 @@
       srctree=${PROJECT_SOURCE_DIR}
       KERNELVERSION=${PROJECT_VERSION}
       KCONFIG_CONFIG=${DOTCONFIG}
+      ENV_VAR_ARCH=$ENV{ENV_VAR_ARCH}
+      ENV_VAR_BOARD_DIR=$ENV{ENV_VAR_BOARD_DIR}
       ${COMMAND_FOR_${kconfig_target}}
       WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig
       USES_TERMINAL