首次提交

This commit is contained in:
2026-06-16 10:23:51 +08:00
commit aaeb52173b
740 changed files with 173337 additions and 0 deletions
+373
View File
@@ -0,0 +1,373 @@
#!/bin/bash
# shellcheck disable=SC2155
if ! type "include" > /dev/null 2>&1; then
include() {
. "$(cd "$(dirname "$1")" && pwd)/${2}";
};
fi
include "${BASH_SOURCE[0]}" ../pragma_once.bash
if ! pragma_once ${BASH_SOURCE[0]}; then return 0; fi
include "${BASH_SOURCE[0]}" ../base/export.bash
false && source ../base/export.bash
insert_after_match() {
local file="$1"
local pattern="$2"
local insert_content="$3"
if [[ ! -f "$file" ]]; then
echo "File not found: $file"
return 75
fi
local tmp="${file}.tmp"
# 使用 awk 插入(比 sed 更稳) awk 是拓展正则表达式 \(是字面量
echo "insert_content ${insert_content}"
awk -v pat="$pattern" -v block="$insert_content" '
{
print
if ($0 ~ pat && inserted != 1) {
print block
inserted=1
}
}
END {
if (inserted == 1)
exit 0
else
exit 100
}
' "$file" >"$tmp"
rc=$?
if [[ $rc -eq 0 ]]; then
mv "$tmp" "$file"
echo "插入成功!"
return 0
else
rm -f "$tmp"
echo "插入失败没找到"
return 76
fi
}
_collect_files() {
local path_list="$1"
local exclude_list="$2"
local -n out_files="$3"
local -n out_skipped="$4"
local paths=()
local excludes=()
local path=""
local file=""
local ex=""
out_files=()
out_skipped=()
IFS=',' read -ra paths <<< "$path_list"
IFS=',' read -ra excludes <<< "$exclude_list"
for path in "${paths[@]}"; do
[[ -z "$path" ]] && continue
if [[ -f "$path" ]]; then
local skip=0
for ex in "${excludes[@]}"; do
[[ -z "$ex" ]] && continue
if [[ "$path" == "$ex" ]] || \
[[ "$(basename "$path")" == "$ex" ]] || \
[[ "$path" == $ex ]]; then
skip=1
break
fi
if [[ -d "$ex" ]]; then
[[ "$path" == "$ex" || "$path" == "$ex"/* ]] && skip=1 && break
fi
done
if [[ $skip -eq 1 ]]; then
out_skipped+=("$path")
else
out_files+=("$path")
fi
elif [[ -d "$path" ]]; then
while IFS= read -r -d '' file; do
local skip=0
for ex in "${excludes[@]}"; do
[[ -z "$ex" ]] && continue
if [[ "$file" == "$ex" ]] || \
[[ "$(basename "$file")" == "$ex" ]] || \
[[ "$file" == $ex ]]; then
skip=1
break
fi
if [[ -d "$ex" ]]; then
[[ "$file" == "$ex" || "$file" == "$ex"/* ]] && skip=1 && break
fi
done
if [[ $skip -eq 1 ]]; then
out_skipped+=("$file")
else
out_files+=("$file")
fi
done < <(find "$path" -type f -print0)
else
echo "WARNING: path not found, skip: $path"
fi
done
}
sed_in_tree() {
local path_list="$1"
local search_str="$2"
local replace_str="$3"
local exclude_list="$4"
local files=()
local skipped=()
_collect_files "$path_list" "$exclude_list" files skipped
[[ -z "$search_str" ]] && {
log_error "search_str is empty"
return 1
}
# ================= sed 替换规则说明 =================
# sed 替换基本格式:
# s<分隔符>pattern<分隔符>replacement<分隔符>flags
# --------------------------------------------------
# 一、分隔符(delimiter
#
# - 可以自定义为任意“单个字符”
# - 常见:/ | # @
# - 如果分隔符出现在 pattern 或 replacement 中,必须转义
#
# 示例:
# s|/home/user|/tmp|g # 推荐(避免转义 /)
#
# --------------------------------------------------
# 二、pattern(左边:正则表达式)
#
# 默认是 BRE(基本正则)
#
# 特殊字符:
# . 任意字符
# * 重复
# ^ 行首
# $ 行尾
# [ ] 字符集合
# \ 转义符
#
# 如果要匹配字面值,需要转义:
# a.b -> a\.b
#
# --------------------------------------------------
# 三、replacement(右边:替换内容)
#
# 特殊符号:
# & 代表“整个匹配内容”
# \1 第1个分组
# \2 第2个分组
# \ 转义符
#
# 示例:
# s/b/&X/ -> b 变成 bX
#
# 如果要替换成字面 &
# \&
#
# --------------------------------------------------
# 四、分隔符冲突
#
# 如果你用:
# s|xxx|yyy|
#
# 那么:
# | 出现在内容里必须写成 \|
#
# --------------------------------------------------
# 五、shell 层注意(非常重要)
#
# 在 bash 中:
# sed "s|$search|$replace|g"
#
# 实际有三层解析:
# 1. shell 变量展开
# 2. sed pattern(正则)
# 3. sed replacement(特殊符号)
#
# 风险:
# - pattern 被当正则(. * 等会生效)
# - replacement 中 & 会被替换
# - 分隔符冲突导致报错
#
# --------------------------------------------------
# 六、结论
#
# - sed 转义符是:\
# - 左边是正则,右边是替换语法
# - 分隔符可以自定义,但要避免冲突
#
# ==================================================
printf '%s\0' "${files[@]}" | xargs -0 sed -i "s|${search_str}|${replace_str}|g"
log_debug "-----------------------------------"
log_debug "$search_str】 替换为 【$replace_str"
log_debug "Files : ${#files[@]}"
log_debug "Files skipped : ${#skipped[@]}"
}
#gen_pth my.pth \
# "D:\wyc\env\...\python3.12" \
# "D:\wyc\env\...\lib-dynload"
gen_python_pth() {
local pth_file="$1"
shift
if [ -z "$pth_file" ] || [ "$#" -eq 0 ]; then
log_warn "Usage: gen_python_pth <output.pth> <path1> [path2 ...]" >&2
return 1
fi
local pth_dir
pth_dir="$(cd "$(dirname "$pth_file")" 2>/dev/null && pwd)"
if [ -z "$pth_dir" ]; then
log_error "Error: cannot resolve pth file directory: $pth_file" >&2
return 1
fi
local p resolved
# 先检查,全部通过后再写文件,避免生成半截内容
for p in "$@"; do
case "$p" in
/*|[A-Za-z]:[\\/]*)
# 绝对路径:Linux /xxx 或 Windows C:\xxx / C:/xxx
resolved="$p"
;;
*)
# 相对路径:相对于 .pth 文件所在目录
resolved="$pth_dir/$p"
;;
esac
if [ ! -d "$resolved" ]; then
log_error "Error: directory does not exist: $p" >&2
log_error " resolved path: $resolved" >&2
return 1
fi
done
: > "$pth_file" || {
log_error "Error: cannot write to $pth_file" >&2
return 1
}
for p in "$@"; do
echo "$p" >> "$pth_file"
done
log_debug "Generated $pth_file"
}
# /ae/bash/gcc/env/win_arm_kylin_930/sysroot/usr/lib/aarch64-linux-gnu/cmake
# sysroot/usr/lib/aarch64-linux-gnu/cmake
patch_system_qt5(){
local SYSROOT="${1}"
local CMAKE_DIR="${2}"
local qt_host_tool_dir="${3}"
check_directory_var qt_host_tool_dir
check_file_ex "传入的qt_host_tool_dir不对,不包含必须文件moc.exe" "${qt_host_tool_dir}/moc.exe"
local dest="${SYSROOT}/usr/lib/qt5/bin"
check_and_create_dir_var dest
cp -r "${qt_host_tool_dir}/"* "${dest}"
check_directory "${SYSROOT}"
check_directory "${CMAKE_DIR}"
local CMAKE_CURRENT_LIST_DIR="${CMAKE_DIR}/Qt5"
check_directory "${CMAKE_CURRENT_LIST_DIR}"
local exclude_list="${CMAKE_CURRENT_LIST_DIR}/Qt5Config.cmake"
local Qt5WidgetsConfigExtras="${CMAKE_DIR}/Qt5Widgets/Qt5WidgetsConfigExtras.cmake"
check_file_var Qt5WidgetsConfigExtras
sed_in_tree \
"${Qt5WidgetsConfigExtras}" \
'bin/uic"' \
'bin/uic.exe"' \
""
local Qt5CoreConfigExtras="${CMAKE_DIR}/Qt5Core/Qt5CoreConfigExtras.cmake"
check_file_var Qt5CoreConfigExtras
sed_in_tree \
"${Qt5CoreConfigExtras}" \
'bin/rcc"' \
'bin/rcc.exe"' \
""
sed_in_tree \
"${Qt5CoreConfigExtras}" \
'bin/moc"' \
'bin/moc.exe"' \
""
#
# sed_in_tree \
# "${Qt5CoreConfigExtras}" \
# 'bin/qmake"' \
# 'bin/qmake.exe"' \
# ""
local QT5_DIR_LIST=""
for d in "$CMAKE_DIR"/Qt5*; do
[[ -d "$d" ]] || continue
QT5_DIR_LIST+="${d},"
done
QT5_DIR_LIST="${QT5_DIR_LIST%,}"
sed_in_tree \
"${QT5_DIR_LIST}" \
'"/usr' \
'"${_psc_sys_root}/usr' \
"${exclude_list}"
local rel_path=$(realpath --relative-to="${CMAKE_CURRENT_LIST_DIR}" "${SYSROOT}")
insert_after_match \
"${CMAKE_DIR}/Qt5/Qt5Config.cmake" \
'get_filename_component[(]_qt5_install_prefix.*[)]' \
"
if(CMAKE_SYSROOT)
set(_psc_sys_root \"\${CMAKE_SYSROOT}\")
message(STATUS \"CMAKE_SYSROOT:psc_sys_root = \${_psc_sys_root} at \${CMAKE_CURRENT_LIST_FILE} \")
else()
set(_psc_sys_root \${CMAKE_CURRENT_LIST_DIR}/${rel_path})
message(STATUS \"psc_sys_root = \${_psc_sys_root} at \${CMAKE_CURRENT_LIST_FILE} \")
endif()
"
log_info "patch_system_qt end!"
}