targets.cmake 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #
  2. # Get target from single sdkconfig file
  3. #
  4. function(__target_from_config config target_out file_out)
  5. set(${target_out} NOTFOUND PARENT_SCOPE)
  6. set(${file_out} NOTFOUND PARENT_SCOPE)
  7. if(NOT EXISTS "${config}")
  8. return()
  9. endif()
  10. file(STRINGS "${config}" lines)
  11. foreach(line ${lines})
  12. if(NOT "${line}" MATCHES "^CONFIG_IDF_TARGET=\"[^\"]+\"$")
  13. continue()
  14. endif()
  15. string(REGEX REPLACE "CONFIG_IDF_TARGET=\"([^\"]+)\"" "\\1" target "${line}")
  16. set(${target_out} ${target} PARENT_SCOPE)
  17. set(${file_out} ${config} PARENT_SCOPE)
  18. return()
  19. endforeach()
  20. endfunction()
  21. #
  22. # Get target from list of sdkconfig files
  23. #
  24. function(__target_from_configs configs target_out file_out)
  25. set(target NOTFOUND)
  26. set(file NOTFOUND)
  27. foreach(config ${configs})
  28. message(DEBUG "Searching for target in '${config}'")
  29. get_filename_component(config "${config}" ABSOLUTE)
  30. __target_from_config("${config}" target file)
  31. if(target)
  32. break()
  33. endif()
  34. endforeach()
  35. set(${target_out} ${target} PARENT_SCOPE)
  36. set(${file_out} ${file} PARENT_SCOPE)
  37. endfunction()
  38. #
  39. # Search for target in config files in the following order.
  40. # SDKCONFIG cmake var, default sdkconfig, SDKCONFIG_DEFAULTS cmake var
  41. # if non-empty or SDKCONFIG_DEFAULTS env var if non-empty or
  42. # sdkconfig.defaults.
  43. #
  44. function(__target_guess target_out file_out)
  45. # Select sdkconfig_defaults to look for target
  46. if(SDKCONFIG_DEFAULTS)
  47. set(defaults "${SDKCONFIG_DEFAULTS}")
  48. elseif(DEFINED ENV{SDKCONFIG_DEFAULTS})
  49. set(defaults "$ENV{SDKCONFIG_DEFAULTS}")
  50. endif()
  51. if(NOT defaults)
  52. set(defaults "${CMAKE_SOURCE_DIR}/sdkconfig.defaults")
  53. endif()
  54. set(configs "${SDKCONFIG}" "${CMAKE_SOURCE_DIR}/sdkconfig" "${defaults}")
  55. message(DEBUG "Searching for target in '${configs}'")
  56. __target_from_configs("${configs}" target file)
  57. set(${target_out} ${target} PARENT_SCOPE)
  58. set(${file_out} ${file} PARENT_SCOPE)
  59. endfunction()
  60. #
  61. # Set the target used for the standard project build.
  62. #
  63. macro(__target_init config_file)
  64. # Input is IDF_TARGET environement variable
  65. set(env_idf_target $ENV{IDF_TARGET})
  66. if(NOT env_idf_target)
  67. # IDF_TARGET not set in environment, see if it is set in cache
  68. if(IDF_TARGET)
  69. set(env_idf_target ${IDF_TARGET})
  70. else()
  71. # Try to guess IDF_TARGET from sdkconfig files while honoring
  72. # SDKCONFIG and SDKCONFIG_DEFAULTS values
  73. __target_guess(env_idf_target where)
  74. if(env_idf_target)
  75. message(STATUS "IDF_TARGET is not set, guessed '${env_idf_target}' from sdkconfig '${where}'")
  76. else()
  77. set(env_idf_target esp32)
  78. message(STATUS "IDF_TARGET not set, using default target: ${env_idf_target}")
  79. endif()
  80. endif()
  81. endif()
  82. # Check if selected target is consistent with CMake cache
  83. if(DEFINED CACHE{IDF_TARGET})
  84. if(NOT $CACHE{IDF_TARGET} STREQUAL ${env_idf_target})
  85. message(FATAL_ERROR " IDF_TARGET '$CACHE{IDF_TARGET}' in CMake"
  86. " cache does not match currently selected IDF_TARGET '${env_idf_target}'."
  87. " To change the target, clear the build directory and sdkconfig file,"
  88. " and build the project again.")
  89. endif()
  90. endif()
  91. # Check if selected target is consistent with sdkconfig
  92. __target_from_config("${config_file}" sdkconfig_target where)
  93. if(sdkconfig_target)
  94. if(NOT ${sdkconfig_target} STREQUAL ${env_idf_target})
  95. message(FATAL_ERROR " Target '${sdkconfig_target}' in sdkconfig '${where}'"
  96. " does not match currently selected IDF_TARGET '${IDF_TARGET}'."
  97. " To change the target, clear the build directory and sdkconfig file,"
  98. " and build the project again.")
  99. endif()
  100. endif()
  101. # IDF_TARGET will be used by component manager, make sure it is set
  102. set(ENV{IDF_TARGET} ${env_idf_target})
  103. # Finally, set IDF_TARGET in cache
  104. set(IDF_TARGET ${env_idf_target} CACHE STRING "IDF Build Target")
  105. endmacro()
  106. #
  107. # Used by the project CMake file to set the toolchain before project() call.
  108. #
  109. macro(__target_set_toolchain)
  110. idf_build_get_property(idf_path IDF_PATH)
  111. # See if Clang toolchain should be used
  112. set(env_idf_toolchain $ENV{IDF_TOOLCHAIN})
  113. if(NOT env_idf_toolchain)
  114. # IDF_TOOLCHAIN not set in environment, see if it is set in cache
  115. if(IDF_TOOLCHAIN)
  116. set(env_idf_toolchain ${IDF_TOOLCHAIN})
  117. else()
  118. set(env_idf_toolchain gcc)
  119. endif()
  120. elseif(DEFINED CACHE{IDF_TOOLCHAIN})
  121. # IDF_TOOLCHAIN set both in environment and in cache, must be the same
  122. if(NOT $CACHE{IDF_TOOLCHAIN} STREQUAL ${env_idf_toolchain})
  123. message(FATAL_ERROR " IDF_TOOLCHAIN '$CACHE{IDF_TOOLCHAIN}' in CMake cache does not match"
  124. " currently selected IDF_TOOLCHAIN '${env_idf_toolchain}'. To change the toolchain, clear"
  125. " the build directory and sdkconfig file, and build the project again.")
  126. endif()
  127. endif()
  128. # Finally, set IDF_TOOLCHAIN in cache
  129. set(IDF_TOOLCHAIN ${env_idf_toolchain} CACHE STRING "IDF Build Toolchain Type")
  130. if(${env_idf_toolchain} STREQUAL "clang")
  131. set(toolchain_type "clang-")
  132. endif()
  133. # Check if selected target is consistent with toolchain file in CMake cache
  134. if(DEFINED CMAKE_TOOLCHAIN_FILE)
  135. string(FIND "${CMAKE_TOOLCHAIN_FILE}" "-${toolchain_type}${IDF_TARGET}.cmake" found)
  136. if(${found} EQUAL -1)
  137. get_filename_component(toolchain "${CMAKE_TOOLCHAIN_FILE}" NAME_WE)
  138. message(FATAL_ERROR " CMAKE_TOOLCHAIN_FILE '${toolchain}'"
  139. " does not match currently selected IDF_TARGET '${IDF_TARGET}'."
  140. " To change the target, clear the build directory and sdkconfig file,"
  141. " and build the project again.")
  142. endif()
  143. endif()
  144. # First try to load the toolchain file from the tools/cmake/directory of IDF
  145. set(toolchain_file_global ${idf_path}/tools/cmake/toolchain-${toolchain_type}${IDF_TARGET}.cmake)
  146. if(EXISTS ${toolchain_file_global})
  147. set(CMAKE_TOOLCHAIN_FILE ${toolchain_file_global})
  148. else()
  149. message(FATAL_ERROR "Toolchain file ${toolchain_file_global} not found")
  150. endif()
  151. endmacro()