eclipse_cdt4_generator_amendment.cmake 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. # SPDX-License-Identifier: Apache-2.0
  2. # cmake: Eclipse CDT4 generator amendment
  3. #
  4. #1. The generator handles just the COMPILE_DEFINITIONS.
  5. # (See: __ZEPHYR_SUPERVISOR__)
  6. # For the defines in INTERFACE_COMPILE_DEFINITIONS
  7. # a special handling is necessary.
  8. #
  9. # Solution:
  10. # The amendment function generates a macro header file
  11. # ${CMAKE_BINARY_DIR}/zephyr/include/generated/cmake_intdef.h
  12. # based on INTERFACE_COMPILE_DEFINITIONS and appends the
  13. # defines from the file to
  14. # CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS.
  15. #
  16. #2. Eclipse CDT4 indexer has problems with CMake 'Eclipse CDT4 - x'
  17. # generator projects that use mixed C/C++.
  18. # The Eclipse CDT4 indexer is showing a lot of unresolved symbol
  19. # errors, when the project was created with CMake generator and
  20. # the code is a mix of C and C++.
  21. # The root cause of the problem is the g++ built-in __cplusplus macro,
  22. # that is passed by CMake generator in the '.cproject' file.
  23. # The defines in '.cproject' are always the same for C and C++.
  24. # In mixed C/C++ projects, the header files often contain the following
  25. # lines to let C++ code call the C functions:
  26. #
  27. # #ifdef __cplusplus
  28. # extern "C" {
  29. # #endif
  30. #
  31. # < header content >
  32. #
  33. # #ifdef __cplusplus
  34. # }
  35. # #endif
  36. #
  37. # Whenever the Eclipse CDT4 indexer compiles the code for
  38. # code analysis, it has the macro __cplusplus set,
  39. # independent of whether standard C or C++ source files are compiled.
  40. # The 'extern "C"' confuses the standard C compilation and the indexer
  41. # is messed up.
  42. #
  43. # Solution:
  44. # The amendment function deletes the __cplusplus entry from
  45. # CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS.
  46. #
  47. #3. The amendment function appends the defines from
  48. # ${CMAKE_BINARY_DIR}/zephyr/include/generated/autoconf.h to
  49. # CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS.
  50. #
  51. function(eclipse_cdt4_generator_amendment _param_defs)
  52. #
  53. # _param_defs handled values:
  54. #
  55. # 1 - work mode: "C and CXX includes, defines in .cproject without __cplusplus"
  56. # 2 - work mode: "C and CXX includes, defines in .cproject with __cplusplus"
  57. # 5 - work mode: "C and CXX includes, defines in Eclipse with project defines"
  58. #
  59. # In any other case,
  60. # the C and CXX includes, defines setting in Eclipse is the user task.
  61. #
  62. ## EXPERIMENTAL:
  63. ## 3 - work mode: "C and CXX includes, defines in .settings - [EXPERIMENTAL]"
  64. ## 4 - work mode: "C and CXX includes, defines in .settings with project defines - [EXPERIMENTAL]"
  65. #
  66. message(" Eclipse CDT4 generator amendment mode:")
  67. if (${_param_defs} EQUAL 1)
  68. set(_work_mode "C and CXX includes, defines in .cproject without __cplusplus")
  69. message(" ${_work_mode}")
  70. message(" with project includes and defines")
  71. elseif (${_param_defs} EQUAL 2)
  72. set(_work_mode "C and CXX includes, defines in .cproject with __cplusplus")
  73. message(" ${_work_mode}")
  74. message(" with project includes and defines")
  75. #elseif (${_param_defs} EQUAL 3)
  76. # set(_work_mode "C and CXX includes, defines in .settings - [EXPERIMENTAL]")
  77. # message(" ${_work_mode}")
  78. # message(" without project defines")
  79. #elseif (${_param_defs} EQUAL 4)
  80. # set(_work_mode "C and CXX includes, defines in .settings with project defines - [EXPERIMENTAL]")
  81. # message(" ${_work_mode}")
  82. elseif (${_param_defs} EQUAL 5)
  83. set(_work_mode "C and CXX includes, defines in Eclipse with project defines")
  84. message(" ${_work_mode}")
  85. else(${_param_defs} EQUAL 1)
  86. set(_work_mode "C and CXX includes, defines setting in Eclipse is the user task")
  87. message(" ${_work_mode}")
  88. endif(${_param_defs} EQUAL 1)
  89. set(OUTPUT_FILE ${CMAKE_BINARY_DIR}/zephyr/include/generated/cmake_intdef.h)
  90. file(WRITE ${OUTPUT_FILE} "/* Generated by eclipse_cd4_generator_amendment.cmake */\n")
  91. file(APPEND ${OUTPUT_FILE} "/* The header contains the defines collected from the */\n")
  92. file(APPEND ${OUTPUT_FILE} "/* INTERFACE_COMPILE_DEFINITIONS target property */\n")
  93. file(APPEND ${OUTPUT_FILE} "/* corresponding to zephyr_interface */\n")
  94. get_target_property(_int_comp_def zephyr_interface INTERFACE_COMPILE_DEFINITIONS)
  95. foreach( d ${_int_comp_def} )
  96. string(REGEX MATCH "([A-Za-z_][A-Za-z0-9_]*) *=* *(.*) *$" _dummy "${d}")
  97. file(APPEND ${OUTPUT_FILE} "#define ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}\n")
  98. endforeach()
  99. if (${_work_mode} STREQUAL "C and CXX includes, defines in Eclipse with project defines")
  100. message("")
  101. message(" -------------------------------------------------------------------------")
  102. message(" Add the following two command line parameters:")
  103. message("")
  104. message(" -imacros ${CMAKE_BINARY_DIR}/zephyr/include/generated/cmake_intdef.h")
  105. message(" -imacros ${AUTOCONF_H}")
  106. message("")
  107. message(" to 'CDT cross GCC Built-in Compiler Settings' provider command definition")
  108. message(" -------------------------------------------------------------------------")
  109. message("")
  110. endif()
  111. if ( (${_work_mode} STREQUAL "C and CXX includes, defines in .settings - [EXPERIMENTAL]") OR
  112. (${_work_mode} STREQUAL "C and CXX includes, defines in .settings with project defines - [EXPERIMENTAL]") )
  113. set(OUTPUT_FILE ${CMAKE_BINARY_DIR}/.settings/language.settings.xml)
  114. file(WRITE ${OUTPUT_FILE} "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n")
  115. file(APPEND ${OUTPUT_FILE} "<project>\n")
  116. file(APPEND ${OUTPUT_FILE} "\t<configuration id=\"org.eclipse.cdt.core.default.config.1\" name=\"Configuration\">\n")
  117. file(APPEND ${OUTPUT_FILE} "\t\t<extension point=\"org.eclipse.cdt.core.LanguageSettingsProvider\">\n")
  118. file(APPEND ${OUTPUT_FILE} "\t\t\t<provider copy-of=\"extension\" id=\"org.eclipse.cdt.ui.UserLanguageSettingsProvider\"/>\n")
  119. file(APPEND ${OUTPUT_FILE} "\t\t\t<provider-reference id=\"org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider\" ref=\"shared-provider\"/>\n")
  120. file(APPEND ${OUTPUT_FILE} "\t\t\t<provider-reference id=\"org.eclipse.cdt.core.PathEntryScannerInfoLanguageSettingsProvider\" ref=\"shared-provider\"/>\n")
  121. if (${_work_mode} STREQUAL "C and CXX includes, defines in .settings with project defines - [EXPERIMENTAL]")
  122. file(APPEND ${OUTPUT_FILE} "\t\t\t<provider class=\"org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector\" console=\"false\" id=\"org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector\" keep-relative-paths=\"false\" name=\"Zephyr autoconf and SDK Compiler Settings\" parameter=\"${CROSS_COMPILE}\${COMMAND} \${FLAGS} -imacros ${CMAKE_BINARY_DIR}/zephyr/include/generated/cmake_intdef.h -imacros ${AUTOCONF_H} -E -P -v -dD &quot;\${INPUTS}&quot;\" store-entries-with-project=\"true\">\n")
  123. else ()
  124. file(APPEND ${OUTPUT_FILE} "\t\t\t<provider class=\"org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector\" console=\"false\" id=\"org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector\" keep-relative-paths=\"false\" name=\"Zephyr autoconf and SDK Compiler Settings\" parameter=\"${CROSS_COMPILE}\${COMMAND} \${FLAGS} -E -P -v -dD &quot;\${INPUTS}&quot;\" store-entries-with-project=\"true\">\n")
  125. endif ()
  126. file(APPEND ${OUTPUT_FILE} "\t\t\t\t<language-scope id=\"org.eclipse.cdt.core.gcc\"/>\n")
  127. file(APPEND ${OUTPUT_FILE} "\t\t\t\t<language-scope id=\"org.eclipse.cdt.core.g++\"/>\n")
  128. file(APPEND ${OUTPUT_FILE} "\t\t\t</provider>\n")
  129. file(APPEND ${OUTPUT_FILE} "\t\t</extension>\n")
  130. file(APPEND ${OUTPUT_FILE} "\t</configuration>\n")
  131. file(APPEND ${OUTPUT_FILE} "</project>\n")
  132. endif ()
  133. if ( (${_work_mode} STREQUAL "C and CXX includes, defines in .cproject without __cplusplus") OR
  134. (${_work_mode} STREQUAL "C and CXX includes, defines in .cproject with __cplusplus") OR
  135. (${_work_mode} STREQUAL "C and CXX includes, defines in .settings - [EXPERIMENTAL]") )
  136. if ( (${_work_mode} STREQUAL "C and CXX includes, defines in .cproject without __cplusplus") OR
  137. (${_work_mode} STREQUAL "C and CXX includes, defines in .cproject with __cplusplus") )
  138. if (${_work_mode} STREQUAL "C and CXX includes, defines in .cproject without __cplusplus")
  139. # Delete __cplusplus define
  140. set(TEMP_VAR "${CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS}")
  141. STRING(REGEX REPLACE "__cplusplus;.*;" "" TEMP_VAR "${TEMP_VAR}")
  142. set(CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS "${TEMP_VAR}" CACHE INTERNAL "CXX compiler system defined macros")
  143. endif()
  144. else()
  145. # Wiping C compiler system defined macros and include directories
  146. if (CMAKE_C_COMPILER_ID MATCHES GNU)
  147. set(CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS "" CACHE INTERNAL "C compiler system include directories")
  148. set(CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS "" CACHE INTERNAL "C compiler system defined macros")
  149. endif ()
  150. # Wiping CXX compiler system defined macros and include directories
  151. if ("${CMAKE_CXX_COMPILER_ID}" MATCHES GNU)
  152. set(CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS "" CACHE INTERNAL "CXX compiler system include directories")
  153. set(CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS "" CACHE INTERNAL "CXX compiler system defined macros")
  154. endif ()
  155. endif()
  156. file(STRINGS ${CMAKE_BINARY_DIR}/zephyr/include/generated/cmake_intdef.h _int_comp_def)
  157. set (_resultDefines "${CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS}")
  158. foreach( d ${_int_comp_def} )
  159. string(REGEX MATCH "^#define +([A-Za-z_][A-Za-z0-9_]*) *(.*) *$" _dummy "${d}")
  160. if (NOT ("${CMAKE_MATCH_1}" STREQUAL "") )
  161. list(APPEND _resultDefines "${CMAKE_MATCH_1}")
  162. if ("${CMAKE_MATCH_2}" STREQUAL "")
  163. list(APPEND _resultDefines "")
  164. else()
  165. list(APPEND _resultDefines "${CMAKE_MATCH_2}")
  166. endif()
  167. endif()
  168. endforeach()
  169. set (CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS "${_resultDefines}" CACHE INTERNAL "C compiler system defined macros")
  170. file(STRINGS ${AUTOCONF_H} _auto_conf)
  171. set (_resultDefines "${CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS}")
  172. foreach( d ${_auto_conf} )
  173. string(REGEX MATCH "^#define +([A-Za-z_][A-Za-z0-9_]*) *(.*) *$" _dummy "${d}")
  174. if (NOT ("${CMAKE_MATCH_1}" STREQUAL "") )
  175. list(APPEND _resultDefines "${CMAKE_MATCH_1}")
  176. if ("${CMAKE_MATCH_2}" STREQUAL "")
  177. list(APPEND _resultDefines " ")
  178. else()
  179. list(APPEND _resultDefines "${CMAKE_MATCH_2}")
  180. endif()
  181. endif()
  182. endforeach()
  183. set (CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS "${_resultDefines}" CACHE INTERNAL "C compiler system defined macros")
  184. endif()
  185. endfunction(eclipse_cdt4_generator_amendment _param_defs)