184 lines
7.4 KiB
CMake
184 lines
7.4 KiB
CMake
# Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
|
|
#
|
|
# CMake helpers to find Spicy and build Spicy code.
|
|
#
|
|
# To have this find the Spicy toolchain, either set PATH to contain
|
|
# spicy-config, set SPICY_ROOT_DIR to the Spicy installation, or set
|
|
# SPICY_CONFIG to the binary.
|
|
#
|
|
# Output:
|
|
# SPICY_FOUND true if Spicy has been found
|
|
#
|
|
# If SPICY_FOUND is true:
|
|
#
|
|
# SPICYC full path to spicyc
|
|
# SPICY_BUILD_MODE Spicy's debug/release build mode
|
|
# SPICY_INCLUDE_DIRS_RUNTIME Spicy C++ include directories for the runtime
|
|
# SPICY_INCLUDE_DIRS_TOOLCHAIN Spicy C++ include directories for the toolchain
|
|
# SPICY_CXX_LIBRARY_DIRS_TOOLCHAIN Spicy C++ library directories
|
|
# SPICY_CXX_LIBRARY_DIRS_RUNTIME Spicy C++ library directories
|
|
# SPICY_CXX_FLAGS Spicy C++ flags with include directories
|
|
# SPICY_PREFIX Spicy installation prefix
|
|
# SPICY_VERSION Spicy version as a string
|
|
# SPICY_VERSION_NUMBER Spicy version as a numerical value
|
|
# SPICY_CMAKE_PATH Spicy cmake directory
|
|
# SPICY_HAVE_TOOLCHAIN True if the compiler is available
|
|
|
|
### Functions
|
|
|
|
# Configure build against Spicy.
|
|
macro (configure)
|
|
### Find spicy-config
|
|
if (NOT SPICY_CONFIG)
|
|
set(SPICY_CONFIG "$ENV{SPICY_CONFIG}")
|
|
endif ()
|
|
|
|
if (SPICY_CONFIG)
|
|
if (EXISTS "${SPICY_CONFIG}")
|
|
set(spicy_config "${SPICY_CONFIG}")
|
|
else ()
|
|
message(STATUS "'${SPICY_CONFIG}' does not exist")
|
|
endif ()
|
|
else ()
|
|
# Attempt to find `spicy-config` only with configured paths.
|
|
find_program(
|
|
spicy_config spicy-config
|
|
HINTS ${SPICY_ROOT_DIR}/bin
|
|
${SPICY_ROOT_DIR}/build/bin
|
|
$ENV{SPICY_ROOT_DIR}/bin
|
|
$ENV{SPICY_ROOT_DIR}/build/bin
|
|
# Try build directory of Spicy distribution we may be part of.
|
|
${PROJECT_SOURCE_DIR}/../../build/bin
|
|
NO_DEFAULT_PATH)
|
|
|
|
# If above search was not successful attempt to find the program in
|
|
# builtin search paths. CMake's `find_program` will only execute a new
|
|
# search if the output variable `spicy-config` is unset.
|
|
find_program(spicy_config spicy-config)
|
|
endif ()
|
|
|
|
if (NOT spicy_config)
|
|
message(STATUS "cannot determine location of Spicy installation")
|
|
set(HAVE_SPICY no)
|
|
else ()
|
|
message(STATUS "Found spicy-config: ${spicy_config}")
|
|
set(HAVE_SPICY yes)
|
|
set(SPICY_CONFIG "${spicy_config}" CACHE FILEPATH "")
|
|
|
|
### Determine properties.
|
|
|
|
run_spicy_config(SPICYC "--spicyc")
|
|
run_spicy_config(SPICY_BUILD_MODE "--build")
|
|
run_spicy_config(SPICY_PREFIX "--prefix")
|
|
run_spicy_config(SPICY_VERSION "--version")
|
|
run_spicy_config(SPICY_VERSION_NUMBER "--version-number")
|
|
run_spicy_config(SPICY_CMAKE_PATH "--cmake-path")
|
|
run_spicy_config(SPICY_HAVE_TOOLCHAIN "--have-toolchain")
|
|
|
|
run_spicy_config(SPICY_INCLUDE_DIRS_RUNTIME --include-dirs)
|
|
string(REPLACE " " ";" SPICY_INCLUDE_DIRS_RUNTIME "${SPICY_INCLUDE_DIRS_RUNTIME}")
|
|
|
|
run_spicy_config(SPICY_LIBRARY_DIRS_RUNTIME --libdirs-cxx-runtime)
|
|
string(REPLACE " " ";" SPICY_LIBRARY_DIRS_RUNTIME "${SPICY_LIBRARY_DIRS_RUNTIME}")
|
|
|
|
run_spicy_config(SPICY_INCLUDE_DIRS_TOOLCHAIN --include-dirs-toolchain)
|
|
string(REPLACE " " ";" SPICY_INCLUDE_DIRS_TOOLCHAIN "${SPICY_INCLUDE_DIRS_TOOLCHAIN}")
|
|
|
|
run_spicy_config(SPICY_LIBRARY_DIRS_TOOLCHAIN --libdirs-cxx-toolchain)
|
|
string(REPLACE " " ";" SPICY_LIBRARY_DIRS_TOOLCHAIN "${SPICY_LIBRARY_DIRS_TOOLCHAIN}")
|
|
|
|
find_library(
|
|
HILTI_LIBRARY
|
|
NAMES hilti
|
|
NO_DEFAULT_PATH
|
|
HINTS "${SPICY_LIBRARY_DIRS_TOOLCHAIN}" "${SPICY_LIBRARY_DIRS_RUNTIME}")
|
|
|
|
find_library(
|
|
SPICY_LIBRARY
|
|
NAMES spicy
|
|
NO_DEFAULT_PATH
|
|
HINTS "${SPICY_LIBRARY_DIRS_TOOLCHAIN}" "${SPICY_LIBRARY_DIRS_RUNTIME}")
|
|
|
|
add_library(hilti SHARED IMPORTED GLOBAL)
|
|
set_target_properties(hilti PROPERTIES IMPORTED_LOCATION "${HILTI_LIBRARY}")
|
|
target_include_directories(hilti BEFORE INTERFACE ${HILTI_INCLUDE_DIRS_TOOLCHAIN}
|
|
${HILTI_INCLUDE_DIRS_RUNTIME})
|
|
|
|
add_library(spicy SHARED IMPORTED GLOBAL)
|
|
set_target_properties(spicy PROPERTIES IMPORTED_LOCATION "${SPICY_LIBRARY}")
|
|
target_include_directories(spicy BEFORE INTERFACE ${SPICY_INCLUDE_DIRS_TOOLCHAIN}
|
|
${SPICY_INCLUDE_DIRS_RUNTIME})
|
|
endif ()
|
|
endmacro ()
|
|
|
|
# Checks that the Spicy version it at least the given version.
|
|
function (spicy_require_version version)
|
|
string(REGEX MATCH "([0-9]*)\.([0-9]*)\.([0-9]*).*" _ ${version})
|
|
math(EXPR version_number "${CMAKE_MATCH_1} * 10000 + ${CMAKE_MATCH_2} * 100 + ${CMAKE_MATCH_3}")
|
|
if ("${SPICY_VERSION_NUMBER}" LESS "${version_number}")
|
|
message(
|
|
FATAL_ERROR "Package requires at least Spicy version ${version}, have ${SPICY_VERSION}")
|
|
endif ()
|
|
endfunction ()
|
|
|
|
# Helper to link with `--whole-archive/-force-load`.
|
|
#
|
|
# This is adapted from https://github.com/horance-liu/flink.cmake
|
|
#
|
|
# With CMake >= 3.24, we could instead use LINK_LIBRARY, see
|
|
# https://cmake.org/cmake/help/v3.24/manual/cmake-generator-expressions.7.html#genex:LINK_LIBRARY
|
|
macro (spicy_get_runtime_libraries out debug)
|
|
if (debug)
|
|
set(hilti_rt ${HILTI_LIBRARY_RT_DEBUG})
|
|
set(spicy_rt ${SPICY_LIBRARY_RT_DEBUG})
|
|
else ()
|
|
set(hilti_rt ${HILTI_LIBRARY_RT})
|
|
set(spicy_rt ${SPICY_LIBRARY_RT})
|
|
endif ()
|
|
|
|
if (MSVC)
|
|
set(${out} "/WHOLEARCHIVE:${hilti_rt};/WHOLEARCHIVE:${spicy_rt}")
|
|
elseif (APPLE)
|
|
set(${out} "-Wl,-force_load;${hilti_rt};-Wl,-force_load;${spicy_rt}")
|
|
else ()
|
|
set(${out} "-Wl,--whole-archive;${hilti_rt};${spicy_rt};-Wl,--no-whole-archive")
|
|
endif ()
|
|
endmacro ()
|
|
|
|
# Runs `spicy-config` and stores its result in the given output variable.
|
|
function (run_spicy_config output)
|
|
execute_process(COMMAND "${spicy_config}" ${ARGN} OUTPUT_VARIABLE output_
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
string(STRIP "${output_}" output_)
|
|
set(${output} "${output_}" PARENT_SCOPE)
|
|
endfunction ()
|
|
|
|
# Prints a summary of detected Spicy.
|
|
function (spicy_print_summary)
|
|
message("\n====================| Spicy Installation Summary |====================" "\n"
|
|
"\nFound Spicy: ${HAVE_SPICY}")
|
|
|
|
if (HAVE_SPICY)
|
|
message(
|
|
"\nVersion: ${SPICY_VERSION} (${SPICY_VERSION_NUMBER})"
|
|
"\nPrefix: ${SPICY_PREFIX}"
|
|
"\nBuild type: ${SPICY_BUILD_MODE}"
|
|
"\nHave toolchain: ${SPICY_HAVE_TOOLCHAIN}"
|
|
"\nSpicy compiler: ${SPICYC}")
|
|
else ()
|
|
message(
|
|
"\n Make sure spicy-config is in your PATH, or set SPICY_CONFIG to its location.")
|
|
endif ()
|
|
|
|
message("\n========================================================================\n")
|
|
endfunction ()
|
|
|
|
### Main
|
|
|
|
if (NOT HAVE_SPICY)
|
|
configure()
|
|
endif ()
|
|
|
|
include(FindPackageHandleStandardArgs)
|
|
find_package_handle_standard_args(Spicy DEFAULT_MSG HAVE_SPICY SPICY_CONFIG)
|