-
Notifications
You must be signed in to change notification settings - Fork 60
/
ZeekSpicyAnalyzerSupport.cmake
180 lines (144 loc) · 6.49 KB
/
ZeekSpicyAnalyzerSupport.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
#
# Helpers for building analyzers. This is can be included from analyzer packages.
#
# Needs SPICYZ to point to the "spicyz" binary in either CMake or environment.
include(GNUInstallDirs)
# Add target to build an analyzer.
#
# Usage:
#
# spicy_add_analyzer(
# NAME <analyzer_name>
# [SOURCES <source files for spicyz>...]
# [PACKAGE_NAME <package_name>]
# [SCRIPTS <additional script files to install>...]
# [CXX_LINK <libraries to link>...]
# [ENV <environment variable=value>...]
# )
function (spicy_add_analyzer)
set(options)
set(oneValueArgs NAME PACKAGE_NAME)
set(multiValueArgs ENV SOURCES SCRIPTS CXX_LINK)
cmake_parse_arguments(PARSE_ARGV 0 SPICY_ANALYZER "${options}" "${oneValueArgs}"
"${multiValueArgs}")
# We also support the legacy behavior where the first arg is
# the analyzer NAME and all remaining arguments are SOURCES.
if (SPICY_ANALYZER_UNPARSED_ARGUMENTS)
if (SPICY_ANALYZER_NAME OR SPICY_ANALYZER_SOURCES OR SPICY_ANALYZER_SCRIPTS)
message(FATAL_ERROR "named an unnamed arguments cannot be mixed")
endif ()
list(GET ARGN 0 SPICY_ANALYZER_NAME)
list(POP_FRONT ARGN)
set(SPICY_ANALYZER_SOURCES ${ARGN})
endif ()
if (NOT DEFINED SPICY_ANALYZER_NAME)
message(FATAL_ERROR "NAME is required")
endif ()
string(TOLOWER "${SPICY_ANALYZER_NAME}" NAME_LOWER)
set(OUTPUT "${SPICY_MODULE_OUTPUT_DIR_BUILD}/${NAME_LOWER}.hlto")
# list(TRANSFORM SPICY_ANALYZER_CXX_LINK PREPEND "--cxx-link ")
foreach (cxx_link ${SPICY_ANALYZER_CXX_LINK})
list(APPEND CXX_LINK "--cxx-link")
list(APPEND CXX_LINK ${cxx_link})
endforeach ()
# Create a link for backwards compatibility with older zkg packages.
file(CREATE_LINK "." ${SPICY_MODULE_OUTPUT_DIR_BUILD}/spicy-modules SYMBOLIC)
add_custom_command(
OUTPUT ${OUTPUT}
DEPENDS ${SPICY_ANALYZER_SOURCES} ${SPICYZ} ${SPICY_ANALYZER_CXX_LINK}
COMMENT "Compiling ${SPICY_ANALYZER_NAME} analyzer"
COMMAND
${CMAKE_COMMAND} -E env ASAN_OPTIONS=$ENV{ASAN_OPTIONS}:detect_leaks=0
${SPICY_ANALYZER_ENV} ${SPICYZ} -o ${OUTPUT} ${_SPICYZ_FLAGS} ${SPICY_ANALYZER_SOURCES}
${CXX_LINK}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_custom_target(${SPICY_ANALYZER_NAME} ALL DEPENDS ${OUTPUT}
COMMENT "Preparing dependencies of ${SPICY_ANALYZER_NAME}")
if (SPICY_MODULE_OUTPUT_DIR_INSTALL)
install(FILES ${OUTPUT} DESTINATION "${SPICY_MODULE_OUTPUT_DIR_INSTALL}")
endif ()
if (SPICY_SCRIPTS_OUTPUT_DIR_INSTALL AND DEFINED SPICY_ANALYZER_SCRIPTS)
if (NOT DEFINED SPICY_ANALYZER_PACKAGE_NAME)
message(FATAL_ERROR "SCRIPTS argument requires PACKAGE_NAME")
endif ()
install(
FILES ${SPICY_ANALYZER_SCRIPTS}
DESTINATION
"${SPICY_SCRIPTS_OUTPUT_DIR_INSTALL}/${SPICY_ANALYZER_PACKAGE_NAME}/${NAME_LOWER}")
endif ()
get_property(tmp GLOBAL PROPERTY __spicy_included_analyzers)
list(APPEND tmp "${SPICY_ANALYZER_NAME}")
set_property(GLOBAL PROPERTY __spicy_included_analyzers "${tmp}")
endfunction ()
# Flag that analyzer is *not* being built. This is purely informational:
# the cmake output will contain a corresponding note. Arguments are the
# name of the analyzers and a descriptive string explaining why it's
# being skipped.
function (spicy_skip_analyzer name reason)
get_property(tmp GLOBAL PROPERTY __spicy_skipped_analyzers)
list(APPEND tmp "${name} ${reason}")
set_property(GLOBAL PROPERTY __spicy_skipped_analyzers "${tmp}")
endfunction ()
# Prints a summary of configured analyzers.
function (print_analyzers)
message("\n======================| Spicy Analyzer Summary |======================")
message(
"\nspicy-config: ${SPICY_CONFIG}"
"\nzeek-config: ${ZEEK_CONFIG}"
"\nSpicy compiler: ${SPICYZ}"
"\nModule directory: ${SPICY_MODULE_OUTPUT_DIR_INSTALL}"
"\nScripts directory: ${SPICY_SCRIPTS_OUTPUT_DIR_INSTALL}"
"\nPlugin version: "
"${ZEEK_SPICY_PLUGIN_VERSION} (${ZEEK_SPICY_PLUGIN_VERSION_NUMBER})")
if (NOT SPICYZ)
message("\n Make sure spicyz is in your PATH, or set SPICYZ to its location.")
endif ()
get_property(included GLOBAL PROPERTY __spicy_included_analyzers)
message("\nAvailable analyzers:\n")
foreach (x ${included})
message(" ${x}")
endforeach ()
get_property(skipped GLOBAL PROPERTY __spicy_skipped_analyzers)
if (skipped)
message("\nSkipped analyzers:\n")
foreach (x ${skipped})
message(" ${x}")
endforeach ()
endif ()
message("\n========================================================================\n")
endfunction ()
### Main
set(SPICYZ_FLAGS "" CACHE STRING "Additional flags for spicyz")
set_property(GLOBAL PROPERTY __spicy_included_analyzers)
set_property(GLOBAL PROPERTY __spicy_skipped_analyzers)
if (NOT SPICYZ)
set(SPICYZ "$ENV{SPICYZ}")
endif ()
if (SPICYZ)
message(STATUS "Using spicyz: ${SPICYZ}")
add_executable(spicyz IMPORTED)
set_property(TARGET spicyz PROPERTY IMPORTED_LOCATION "${SPICYZ}")
string(REPLACE " " ";" _SPICYZ_FLAGS "${SPICYZ_FLAGS}")
# Allow passing further SPICYZ_FLAGS via environment variable.
string(REPLACE " " ";" _spicyz_flags_env "$ENV{SPICYZ_FLAGS}")
if (_spicyz_flags_env)
list(APPEND _SPICYZ_FLAGS ${_spicyz_flags_env})
endif ()
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
list(APPEND _SPICYZ_FLAGS "-d")
endif ()
message(STATUS "Using spicyz with flags: ${_SPICYZ_FLAGS}")
set(SPICY_MODULE_OUTPUT_DIR_BUILD "${PROJECT_BINARY_DIR}")
execute_process(COMMAND "${SPICYZ}" "--print-module-path" OUTPUT_VARIABLE output
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(SPICY_MODULE_OUTPUT_DIR_INSTALL "${output}" CACHE STRING "")
execute_process(COMMAND "${SPICYZ}" "--version" OUTPUT_VARIABLE output
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(ZEEK_SPICY_PLUGIN_VERSION "${output}" CACHE STRING "")
execute_process(COMMAND "${SPICYZ}" "--version-number" OUTPUT_VARIABLE output
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(ZEEK_SPICY_PLUGIN_VERSION_NUMBER "${output}" CACHE STRING "")
else ()
message(WARNING "spicyz: not specified")
endif ()