Skip to content

Commit e0db9ce

Browse files
simheinnashif
authored andcommitted
sca: Add ECLAIR sca cmake implementation
Add the ECLAIR calls for the zephyr cmake environment to call ECLAIR while the firmware is build by replacing the actual compiler call and setup the eclair environment and call the compiler through the eclair. The Integration accepts a kconfig file for configuring the analysis and the generation of the reports. The path of the kconfig file should be provided via the variable ECLAIR_CONFIG. db_generation.ecl has be created and introduced instead of reports.ecl because the report generation is handled by the sca.cmake directly. Signed-off-by: Simon Hein <[email protected]>
1 parent 4c7d86a commit e0db9ce

File tree

5 files changed

+196
-59
lines changed

5 files changed

+196
-59
lines changed

cmake/sca/eclair/ECL/analysis.ecl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
-project_name=getenv("ECLAIR_PROJECT_NAME")
2-
-project_root=getenv("ECLAIR_PROJECT_ROOT")
31
-setq=data_dir,getenv("ECLAIR_DATA_DIR")
42
-setq=set,getenv("ECLAIR_RULESET")
53

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# eclair_report
2+
3+
# NEEDED: set the variable for the binary output directory from the environment
4+
# variable.
5+
setq(data_dir,getenv("ECLAIR_DATA_DIR"))
6+
7+
# NEEDED: set the variable for the ECLAIR project database from the environment
8+
# variable.
9+
setq(ecd_file,getenv("ECLAIR_PROJECT_ECD"))
10+
11+
# NEEDED: set the variable for the output directory from the environment
12+
# variable.
13+
setq(output_dir,getenv("ECLAIR_OUTPUT_DIR"))
14+
15+
if(file_exists(ecd_file),
16+
db(ecd_file),
17+
create_db(ecd_file))
18+
19+
setq(loaded_dir,join_paths(data_dir,"loaded"))
20+
make_dirs(loaded_dir)
21+
22+
# NEEDED: generate the ecd from frame files
23+
strings_map("load_ecb",500,"",".+\\.ecb",0,setq(ecb,join_paths(data_dir,$0)),load(ecb),rename(ecb,join_paths(loaded_dir,$0)))
24+
strings_map("load_ecb",500,"",".*",0)
25+
26+
loading()
27+
map_strings("load_ecb", dir_entries(data_dir))
28+
loaded()

cmake/sca/eclair/ECL/reports.ecl

Lines changed: 0 additions & 57 deletions
This file was deleted.

cmake/sca/eclair/eclair.template

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
#
3+
# Copyright (c) 2024, Baumer (www.baumer.com)
4+
5+
# Everything before `--` are arguments for cmake invocation, those must be ignored.
6+
# The first argument after `--` is the start of the compiler call, which is
7+
# what we want to get to invoke ECLAIR with the compiler call which is used in the zephyr
8+
# environment
9+
foreach(i RANGE ${CMAKE_ARGC})
10+
if("${CMAKE_ARGV${i}}" STREQUAL "--")
11+
math(EXPR end_of_options "${i} + 1")
12+
break()
13+
endif()
14+
endforeach()
15+
16+
foreach(i RANGE ${end_of_options} ${CMAKE_ARGC})
17+
list(APPEND ZEPHYR_COMPILER_CALL ${CMAKE_ARGV${i}})
18+
endforeach()
19+
20+
list(APPEND ECLAIR_ARGS +incremental
21+
-project_name=@ECLAIR_PROJECT_NAME@ -project_root=@ZEPHYR_BASE@
22+
-eval_file=@ECLAIR_ECL_DIR@/analysis.ecl
23+
-eval_file=@ECLAIR_ANALYSIS_ECL_DIR@/analysis_@[email protected]
24+
@ECLAIR_ENV_ADDITIONAL_OPTIONS@)
25+
26+
execute_process(
27+
COMMAND @CMAKE_COMMAND@ -E env
28+
ECLAIR_DIAGNOSTICS_OUTPUT=@ECLAIR_DIAGNOSTICS_OUTPUT@
29+
ECLAIR_DATA_DIR=@ECLAIR_ANALYSIS_DATA_DIR@
30+
CC_ALIASES=@CC_ALIASES@
31+
CXX_ALIASES=@CXX_ALIASES@
32+
AS_ALIASES=@AS_ALIASES@
33+
LD_ALIASES=@LD_ALIASES@
34+
AR_ALIASES=@AR_ALIASES@
35+
@ECLAIR_ENV@ ${ECLAIR_ARGS} -- ${ZEPHYR_COMPILER_CALL}
36+
COMMAND_ERROR_IS_FATAL ANY
37+
)

