233 lines
8.6 KiB
CMake
233 lines
8.6 KiB
CMake
# Copyright (c) 2020-now by the Zeek Project. See LICENSE for details.
|
|
|
|
### A collection of small helpers for the HILTI/Spicy build system.
|
|
|
|
# Add the likely Bison include directory to Bison sources to avoid version mismatches.
|
|
function (bison_source src output_dir)
|
|
string(REGEX REPLACE "/bin/bison" "/include" bison_include "${BISON_EXECUTABLE}")
|
|
set_source_files_properties(
|
|
${src} PROPERTIES INCLUDE_DIRECTORIES "${bison_include};${FLEX_INCLUDE_DIR};${output_dir}")
|
|
endfunction ()
|
|
|
|
# Install a set of header files from a directory location.
|
|
function (install_headers src dst)
|
|
if (NOT IS_ABSOLUTE "${src}")
|
|
set(src "${CMAKE_CURRENT_SOURCE_DIR}/${src}")
|
|
endif ()
|
|
|
|
if (NOT IS_ABSOLUTE "${dst}")
|
|
set(dst_msg "${CMAKE_INSTALL_FULL_INCLUDEDIR}/${dst}")
|
|
set(dst "${CMAKE_INSTALL_INCLUDEDIR}/${dst}")
|
|
endif ()
|
|
|
|
if (ARGN)
|
|
foreach (i ${ARGN})
|
|
install(FILES ${src}/${i} DESTINATION ${dst})
|
|
endforeach ()
|
|
else ()
|
|
install(CODE "message(STATUS \"Installing: ${dst_msg}/*\")")
|
|
|
|
install(
|
|
DIRECTORY ${src}/
|
|
DESTINATION ${dst}
|
|
MESSAGE_NEVER FILES_MATCHING
|
|
PATTERN "*.h"
|
|
PATTERN "*.hpp"
|
|
PATTERN "*.hh"
|
|
PATTERN "3rdparty*" EXCLUDE)
|
|
endif ()
|
|
endfunction ()
|
|
|
|
# Add a symlink at installation time.
|
|
function (install_symlink filepath sympath)
|
|
install(CODE "message(\"-- Creating symbolic link: ${sympath} -> ${filepath}\")")
|
|
install(
|
|
CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${filepath} ${sympath})")
|
|
endfunction (install_symlink)
|
|
|
|
# Initialize a variable that'll go into a {hilti,spicy}/config.cc
|
|
# file. This performs some normalization: turn lists into
|
|
# space-separated strings and strip/reduce whitespace.
|
|
function (set_config_val dst val)
|
|
if (NOT "${val}" STREQUAL "")
|
|
string(REPLACE ";" " " _x "${val}")
|
|
string(STRIP "${_x}" _x)
|
|
string(REGEX REPLACE " *" " " _x "${_x}")
|
|
set(${dst} "${_x}" PARENT_SCOPE)
|
|
else ()
|
|
set(${dst} "" PARENT_SCOPE)
|
|
endif ()
|
|
endfunction ()
|
|
|
|
# Sets an appropriate RPATH for the system.
|
|
function (make_install_rpath dst relative_from relative_to)
|
|
# The following is from "Professional CMake" to set target's RPATH relative to their location.
|
|
if (APPLE)
|
|
set(base_point "@loader_path")
|
|
else ()
|
|
set(base_point "$ORIGIN")
|
|
endif ()
|
|
|
|
file(RELATIVE_PATH relative_lib_path ${relative_from} ${relative_to})
|
|
set(${dst} "${base_point};${base_point}/${relative_lib_path}" PARENT_SCOPE)
|
|
endfunction ()
|
|
|
|
# Warn or abort if we don't a given version isn't recent enough.
|
|
function (require_version name found have need require)
|
|
if (NOT ${found})
|
|
if (require)
|
|
message(FATAL_ERROR "${name} required, but not found")
|
|
else ()
|
|
set(${found} no PARENT_SCOPE)
|
|
set(${have} "not found")
|
|
endif ()
|
|
else ()
|
|
if (${have} VERSION_LESS "${need}")
|
|
if (require)
|
|
message(FATAL_ERROR "Need ${name} version >= ${need}, found ${${have}}")
|
|
endif ()
|
|
|
|
message(STATUS "Warning: Need ${name} version >= ${need}, found ${${have}}")
|
|
set(${found} no PARENT_SCOPE)
|
|
set(${have} "${${have}} (error: too old, must be at least ${need})" PARENT_SCOPE)
|
|
endif ()
|
|
endif ()
|
|
endfunction ()
|
|
|
|
# Internal helper to link in all object libraries that libhilti needs.
|
|
function (hilti_link_object_libraries_in_tree lib)
|
|
if (HAVE_TOOLCHAIN)
|
|
target_link_libraries(${lib} "${ARGN}" hilti-objects)
|
|
endif ()
|
|
|
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
target_link_libraries(${lib} "${ARGN}" hilti-rt-debug-objects)
|
|
else ()
|
|
target_link_libraries(${lib} "${ARGN}" hilti-rt-objects)
|
|
endif ()
|
|
|
|
set(_private "")
|
|
if (NOT "${ARGN}" STREQUAL "")
|
|
set(_private "PRIVATE")
|
|
endif ()
|
|
|
|
target_link_libraries(${lib} ${_private} reproc++)
|
|
target_link_libraries(${lib} ${_private} jrx-objects)
|
|
target_link_libraries(${lib} ${_private} fiber)
|
|
endfunction ()
|
|
|
|
# Link a library against libhilti. This picks the right version of
|
|
# libhilti (shared or object) based on the build configuration.
|
|
function (hilti_link_libraries_in_tree lib)
|
|
if (BUILD_SHARED_LIBS)
|
|
target_link_libraries(${lib} "${ARGN}" hilti)
|
|
else ()
|
|
hilti_link_object_libraries_in_tree(${lib} "${ARGN}")
|
|
endif ()
|
|
endfunction ()
|
|
|
|
# Link an executable against libhilti. This picks the right version of
|
|
# libhilti (shared or object) based on the build configuration.
|
|
function (hilti_link_executable_in_tree exec)
|
|
# Ideally, we'd just link against the static hilti library here. However,
|
|
# ENABLE_EXPORTS doesn't seem to apply through to that, and we'd get
|
|
# missing symbol errors at runtime. So instead we link directly
|
|
# against our set of objects libraries by calling hilti_link_libraries_in_tree().
|
|
hilti_link_libraries_in_tree(${exec} "${ARGN}")
|
|
set_property(TARGET ${exec} PROPERTY ENABLE_EXPORTS true)
|
|
endfunction ()
|
|
|
|
# Internal helper to link in all object libraries that libspicy needs.
|
|
function (spicy_link_object_libraries_in_tree lib)
|
|
if (HAVE_TOOLCHAIN)
|
|
target_link_libraries(${lib} "${ARGN}" spicy-objects)
|
|
endif ()
|
|
|
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
target_link_libraries(${lib} "${ARGN}" spicy-rt-debug-objects)
|
|
else ()
|
|
target_link_libraries(${lib} "${ARGN}" spicy-rt-objects)
|
|
endif ()
|
|
endfunction ()
|
|
|
|
# Link a library against libspicy. This picks the right version of
|
|
# libspicy (shared or object) based on the build configuration.
|
|
function (spicy_link_libraries_in_tree lib)
|
|
if (BUILD_SHARED_LIBS)
|
|
target_link_libraries(${lib} "${ARGN}" spicy)
|
|
else ()
|
|
spicy_link_object_libraries_in_tree(${lib} "${ARGN}")
|
|
endif ()
|
|
endfunction ()
|
|
|
|
# Link an executable against libspicy. This picks the right version of
|
|
# libspicy (shared or object) based on the build configuration.
|
|
function (spicy_link_executable_in_tree exec)
|
|
# Similar comment here as hilti_link_executable_in_tree().
|
|
hilti_link_libraries_in_tree(${exec} "${ARGN}")
|
|
spicy_link_libraries_in_tree(${exec} "${ARGN}")
|
|
set_property(TARGET ${exec} PROPERTY ENABLE_EXPORTS true)
|
|
endfunction ()
|
|
|
|
include(CheckCXXCompilerFlag)
|
|
|
|
# Wrapper around `BISON_TARGET` with Spicy-specific preprocessing.
|
|
macro (BISON_TARGET_PP Name BisonInput BisonOutput)
|
|
# Name of the preprocessed Bison input.
|
|
string(JOIN "." BisonInputPP "${BisonOutput}" "pp")
|
|
|
|
# Preprocess the input file:
|
|
#
|
|
# - in versions <bison-3.3.0 `api.parser.name` was called `parser_class_name`
|
|
if (${BISON_VERSION} VERSION_LESS "3.3.0")
|
|
add_custom_command(
|
|
OUTPUT ${BisonInputPP}
|
|
DEPENDS ${BisonInput}
|
|
COMMAND sed -e 's/%require\ \"3.3\"/%require\ \"3.0\"/' -e
|
|
's/api.parser.class/parser_class_name/' ${BisonInput} > ${BisonInputPP}
|
|
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
|
COMMENT "Preprocessing Bison file ${BisonInput}")
|
|
else ()
|
|
add_custom_command(
|
|
OUTPUT ${BisonInputPP}
|
|
DEPENDS ${BisonInput}
|
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${BisonInput} ${BisonInputPP}
|
|
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
|
COMMENT "Preprocessing Bison file ${BisonInput}")
|
|
endif ()
|
|
|
|
# Pass preprocessed file to `BISON_TARGET`.
|
|
#
|
|
# TODO(bbannier): Since `ARGV` is a list of lists normal list manipulations like
|
|
# `list(REPLACE_AT ...)` do not seem to work so we create a new output list.
|
|
set(i 0)
|
|
foreach (arg ${ARGV})
|
|
if (i EQUAL 1)
|
|
list(APPEND args "${BisonInputPP}")
|
|
else ()
|
|
list(APPEND args "${arg}")
|
|
endif ()
|
|
math(EXPR i "${i}+1")
|
|
endforeach ()
|
|
|
|
# Invoke the actual Bison processing.
|
|
if (BISON_VERSION VERSION_GREATER_EQUAL "3.7.0")
|
|
bison_target(
|
|
${args}
|
|
COMPILE_FLAGS
|
|
"--file-prefix-map=${BisonInputPP}=${CMAKE_CURRENT_SOURCE_DIR}/${BisonInput}")
|
|
else ()
|
|
# This works but will leave locations in compiler error messages point to the preprocessed file.
|
|
bison_target(${args})
|
|
endif ()
|
|
|
|
check_cxx_compiler_flag("-Wunused-but-set-variable" have_unused_but_set_variable)
|
|
if (have_unused_but_set_variable)
|
|
# Suppress warnings in generated code.
|
|
# cmake-format: off
|
|
# (cmake-format and cmake-lint don't agree on how this line should be formatted).
|
|
set_source_files_properties(${BisonOutput} PROPERTIES COMPILE_FLAGS "-Wno-unused-but-set-variable")
|
|
# cmake-format: on
|
|
endif ()
|
|
endmacro ()
|