1# SPDX-License-Identifier: Apache-2.0
2#
3# Copyright (c) 2023, BUGSENG Srl
4
5find_program(ECLAIR_ENV eclair_env REQUIRED)
6message(STATUS "Found eclair_env: ${ECLAIR_ENV}")
7
8find_program(ECLAIR_REPORT eclair_report REQUIRED)
9message(STATUS "Found eclair_report: ${ECLAIR_REPORT}")
10
11# Get eclair specific option file variables, also needed if invoked with sysbuild
12zephyr_get(ECLAIR_OPTIONS_FILE)
13
14if(ECLAIR_OPTIONS_FILE)
15  if(IS_ABSOLUTE ${ECLAIR_OPTIONS_FILE})
16    set(ECLAIR_OPTIONS ${ECLAIR_OPTIONS_FILE})
17  else()
18    set(ECLAIR_OPTIONS ${APPLICATION_CONFIG_DIR}/${ECLAIR_OPTIONS_FILE})
19  endif()
20  include(${ECLAIR_OPTIONS})
21else()
22  include(${CMAKE_CURRENT_LIST_DIR}/sca_options.cmake)
23endif()
24
25# ECLAIR Settings
26set(ECLAIR_PROJECT_NAME "Zephyr-${BOARD}${BOARD_QUALIFIERS}")
27set(ECLAIR_PROJECT_ROOT "${ZEPHYR_BASE}")
28set(ECLAIR_OUTPUT_DIR "${CMAKE_BINARY_DIR}/sca/eclair")
29set(ECLAIR_ECL_DIR "${ZEPHYR_BASE}/cmake/sca/eclair/ECL")
30set(ECLAIR_ANALYSIS_ECL_DIR "${ZEPHYR_BASE}/cmake/sca/eclair/ECL")
31set(ECLAIR_DIAGNOSTICS_OUTPUT "${ECLAIR_OUTPUT_DIR}/DIAGNOSTIC.txt")
32set(ECLAIR_ANALYSIS_DATA_DIR "${ECLAIR_OUTPUT_DIR}/analysis_data")
33set(ECLAIR_PROJECT_ECD "${ECLAIR_OUTPUT_DIR}/PROJECT.ecd")
34set(ECLAIR_WORKSPACE "${ECLAIR_OUTPUT_DIR}/eclair_workspace")
35set(CC_ALIASES "${CMAKE_C_COMPILER}")
36set(CXX_ALIASES "${CMAKE_CXX_COMPILER}")
37set(AS_ALIASES "${CMAKE_AS}")
38set(LD_ALIASES "${CMAKE_LINKER}")
39set(AR_ALIASES "${CMAKE_ASM_COMPILER_AR} ${CMAKE_C_COMPILER_AR} ${CMAKE_CXX_COMPILER_AR}")
40
41set(ECLAIR_ENV_ADDITIONAL_OPTIONS "")
42set(ECLAIR_REPORT_ADDITIONAL_OPTIONS "")
43
44# Default value
45set(ECLAIR_RULESET first_analysis)
46
47# ECLAIR env
48if(ECLAIR_RULESET_USER)
49  set(ECLAIR_RULESET ${ECLAIR_USER_RULESET_NAME})
50  if(IS_ABSOLUTE ${ECLAIR_USER_RULESET_PATH})
51      set(ECLAIR_ANALYSIS_ECL_DIR ${ECLAIR_USER_RULESET_PATH})
52  else()
53    set(ECLAIR_ANALYSIS_ECL_DIR ${APPLICATION_CONFIG_DIR}/${ECLAIR_USER_RULESET_PATH})
54  endif()
55elseif(ECLAIR_RULESET_FIRST_ANALYSIS)
56  set(ECLAIR_RULESET first_analysis)
57elseif(ECLAIR_RULESET_STU)
58  set(ECLAIR_RULESET STU)
59elseif(ECLAIR_RULESET_STU_HEAVY)
60  set(ECLAIR_RULESET STU_heavy)
61elseif(ECLAIR_RULESET_WP)
62  set(ECLAIR_RULESET WP)
63elseif(ECLAIR_RULESET_STD_LIB)
64  set(ECLAIR_RULESET std_lib)
65elseif(ECLAIR_RULESET_ZEPHYR_GUIDELINES)
66  set(ECLAIR_RULESET zephyr_guidelines)
67endif()
68
69# ECLAIR report
70if (ECLAIR_METRICS_TAB)
71  list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-metrics_tab=${ECLAIR_OUTPUT_DIR}/metrics")
72endif()
73if (ECLAIR_REPORTS_TAB)
74  list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-reports_tab=${ECLAIR_OUTPUT_DIR}/reports")
75endif()
76if (ECLAIR_REPORTS_SARIF)
77  list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-reports_sarif=${ECLAIR_OUTPUT_DIR}/reports.sarif")
78endif()
79if (ECLAIR_SUMMARY_TXT)
80  list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-summary_txt=${ECLAIR_OUTPUT_DIR}/summary_txt")
81endif()
82if (ECLAIR_SUMMARY_DOC)
83  list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-summary_doc=${ECLAIR_OUTPUT_DIR}/summary_doc")
84endif()
85if (ECLAIR_SUMMARY_ODT)
86  list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-summary_odt=${ECLAIR_OUTPUT_DIR}/summary_odt")
87endif()
88if (ECLAIR_SUMMARY_HTML)
89  list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-summary_html=${ECLAIR_OUTPUT_DIR}/summary_html")
90endif()
91if (ECLAIR_FULL_TXT_ALL_AREAS)
92  list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-setq=report_areas,areas")
93endif()
94if (ECLAIR_FULL_TXT_FIRST_AREA)
95  list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-setq=report_areas,first_area")
96endif()
97if (ECLAIR_FULL_TXT)
98  list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-full_txt=${ECLAIR_OUTPUT_DIR}/report_full_txt")
99endif()
100if (ECLAIR_FULL_DOC_ALL_AREAS)
101  list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-setq=report_areas,areas")
102endif()
103if (ECLAIR_FULL_DOC_FIRST_AREA)
104  list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-setq=report_areas,first_area")
105endif()
106if (ECLAIR_FULL_DOC)
107  list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-full_doc=${ECLAIR_OUTPUT_DIR}/report_full_doc")
108endif()
109if (ECLAIR_FULL_ODT)
110  list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-full_odt=${ECLAIR_OUTPUT_DIR}/report_full_odt")
111endif()
112if (ECLAIR_FULL_HTL)
113  list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-full_html=${ECLAIR_OUTPUT_DIR}/report_full_html")
114endif()
115
116message(STATUS "ECLAIR project name: ${ECLAIR_PROJECT_NAME}")
117message(STATUS "ECLAIR project root is: ${ECLAIR_PROJECT_ROOT}")
118message(STATUS "ECLAIR outputs will be written to: ${ECLAIR_OUTPUT_DIR}")
119message(STATUS "ECLAIR ECB files will be written to: ${ECLAIR_ANALYSIS_DATA_DIR}")
120
121list(APPEND ECLAIR_CLEAN_ARGS
122                        +clean
123                        -project_name=${ECLAIR_PROJECT_NAME}
124                        -project_root=${ECLAIR_PROJECT_ROOT}
125                        -eval_file=${ECLAIR_ECL_DIR}/analysis.ecl
126                        -eval_file=${ECLAIR_ANALYSIS_ECL_DIR}/analysis_${ECLAIR_RULESET}.ecl
127                        ${ECLAIR_ENV_ADDITIONAL_OPTIONS})
128
129add_custom_target(eclair_setup_analysis_dir ALL
130  COMMAND ${CMAKE_COMMAND} -E remove_directory ${ECLAIR_ANALYSIS_DATA_DIR}
131  COMMAND ${CMAKE_COMMAND} -E make_directory ${ECLAIR_ANALYSIS_DATA_DIR}
132  COMMAND ${CMAKE_COMMAND} -E env
133    ECLAIR_DIAGNOSTICS_OUTPUT=${ECLAIR_DIAGNOSTICS_OUTPUT}
134    ECLAIR_DATA_DIR=${ECLAIR_ANALYSIS_DATA_DIR}
135    ${ECLAIR_ENV} ${ECLAIR_CLEAN_ARGS} --
136  VERBATIM
137  USES_TERMINAL
138)
139
140# configure the cmake script which will be used to replace the compiler call with the eclair_env
141# call which calls the compiler and to generate analysis files.
142configure_file(${CMAKE_CURRENT_LIST_DIR}/eclair.template ${ECLAIR_OUTPUT_DIR}/eclair.cmake @ONLY)
143
144set(launch_environment ${CMAKE_COMMAND} -P ${ECLAIR_OUTPUT_DIR}/eclair.cmake --)
145set(CMAKE_C_COMPILER_LAUNCHER ${launch_environment} CACHE INTERNAL "")
146
147list(APPEND ECLAIR_PROJECT_ARGS
148                        +project
149                        -project_name=${ECLAIR_PROJECT_NAME}
150                        -project_root=${ECLAIR_PROJECT_ROOT}
151                        -eval_file=${ECLAIR_ECL_DIR}/analysis.ecl
152                        -eval_file=${ECLAIR_ANALYSIS_ECL_DIR}/analysis_${ECLAIR_RULESET}.ecl
153                        ${ECLAIR_ENV_ADDITIONAL_OPTIONS})
154
155add_custom_target(eclair_project_analysis ALL
156  COMMAND ${CMAKE_COMMAND} -E env
157    ECLAIR_DIAGNOSTICS_OUTPUT=${ECLAIR_DIAGNOSTICS_OUTPUT}
158    ECLAIR_DATA_DIR=${ECLAIR_ANALYSIS_DATA_DIR}
159    ${ECLAIR_ENV} ${ECLAIR_PROJECT_ARGS} --
160  VERBATIM
161  USES_TERMINAL
162)
163
164# This target is used to generate the ECLAIR database when all the compilation is done and the
165# elf file was generated with this we cane make sure that the analysis is completed.
166add_custom_target(eclair_report ALL
167  COMMAND ${CMAKE_COMMAND} -E env
168    ECLAIR_DATA_DIR=${ECLAIR_ANALYSIS_DATA_DIR}
169    ECLAIR_OUTPUT_DIR=${ECLAIR_OUTPUT_DIR}
170    ECLAIR_PROJECT_ECD=${ECLAIR_PROJECT_ECD}
171    ${ECLAIR_REPORT} -quiet -eval_file=${ECLAIR_ECL_DIR}/db_generation.ecl
172  DEPENDS ${CMAKE_BINARY_DIR}/zephyr/zephyr.elf
173  VERBATIM
174  USES_TERMINAL
175  COMMAND_EXPAND_LISTS
176)
177
178# This command is used to generate the final reports from the database and print the overall results
179add_custom_target(eclair_summary_print ALL
180  COMMAND ${ECLAIR_REPORT}
181    -db=${ECLAIR_PROJECT_ECD} ${ECLAIR_REPORT_ADDITIONAL_OPTIONS}
182    -overall_txt=${ECLAIR_OUTPUT_DIR}/summary_overall.txt
183  COMMAND ${CMAKE_COMMAND} -E cat ${ECLAIR_OUTPUT_DIR}/summary_overall.txt
184)
185
186add_dependencies(eclair_report eclair_project_analysis)
187add_dependencies(eclair_summary_print eclair_report)
188