agent-enviroments/builder/libs/seastar/cooking.sh
2024-09-10 17:06:08 +03:00

973 lines
26 KiB
Bash
Executable File

#!/bin/bash
#
# Copyright 2018 Jesse Haber-Kucharsky
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# This is cmake-cooking v0.10.0
# The home of cmake-cooking is https://github.com/hakuch/CMakeCooking
#
set -e
CMAKE=${CMAKE:-cmake}
invoked_args=("$@")
source_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
initial_wd=$(pwd)
memory_file="${initial_wd}/.cooking_memory"
recipe="${source_dir}/cooking_recipe.cmake"
declare -a excluded_ingredients
declare -a included_ingredients
build_dir="${initial_wd}/build"
build_type="Debug"
# Depends on `build_dir`.
ingredients_dir=""
generator="Ninja"
list_only=""
nested=""
usage() {
cat <<EOF
Fetch, configure, build, and install dependencies ("ingredients") for a CMake project
in a local and repeatable development environment.
Usage: $0 [OPTIONS]
where OPTIONS are:
-a
-r RECIPE
-e INGREDIENT
-i INGREDIENT
-d BUILD_DIR (=${build_dir})
-p INGREDIENTS_DIR (=${build_dir}/_cooking/installed)
-t BUILD_TYPE (=${build_type})
-g GENERATOR (=${generator})
-s VAR=VALUE
-f EXPORT_DIR
-l
-h
By default, cmake-cooking reads a file called 'cooking_recipe.cmake'.
If neither [-i] nor [-e] are specified with a recipe ([-r]), then all ingredients of the recipe
will be fetched and built.
[-i] and [-e] are mutually-exclusive options: only provide one.
Option details:
-a
Invoke 'cooking.sh' with the arguments that were provided to it last time, instead
of the arguments provided.
-r RECIPE
Instead of reading the recipe in a file called 'cooking_recipe.cmake', follow the recipe
in the named file.
If the recipe file is a relative path, it is interpretted relative to the source directory
of the project.
-e INGREDIENT
Exclude an ingredient from a recipe. This option can be supplied many times.
For example, if a recipe consists of 'apple', 'banana', 'carrot', and 'donut', then
./cooking.sh -r dev -e apple -e donut
will prepare 'banana' and 'carrot' but not prepare 'apple' and 'donut'.
If an ingredient is excluded, then it is assumed that all ingredients that depend on it
can satisfy that dependency in some other way from the system (ie, the dependency is
removed internally).
-i INGREDIENT
Include an ingredient from a recipe, ignoring the others. This option can be supplied
many times.
Similar to [-e], but the opposite.
For example, if a recipe consists of 'apple', 'banana', 'carrot', and 'donut' then
./cooking.sh -r dev -i apple -i donut
will prepare 'apple' and 'donut' but not prepare 'banana' and 'carrot'.
If an ingredient is not in the "include-list", then it is assumed that all
ingredients that are in the list and which depend on it can satisfy that dependency
in some other way from the system.
-d BUILD_DIR (=${build_dir})
Configure the project and build it in the named directory.
-p INGREDIENTS_DIR (=${build_dir}/_cooking/installed)
Install compiled ingredients into this directory.
-t BUILD_TYPE (=${build_type})
Configure all ingredients and the project with the named CMake build-type.
An example build type is "Release".
-g GENERATOR (=${generator})
Use the named CMake generator for building all ingredients and the project.
An example generator is "Unix Makfiles".
-s VAR=VALUE
Set an environmental variable 'VAR' to the value 'VALUE' during the invocation of CMake.
-f EXPORT_DIR
If provided, and the project is successfully configured, then the tree of installed ingredients
is exported to this directory (the actual files: not symbolic links).
This option requires rsync.
This may be useful for preparing continuous integration environments, but it is not
recommended for distribution or release purposes (since this would be counter
to the goal of cmake-cooking).
-l
Only list available ingredients for a given recipe, and don't do anything else.
-h
Show this help information and exit.
EOF
}
parse_assignment() {
local var
local value
IFS='=' read -r var value <<< "${1}"
export "${var}"="${value}"
}
yell_include_exclude_mutually_exclusive() {
echo "Cooking: [-e] and [-i] are mutually exclusive options!" >&2
}
while getopts "ar:e:i:d:p:t:g:s:f:lhx" arg; do
case "${arg}" in
a)
if [ ! -f "${memory_file}" ]; then
echo "No previous invocation found to recall!" >&2
exit 1
fi
source "${memory_file}"
run_previous && exit 0
;;
r)
if [[ "${OPTARG}" = /* ]]; then
recipe=${OPTARG}
else
recipe="${source_dir}/${OPTARG}"
fi
;;
e)
if [[ ${#included_ingredients[@]} -ne 0 ]]; then
yell_include_exclude_mutually_exclusive
exit 1
fi
excluded_ingredients+=(${OPTARG})
;;
i)
if [[ ${#excluded_ingredients[@]} -ne 0 ]]; then
yell_include_exclude_mutually_exclusive
exit 1
fi
included_ingredients+=(${OPTARG})
;;
d) build_dir=$(realpath "${OPTARG}") ;;
p) ingredients_dir=$(realpath "${OPTARG}") ;;
t) build_type=${OPTARG} ;;
g) generator=${OPTARG} ;;
s) parse_assignment "${OPTARG}" ;;
f) export_dir=$(realpath "${OPTARG}") ;;
l) list_only="1" ;;
h) usage; exit 0 ;;
x) nested="1" ;;
*) usage; exit 1 ;;
esac
done
shift $((OPTIND - 1))
cooking_dir="${build_dir}/_cooking"
cache_file="${build_dir}/CMakeCache.txt"
ingredients_ready_file="${cooking_dir}/ready.txt"
if [ -z "${ingredients_dir}" ]; then
ingredients_dir="${cooking_dir}/installed"
fi
mkdir -p "${build_dir}"
cat <<'EOF' > "${build_dir}/Cooking.cmake"
#
# Copyright 2018 Jesse Haber-Kucharsky
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# This file was generated by cmake-cooking v0.10.0
# The home of cmake-cooking is https://github.com/hakuch/CMakeCooking
#
macro (project name)
set (_cooking_dir ${CMAKE_CURRENT_BINARY_DIR}/_cooking)
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set (_cooking_root ON)
else ()
set (_cooking_root OFF)
endif ()
find_program (Cooking_STOW_EXECUTABLE
stow
"Executable path of GNU Stow.")
if (NOT Cooking_STOW_EXECUTABLE)
message (FATAL_ERROR "Cooking: GNU Stow is required!")
endif ()
set (Cooking_INGREDIENTS_DIR
${_cooking_dir}/installed
CACHE
PATH
"Directory where ingredients will be installed.")
set (Cooking_EXCLUDED_INGREDIENTS
""
CACHE
STRING
"Semicolon-separated list of ingredients that are not provided by Cooking.")
set (Cooking_INCLUDED_INGREDIENTS
""
CACHE
STRING
"Semicolon-separated list of ingredients that are provided by Cooking.")
option (Cooking_LIST_ONLY
"Available ingredients will be listed and nothing will be installed."
OFF)
set (Cooking_RECIPE "" CACHE STRING "Configure ${name}'s dependencies according to the named recipe.")
if ((NOT DEFINED Cooking_EXCLUDED_INGREDIENTS) OR (Cooking_EXCLUDED_INGREDIENTS STREQUAL ""))
set (_cooking_is_excluding OFF)
else ()
set (_cooking_is_excluding ON)
endif ()
if ((NOT DEFINED Cooking_INCLUDED_INGREDIENTS) OR (Cooking_INCLUDED_INGREDIENTS STREQUAL ""))
set (_cooking_is_including OFF)
else ()
set (_cooking_is_including ON)
endif ()
if (_cooking_is_excluding AND _cooking_is_including)
message (
FATAL_ERROR
"Cooking: The EXCLUDED_INGREDIENTS and INCLUDED_INGREDIENTS lists are mutually exclusive options!")
endif ()
if (_cooking_root)
_project (${name} ${ARGN})
if (NOT ("${Cooking_RECIPE}" STREQUAL ""))
add_custom_target (_cooking_ingredients)
set (_cooking_ready_marker_file ${_cooking_dir}/ready.txt)
add_custom_command (
OUTPUT ${_cooking_ready_marker_file}
DEPENDS _cooking_ingredients
COMMAND ${CMAKE_COMMAND} -E touch ${_cooking_ready_marker_file})
add_custom_target (_cooking_ingredients_ready
DEPENDS ${_cooking_ready_marker_file})
set (_cooking_local_synchronize_marker_file ${Cooking_INGREDIENTS_DIR}/.cooking_local_synchronize)
add_custom_command (
OUTPUT ${_cooking_local_synchronize_marker_file}
COMMAND ${CMAKE_COMMAND} -E touch ${_cooking_local_synchronize_marker_file})
add_custom_target (_cooking_marked_for_local_synchronization
DEPENDS ${_cooking_local_synchronize_marker_file})
list (APPEND CMAKE_PREFIX_PATH ${Cooking_INGREDIENTS_DIR})
include (${Cooking_RECIPE})
if (NOT EXISTS ${_cooking_ready_marker_file})
return ()
endif ()
endif ()
endif ()
endmacro ()
function (_cooking_set_union x y var)
set (r ${${x}})
foreach (e ${${y}})
list (APPEND r ${e})
endforeach ()
list (REMOVE_DUPLICATES r)
set (${var} ${r} PARENT_SCOPE)
endfunction ()
function (_cooking_set_difference x y var)
set (r ${${x}})
foreach (e ${${y}})
if (${e} IN_LIST ${x})
list (REMOVE_ITEM r ${e})
endif ()
endforeach ()
set (${var} ${r} PARENT_SCOPE)
endfunction ()
function (_cooking_set_intersection x y var)
set (r "")
foreach (e ${${y}})
if (${e} IN_LIST ${x})
list (APPEND r ${e})
endif ()
endforeach ()
list (REMOVE_DUPLICATES r)
set (${var} ${r} PARENT_SCOPE)
endfunction ()
function (_cooking_query_by_key list key var)
list (FIND ${list} ${key} index)
if (${index} EQUAL "-1")
set (value NOTFOUND)
else ()
math (EXPR value_index "${index} + 1")
list (GET ${list} ${value_index} value)
endif ()
set (${var} ${value} PARENT_SCOPE)
endfunction ()
function (_cooking_populate_ep_parameter)
cmake_parse_arguments (
pa
""
"EXTERNAL_PROJECT_ARGS_LIST;PARAMETER;DEFAULT_VALUE"
""
${ARGN})
string (TOLOWER ${pa_PARAMETER} parameter_lower)
_cooking_query_by_key (${pa_EXTERNAL_PROJECT_ARGS_LIST} ${pa_PARAMETER} ${parameter_lower})
set (value ${${parameter_lower}})
set (var_name _cooking_${parameter_lower})
set (ep_var_name _cooking_ep_${parameter_lower})
if (NOT value)
set (${var_name} ${pa_DEFAULT_VALUE} PARENT_SCOPE)
set (${ep_var_name} ${pa_PARAMETER} ${pa_DEFAULT_VALUE} PARENT_SCOPE)
else ()
set (${var_name} ${value} PARENT_SCOPE)
set (${ep_var_name} "" PARENT_SCOPE)
endif ()
endfunction ()
function (_cooking_define_listing_targets)
cmake_parse_arguments (
pa
""
"NAME;SOURCE_DIR;RECIPE"
"REQUIRES"
${ARGN})
set (stale_file ${Cooking_INGREDIENTS_DIR}/.cooking_stale_ingredient_${pa_NAME})
add_custom_command (
OUTPUT ${stale_file}
COMMAND ${CMAKE_COMMAND} -E touch ${stale_file})
add_custom_target (_cooking_ingredient_${pa_NAME}_stale
DEPENDS ${stale_file})
set (commands
COMMAND
${CMAKE_COMMAND} -E touch ${Cooking_INGREDIENTS_DIR}/.cooking_ingredient_${pa_NAME})
if (pa_RECIPE)
if (pa_RECIPE STREQUAL <DEFAULT>)
set (recipe_args "")
else ()
set (recipe_args -r ${pa_RECIPE})
endif ()
list (INSERT commands 0
COMMAND
${pa_SOURCE_DIR}/cooking.sh
${recipe_args}
-p ${Cooking_INGREDIENTS_DIR}
-g ${CMAKE_GENERATOR}
-x
-l)
endif ()
add_custom_command (
OUTPUT ${Cooking_INGREDIENTS_DIR}/.cooking_ingredient_${pa_NAME}
DEPENDS
_cooking_ingredient_${pa_NAME}_stale
${stale_file}
${commands})
add_custom_target (_cooking_ingredient_${pa_NAME}_listed
DEPENDS ${Cooking_INGREDIENTS_DIR}/.cooking_ingredient_${pa_NAME})
foreach (d ${pa_REQUIRES})
add_dependencies (_cooking_ingredient_${pa_NAME}_listed _cooking_ingredient_${d}_listed)
endforeach ()
add_dependencies (_cooking_ingredients _cooking_ingredient_${pa_NAME}_listed)
endfunction ()
function (_cooking_adjust_requirements)
cmake_parse_arguments (
pa
""
"IS_EXCLUDING;IS_INCLUDING;OUTPUT_LIST"
"REQUIREMENTS"
${ARGN})
if (pa_IS_EXCLUDING)
# Strip out any dependencies that are excluded.
_cooking_set_difference (
pa_REQUIREMENTS
Cooking_EXCLUDED_INGREDIENTS
pa_REQUIREMENTS)
elseif (_cooking_is_including)
# Eliminate dependencies that have not been included.
_cooking_set_intersection (
pa_REQUIREMENTS
Cooking_INCLUDED_INGREDIENTS
pa_REQUIREMENTS)
endif ()
set (${pa_OUTPUT_LIST} ${pa_REQUIREMENTS} PARENT_SCOPE)
endfunction ()
function (_cooking_populate_ep_depends)
cmake_parse_arguments (
pa
""
""
"REQUIREMENTS"
${ARGN})
if (pa_REQUIREMENTS)
set (value DEPENDS)
foreach (d ${pa_REQUIREMENTS})
list (APPEND value ingredient_${d})
endforeach ()
else ()
set (value "")
endif ()
set (_cooking_ep_depends ${value} PARENT_SCOPE)
endfunction ()
function (_cooking_prepare_restrictions_arguments)
cmake_parse_arguments (
pa
""
"IS_EXCLUDING;IS_INCLUDING;OUTPUT_LIST"
"REQUIREMENTS"
${ARGN})
set (args "")
if (pa_IS_INCLUDING)
_cooking_set_difference (
Cooking_INCLUDED_INGREDIENTS
pa_REQUIREMENTS
included)
foreach (x ${included})
list (APPEND args -i ${x})
endforeach ()
elseif (pa_IS_EXCLUDING)
_cooking_set_union (
Cooking_EXCLUDED_INGREDIENTS
pa_REQUIREMENTS
excluded)
foreach (x ${excluded})
list (APPEND args -e ${x})
endforeach ()
else ()
foreach (x ${pa_REQUIREMENTS})
list (APPEND args -e ${x})
endforeach ()
endif ()
set (${pa_OUTPUT_LIST} ${args} PARENT_SCOPE)
endfunction ()
function (_cooking_determine_common_cmake_args output)
string (REPLACE ";" ":::" prefix_path_with_colons "${CMAKE_PREFIX_PATH}")
set (cmake_args "-G" "${CMAKE_GENERATOR}")
if (CMAKE_CXX_FLAGS)
list(APPEND cmake_args -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS})
endif ()
if (CMAKE_C_FLAGS)
list(APPEND cmake_args -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS})
endif ()
list (APPEND cmake_args
-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
-DCMAKE_PREFIX_PATH=${prefix_path_with_colons}
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS})
set (${output} ${cmake_args}
PARENT_SCOPE)
endfunction ()
function (_cooking_populate_ep_configure_command)
cmake_parse_arguments (
pa
""
"IS_EXCLUDING;IS_INCLUDING;RECIPE;EXTERNAL_PROJECT_ARGS_LIST"
"REQUIREMENTS;CMAKE_ARGS;COOKING_CMAKE_ARGS"
${ARGN})
if (pa_RECIPE)
if (pa_RECIPE STREQUAL <DEFAULT>)
set (recipe_args "")
else ()
set (recipe_args -r ${pa_RECIPE})
endif ()
_cooking_prepare_restrictions_arguments (
IS_EXCLUDING ${pa_IS_EXCLUDING}
IS_INCLUDING ${pa_IS_INCLUDING}
REQUIREMENTS ${pa_REQUIREMENTS}
OUTPUT_LIST restrictions_args)
set (value
CONFIGURE_COMMAND
<SOURCE_DIR>/cooking.sh
${recipe_args}
-d <BINARY_DIR>
-p ${Cooking_INGREDIENTS_DIR}
-g ${CMAKE_GENERATOR}
-x
${restrictions_args}
--
${pa_COOKING_CMAKE_ARGS})
elseif (NOT (CONFIGURE_COMMAND IN_LIST ${pa_EXTERNAL_PROJECT_ARGS_LIST}))
set (value
CONFIGURE_COMMAND
${CMAKE_COMMAND}
${pa_CMAKE_ARGS}
<SOURCE_DIR>)
else ()
set (value "")
endif ()
set (_cooking_ep_configure_command ${value} PARENT_SCOPE)
endfunction ()
function (_cooking_populate_ep_build_command ep_args_list)
if (NOT (BUILD_COMMAND IN_LIST ${ep_args_list}))
set (value BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR>)
else ()
set (value "")
endif ()
set (_cooking_ep_build_command ${value} PARENT_SCOPE)
endfunction ()
function (_cooking_populate_ep_install_command ep_args_list)
if (NOT (INSTALL_COMMAND IN_LIST ${ep_args_list}))
set (value INSTALL_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --target install)
else ()
set (value "")
endif ()
set (_cooking_ep_install_command ${value} PARENT_SCOPE)
endfunction ()
function (_cooking_define_ep)
cmake_parse_arguments (
pa
""
"NAME;SOURCE_DIR;BINARY_DIR;EXTERNAL_PROJECT_ARGS_LIST;RECIPE;INGREDIENT_DIR;STOW_DIR;LOCAL_RECONFIGURE;LOCAL_REBUILD"
"DEPENDS;CONFIGURE_COMMAND;BUILD_COMMAND;INSTALL_COMMAND;CMAKE_ARGS"
${ARGN})
string (REPLACE "<DISABLE>" "" forwarded_ep_args "${${pa_EXTERNAL_PROJECT_ARGS_LIST}}")
set (ep_name ingredient_${pa_NAME})
include (ExternalProject)
set (stamp_dir ${pa_INGREDIENT_DIR}/stamp)
ExternalProject_add (${ep_name}
DEPENDS ${pa_DEPENDS}
SOURCE_DIR ${pa_SOURCE_DIR}
BINARY_DIR ${pa_BINARY_DIR}
CONFIGURE_COMMAND ${pa_CONFIGURE_COMMAND}
BUILD_COMMAND ${pa_BUILD_COMMAND}
INSTALL_COMMAND ${pa_INSTALL_COMMAND}
PREFIX ${pa_INGREDIENT_DIR}
STAMP_DIR ${stamp_dir}
INSTALL_DIR ${pa_STOW_DIR}/${pa_NAME}
CMAKE_ARGS ${pa_CMAKE_ARGS}
LIST_SEPARATOR :::
STEP_TARGETS install
"${forwarded_ep_args}")
set (stow_marker_file ${Cooking_INGREDIENTS_DIR}/.cooking_ingredient_${pa_NAME})
set (lock_file ${Cooking_INGREDIENTS_DIR}/.cooking_stow.lock)
add_custom_command (
OUTPUT ${stow_marker_file}
DEPENDS
${ep_name}-install
${stamp_dir}/ingredient_${pa_NAME}-install
COMMAND
flock
--wait 30
${lock_file}
${Cooking_STOW_EXECUTABLE}
-t ${Cooking_INGREDIENTS_DIR}
-d ${pa_STOW_DIR}
${pa_NAME}
COMMAND ${CMAKE_COMMAND} -E touch ${stow_marker_file})
add_custom_target (_cooking_ingredient_${pa_NAME}_stowed
DEPENDS ${stow_marker_file})
if (pa_RECIPE)
set (reconfigure_marker_file ${Cooking_INGREDIENTS_DIR}/.cooking_reconfigure_ingredient_${pa_NAME})
add_custom_command (
OUTPUT ${reconfigure_marker_file}
COMMAND ${CMAKE_COMMAND} -E touch ${reconfigure_marker_file})
add_custom_target (_cooking_ingredient_${pa_NAME}_marked_for_reconfigure
DEPENDS ${reconfigure_marker_file})
ExternalProject_add_step (${ep_name}
cooking-reconfigure
DEPENDERS configure
DEPENDS ${reconfigure_marker_file}
COMMAND ${CMAKE_COMMAND} -E echo_append)
ExternalProject_add_stepdependencies (${ep_name}
cooking-reconfigure
_cooking_ingredient_${pa_NAME}_marked_for_reconfigure)
endif ()
foreach (d ${pa_DEPENDS})
ExternalProject_add_stepdependencies (${ep_name}
configure
_cooking_${d}_stowed)
endforeach ()
add_dependencies (_cooking_ingredients _cooking_ingredient_${pa_NAME}_stowed)
if (pa_LOCAL_RECONFIGURE OR pa_LOCAL_REBUILD)
if (pa_LOCAL_RECONFIGURE)
set (step configure)
else ()
set (step build)
endif ()
ExternalProject_add_step (${ep_name}
cooking-local-${step}
DEPENDERS ${step}
DEPENDS ${_cooking_local_synchronize_marker_file}
COMMAND ${CMAKE_COMMAND} -E echo_append)
ExternalProject_add_stepdependencies (${ep_name}
cooking-local-${step}
_cooking_marked_for_local_synchronization)
endif ()
endfunction ()
macro (cooking_ingredient name)
set (_cooking_args "${ARGN}")
if ((_cooking_is_excluding AND (${name} IN_LIST Cooking_EXCLUDED_INGREDIENTS))
OR (_cooking_is_including AND (NOT (${name} IN_LIST Cooking_INCLUDED_INGREDIENTS))))
# Nothing.
else ()
set (_cooking_ingredient_dir ${_cooking_dir}/ingredient/${name})
cmake_parse_arguments (
_cooking_pa
"LOCAL_RECONFIGURE;LOCAL_REBUILD"
"COOKING_RECIPE"
"CMAKE_ARGS;COOKING_CMAKE_ARGS;EXTERNAL_PROJECT_ARGS;REQUIRES"
${_cooking_args})
_cooking_populate_ep_parameter (
EXTERNAL_PROJECT_ARGS_LIST _cooking_pa_EXTERNAL_PROJECT_ARGS
PARAMETER SOURCE_DIR
DEFAULT_VALUE ${_cooking_ingredient_dir}/src)
_cooking_populate_ep_parameter (
EXTERNAL_PROJECT_ARGS_LIST _cooking_pa_EXTERNAL_PROJECT_ARGS
PARAMETER BINARY_DIR
DEFAULT_VALUE ${_cooking_ingredient_dir}/build)
_cooking_populate_ep_parameter (
EXTERNAL_PROJECT_ARGS_LIST _cooking_pa_EXTERNAL_PROJECT_ARGS
PARAMETER BUILD_IN_SOURCE
DEFAULT_VALUE OFF)
if (_cooking_build_in_source)
set (_cooking_ep_binary_dir "")
endif ()
if (Cooking_LIST_ONLY)
_cooking_define_listing_targets (
NAME ${name}
SOURCE_DIR ${_cooking_source_dir}
RECIPE ${_cooking_pa_COOKING_RECIPE}
REQUIRES ${_cooking_pa_REQUIRES})
else ()
_cooking_adjust_requirements (
IS_EXCLUDING ${_cooking_is_excluding}
IS_INCLUDING ${_cooking_is_including}
REQUIREMENTS ${_cooking_pa_REQUIRES}
OUTPUT_LIST _cooking_pa_REQUIRES)
_cooking_populate_ep_depends (
REQUIREMENTS ${_cooking_pa_REQUIRES})
_cooking_determine_common_cmake_args (_cooking_common_cmake_args)
_cooking_populate_ep_configure_command (
IS_EXCLUDING ${_cooking_is_excluding}
IS_INCLUDING ${_cooking_is_including}
RECIPE ${_cooking_pa_COOKING_RECIPE}
REQUIREMENTS ${_cooking_pa_REQUIRES}
EXTERNAL_PROJECT_ARGS_LIST _cooking_pa_EXTERNAL_PROJECT_ARGS
CMAKE_ARGS
${_cooking_common_cmake_args}
${_cooking_pa_CMAKE_ARGS}
COOKING_CMAKE_ARGS
${_cooking_common_cmake_args}
${_cooking_pa_COOKING_CMAKE_ARGS})
_cooking_populate_ep_build_command (_cooking_pa_EXTERNAL_PROJECT_ARGS)
_cooking_populate_ep_install_command (_cooking_pa_EXTERNAL_PROJECT_ARGS)
_cooking_define_ep (
NAME ${name}
RECIPE ${_cooking_pa_COOKING_RECIPE}
DEPENDS ${_cooking_ep_depends}
SOURCE_DIR ${_cooking_ep_source_dir}
BINARY_DIR ${_cooking_ep_binary_dir}
CONFIGURE_COMMAND ${_cooking_ep_configure_command}
BUILD_COMMAND ${_cooking_ep_build_command}
INSTALL_COMMAND ${_cooking_ep_install_command}
INGREDIENT_DIR ${_cooking_ingredient_dir}
STOW_DIR ${_cooking_dir}/stow
CMAKE_ARGS ${_cooking_common_cmake_args}
EXTERNAL_PROJECT_ARGS_LIST _cooking_pa_EXTERNAL_PROJECT_ARGS
LOCAL_RECONFIGURE ${_cooking_pa_LOCAL_RECONFIGURE}
LOCAL_REBUILD ${_cooking_pa_LOCAL_REBUILD})
endif ()
endif ()
endmacro ()
EOF
cmake_cooking_args=(
"-DCooking_INGREDIENTS_DIR=${ingredients_dir}"
"-DCooking_RECIPE=${recipe}"
)
#
# Remove any `Cooking.cmake` file from the source directory. We now generate this file in the build directory, and old
# copies will cause conflicts.
#
old_cooking_file="${source_dir}/cmake/Cooking.cmake"
if [ -f "${old_cooking_file}" ]; then
grep 'This file was generated by cmake-cooking' "${old_cooking_file}" > /dev/null && rm "${old_cooking_file}"
fi
#
# Clean-up from a previous run.
#
if [ -e "${ingredients_ready_file}" ]; then
rm "${ingredients_ready_file}"
fi
if [ -e "${cache_file}" ]; then
rm "${cache_file}"
fi
if [ -d "${ingredients_dir}" -a -z "${nested}" ]; then
rm -r --preserve-root "${ingredients_dir}"
fi
mkdir -p "${ingredients_dir}"
#
# Validate recipe.
#
if [ -n "${recipe}" ]; then
if [ ! -f "${recipe}" ]; then
echo "Cooking: The '${recipe}' recipe does not exist!" >&2
exit 1
fi
fi
#
# Prepare lists of included and excluded ingredients.
#
if [ -n "${excluded_ingredients}" ] && [ -z "${list_only}" ]; then
cmake_cooking_args+=(
-DCooking_EXCLUDED_INGREDIENTS=$(printf "%s;" "${excluded_ingredients[@]}")
-DCooking_INCLUDED_INGREDIENTS=
)
fi
if [ -n "${included_ingredients}" ] && [ -z "${list_only}" ]; then
cmake_cooking_args+=(
-DCooking_EXCLUDED_INGREDIENTS=
-DCooking_INCLUDED_INGREDIENTS=$(printf "%s;" "${included_ingredients[@]}")
)
fi
#
# Configure and build ingredients.
#
mkdir -p "${cooking_dir}"/stow
touch "${cooking_dir}"/stow/.stow
cd "${build_dir}"
declare -a build_args
if [ "${generator}" == "Ninja" ]; then
build_args+=(-v)
fi
if [ -n "${list_only}" ]; then
cmake_cooking_args+=("-DCooking_LIST_ONLY=ON")
fi
${CMAKE} -DCMAKE_BUILD_TYPE="${build_type}" "${cmake_cooking_args[@]}" -G "${generator}" "${source_dir}" "${@}"
if [ -n "${recipe}" ]; then
${CMAKE} --build . --target _cooking_ingredients_ready -- "${build_args[@]}"
#
# Report what we've done (if we're not nested).
#
if [ -z "${nested}" ]; then
ingredients=($(find "${ingredients_dir}" -name '.cooking_ingredient_*' -printf '%f\n' | sed -r 's/\.cooking_ingredient_(.+)/\1/'))
if [ -z "${list_only}" ]; then
printf "\nCooking: Installed the following ingredients:\n"
else
printf "\nCooking: The following ingredients are necessary for this recipe:\n"
fi
for ingredient in "${ingredients[@]}"; do
echo " - ${ingredient}"
done
printf '\n'
fi
if [ -n "${list_only}" ]; then
exit 0
fi
#
# Configure the project, expecting all requirements satisfied.
#
${CMAKE} -DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=ON "${@}" .
#
# Optionally export the installed files.
#
if [ -n "${export_dir}" ]; then
rsync "${ingredients_dir}/" "${export_dir}" -a --copy-links
printf "\nCooking: Exported ingredients to ${export_dir}\n"
fi
fi
#
# Save invocation information.
#
cd "${initial_wd}"
cat <<EOF > "${memory_file}"
run_previous() {
"${0}" ${invoked_args[@]@Q}
}
EOF