-
Notifications
You must be signed in to change notification settings - Fork 60
/
ZeekPlugin.cmake
200 lines (189 loc) · 7.63 KB
/
ZeekPlugin.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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# This function wraps the find_package call for Zeek to allow us to override
# variables such as CMAKE_PREFIX_PATH in the function scope without changing the
# variable at directory scope. The function also locates dependencies for
# dynamic plugins like BinPAC and BifCl.
function (zeek_plugin_bootstrapping)
# Plugins that build against the source tree set ZEEK_DIST. Here, we have our
# package file plus ZeekPluginConfig.cmake to help out.
if (ZEEK_DIST)
message("-- Using ZEEK_DIST: ${ZEEK_DIST}")
find_package(Zeek REQUIRED CONFIG NO_DEFAULT_PATH PATHS "${ZEEK_DIST}/build")
return()
endif ()
# When building plugins against an installed Zeek, this file must be installed
# alongside this script. It provides the variables ZEEK_CMAKE_CONFIG_DIR and
# ZEEK_CMAKE_INSTALL_PREFIX.
include(ZeekPluginBootstrap)
# When looking for dependencies, make sure to look into the install prefix.
list(PREPEND CMAKE_PREFIX_PATH "${ZEEK_CMAKE_INSTALL_PREFIX}")
# We also needs to find Broker, which we usually can find through the install
# prefix. Plugins may also set BROKER_ROOT_DIR to help find Broker, which we
# forward to the actual CMake variable if present.
if (NOT Broker_DIR AND BROKER_ROOT_DIR)
set(Broker_DIR "${BROKER_ROOT_DIR}")
endif ()
# Load the CMake package for Zeek. This pulls in dependencies as well as
# targets such as Zeek::DynamicPluginBase.
find_package(Zeek REQUIRED CONFIG NO_DEFAULT_PATH PATHS "${ZEEK_CMAKE_CONFIG_DIR}")
# Find BinPAC via Zeek's FindBinPAC.cmake script.
if (NOT TARGET Zeek::BinPAC)
find_package(BinPAC REQUIRED)
add_executable(Zeek::BinPAC IMPORTED)
set_property(TARGET Zeek::BinPAC PROPERTY IMPORTED_LOCATION "${BinPAC_EXE}")
endif ()
# Find BifCl. This should be located under ZEEK_CMAKE_INSTALL_PREFIX/bin.
if (NOT TARGET Zeek::BifCl)
list(PREPEND CMAKE_PROGRAM_PATH "${ZEEK_CMAKE_INSTALL_PREFIX}/bin")
find_program(ZeekBifClPath bifcl)
if (NOT ZeekBifClPath) # Note: CMake > 3.18 has REQUIRED for find_program.
message(
FATAL_ERROR
"failed to find bifcl, please add hints to CMAKE_PREFIX_PATH or CMAKE_PROGRAM_PATH"
)
endif ()
message(STATUS "Found BifCl at ${ZeekBifClPath}")
add_executable(Zeek::BifCl IMPORTED)
set_property(TARGET Zeek::BifCl PROPERTY IMPORTED_LOCATION "${ZeekBifClPath}")
endif ()
# For historic reasons, we also automagically add <plugin-src>/cmake (if it
# exists) to CMAKE_MODULE_PATH.
if (EXISTS "${PROJECT_SOURCE_DIR}/cmake")
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" PARENT_SCOPE)
endif ()
# Another historic quirk: force CMAKE_EXPORT_COMPILE_COMMANDS to ON.
set(CMAKE_EXPORT_COMPILE_COMMANDS ON
CACHE PATH "Configures whether to write a compile database." FORCE)
# When CMAKE_BUILD_TYPE is not set, use the one from Zeek.
if (NOT CMAKE_BUILD_TYPE)
message(STATUS "Setting plugin CMAKE_BUILD_TYPE to ${ZEEK_CMAKE_BUILD_TYPE}")
set(CMAKE_BUILD_TYPE "${ZEEK_CMAKE_BUILD_TYPE}"
CACHE STRING "Configures the CMAKE_BUILD_TYPE for the plugin." FORCE)
endif ()
endfunction ()
# Make sure BifCl and BinPAC are available.
if (NOT ZEEK_PLUGIN_INTERNAL_BUILD)
zeek_plugin_bootstrapping()
endif ()
include(BifCl)
include(BinPAC)
# Wrapper include file that loads the macros for building a Zeek
# plugin either statically or dynamically, depending on whether
# we're building as part of the main Zeek source tree, or externally.
# Utility function for zeek_add_*plugin functions. Those functions use
# cmake_parse_arguments, which lumps together all arguments for the 'PAC'
# sections into one array. This function simply allows us to traverse all 'PAC'
# sections individually.
#
# Usage example:
#
# zeek_next_pac_block(at_end pacInputs pacRemainder ${args})
# while (NOT at_end)
# message(STATUS "inputs ${pacInputs}")
# message(STATUS "pacRemainder ${pacRemainder}")
# zeek_next_pac_block(at_end pacInputs pacRemainder ${pacRemainder})
# endwhile()
function (zeek_next_pac_block at_end inputs remainder)
# Sanity checking.
list(LENGTH ARGN n)
if (n EQUAL "0")
set(${at_end} ON PARENT_SCOPE)
return()
endif ()
# List of separators, i.e., keywords recognized by zeek_add_*plugin functions.
set(separators INCLUDE_DIRS DEPENDENCIES SOURCES BIFS DIST_FILES PAC)
# Seek to the first PAC block.
set(i 0)
foreach (arg ${ARGN})
math(EXPR i "${i}+1")
if (arg STREQUAL "PAC")
break()
endif ()
endforeach ()
# Bail out if no block was found.
if (i EQUAL n)
set(${at_end} ON PARENT_SCOPE)
return()
endif ()
# Fill the result list.
set(j ${i})
list(SUBLIST ARGN ${i} -1 subArgs)
set(res "")
foreach (arg ${subArgs})
if (arg IN_LIST separators)
break()
endif ()
list(APPEND res ${arg})
math(EXPR j "${j}+1")
endforeach ()
if (j EQUAL n)
set(unusedArgs "")
else ()
list(SUBLIST ARGN ${j} -1 unusedArgs)
endif ()
# Fill the result variables.
set(${at_end} OFF PARENT_SCOPE)
set(${inputs} ${res} PARENT_SCOPE)
set(${remainder} ${unusedArgs} PARENT_SCOPE)
endfunction ()
include(ZeekPluginStatic)
include(ZeekPluginDynamic)
if (NOT ZEEK_PLUGIN_INTERNAL_BUILD AND ${CMAKE_MINIMUM_REQUIRED_VERSION} VERSION_LESS 3.15.0)
message(
FATAL_ERROR
"Plugin requires CMake ${CMAKE_MINIMUM_REQUIRED_VERSION} which is less than Zeek's requirement (3.15.0). Please update cmake_minimum_required VERSION to 3.15 or higher."
)
endif ()
if (ZEEK_PLUGIN_INTERNAL_BUILD AND NOT ZEEK_PLUGIN_BUILD_DYNAMIC)
set(ZEEK_PLUGIN_BUILD_DYNAMIC OFF)
elseif (NOT ZEEK_PLUGIN_BUILD_DYNAMIC)
set(ZEEK_PLUGIN_BUILD_DYNAMIC ON)
endif ()
# Sets `target` to contain the CMake target name for a plugin.
macro (zeek_get_plugin_target var ns name)
if (ZEEK_PLUGIN_BUILD_DYNAMIC)
zeek_get_dynamic_plugin_target(${var} ${ns} ${name})
else ()
zeek_get_static_plugin_target(${var} ${ns} ${name})
endif ()
endmacro ()
# Usage:
# zeek_add_plugin(
# <namespace>
# <name>
# [INCLUDE_DIRS ...]
# [DEPENDENCIES ...]
# [DIST_FILES ...]
# [SCRIPT_FILES ...]
# [SOURCES ...]
# [BIFS ...]
# [[PAC ...] ... ]
# )
# * INCLUDE_DIRS:
# Adds additional include directories for building the plugin. By default, the
# function adds `CMAKE_CURRENT_BINARY_DIR` as additional include directory.
# * DEPENDENCIES:
# Adds additional CMake targets as extra dependencies.
# * DIST_FILES:
# Adds additional files to install alongside the plugin when building a
# dynamic plugin. Ignored when building static plugins.
# * SCRIPT_FILES:
# Marks the given script files as dependencies for the tarball when building
# a dynamic plugin. This is currently for dependency tracking only - the
# plugin's whole script directory is included in the resulting tarball
# regardless of the files provided here. Ignored when building static plugins.
# * SOURCES:
# List of C++ files for compiling the plugin.
# * BIFS:
# List of BIF files (*.bif) for compiling the plugin.
# * PAC:
# Adds a BinPAC parser to the plugin. The function accepts multiple `PAC`
# blocks. Each block defines a single BinPAC parser.
function (zeek_add_plugin ns name)
if (ZEEK_PLUGIN_BUILD_DYNAMIC)
zeek_add_dynamic_plugin(${ns} ${name} ${ARGV})
else ()
zeek_add_static_plugin(${ns} ${name} ${ARGV})
endif ()
endfunction ()
include(ZeekPluginCommon)