140 lines
5.1 KiB
CMake
140 lines
5.1 KiB
CMake
# CMake dependencies.
|
|
include(FetchContent)
|
|
|
|
# Users may override this path to place the compiled packages elsewhere.
|
|
set(ZEEK_BUNDLE_PREFIX "${PROJECT_BINARY_DIR}/zeek-bundle"
|
|
CACHE STRING "Path to the Zeek packages cache directory")
|
|
|
|
# Opt-in to changed CMake behavior for fetching ZIP files.
|
|
if (POLICY CMP0135)
|
|
cmake_policy(SET CMP0135 NEW)
|
|
endif ()
|
|
|
|
# Tries to find a package in the Zeek package cache.
|
|
function (ZeekBundle_Find name)
|
|
find_package(${name} CONFIG QUIET NO_DEFAULT_PATH HINTS ${ZEEK_BUNDLE_PREFIX})
|
|
if (${name}_FOUND)
|
|
set(ZeekBundle_FOUND ON PARENT_SCOPE)
|
|
else ()
|
|
set(ZeekBundle_FOUND OFF PARENT_SCOPE)
|
|
endif ()
|
|
endfunction ()
|
|
|
|
# Runs the build and install steps for an external project.
|
|
function (ZeekBundle_BuildStep name type binDir)
|
|
# Build the external project.
|
|
message(STATUS "Building bundled project: ${name} as ${type}")
|
|
execute_process(
|
|
COMMAND "${CMAKE_COMMAND}" --build "${binDir}" --config ${type}
|
|
OUTPUT_FILE "${binDir}/build${type}.out"
|
|
ERROR_FILE "${binDir}/build${type}.err"
|
|
RESULT_VARIABLE buildResult)
|
|
if (NOT buildResult EQUAL 0)
|
|
file(READ "${binDir}/build${type}.err" cmakeErr)
|
|
message(FATAL_ERROR "Failed to build ${name}:\n\n${cmakeErr}")
|
|
endif ()
|
|
# Install the external project.
|
|
message(STATUS "Installing bundled project: ${name} as ${type}")
|
|
execute_process(
|
|
COMMAND "${CMAKE_COMMAND}" --build "${binDir}" --config ${type} --target install
|
|
OUTPUT_FILE "${binDir}/install${type}.out"
|
|
ERROR_FILE "${binDir}/install${type}.err"
|
|
RESULT_VARIABLE installResult)
|
|
if (NOT installResult EQUAL 0)
|
|
file(READ "${binDir}/install${type}.err" cmakeErr)
|
|
message(FATAL_ERROR "Failed to install ${name}:\n\n${cmakeErr}")
|
|
endif ()
|
|
endfunction ()
|
|
|
|
# Builds an external project at configure time.
|
|
function (ZeekBundle_Build name srcDir binDir)
|
|
# Extra arguments are passed as CMake options to the external project.
|
|
set(cmakeArgs "")
|
|
foreach (arg IN LISTS ARGN)
|
|
list(APPEND cmakeArgs "-D${arg}")
|
|
endforeach ()
|
|
# Make sure we can build debug and release versions of the project separately.
|
|
list(APPEND cmakeArgs "-DCMAKE_DEBUG_POSTFIX=d")
|
|
# Run CMake for the external project.
|
|
message(STATUS "Configuring bundled project: ${name}")
|
|
execute_process(
|
|
COMMAND
|
|
"${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" ${cmakeArgs} -DBUILD_SHARED_LIBS=OFF
|
|
-DCMAKE_POSITION_INDEPENDENT_CODE=ON -DENABLE_TESTING=OFF
|
|
"-DCMAKE_INSTALL_PREFIX=${ZEEK_BUNDLE_PREFIX}" "${srcDir}"
|
|
WORKING_DIRECTORY "${binDir}"
|
|
OUTPUT_FILE "${binDir}/cmake.out"
|
|
ERROR_FILE "${binDir}/cmake.err"
|
|
RESULT_VARIABLE cmakeResult)
|
|
if (NOT cmakeResult EQUAL 0)
|
|
file(READ "${binDir}/cmake.err" cmakeErr)
|
|
message(FATAL_ERROR "Failed to configure external project ${name}:\n\n${cmakeErr}")
|
|
endif ()
|
|
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
|
if (isMultiConfig)
|
|
zeekbundle_buildstep(${name} Debug ${binDir})
|
|
zeekbundle_buildstep(${name} Release ${binDir})
|
|
else ()
|
|
# On Windows, we cannot mix debug and release libraries.
|
|
if (WIN32)
|
|
zeekbundle_buildstep(${name} ${CMAKE_BUILD_TYPE} ${binDir})
|
|
else ()
|
|
zeekbundle_buildstep(${name} Release ${binDir})
|
|
endif ()
|
|
endif ()
|
|
|
|
endfunction ()
|
|
|
|
# Adds a bundled package to Zeek.
|
|
#
|
|
# Usage:
|
|
# ZeekBundle_Add(
|
|
# NAME <name>
|
|
# FETCH (URL <url> | GIT_REPOSITORY <repo> GIT_TAG <tag> | SOURCE_DIR <path>)
|
|
# [CONFIGURE <args>]
|
|
# )
|
|
function (ZeekBundle_Add)
|
|
# Parse the function arguments.
|
|
cmake_parse_arguments(arg "" "NAME" "FETCH;CONFIGURE" ${ARGN})
|
|
if (NOT arg_NAME)
|
|
message(FATAL_ERROR "ZeekBundle_Add: mandatory argument NAME is missing!")
|
|
endif ()
|
|
if (NOT arg_FETCH)
|
|
message(FATAL_ERROR "ZeekBundle_Add: mandatory argument FETCH is missing!")
|
|
endif ()
|
|
# Use find_package if the user explicitly requested the package.
|
|
if (DEFINED ${arg_NAME}_ROOT)
|
|
message(STATUS "ZeekBundle: use system library for ${arg_NAME}")
|
|
find_package(
|
|
${arg_NAME}
|
|
CONFIG
|
|
QUIET
|
|
REQUIRED
|
|
NO_DEFAULT_PATH
|
|
PATHS
|
|
${${arg_NAME}_ROOT})
|
|
return()
|
|
endif ()
|
|
# Check if we already have the package.
|
|
zeekbundle_find(${arg_NAME})
|
|
if (ZeekBundle_FOUND)
|
|
return()
|
|
endif ()
|
|
# Fetch the package by delegating to FetchContent.
|
|
FetchContent_Declare(dl_${arg_NAME} ${arg_FETCH})
|
|
string(TOLOWER "dl_${arg_NAME}" internalName)
|
|
FetchContent_Populate(${internalName} SOURCE_DIR ${arg_FETCH})
|
|
file(MAKE_DIRECTORY "${${internalName}_BINARY_DIR}")
|
|
# Build the package and verify that it was found.
|
|
zeekbundle_build(${arg_NAME} "${${internalName}_SOURCE_DIR}" "${${internalName}_BINARY_DIR}"
|
|
${arg_CONFIGURE})
|
|
find_package(
|
|
${arg_NAME}
|
|
CONFIG
|
|
QUIET
|
|
REQUIRED
|
|
NO_DEFAULT_PATH
|
|
PATHS
|
|
${ZEEK_BUNDLE_PREFIX})
|
|
endfunction ()
|