cmake/sca/eclair/sca.cmake

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
#
3+
# Copyright (c) 2023, BUGSENG Srl
4+
5+
find_program(ECLAIR_ENV eclair_env REQUIRED)
6+
message(STATUS "Found eclair_env: ${ECLAIR_ENV}")
7+
8+
find_program(ECLAIR_REPORT eclair_report REQUIRED)
9+
message(STATUS "Found eclair_report: ${ECLAIR_REPORT}")
10+
11+
12+
# ECLAIR Settings
13+
set(ECLAIR_PROJECT_NAME "Zephyr-${BOARD}${BOARD_QUALIFIERS}")
14+
set(ECLAIR_OUTPUT_DIR "${CMAKE_BINARY_DIR}/sca/eclair")
15+
set(ECLAIR_ECL_DIR "${ZEPHYR_BASE}/cmake/sca/eclair/ECL")
16+
set(ECLAIR_ANALYSIS_ECL_DIR "${ZEPHYR_BASE}/cmake/sca/eclair/ECL")
17+
set(ECLAIR_DIAGNOSTICS_OUTPUT "${ECLAIR_OUTPUT_DIR}/DIAGNOSTIC.txt")
18+
set(ECLAIR_ANALYSIS_DATA_DIR "${ECLAIR_OUTPUT_DIR}/analysis_data")
19+
set(ECLAIR_PROJECT_ECD "${ECLAIR_OUTPUT_DIR}/PROJECT.ecd")
20+
set(CC_ALIASES "${CMAKE_C_COMPILER}")
21+
set(CXX_ALIASES "${CMAKE_CXX_COMPILER}")
22+
set(AS_ALIASES "${CMAKE_AS}")
23+
set(LD_ALIASES "${CMAKE_LINKER}")
24+
set(AR_ALIASES "${CMAKE_ASM_COMPILER_AR} ${CMAKE_C_COMPILER_AR} ${CMAKE_CXX_COMPILER_AR}")
25+
26+
set(ECLAIR_ENV_ADDITIONAL_OPTIONS "")
27+
set(ECLAIR_REPORT_ADDITIONAL_OPTIONS "")
28+
29+
# Default value
30+
set(ECLAIR_RULESET first_analysis)
31+
32+
# ECLAIR env
33+
if(ECLAIR_RULESET_FIRST_ANALYSIS)
34+
set(ECLAIR_RULESET first_analysis)
35+
elseif(ECLAIR_RULESET_STU)
36+
set(ECLAIR_RULESET STU)
37+
elseif(ECLAIR_RULESET_STU_HEAVY)
38+
set(ECLAIR_RULESET STU_heavy)
39+
elseif(ECLAIR_RULESET_WP)
40+
set(ECLAIR_RULESET WP)
41+
elseif(ECLAIR_RULESET_STD_LIB)
42+
set(ECLAIR_RULESET std_lib)
43+
elseif(ECLAIR_RULESET_USER)
44+
set(ECLAIR_RULESET ${ECLAIR_USER_RULESET_NAME})
45+
if(IS_ABSOLUTE ${ECLAIR_USER_RULESET_PATH})
46+
set(ECLAIR_ANALYSIS_ECL_DIR ${ECLAIR_USER_RULESET_PATH})
47+
else()
48+
set(ECLAIR_ANALYSIS_ECL_DIR ${APPLICATION_CONFIG_DIR}/${ECLAIR_USER_RULESET_PATH})
49+
endif()
50+
endif()
51+
52+
# ECLAIR report
53+
if (ECLAIR_METRICS_TAB)
54+
list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-metrics_tab=${ECLAIR_OUTPUT_DIR}/metrics")
55+
endif()
56+
if (ECLAIR_REPORTS_TAB)
57+
list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-reports_tab=${ECLAIR_OUTPUT_DIR}/reports")
58+
endif()
59+
if (ECLAIR_REPORTS_SARIF)
60+
list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-reports_sarif=${ECLAIR_OUTPUT_DIR}/reports.sarif")
61+
endif()
62+
if (ECLAIR_SUMMARY_TXT)
63+
list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-summary_txt=${ECLAIR_OUTPUT_DIR}/summary_txt")
64+
endif()
65+
if (ECLAIR_SUMMARY_DOC)
66+
list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-summary_doc=${ECLAIR_OUTPUT_DIR}/summary_doc")
67+
endif()
68+
if (ECLAIR_SUMMARY_ODT)
69+
list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-summary_odt=${ECLAIR_OUTPUT_DIR}/summary_odt")
70+
endif()
71+
if (ECLAIR_FULL_TXT_ALL_AREAS)
72+
list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-setq=report_areas,areas")
73+
endif()
74+
if (ECLAIR_FULL_TXT_FIRST_AREA)
75+
list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-setq=report_areas,first_area")
76+
endif()
77+
if (ECLAIR_FULL_TXT)
78+
list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-full_txt=${ECLAIR_OUTPUT_DIR}/report_full_txt")
79+
endif()
80+
if (ECLAIR_FULL_DOC_ALL_AREAS)
81+
list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-setq=report_areas,areas")
82+
endif()
83+
if (ECLAIR_FULL_DOC_FIRST_AREA)
84+
list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-setq=report_areas,first_area")
85+
endif()
86+
if (ECLAIR_FULL_DOC)
87+
list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-full_doc=${ECLAIR_OUTPUT_DIR}/report_full_doc")
88+
endif()
89+
if (ECLAIR_FULL_ODT)
90+
list(APPEND ECLAIR_REPORT_ADDITIONAL_OPTIONS "-full_odt=${ECLAIR_OUTPUT_DIR}/report_full_odt")
91+
endif()
92+
93+
message(STATUS "ECLAIR outputs have been written to: ${ECLAIR_OUTPUT_DIR}")
94+
message(STATUS "ECLAIR ECB files have been written to: ${ECLAIR_ANALYSIS_DATA_DIR}")
95+
96+
add_custom_target(eclair_setup_analysis_dir ALL
97+
COMMAND ${CMAKE_COMMAND} -E remove_directory ${ECLAIR_ANALYSIS_DATA_DIR}
98+
COMMAND ${CMAKE_COMMAND} -E make_directory ${ECLAIR_ANALYSIS_DATA_DIR}
99+
VERBATIM
100+
USES_TERMINAL
101+
)
102+
103+
# configure the camke script which will be used to replace the compiler call with the eclair_env
104+
# call which calls the compiler and to generate analysis files.
105+
configure_file(${CMAKE_CURRENT_LIST_DIR}/eclair.template ${ECLAIR_OUTPUT_DIR}/eclair.cmake @ONLY)
106+
107+
set(launch_environment ${CMAKE_COMMAND} -P ${ECLAIR_OUTPUT_DIR}/eclair.cmake --)
108+
set(CMAKE_C_COMPILER_LAUNCHER ${launch_environment} CACHE INTERNAL "")
109+
110+
# This target is used to generate the ECLAIR database when all the compilation is done and the
111+
# elf file was generated with this we cane make sure that the analysis is completed.
112+
add_custom_target(eclair_report ALL
113+
COMMAND ${CMAKE_COMMAND} -E env
114+
ECLAIR_DATA_DIR=${ECLAIR_ANALYSIS_DATA_DIR}
115+
ECLAIR_OUTPUT_DIR=${ECLAIR_OUTPUT_DIR}
116+
ECLAIR_PROJECT_ECD=${ECLAIR_PROJECT_ECD}
117+
${ECLAIR_REPORT} -quiet -eval_file=${ECLAIR_ECL_DIR}/db_generation.ecl
118+
DEPENDS ${CMAKE_BINARY_DIR}/zephyr/zephyr.elf
119+
VERBATIM
120+
USES_TERMINAL
121+
COMMAND_EXPAND_LISTS
122+
)
123+
124+
# This command is used to generate the final reports from the database and print the overall results
125+
add_custom_target(eclair_summary_print ALL
126+
COMMAND ${ECLAIR_REPORT}
127+
-db=${ECLAIR_PROJECT_ECD} ${ECLAIR_REPORT_ADDITIONAL_OPTIONS}
128+
-overall_txt=${ECLAIR_OUTPUT_DIR}/summary_overall.txt
129+
COMMAND ${CMAKE_COMMAND} -E cat ${ECLAIR_OUTPUT_DIR}/summary_overall.txt
130+
)
131+
add_dependencies(eclair_summary_print eclair_report)

0 commit comments

Comments
 (0)