project.cmake 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. # Designed to be included from an IDF app's CMakeLists.txt file
  2. #
  3. cmake_minimum_required(VERSION 3.5)
  4. include(${CMAKE_CURRENT_LIST_DIR}/idf_functions.cmake)
  5. # Set the path of idf.py.
  6. set(IDFTOOL ${PYTHON} "${IDF_PATH}/tools/idf.py")
  7. # Trick to temporarily redefine project(). When functions are overriden in CMake, the originals can still be accessed
  8. # using an underscore prefixed function of the same name. The following lines make sure that __project calls
  9. # the original project(). See https://cmake.org/pipermail/cmake/2015-October/061751.html.
  10. function(project)
  11. endfunction()
  12. function(_project)
  13. endfunction()
  14. macro(project name)
  15. # Bridge existing documented variable names with library namespaced
  16. # variables in order for old projects to work.
  17. if(COMPONENT_DIRS)
  18. spaces2list(COMPONENT_DIRS)
  19. foreach(component_dir ${COMPONENT_DIRS})
  20. get_filename_component(component_dir ${component_dir} ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
  21. list(APPEND IDF_COMPONENT_DIRS "${component_dir}")
  22. endforeach()
  23. endif()
  24. if(NOT MAIN_SRCS)
  25. list(APPEND IDF_EXTRA_COMPONENT_DIRS "${CMAKE_SOURCE_DIR}/main")
  26. endif()
  27. list(APPEND IDF_EXTRA_COMPONENT_DIRS "${CMAKE_SOURCE_DIR}/components")
  28. if(EXTRA_COMPONENT_DIRS)
  29. spaces2list(EXTRA_COMPONENT_DIRS)
  30. foreach(component_dir ${EXTRA_COMPONENT_DIRS})
  31. get_filename_component(component_dir ${component_dir} ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
  32. list(APPEND IDF_EXTRA_COMPONENT_DIRS "${component_dir}")
  33. endforeach()
  34. endif()
  35. if(COMPONENTS)
  36. set(IDF_COMPONENTS "${COMPONENTS}")
  37. endif()
  38. if(COMPONENT_REQUIRES_COMMON)
  39. set(IDF_COMPONENT_REQUIRES_COMMON "${COMPONENT_REQUIRES_COMMON}")
  40. endif()
  41. if(EXCLUDE_COMPONENTS)
  42. set(IDF_EXCLUDE_COMPONENTS "${COMPONENT_EXCLUDES}")
  43. endif()
  44. if(TESTS_ALL EQUAL 1 OR TEST_COMPONENTS)
  45. set(IDF_BUILD_TESTS 1)
  46. endif()
  47. if(TEST_COMPONENTS)
  48. set(IDF_TEST_COMPONENTS "${TEST_COMPONENTS}")
  49. endif()
  50. if(TEST_EXCLUDE_COMPONENTS)
  51. set(IDF_TEST_EXCLUDE_COMPONENTS "${TEST_EXCLUDE_COMPONENTS}")
  52. endif()
  53. if(NOT SDKCONFIG_DEFAULTS)
  54. if(EXISTS ${CMAKE_SOURCE_DIR}/sdkconfig.defaults)
  55. set(IDF_SDKCONFIG_DEFAULTS ${CMAKE_SOURCE_DIR}/sdkconfig.defaults)
  56. endif()
  57. else()
  58. set(IDF_SDKCONFIG_DEFAULTS ${SDKCONFIG_DEFAULTS})
  59. endif()
  60. # Set build variables
  61. idf_set_variables()
  62. # Now the configuration is loaded, set the toolchain appropriately
  63. idf_set_toolchain()
  64. # Enable ccache if it's on the path
  65. if(NOT CCACHE_DISABLE)
  66. find_program(CCACHE_FOUND ccache)
  67. if(CCACHE_FOUND)
  68. message(STATUS "ccache will be used for faster builds")
  69. set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
  70. endif()
  71. endif()
  72. __project(${name} C CXX ASM)
  73. set(IDF_BUILD_ARTIFACTS ON)
  74. set(IDF_PROJECT_EXECUTABLE ${CMAKE_PROJECT_NAME}.elf)
  75. set(IDF_BUILD_ARTIFACTS_DIR ${CMAKE_BINARY_DIR})
  76. if(MAIN_SRCS)
  77. spaces2list(MAIN_SRCS)
  78. add_executable(${IDF_PROJECT_EXECUTABLE} ${MAIN_SRCS})
  79. else()
  80. # Create a dummy file to work around CMake requirement of having a source
  81. # file while adding an executable
  82. add_executable(${IDF_PROJECT_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/dummy_main_src.c")
  83. add_custom_command(OUTPUT dummy_main_src.c
  84. COMMAND ${CMAKE_COMMAND} -E touch dummy_main_src.c
  85. WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
  86. VERBATIM)
  87. add_custom_target(dummy_main_src DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/dummy_main_src.c)
  88. add_dependencies(${IDF_PROJECT_EXECUTABLE} dummy_main_src)
  89. endif()
  90. set(mapfile "${CMAKE_PROJECT_NAME}.map")
  91. target_link_libraries(${IDF_PROJECT_EXECUTABLE} "-Wl,--cref -Wl,--Map=${mapfile}")
  92. set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY
  93. ADDITIONAL_MAKE_CLEAN_FILES
  94. "${CMAKE_CURRENT_BINARY_DIR}/${mapfile}")
  95. # Add size targets, depend on map file, run idf_size.py
  96. add_custom_target(size
  97. DEPENDS ${exe_target}
  98. COMMAND ${PYTHON} ${IDF_PATH}/tools/idf_size.py ${mapfile}
  99. )
  100. add_custom_target(size-files
  101. DEPENDS ${exe_target}
  102. COMMAND ${PYTHON} ${IDF_PATH}/tools/idf_size.py --files ${mapfile}
  103. )
  104. add_custom_target(size-components
  105. DEPENDS ${exe_target}
  106. COMMAND ${PYTHON} ${IDF_PATH}/tools/idf_size.py --archives ${mapfile}
  107. )
  108. # Since components can import third-party libraries, the original definition of project() should be restored
  109. # before the call to add components to the build.
  110. function(project)
  111. set(project_ARGV ARGV)
  112. __project(${${project_ARGV}})
  113. # Set the variables that project() normally sets, documented in the
  114. # command's docs.
  115. #
  116. # https://cmake.org/cmake/help/v3.5/command/project.html
  117. #
  118. # There is some nuance when it comes to setting version variables in terms of whether
  119. # CMP0048 is set to OLD or NEW. However, the proper behavior should have bee already handled by the original
  120. # project call, and we're just echoing the values those variables were set to.
  121. set(PROJECT_NAME "${PROJECT_NAME}" PARENT_SCOPE)
  122. set(PROJECT_BINARY_DIR "${PROJECT_BINARY_DIR}" PARENT_SCOPE)
  123. set(PROJECT_SOURCE_DIR "${PROJECT_SOURCE_DIR}" PARENT_SCOPE)
  124. set(PROJECT_VERSION "${PROJECT_VERSION}" PARENT_SCOPE)
  125. set(PROJECT_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}" PARENT_SCOPE)
  126. set(PROJECT_VERSION_MINOR "${PROJECT_VERSION_MINOR}" PARENT_SCOPE)
  127. set(PROJECT_VERSION_PATCH "${PROJECT_VERSION_PATCH}" PARENT_SCOPE)
  128. set(PROJECT_VERSION_TWEAK "${PROJECT_VERSION_TWEAK}" PARENT_SCOPE)
  129. set(${PROJECT_NAME}_BINARY_DIR "${${PROJECT_NAME}_BINARY_DIR}" PARENT_SCOPE)
  130. set(${PROJECT_NAME}_SOURCE_DIR "${${PROJECT_NAME}_SOURCE_DIR}" PARENT_SCOPE)
  131. set(${PROJECT_NAME}_VERSION "${${PROJECT_NAME}_VERSION}" PARENT_SCOPE)
  132. set(${PROJECT_NAME}_VERSION_MAJOR "${${PROJECT_NAME}_VERSION_MAJOR}" PARENT_SCOPE)
  133. set(${PROJECT_NAME}_VERSION_MINOR "${${PROJECT_NAME}_VERSION_MINOR}" PARENT_SCOPE)
  134. set(${PROJECT_NAME}_VERSION_PATCH "${${PROJECT_NAME}_VERSION_PATCH}" PARENT_SCOPE)
  135. set(${PROJECT_NAME}_VERSION_TWEAK "${${PROJECT_NAME}_VERSION_TWEAK}" PARENT_SCOPE)
  136. endfunction()
  137. # Finally, add the rest of the components to the build.
  138. idf_import_components(components $ENV{IDF_PATH} esp-idf)
  139. idf_link_components(${IDF_PROJECT_EXECUTABLE} "${components}")
  140. endmacro()