fix(cmake): use proper CMakePresets.json parsing
This commit is contained in:
parent
bea1fb2a32
commit
3d348d410d
86
src/_cmake
86
src/_cmake
|
|
@ -172,6 +172,61 @@ _cmake_json_field() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ----------------------
|
||||||
|
# _cmake_json_preset_block
|
||||||
|
#
|
||||||
|
# Slice out one preset object (by its "name") from a presets-array section
|
||||||
|
# (the text following the "buildPresets"/"configurePresets" key). Returns the
|
||||||
|
# object's text from its "name" entry up to the start of the next preset's
|
||||||
|
# "name" entry.
|
||||||
|
# ----------------------
|
||||||
|
(( $+functions[_cmake_json_preset_block] )) ||
|
||||||
|
_cmake_json_preset_block() {
|
||||||
|
local section="$1" name="$2"
|
||||||
|
local after="${section#*\"name\"[[:space:]]#:[[:space:]]#\"$name\"}"
|
||||||
|
[[ $after == "$section" ]] && return 1
|
||||||
|
print -r -- "${after%%\"name\"[[:space:]]#:*}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----------------------
|
||||||
|
# _cmake_json_inherited_field
|
||||||
|
#
|
||||||
|
# Look up $field on preset $name inside array-section $section, following
|
||||||
|
# "inherits" (a string or an array of strings) when the preset itself
|
||||||
|
# doesn't set the field, depth-first with first-match-wins -- matching
|
||||||
|
# CMake's own resolution order. $4 is an internal "seen names" guard
|
||||||
|
# against cyclic (invalid) inherits.
|
||||||
|
# ----------------------
|
||||||
|
(( $+functions[_cmake_json_inherited_field] )) ||
|
||||||
|
_cmake_json_inherited_field() {
|
||||||
|
local section="$1" name="$2" field="$3" seen="$4"
|
||||||
|
[[ " $seen " == *" $name "* ]] && return 1
|
||||||
|
|
||||||
|
local block
|
||||||
|
block=$(_cmake_json_preset_block "$section" "$name") || return 1
|
||||||
|
|
||||||
|
local value
|
||||||
|
value=$(_cmake_json_field "$block" "$field")
|
||||||
|
if [[ -n $value ]]; then
|
||||||
|
print -r -- "$value"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local parent
|
||||||
|
if [[ $block =~ '"inherits"[[:space:]]*:[[:space:]]*\[([^]]*)\]' ]]; then
|
||||||
|
for parent in ${(s:,:)match[1]}; do
|
||||||
|
parent=${parent//[\"[:space:]]/}
|
||||||
|
[[ -z $parent ]] && continue
|
||||||
|
value=$(_cmake_json_inherited_field "$section" "$parent" "$field" "$seen $name") && \
|
||||||
|
{ print -r -- "$value"; return 0 }
|
||||||
|
done
|
||||||
|
elif [[ $block =~ '"inherits"[[:space:]]*:[[:space:]]*"([^"]*)"' ]]; then
|
||||||
|
_cmake_json_inherited_field "$section" "$match[1]" "$field" "$seen $name"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
# ----------------------
|
# ----------------------
|
||||||
# _cmake_json_preset_dir
|
# _cmake_json_preset_dir
|
||||||
#
|
#
|
||||||
|
|
@ -180,12 +235,9 @@ _cmake_json_field() {
|
||||||
# $2 = build preset name
|
# $2 = build preset name
|
||||||
#
|
#
|
||||||
# Steps:
|
# Steps:
|
||||||
# a) Slice out the build preset object (from its "name" entry up to the next "name" entry)
|
# a) Find the build preset's "configurePreset" (following "inherits" if needed).
|
||||||
# and read its "configurePreset".
|
# b) Find that configure preset's "binaryDir" (following "inherits" if needed).
|
||||||
# b) Slice out that configure preset object the same way and read its "binaryDir".
|
# c) Expand the ${sourceDir}/${presetName} macros and strip a trailing slash.
|
||||||
# c) Expand the ${sourceDir} macro and strip a trailing slash.
|
|
||||||
# Inheritance ("inherits") is not resolved; the caller's glob fallback covers
|
|
||||||
# those uncommon setups.
|
|
||||||
# ----------------------
|
# ----------------------
|
||||||
(( $+functions[_cmake_json_preset_dir] )) ||
|
(( $+functions[_cmake_json_preset_dir] )) ||
|
||||||
_cmake_json_preset_dir() {
|
_cmake_json_preset_dir() {
|
||||||
|
|
@ -193,29 +245,23 @@ _cmake_json_preset_dir() {
|
||||||
setopt extendedglob
|
setopt extendedglob
|
||||||
local json="$1" name="$2"
|
local json="$1" name="$2"
|
||||||
|
|
||||||
# --- a) locate the build preset object, read its configurePreset ---
|
# Restrict the "name" search to the right array so a configurePreset and
|
||||||
# Everything from `"name": "<name>"` onward:
|
# a buildPreset sharing the same name (a common CMakePresets pattern)
|
||||||
local after="${json#*\"name\"[[:space:]]#:[[:space:]]#\"$name\"}"
|
# don't get confused for one another.
|
||||||
[[ $after == "$json" ]] && return # name not found
|
local build_section="${json#*\"buildPresets\"}"
|
||||||
# Trim at the start of the *next* preset object's name field, so we only
|
local configure_section="${json#*\"configurePresets\"}"
|
||||||
# look inside this preset.
|
|
||||||
local block="${after%%\"name\"[[:space:]]#:*}"
|
|
||||||
|
|
||||||
local configPreset
|
local configPreset
|
||||||
configPreset=$(_cmake_json_field "$block" configurePreset)
|
configPreset=$(_cmake_json_inherited_field "$build_section" "$name" configurePreset)
|
||||||
[[ -z $configPreset ]] && return
|
[[ -z $configPreset ]] && return
|
||||||
|
|
||||||
# --- b) locate that configure preset object, read its binaryDir ---
|
|
||||||
after="${json#*\"name\"[[:space:]]#:[[:space:]]#\"$configPreset\"}"
|
|
||||||
[[ $after == "$json" ]] && return
|
|
||||||
block="${after%%\"name\"[[:space:]]#:*}"
|
|
||||||
|
|
||||||
local bd
|
local bd
|
||||||
bd=$(_cmake_json_field "$block" binaryDir)
|
bd=$(_cmake_json_inherited_field "$configure_section" "$configPreset" binaryDir)
|
||||||
[[ -z $bd ]] && return
|
[[ -z $bd ]] && return
|
||||||
|
|
||||||
# --- c) expand macros ---
|
# --- c) expand macros ---
|
||||||
bd="${bd//\$\{sourceDir\}/$PWD}"
|
bd="${bd//\$\{sourceDir\}/$PWD}"
|
||||||
|
bd="${bd//\$\{presetName\}/$configPreset}"
|
||||||
bd="${bd%/}"
|
bd="${bd%/}"
|
||||||
print -r -- "$bd"
|
print -r -- "$bd"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue