198 lines
7.8 KiB
CMake
198 lines
7.8 KiB
CMake
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 ()
|