-
Notifications
You must be signed in to change notification settings - Fork 60
/
ZeekPluginDynamic.cmake
197 lines (169 loc) · 7.83 KB
/
ZeekPluginDynamic.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
include(FindClangTidy)
include(GetArchitecture)
# Sets `target` to contain the CMake target name for a dynamic plugin.
macro (zeek_get_dynamic_plugin_target target ns name)
set(${target} "${ns}_${name}")
endmacro ()
# Implements the dynamically linked version of zeek_add_plugin.
function (zeek_add_dynamic_plugin ns name)
# Sanity check: need ZEEK_PLUGIN_SCRIPTS_PATH.
if (NOT EXISTS "${ZEEK_PLUGIN_SCRIPTS_PATH}")
message(
FATAL_ERROR
"Cannot build dynamic plugins: ZEEK_PLUGIN_SCRIPTS_PATH is undefined or invalid")
endif ()
# Helper variables.
zeek_get_dynamic_plugin_target(target_name ${ns} ${name})
set(full_name "${ns}::${name}")
set(canon_name "${ns}_${name}")
set(base_dir "${CMAKE_CURRENT_BINARY_DIR}")
set(lib_dir "${base_dir}/lib")
set(bif_dir "${lib_dir}/bif")
set(readme "${base_dir}/README")
set(scripts_bin "${base_dir}/scripts")
set(scripts_src "${CMAKE_CURRENT_SOURCE_DIR}/scripts")
# Create the target if no begin function has been used.
if (NOT TARGET ${target_name})
add_library(${target_name} MODULE)
target_compile_features(${target_name} PRIVATE cxx_std_17)
set_target_properties(${target_name} PROPERTIES CXX_EXTENSIONS OFF)
endif ()
# Place library file into the 'lib' directory, drop default-generated file
# prefix and override the default file name to include the architecture.
set_target_properties(
${target_name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${lib_dir}" PREFIX ""
LIBRARY_OUTPUT_NAME "${ns}-${name}.${HOST_ARCHITECTURE}")
# Parse arguments (note: DIST_FILES and SCRIPT_FILES are ignored in static builds).
set(fn_varargs
INCLUDE_DIRS
DEPENDENCIES
SOURCES
BIFS
DIST_FILES
SCRIPT_FILES
PAC)
cmake_parse_arguments(FN_ARGS "" "" "${fn_varargs}" ${ARGN})
# Take care of compiling BIFs.
if (FN_ARGS_BIFS)
# Generate the targets and add the .cc files.
foreach (bif ${FN_ARGS_BIFS})
bif_target(${bif} "plugin" ${full_name} ${canon_name} OFF)
target_sources(${target_name} PRIVATE ${BIF_OUTPUT_CC})
endforeach ()
# Generate __load__.zeek when building the plugin outside of Zeek.
if (ZEEK_PLUGIN_INTERNAL_BUILD)
set(loader_target ${target_name}_bif_loader)
bro_bif_create_loader(${loader_target} ${FN_ARGS_BIFS})
add_dependencies(${target_name} ${loader_target})
else ()
set(load_script "${bif_dir}/__load__.zeek")
file(WRITE ${load_script} "# Warning, this is an autogenerated file!\n")
foreach (bif ${FN_ARGS_BIFS})
get_filename_component(file_name ${bif} NAME)
file(APPEND ${load_script} "@load ./${file_name}.zeek\n")
endforeach ()
endif ()
endif ()
# Take care of PAC files.
zeek_next_pac_block(at_end pacInputs pacRemainder ${ARGN})
while (NOT at_end)
binpac_target(${pacInputs})
target_sources(${target_name} PRIVATE ${BINPAC_OUTPUT_CC})
zeek_next_pac_block(at_end pacInputs pacRemainder ${pacRemainder})
endwhile ()
# Add user-defined extra include directories.
if (FN_ARGS_INCLUDE_DIRS)
target_include_directories(${target_name} PRIVATE ${FN_ARGS_INCLUDE_DIRS})
endif ()
# Add user-defined extra dependencies.
if (FN_ARGS_DEPENDENCIES)
target_link_libraries(${target_name} PUBLIC ${FN_ARGS_DEPENDENCIES})
endif ()
# Add the sources for the plugin.
if (FN_ARGS_SOURCES)
target_sources(${target_name} PRIVATE ${FN_ARGS_SOURCES})
endif ()
# Add extra dependencies when compiling with MSVC.
if (MSVC)
target_link_libraries(${target_name} ws2_32)
endif ()
# Pass compiler flags, paths and dependencies to the target.
target_link_libraries(${target_name} PRIVATE Zeek::DynamicPluginBase)
target_include_directories(${target_name} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
# Per convention, plugins have their headers and sources under src/ and
# legacy/external plugins expect this to auto-magically be available as
# include path.
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src)
target_include_directories(${target_name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
endif ()
# Link scripts into the build directory (if present).
if (IS_DIRECTORY "${scripts_src}")
set(symlink_target ${target_name}_symlink)
add_custom_target(${symlink_target} COMMAND "${CMAKE_COMMAND}" -E create_symlink
"${scripts_src}" "${scripts_bin}")
add_dependencies(${target_name} ${symlink_target})
endif ()
# Add BinPAC_INCLUDE_DIR for picking up paths from FindBinPAC.cmake.
if (BinPAC_INCLUDE_DIR)
target_include_directories(${target_name} PRIVATE ${BinPAC_INCLUDE_DIR})
endif ()
# Write the 'magic' __zeek_plugin__ file. We can do that once during CMake
# invocation since it won't change.
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/__zeek_plugin__" "${full_name}\n")
# Stop here unless building 3rd party plugins.
if (ZEEK_PLUGIN_INTERNAL_BUILD)
return()
endif ()
# Plugins may set BRO_PLUGIN_INSTALL_ROOT to override the default
# installation directory. Otherwise, we use ZEEK_PLUGIN_DIR from Zeek.
if (BRO_PLUGIN_INSTALL_ROOT)
set(install_dir "${BRO_PLUGIN_INSTALL_ROOT}")
else ()
set(install_dir ${ZEEK_PLUGIN_DIR})
endif ()
# Create the binary install package.
set(dist_tarball_dir ${CMAKE_CURRENT_BINARY_DIR}/dist/${canon_name})
set(dist_tarball_name ${canon_name}.tgz)
set(dist_tarball_path ${CMAKE_CURRENT_BINARY_DIR}/${dist_tarball_name})
message(STATUS "Install prefix for plugin ${canon_name}: ${install_dir}")
message(STATUS "Tarball path for plugin ${canon_name}: ${dist_tarball_path}")
add_custom_command(OUTPUT ${dist_tarball_path} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Building binary plugin package: ${dist_tarball_path}")
# Handle dist files: Pre-place user provided dist files into the
# directory that zeek-plugin-create-package.sh will tar up. Previously,
# the zeek-plugin-create-package.sh script had done this itself.
#
# This computes the relative path of individual DIST_FILES to the
# PROJECT_SOURCE_DIR (last project() invocation) and uses the
# resulting path in the tarball.
foreach (df ${FN_ARGS_DIST_FILES})
get_filename_component(df_src "${df}" ABSOLUTE)
if (NOT EXISTS "${df_src}")
# This was silently ignored previously.
message(WARNING "The file ${df} (${df_src}) given to DIST_FILES does not exist")
continue()
endif ()
file(RELATIVE_PATH df_dist ${PROJECT_SOURCE_DIR} ${df_src})
add_custom_command(
OUTPUT ${dist_tarball_path}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${df}
${dist_tarball_dir}/${df_dist}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${df}
APPEND)
endforeach ()
add_custom_command(
OUTPUT ${dist_tarball_path}
COMMAND ${ZEEK_PLUGIN_SCRIPTS_PATH}/zeek-plugin-create-package.sh ${canon_name}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${target_name} ${FN_ARGS_SCRIPT_FILES}
APPEND)
add_custom_target(${target_name}_tarball ALL DEPENDS ${dist_tarball_path})
# Tell CMake to install our tarball. Note: This usually runs from our
# plugin-support skeleton.
install(
CODE "execute_process(
COMMAND ${ZEEK_PLUGIN_SCRIPTS_PATH}/zeek-plugin-install-package.sh ${canon_name} \$ENV{DESTDIR}/${install_dir}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND_ECHO STDOUT
)")
endfunction ()