diff --git a/cmake/nuttx_kconfig.cmake b/cmake/nuttx_kconfig.cmake index 923b2a03d67..f9364ea9a2c 100644 --- a/cmake/nuttx_kconfig.cmake +++ b/cmake/nuttx_kconfig.cmake @@ -122,59 +122,77 @@ function(nuttx_generate_kconfig) REQUIRED ARGN ${ARGN}) + + # Exit early if: - The current directory does NOT contain a CMakeLists.txt + # (not an app dir), OR - The output Kconfig already exists in the apps binary + # directory if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt" OR EXISTS "${NUTTX_APPS_BINDIR}/Kconfig") return() endif() + # Determine output Kconfig file path set(KCONFIG_OUTPUT_FILE) if(MENUDESC) string(REPLACE "/" "_" KCONFIG_PREFIX ${CMAKE_CURRENT_LIST_DIR}) if(WIN32) + # On Windows, also replace drive letter separators like "C:". string(REPLACE ":" "_" KCONFIG_PREFIX ${KCONFIG_PREFIX}) endif() + + # Output Kconfig file path: /_Kconfig string(APPEND KCONFIG_OUTPUT_FILE ${NUTTX_APPS_BINDIR} "/" ${KCONFIG_PREFIX} "_Kconfig") + + # Start a menu block file(WRITE ${KCONFIG_OUTPUT_FILE} "menu \"${MENUDESC}\"\n") else() + # Without MENUDESC, generate the root Kconfig file. set(KCONFIG_OUTPUT_FILE ${NUTTX_APPS_BINDIR}/Kconfig) endif() - file( - GLOB SUB_CMAKESCRIPTS - LIST_DIRECTORIES false - ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/*/CMakeLists.txt) + # Collect valid directories that contain Kconfig or CMakeLists + set(DIR_LIST) + foreach(external_dir ${EXTERNAL_DIRECTORIES}) + get_filename_component(external_reldir "${external_dir}" REALPATH) + if(IS_DIRECTORY ${external_reldir}) + list(APPEND DIR_LIST "${external_reldir}") + endif() + endforeach() - if(NOT MENUDESC) - set(EXTERNAL_CMAKESCRIPTS) - foreach(external_dir ${EXTERNAL_DIRECTORIES}) - if(EXISTS ${external_dir}/CMakeLists.txt) - list(APPEND EXTERNAL_CMAKESCRIPTS "${external_dir}/CMakeLists.txt") + # Get all entries directly under the current app directory + file(GLOB FIRST_LEVEL_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/*") + + # Add directories that contain either CMakeLists.txt or Kconfig + foreach(dir IN LISTS FIRST_LEVEL_DIRS) + if(IS_DIRECTORY "${dir}") + if(EXISTS "${dir}/CMakeLists.txt" OR EXISTS "${dir}/Kconfig") + list(APPEND DIR_LIST "${dir}") endif() - endforeach() - endif() + endif() + endforeach() - # we need to recursively generate the Kconfig menus of multi-level - # directories. - # - # when generating a Kconfig file for the current directory, it should include - # and invoke all the Kconfig files gathered from its subdirectories. - foreach(SUB_CMAKESCRIPT ${SUB_CMAKESCRIPTS} ${EXTERNAL_CMAKESCRIPTS}) - string(REPLACE "CMakeLists.txt" "Kconfig" SUB_KCONFIG ${SUB_CMAKESCRIPT}) + # Generate "source" entries for each discovered Kconfig + foreach(dir ${DIR_LIST}) + set(SUB_KCONFIG "${dir}/Kconfig") string(REPLACE "/" "_" MENUCONFIG ${SUB_KCONFIG}) if(WIN32) string(REPLACE ":" "_" MENUCONFIG ${MENUCONFIG}) endif() - # check whether the subdirectory will include a generated Kconfig file. + + # Source Kconfig from the corresponding apps binary directory if present if(EXISTS ${NUTTX_APPS_BINDIR}/${MENUCONFIG}) file(APPEND ${KCONFIG_OUTPUT_FILE} "source \"${NUTTX_APPS_BINDIR}/${MENUCONFIG}\"\n") endif() + + # Source Kconfig from the directory if present if(EXISTS ${SUB_KCONFIG}) file(APPEND ${KCONFIG_OUTPUT_FILE} "source \"${SUB_KCONFIG}\"\n") endif() endforeach() + # Close the menu block if MENUDESC was used if(MENUDESC) file(APPEND ${KCONFIG_OUTPUT_FILE} "endmenu # ${MENUDESC}\n") endif()