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