AQStack test code.
[reglxgmr.git] / tools / cmpl / shlib / steplist.shlib
blob75495a87639b9ac5044cda5ae200ca5d05345fc0
1 #!/bin/bash
2 ############################################################
3 # source: steplist.shlib
4 # author: CottonCandyOwner(CottonCandyOwner@126.com)
5 # date: 2024-01-01
6 ############################################################
7 # Copyright (C) 2022- Free Software Foundation, Inc.
8 # This configure script is free software; the Free Software
9 # Foundation gives unlimited permission to copy, distribute
10 # and modify it.
11 ############################################################
12 # note:
13 # this file is the supporting libarary for bulid-step.
15 ############################################################
19 # todoļ¼š
20 # @ modify prefix CATA_ID_ to <XXX>_CID_, and change code in relative
21 # functions. use create catalog id function to create/release a catalog
22 # id. so, thare are more then one catalog id can work in a time.
23 # todo: to be tested
25 # @ ${var//str/rplc}, ${var#str}, by using cmd, it cost more cpu res.
26 # @ param-load-init, trim code, put to param-load.shlib.
27 # @ tpchk, trim code.
30 #. shlibinc
32 inc porting.shlib
35 ##############################
36 # section: public comment info
37 ##############################
41 ##############################
42 # section: variable define
43 ##############################
46 shlib_steplist_init ()
51 shlib_steplist_init
54 # global variable init function invoking.
55 # invoke GVAR_INIT if it is running at first time.
57 #GVAR_INIT steplist
60 ##############################
61 # section: private function
62 ##############################
64 infoo ()
66 echo -ne "$@\n"
70 # fsyntax: cmpl_dbgout <srcfile> <dstfile>
71 # fdesc: display compile info.
73 cmpl_dbgout ()
75 infoo " [CC] $1 => $(basename ${1} | sed -E "s/(.*)\..*\$/\1/g")${EXT_NAME_obj}"
79 # fsyntax: link_dbgout <srcfile> <dstfile>
80 # fdesc: display link info.
82 link_dbgout ()
84 local DST_FILE="${OUTDIR}/${!2}"
85 # local SRC_FILE="$(echo $OBJ_LIST | sed -E "s/\ /\n/g")"
86 local tmp="$(($(echo "$OBJ_LIST" | wc -l) + $(echo "$STATIC_LIB_FILE_LIST_Y" | wc -l) ))"
88 if test "$tmp" -gt 10 ; then
89 infoo " [LINK] $(echo "$OBJ_LIST" | head -n 1) ... $(echo "$OBJ_LIST" | tail -n -1)"
90 else
91 tmp="$OBJ_LIST"$'\n'"${STATIC_LIB_FILE_LIST_Y}"
92 tmp="$(echo "$tmp" | tr -s '[[:space:]]')"
93 # tmp="$(echo ${tmp} | sed -zE 's/[\n]/\ /g; s/[[:space:]]+/ /g')"
94 infoo " [LINK] ${tmp//$'\n'/$'\n '}"
97 if test "${DEST_TYPE,,}" == 'libdll' ; then
98 infoo " [LINK] => $(basename ${DST_FILE%\.*}).a"
99 infoo " [LINK] => $(basename ${DST_FILE%\.*}).so"
100 else
101 infoo " [LINK] => $(basename ${DST_FILE})"
106 # fsyntax: src2exe_dbgout <srcfile> <dstfile>
107 # fdesc: display compile info.
109 src2exe_dbgout ()
111 infoo " [EXE] $1 => $(basename ${1%%.*})"
114 warn ()
116 echo "[warn]: $@"
119 dbgoutd ()
121 echo "$@" >&2
126 # fsyntax: taskinfo_dbgout <output-string>
127 # fdesc: output string by dbgout switch.
129 taskinfo_dbgout ()
131 if test "$__taskinfo_dbgout" != 1; then
132 return
135 dbgoutd "$@"
136 echo -ne "$@" >> ${OUTDIR}/buildinfo.log
137 return
141 # fsyntax: taskfunc_dbgout <output-string>
142 # fdesc: task func info.
144 taskfunc_dbgout ()
146 local pfx=
147 local i=
149 if test "$__taskfunc_dbgout" != 1; then
150 return
153 for ((i=0; i<$task_level; i++)); do
154 pfx="${pfx}="
155 done
157 dbgoutd "${pfx}>$@"
158 echo -ne "${pfx}>$@" >> ${OUTDIR}/buildstep.log
159 test "$__taskinfo_dbgout" = 1 && echo -ne "${pfx}>$@" >> ${OUTDIR}/buildinfo.log
160 return
164 # fsyntax: taskstep_dbgout <output-string>
165 # fdesc: used for task info output, and it can be setted in
166 # build_step_dbgout_list.
168 taskstep_dbgout ()
170 local pfx=
171 local i=
172 local step=$1
174 if test "$__taskstep_dbgout" != 1; then
175 return
178 test -z "$1" && err "taskstep_dbgout() invoked without parameter." && return
179 # step info filter by env.
180 if [[ -n $build_step_dbgout_list && ! "${build_step_dbgout_list}" =~ "$1" ]]; then
181 return
182 else
183 if [[ -n $build_step_dbgout_dis_list && "${build_step_dbgout_dis_list}" =~ "$1" ]]; then
184 return
187 shift
188 test -z "$1" && err "taskstep_dbgout() invoked without parameter." && return
190 for ((i=0; i<$task_level; i++)); do
191 pfx="${pfx}="
192 done
194 dbgoutd "${pfx}>$@"
195 echo -ne "${pfx}>$@" >> ${OUTDIR}/buildstep.log
196 test "$__taskinfo_dbgout" = 1 && echo -ne "${pfx}>$@" >> ${OUTDIR}/buildinfo.log
197 return
201 # fsyntax: tasklist_dbgout <output-string>
202 # fdesc: used for tasklist info output.
204 tasklist_dbgout ()
206 local pfx=
207 local i=
209 if test "$__tasklist_dbgout" != 1; then
210 return
213 for ((i=0; i<$task_level; i++)); do
214 pfx="${pfx}="
215 done
217 dbgoutd "${pfx}>$@"
218 echo -ne "${pfx}>$@" >> ${OUTDIR}/buildstep.log
219 test "$__buildstep_dbgout" = 1 && echo -ne "${pfx}>$@" >> ${OUTDIR}/buildinfo.log
220 return
224 # fsyntax: buildstep_dbgout <output-string>
225 # fdesc: used in build step func.
227 buildstep_dbgout ()
229 local pfx=
230 local i=
232 if test "$__buildstep_dbgout" != 1; then
233 return
236 for ((i=0; i<$task_level; i++)); do
237 pfx="${pfx}="
238 done
240 echo -ne "${pfx}>$@"
241 echo -ne "${pfx}>$@" >> ${OUTDIR}/buildstep.log
242 test "$__taskinfo_dbgout" = 1 && echo -ne "${pfx}>$@" >> ${OUTDIR}/buildinfo.log
243 return
247 # fsyntax: info_dbgout_init <output-string>
248 # fdesc: init debug out info.
250 info_dbgout_init ()
252 task_level=0
253 # echo "info_dbgout_init()"
254 test -z "${OUTDIR}" && err "\${OUTDIR} is NULL string.\n" && return
256 mkdir -p "${OUTDIR}"
257 # echo \${OUTDIR}=${OUTDIR}
259 strstr "${dbgout_switch}" =~ taskinfo && __taskinfo_dbgout=1
260 strstr "${dbgout_switch}" =~ taskfunc && __taskfunc_dbgout=1
261 strstr "${dbgout_switch}" =~ taskstep && __taskstep_dbgout=1
262 strstr "${dbgout_switch}" =~ tasklist && __tasklist_dbgout=1
263 strstr "${dbgout_switch}" =~ buildstep && __buildstep_dbgout=1
264 strstr "${dbgout_switch}" =~ buildparam && __buildparam_dbgout=1
266 test "$__buildstep_dbgout" = 1 -o "$__taskstep_dbgout" = 1 &&
267 echo > ${OUTDIR}/buildstep.log
269 test "$__taskinfo_dbgout" = 1 &&
270 echo > ${OUTDIR}/buildinfo.log
272 test "$__buildparam_dbgout" = 1 &&
273 echo > ${OUTDIR}/buildparam.log
278 ##############################
279 # section: public function
280 ##############################
282 #############################################################################
284 # tpchk funcs.
285 # @ ftpchk(): general file tp check. return 0 if need to be updated.
286 # @ desttpchk(): dest & obj tp chk.
287 # @ step_lang_src_tpchk(): lang src list to dest tp chk.
288 # @ tpchk(): src & obj tp chk, and hdr tp chk.
289 # @ srcdesttpchk(): src & dest tp chk, and hdr tp chk.
290 # @ tpchk(): src & obj tp chk, and hdr tp chk.
292 ############################################################################
294 ftpchk ()
296 test ! -f "$1" && return 1
297 test ! -f "$2" && return 0
298 test "$1" -nt "$2" && return 0
299 return 1
302 libtpchk ()
304 local srcfile=
305 local dstfile=$1
306 local param=
307 local libdir=
308 local flag=
309 local filelist=
311 # skip condition for .a file checking changing.
312 # get lib paths in compiler.
313 unsetenv SRC_FILE
314 get_toolchain_info
315 libdir="$(echo " $LDFLAGS" | grep -oE "[[:blank:]]+-L([^[:blank:]]+)[[:blank:]]*" | sed -E "s|[[:blank:]]+-L([^[:blank:]]+)[[:blank:]]*|\1\n|g")"
316 libdir="$libdir $(envar LIB_PATHS[@])"
317 libdir="$(echo $libdir | tr ' ' '\n')"
319 filelist="$(echo " $LDFLAGS" | grep -oE "[[:blank:]]+-l([^[:blank:]]+)[[:blank:]]*" | sed -E "s|[[:blank:]]+-l([^[:blank:]]+)[[:blank:]]*|lib\1.a\n|g")"
320 filelist="$(echo "$STATIC_LIB_FILE_LIST_Y"$'\n'"$filelist" | sort | uniq)"
322 # skip condition for .a file checking changing.
323 for srcfile in $filelist; do
324 flag=0
325 if test -f $srcfile ; then
326 test "$srcfile" -nt "$dstfile" && echo 1 "$srcfile" \-nt "$dstfile" && return 0
327 elif test -f "${OUTDIR}/${srcfile}" ; then
328 srcfile="${OUTDIR}/${srcfile}"
329 test "$srcfile" -nt "$dstfile" && echo 2 "$srcfile" \-nt "$dstfile" && return 0
330 else
331 for param in ${libdir}; do
332 if test -f $param/$srcfile ; then
333 test $param/"$srcfile" -nt "$dstfile" && echo 3 $param/"$srcfile" \-nt "$dstfile" && return
334 # echo srcfile=$srcfile
335 # echo dstfile=$dstfile
336 filelist="$filelist"$'\n'"$param/$srcfile"
337 flag=1
338 break;
340 done
341 test $flag != 1 && warn "static lib file '$srcfile'($filelist) is not in specified lib path.\n"
343 done
345 # STATIC_LIB_FILE_LIST_Y="$filelist"
346 infoo "dest file ($dstfile) is existing, skip linking."
347 return 1
351 # fsyntax: srcdesttpchk
352 # fdesc: load src-list file.
354 srcdesttpchk ()
356 local dstfile=
357 local srcfile=
359 # skip condition for .o file checking changing.
360 dstfile="${OUTDIR}/$(basename $(echo $1 | sed -E "s/\,.*\$//g; s/(.*)\..*\$/\1/g"))"
361 EXE_LIST="${EXE_LIST} ${dstfile}"
363 for srcfile in $(echo $1 | tr ',' ' '); do
364 if test -f "${dstfile}" ; then
365 test $srcfile -nt "$dstfile" && echo $srcfile newer then $dstfile && return 0
366 else
367 return 0
369 done
371 libtpchk $dstfile
372 return $?
376 # fsyntax: desttpchk
377 # fdesc: load src-list file.
379 desttpchk ()
381 local srcfile=
382 local dstfile=
383 local param=
384 local libdir=
385 local flag=
386 local filelist=
388 # skip condition for .o file checking changing.
389 eval dstfile=\"\${OUTDIR}/\${$2}\"
390 if test -f "${dstfile}" ; then
391 eval filelist=\"\${$1}\"
392 for srcfile in $filelist; do
393 test ${OUTDIR}/${DEST_CFG_DIR_NAME}/$srcfile -nt "$dstfile" && return 0
394 done
395 else
396 return 0
399 libtpchk $dstfile
400 return $?
404 # fsyntax: src_hdr_tpchk <dstfile>
405 # fdesc: chk tp between srcfile and hdrfile.
407 src_hdr_tpchk ()
409 local line=
410 local objfile="$1"
411 local deplistfile="${objfile/\.o/.dephdr}"
413 buildstep_dbgout "src_hdr_tpchk ($@) $deplistfile\n"
415 # echo "src_hdr_tpchk ($@) $deplistfile\n"
417 test ! -f "$deplistfile" -a -n $OPT_DEPHDR && echo "deplistfile does not compiled. cmpl" && return 0
418 test ! -f "$deplistfile" -a -z $OPT_DEPHDR && echo "deplistfile does not compiled. skip." && return 1
420 while read line; do
421 test ! -n "$line" && continue
422 line="${line%:*}"
423 test ! -e "$line" && warn "hdr file ($line) in $deplistfile file does not exist." && return 2
425 if test ${line:0:1} == '/' ; then
426 SYS_INC_LIST="$SYS_INC_LIST"$'\n'"$line"
427 test "$line" -nt "$1" && echo "sys inc file in file $line is modified." && return 0
428 else
429 SYS_INC_LIST="$SYS_INC_LIST"$'\n'"$line"
431 # hdr file newer then src file,
432 # src file to be recompiled.
434 test "$line" -nt "$objfile" && echo "file $line is modified." && return 0
436 done < <(cat ${deplistfile} | grep -v "[\\]$" | tr -s ' ' $'\n')
438 return 1
442 # fsyntax: tpchk <srcfile> <dstfile>
443 # fdesc: chk tp between src-file and dest-file, it also chk tp
444 # between src & hdr.
446 tpchk ()
448 # echo "tpchk($@)"
449 fname_objdir
450 local dstext="$(eval echo "\${SRC2DST_$2}")"
451 local destfile="$(echo "${dstext}" | tr '[[:lower:]]' '[[:upper:]]')DSTDIR"
453 eval $destfile=\"\${${destfile}_EVL}\"
455 eval destfile=\"\${${destfile}}\"
457 eval destfile="\"${destfile}\""
459 mkdir -p $destfile
460 eval vname="\${EXT_NAME_$dstext}"
461 destfile="$(echo "$destfile/$1" | sed -E "s/,.*$//g; s/(.*)\..*\$/\1${vname}/g;")"
462 # declare -p vname destfile
463 test ! -f "${destfile}" && return 0
465 local file=
466 local srcfile="$1"
468 for file in $(echo ${srcfile} | tr ',' ' '); do
469 test "${file}" -nt "${destfile}" && echo "recompile $file" && return 0
470 done
472 eval test "\"\${$(echo "${2}" | tr '[[:lower:]]' '[[:upper:]]')_HDRCHK_DISABLE}\"" = y &&
473 return 1
474 src_hdr_tpchk "${destfile}"
475 test $? = 0 && return 0;
477 # skip
478 return 1
482 # fsyntax: step_lang_src_tpchk <langlist-var> [<parameter-list> ... ]
483 # fdesc: chk tp between srcfile and dstfile(obj).
485 step_lang_src_tpchk ()
487 local extname=
488 local obj=
489 local srcfile=
490 local dstfile=
491 local SRC_LIST_N2B_CMPL=
492 local lang=
493 local vname=
494 local tmp=
496 # echo "step_lang_src_tpchk ($@)"
499 # check langlist ${lang}_SRC_LIST_Y list.
501 lang="$(echo ${1} | tr '[[:upper:]]' '[[:lower:]]')"
502 eval extname=\"\${EXT_NAME_${lang}}\"
503 lang="$(echo ${1} | tr '[[:lower:]]' '[[:upper:]]')"
504 vname="${lang}_SRC_FILE_LIST_Y"
505 # eval ${vname}="\"\$(echo ${vname} | sed -E "s/,.*\$//g")\""
507 if test -z "${!vname}" ; then
508 eval ${lang}_SRC_CMPL_LIST=""
509 taskinfo_dbgout "no src file in src list \'\${${lang}_SRC_FILE_LIST_Y}\'."
510 return 0
512 OBJ_LIST="${OBJ_LIST} ${!vname//${extname}/\.o}"
513 # OBJ_LIST+="${!vname}"
515 # get obj file list that has been compiled.
516 mkdir -p ${OBJDIR}/
517 tmp="$(eval echo "\"\${$vname}\"" | sed -E "s/\,.*\$//g; s/(.*)\.[[:alnum:]_]*/\1\\${EXT_NAME_obj}/g;")"
518 OBJ_LIST_N2B_CPLE=`cd ${OBJDIR}/; ls -1 $tmp 2>/dev/null`
520 test -z "$OBJ_LIST_N2B_CPLE" && eval ${lang}_SRC_CMPL_LIST=\"\${$vname}\" && return 0
522 # test compiled obj file, to check if it need to be recompiled.
523 for obj in ${OBJ_LIST_N2B_CPLE}; do
524 srcfile="${obj//\.o/${extname}}"
525 dstfile="${OBJDIR}/${obj}"
527 # check if file does not need to be compiled.
528 if test "${srcfile}" -nt "${dstfile}" ; then
529 # hdr file tp chk.
530 src_hdr_tpchk $dstfile
531 test $? == 1 && SRC_LIST_N2B_CMPL="$SRC_LIST_N2B_CMPL"$'\n'"${srcfile}"
532 test $? == 2 && echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
534 done
535 # echo "SRC_LIST_N2B_CMPL=$SRC_LIST_N2B_CMPL"
537 # get files to be compiled.
538 if test -n "$SRC_LIST_N2B_CMPL" ; then
539 flag=compile
540 eval "${lang}_SRC_CMPL_LIST=\"`comm <(eval \"echo \\\"\\\${$vname}\\\"\" | sort) <(echo "$SRC_LIST_N2B_CMPL" | sort) -3`\""
541 # | sed -e "/^\t/d"
542 else
543 eval "${lang}_SRC_CMPL_LIST=\"${!vname}\""
546 # eval taskinfo_dbgout "========= ${lang}_SRC_CMPL_LIST=\"\${${lang}_SRC_CMPL_LIST}\""
547 # done
549 return 0
552 #############################################################################
554 # general.
556 ############################################################################
558 # $ [[ "VOID on_prev_construct (int a)" =~ ((.*)[[:space:]]+)?([[:alnum:]_]*)[[:space:]]*([\(](.*)[\)])? ]] && echo "BASH_REMATCH=\"${BASH_REMATCH[@]}\""
559 # BASH_REMATCH="VOID on_prev_construct (int a) VOID on_prev_construct VOID on_prev_construct (int a) int a"
561 # @ detect latest non "(" string as the function name.
562 # @ string after "(" string is paramter
563 # @ string before function name is ret type.
566 # fsyntax:
567 # fdesc: dispose input string in $1, output P_RET P_FUNC & P_PARAM[]
569 str2func ()
571 local i=
572 local idx=
574 unset P_RET P_PARAM P_FUNC
575 P_RET=""
576 P_PARAM=""
577 P_FUNC=""
579 # check if func expr
580 # echo \$@=$@
581 if [[ "$1" =~ ((.*)[[:space:]]+)?([[:alnum:]_]*)[[:space:]]*([\(](.*)[\)])? ]]; then
582 for ((i=0; i<${#BASH_REMATCH[@]}; i++)); do
583 # echo BASH_REMATCH[$i]=${BASH_REMATCH[$i]}
584 test -n "${BASH_REMATCH[$i]}" && idx=$i
585 [[ ${BASH_REMATCH[$i]:0:1} == '(' ]] && idx=$((i-1)) && break;
586 done
587 # dbgoutd "idx=$idx\n"
588 P_FUNC="${BASH_REMATCH[$idx]}"
589 P_PARAM="${BASH_REMATCH[$((idx+2))]}"
590 P_RET="${BASH_REMATCH[$((idx-1))]}"
592 if test -n "$P_PARAM" ; then
593 # dbgoutd "P_PARAM=$P_PARAM\n"
594 P_PARAM="${P_PARAM//,/ }"
596 # eval P_PARAM=( ${P_PARAM} )
597 # dbgoutd "P_PARAM=${P_PARAM}\n"
599 # dbgoutd "P_RET=$P_RET\n"
600 # dbgoutd "P_FUNC=$P_FUNC\n"
601 # dbgoutd "P_PARAM=${P_PARAM}\n"
602 elif test -z "${1//[[:alnum:]_]/}" ; then
603 P_FUNC="$1"
604 else
605 P_FUNC="$1"
606 return 2
609 declare -F $P_FUNC >/dev/null 2>&1
610 # test $? != 0 && warn "'$P_FUNC' is a defination of func form, but it is not defined." && return 2
611 test $? != 0 && return 3
612 return 0
616 # fsyntax: TASK_RUNNING <task-name-var> [<taskparam>, ... ]
617 # fdesc: running a task by the name of var in arg.
618 # freturn: 0, normal.
619 # 1, break current step.
620 # 2, err, stop doing.
621 # 3,
622 TASK_RUNNING ()
624 local j=
625 local ret=
626 local step=
627 local bakstep="$1"
628 local name=
629 local content=
630 local stepcnt=
631 local param=
633 if test -n $task_skip_list && strstr "$task_skip_list" =~ "$bakstep" ; then
634 return 0;
637 test -z "$1" && err "task name is not specified.\n" && return 0;
639 : $((task_level++))
640 taskstep_dbgout "$1" "TASK_RUNNING ($@)\n"
642 while true; do
643 test ! -n "$1" && warn "'$1' is not a valid step name." && ret=2 && break
645 # TBD:
646 # check if it is an array.
647 # if yes, use array directly.
648 # the form between multi-line string and array define are all well.
649 # sometimes, use array is better, it can write config info in the
650 # same line.
652 # use seperator with new line, to avoid ' ' in func param.
653 OLD_IFS="$IFS"
654 IFS=$'\n'
655 # use cmdline to strip string.
656 name="$(echo $1)"
657 # content="${!1}"
658 content="$(echo "${!1}" | sed -E "/[[:blank:]]*[#].*[\r]?/d")"
659 stepcnt="$(echo "content" | wc -l)"
660 IFS="$OLD_IFS"
662 shift 1
663 # if param contains blank, use ( "$@" ) to assign as an array.
664 param="$@"
666 # skip undefined step.
667 if test "${stepcnt}" = 0 && testv $content ]]; then
668 warn "\$name=$name"
669 warn "\$content=$content"
670 warn "'$name' is not a valid step.\${stepcnt}=${stepcnt}"
671 warn "set it in 'tools/cmpl/defination/buildstep.imi'."
672 ret=0
673 break
677 # if only one item in defination, and it's not a variable define,
678 # it's a func, invoke it.
680 if test "${stepcnt}" == 1 ; then
681 str2func "$content"
682 ret=$?
683 if test $ret != 3 && test ! -n "${!P_FUNC}" ; then
684 : $((task_level++))
685 taskfunc_dbgout "func $P_FUNC(${P_PARAM} "$@")\n"
686 $P_FUNC ${P_PARAM} "$@"
687 ret=$?
688 taskfunc_dbgout "func ret $P_FUNC($ret)\n"
689 : $((task_level--))
690 test $ret = 1 && ret=0 && break
691 test $ret != 0 && warn "1 func '$P_FUNC (${P_PARAM//\ /,\ })("$@")' return failed($ret)." && break
692 ret=0
693 break
697 taskstep_dbgout "$bakstep" "xxxxxxxxxxxxxxxxxxxxxxxxx x content=$(echo "$content" | tr -s '\t' $'\n')\n"
700 # if there are several sub-steps, or the only one is also a step defination,
701 # use nestly invoking.
704 while read step; do
705 : $((j++))
706 # taskinfo_dbgout "x xxxxxxxxxxxxxxxxxxxxxxxx xx step[$j]=$step\n"
708 # skip null content and comment content
709 test -z "$step" && continue
710 strstr "$step" =~ '^[[:blank:]]*#' && continue
712 if strstr ! $step =~ '\(' ; then
713 # if it's an existing var, it's may be a sub-step, invoke TASK_RUNNING() nestly.
714 # but not use ${!step} to access content.
715 # if it's also an existing func, it will be invoked in TASK_RUNNING.
717 #[[ -v $step ]] &&
718 # $step="$(echo $step)"
719 TASK_RUNNING "$step" ${param}
720 ret=$?
721 # test $ret == 1 && ret=0 && break
722 test $ret != 0 && break
723 else
724 # if it's a func, invoke func also.
725 str2func "${step}"
726 ret=$?
727 # taskinfo_dbgout "ret=$ret\n"
728 if test $ret == 0 ; then
729 if test "${P_FUNC^^}" == "${P_FUNC}" ; then
730 # if full upper char, it's a step
731 # P_FUNC="$(echo $P_FUNC)"
732 TASK_RUNNING $P_FUNC ${P_PARAM} ${param}
733 # test "$ret" = 1 && ret=0 && break
734 test $? != 0 && taskinfo_dbgout "aaaaaaaaa" && break
735 continue
736 else
737 # otherwize, it's a normal function.
740 : $((task_level++))
741 taskfunc_dbgout "func $P_FUNC(${P_PARAM} "$@")\n"
742 $P_FUNC ${P_PARAM} "$@"
743 ret=$?
744 taskfunc_dbgout "func ret $P_FUNC($ret)\n"
745 : $((task_level--))
746 test $ret = 1 && ret=0 && break
747 test "$ret" != 0 && warn "2 func '$P_FUNC (${P_PARAM//\ /,\ })("$@")' return failed($ret)." && break
748 elif test $ret == 3 ; then
749 # $P_FUNC="$(echo $P_FUNC)"
750 step="$P_FUNC"
751 TASK_RUNNING $P_FUNC ${P_PARAM} ${param}
752 ret=$?
753 # test $ret = 1 && ret=0 && break
754 test $ret != 0 && taskinfo_dbgout "task ($step) invoking failed($ret).\n" && break
755 else
756 dbgoutd "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
759 done << EOF
760 $content
763 # echo "if it's a func, invoke func also."
764 if test ! "$j" -lt "${stepcnt}" && test ret == 0 ; then
765 str2func "${name}"
766 ret=$?
767 if test $ret == 0 ; then
768 : $((task_level++))
769 taskfunc_dbgout "func $P_FUNC(${P_PARAM} "$@")\n"
770 $P_FUNC ${P_PARAM} "$@"
771 ret=$?
772 taskfunc_dbgout "func ret $P_FUNC($ret)\n"
773 : $((task_level--))
774 test $ret = 1 && ret=0 && break
775 test $ret != 0 && warn "3 func '$P_FUNC (${P_PARAM//\ /,\ })("$@")' return failed($ret)." && break
779 # ret=0
780 break
781 done
783 taskstep_dbgout "$bakstep" "ret $ret TASK_RUNNING ($name)\n"
784 : $((task_level--))
786 return $ret
789 foo () { local i=0; while test -n "$1"; do echo "\$1=$1"; shift; done; }
790 # $ foo a b "cd e" f
791 # $1=a
792 # $1=b
793 # $1=cd e
794 # $1=f
795 # $ abc=( aaa "a b c" abc a b c )
796 # $ foo "${abc[@]}"
797 # $1=aaa
798 # $1=a b c
799 # $1=abc
800 # $1=a
801 # $1=b
802 # $1=c
807 # fsyntax: tasklist <list> <task> [<taskparam> ... ]
808 # fdesc: running task accroding the list variable.
810 step_tasklist ()
812 local data=
813 local list="$1"
814 local task="$(echo $2)"
816 : $((task_level++))
817 tasklist_dbgout "x TASK_RUNNING TASKLIST ($@)\n"
819 if test -z "$1" ; then
820 warn "specified list var name '$1' is not valid."
821 return 2
824 tasklist_dbgout "list=$list\n"
825 tasklist_dbgout "$list=${!list}\n"
826 shift 2
827 while read data; do
828 test -z "$data" && continue
829 # XXX: this param can be transmited in task func param,
830 # and disable this assignment.
831 loadarr SRC_FILE = "($data)"
832 # taskinfo_dbgout "SRC_FILE=${SRC_FILE[@]}\n"
833 TASK_RUNNING "$task" $data "$@"
834 # break tasklist running if one of them failed.
835 if test $? != 0 ; then
836 tasklist_dbgout "x ret 2 TASK_RUNNING TASKLIST ($@)\n"
837 : $((task_level--))
839 return 2
841 done <<EOF
842 $(eval echo \"\${$list}\")
845 tasklist_dbgout "ret 0 TASK_RUNNING TASKLIST ($@)\n"
846 : $((task_level--))
848 return 0
851 step_build_one_dest ()
853 DEST_NAME=${1}
854 # echo "step_build_one_dest($@)[$DEST_NAME]"
855 # echo "DEST_NAME=$DEST_NAME"
856 # echo "DEST_TYPE=$DEST_TYPE"
857 # echo "DEST_LIST_Y=$DEST_LIST_Y"
858 dest_info_init
859 # echo "DEST_NAME=$DEST_NAME"
860 # echo "DEST_TYPE=$DEST_TYPE"
861 # echo "DEST_LIST_Y=$DEST_LIST_Y"
863 TASK_RUNNING "STEP_$(struupper DEST_TYPE)_DEST" $DEST_NAME
867 # fsyntax: step_one_dest_init
868 # fdesc: init one dest build. it loads the relative paramter files.
870 step_one_dest_init ()
872 local dest=${2}
873 local step=
874 local ret=
876 buildstep_dbgout "############################\n"
877 buildstep_dbgout "step_one_dest_init($1, ${!1}, ${2#*-})\n"
878 buildstep_dbgout "############################\n"
880 test -n "$2" && eval $1=\"$(echo "${2}" | sed -E "s/-(.*)\$/\1/g")\"
882 # init one dest cfg paramter
883 eval "DEST_GENERAL_CFG_DIR=\"${DEST_GENERAL_CFG_DIR_EVL}\""
885 one_dest_init $dest
887 CFLAGS="$CFLAGS"
889 mkdir -p ${OUTDIR}/${DEST_CFG_DIR_NAME}/
891 unset OBJ_LIST EXE_LIST
892 OBJ_LIST=""
893 EXE_LIST=""
895 return 0
898 step_one_lang_cmpl ()
900 local lang=$1
901 local langlist="${!1}"
903 # echo "step_one_lang_cmpl($@)"
904 # for lang in $langlist; do
905 TASK_RUNNING STEP_$(struupper lang)_LANG_CMPL "$@"
906 # done
908 return $?
911 step_link ()
913 local linkstep=
915 taskinfo_dbgout "OBJ_LIST=$OBJ_LIST"
917 DST_FILE="${OUTDIR}/${!2}"
918 loadarr SRC_FILE = "( $OBJ_LIST )"
920 taskinfo_dbgout "DST_FILE=$DST_FILE\n"
921 taskinfo_dbgout "DEST_NAME=$DEST_NAME\n"
922 taskinfo_dbgout "DEST_FILENAME=$DEST_FILENAME\n"
923 taskinfo_dbgout "DEST_TYPE=$DEST_TYPE\n"
924 taskinfo_dbgout "DEST_EXTNAME=$DEST_EXTNAME\n"
926 if test "${DEST_TYPE:0:1}" == '[' ; then
927 DEST_TYPE=${DEST_TYPE:1:-1}
929 taskinfo_dbgout "DEST_TYPE=$DEST_TYPE\n"
931 linkstep="STEP_${DEST_TYPE^^}_LINK"
932 taskinfo_dbgout "${linkstep}=${!linkstep}"
933 eval test -z \"\${$linkstep}\" && err "dest type ${DEST_TYPE} have not define a step named 'STEP_${DEST_TYPE^^}_LINK'.\n" && return 2
935 TASK_RUNNING "${linkstep}" "$@"
937 test $? != 0 && err "${CHIGHL}[build-link]: link file \"$DEST_FILENAME\" err.${CNORMAL}" && exit && return 2
939 return 0
942 step_hostutils_init ()
944 prev_build
947 step_hostutils_ln2host ()
949 local file=
951 echo "step_hostutils_ln2host($@)[${EXE_LIST}]"
953 for file in $EXE_LIST; do
954 echo ln -s $file $HOSTBIN_DIR/$(basename $file)
955 ln -s $file $HOSTBIN_DIR/$(basename $file)
956 done
959 step_lang_src2exe ()
961 local lang=
963 for lang in $1; do
964 TASK_RUNNING STEP_$(struupper lang)_LANG_SRC2EXE
965 done
968 step_lang_src2unitsrc ()
970 local lang=
971 local filelist=
972 local vflist=
974 lang="$1"
975 vflist="$(eval echo \"\${$(struupper lang)_SRC_FILE_LIST_Y}\")"
976 for file in ${vflist}; do
977 # echo "file=${file%%\.*}_test.${file##*.}"
978 filelist="$filelist"$'\n'"${file%%\.*}_test.${file##*.}"
979 done
981 if test -n "$filelist" ; then
982 eval "$(struupper lang)_SRC_FILE_LIST_Y=\"\${filelist}\"\$'\n'\"$OUTDIR/greatest/greatest.c\""
983 OBJ_LIST=""
984 CFLAGS_EXT="-DGREATEST_MULTIPLE"
985 # LDFLAGS_EXT="-Wl,-T,tools/greatest/test.lds"
986 STATIC_LIB_FILE_LIST_Y="${STATIC_LIB_FILE_LIST_Y}"$'\n'"${OUTDIR}/${DEST_FILENAME}"
987 DEST_FILENAME="$(getenv DEST_FILENAME[1])"
988 DEST_TYPE="exe"
990 mkdir -p $OUTDIR/greatest/
991 test ! -e $OUTDIR/greatest/greatest.c && cat - > $OUTDIR/greatest/greatest.c << EOF
992 #include "greatest.h"
994 TEST_MAIN_DEFS();
998 unsetenv SRC_FILE
999 unsetenv DST_FILE
1003 # fsyntax: build_step_init
1004 # fdesc: load buildstep.imi cfg file.
1006 build_step_init ()
1008 # load CFLAGS-MISC.imi
1009 eval "BUILD_STEP_IMI=\"${BUILD_STEP_IMI_EVL}\""
1010 buildparam_dbgout "BUILD_STEP_IMI=$BUILD_STEP_IMI\n"
1011 loadimi $BUILD_STEP_IMI
1013 # load lang.list
1014 eval "BUILD_LANG_LIST=\"${BUILD_LANG_LIST_EVL}\""
1015 loadlist $BUILD_LANG_LIST
1019 # fsyntax: dest_list_init
1020 # fdesc: load dest.imi cfg file, to get dest-list.
1022 dest_list_init ()
1024 buildparam_dbgout "SRCPKG_DIR=$SRCPKG_DIR\n"
1026 # BUILD_DEST is defined in this file
1027 eval DEST_LIST_FILE="$DEST_LIST_FILE_EVL"
1028 loadlist $DEST_LIST_FILE
1029 DEST_LIST_Y="$(echo "$DEST_LIST_Y" | sed -E "s/dest-//g")"
1031 buildparam_dbgout "###############################\n"
1032 buildparam_dbgout "dest_list_init($DEST_LIST_FILE)\n"
1033 buildparam_dbgout "DEST_LIST_Y=\"$DEST_LIST_Y\"\n"
1035 # declare -g -A DEST_CFG_DIR=( )
1036 # INST_PKG is defined in this file
1037 eval INSTPKG_LIST_FILE="$INSTPKG_LIST_FILE_EVL"
1038 # declare -g -A INSTPKG_CFG_DIR=( )
1041 construct_init_flag=
1043 construct_init ()
1045 # skip if initialized.
1046 test "$construct_init_flag" = 1 && return
1048 construct_init_work
1050 construct_init_flag=1
1054 # fsyntax: construct_init
1055 # fdesc: init construct variables.
1056 # output:
1057 # SRCPKG_DIR, src pkg root dir.
1058 # OUTDIR, it stores compile mid-file.
1059 # VERSION_STRING,
1060 # SRCPKG_FILENAME,
1061 # SRCPKG_VNAME,
1063 construct_init_work ()
1065 local dest=
1067 # SRCPKG_DIR
1068 if test -d build ; then
1069 SRCPKG_DIR="."
1070 eval "SRCPKG_DIR_ABP=\"$PWD\""
1071 elif test "$(basename $PWD)" = build ; then
1072 SRCPKG_DIR=".."
1073 cd ..
1074 eval "SRCPKG_DIR_ABP=\"$PWD\""
1077 # if it has been defined, create src-pkg name sub-dir
1078 if test -z $OUTDIR ; then
1079 eval "OUTDIR=\"$OUTDIR_EVL\""
1081 if test -z $OUTDIR_ABP ; then
1082 eval "OUTDIR_ABP=\"$OUTDIR_ABP_EVL\""
1085 info_dbgout_init
1087 date > ${OUTDIR}/build.log
1088 echo >> ${OUTDIR}/build.log
1090 # translate OPT_* to CFG_*
1091 opt2cfg
1093 # load srcpkg name & version string.
1094 eval "VERSION_FILE=\"$VERSION_FILE_EVL\""
1096 source $VERSION_FILE
1097 SRCPKG_VNAME="$VNAME"
1098 SRCPKG_VMAJOR="$VMAJOR"
1099 SRCPKG_VMINOR="$VMINOR"
1100 SRCPKG_VPATCH="$VPATCH"
1101 SRCPKG_VDATE="$VDATE"
1102 SRCPKG_VEXT="$VEXT"
1103 SRCPKG_VERSION="$VERSION"
1104 SRCPKG_VSTR="$VSTR"
1106 buildparam_dbgout VERSION_STRING=$VERSION_STRING
1107 buildparam_dbgout SRCPKG_FILENAME=$SRCPKG_FILENAME
1108 buildparam_dbgout SRCPKG_VNAME=$SRCPKG_VNAME
1110 # set env $PATH
1111 PATH="$SRCPKG_DIR/support/:$PATH"
1113 mkdir -p ${OUTDIR}
1115 # load dest.list & buildstep.imi to get dest list.
1116 dest_list_init
1117 build_step_init
1119 # load srcpkg shlib file, for some on_xxx() funcs.
1120 test -z $SRCPKG_VNAME && err "SRCPKG_VNAME defined in file of doc/VERSION is not valid.\n"
1121 if test -f build/${SRCPKG_VNAME}.shlib ; then
1122 echo build/${SRCPKG_VNAME}.shlib
1123 inc build/${SRCPKG_VNAME}.shlib
1124 elif test -f build/shlib/${SRCPKG_VNAME}.shlib ; then
1125 echo build/shlib/${SRCPKG_VNAME}.shlib
1126 inc build/shlib/${SRCPKG_VNAME}.shlib
1127 else
1131 if test -f build/shlib/ext-param.imi ; then
1132 inc build/shlib/ext-param.imi
1134 if test -f build/shlib/ext-buildstep.imi ; then
1135 inc build/shlib/ext-buildstep.imi
1137 if test -f build/shlib/ext-toolchain.shlib ; then
1138 inc build/shlib/ext-toolchain.shlib
1141 PATH="${PATH}:$PWD/build/output"
1142 buildstep_dbgout "############################\n"
1143 buildstep_dbgout "construct_init()\n"
1144 buildstep_dbgout "############################\n"
1148 # construct
1149 # construct_all_dest => dest_list_init()/construct_one_dest() => one_dest_init() =>
1150 # compile_src_list()/link_list() => c2o()/o2exe()
1152 construct ()
1154 construct_init
1156 TASK_RUNNING "STEP_BUILD_DEST"
1159 VNAME=
1160 VMAJOR=
1161 VMINOR=
1162 VPATCH=
1163 VDATE=
1164 VEXT=
1165 SRCPKG_VERSION=
1166 SRCPKG_VSTR=
1168 stdh_begin ()
1170 local name="$(basename $1 | tr '[[:punct:]]' '_' | tr '[[:lower:]]' '[[:upper:]]')"
1172 echo > $1
1173 echo "#ifndef __${name}__" >> $1
1174 echo "#define __${name}__" >> $1
1175 echo >> $1
1179 stdh_end ()
1181 local name="$(basename $1 | tr '[[:punct:]]' '_' | tr '[[:lower:]]' '[[:upper:]]')"
1183 echo >> $1
1184 echo "#endif /* __${name}__ */" >> $1
1187 cfg_envar2macro ()
1189 # if CFG OPT intrduction string should be appended,
1190 # it need to grep text in Config.in.
1191 # but config.h is generated in compile, it's not used for
1192 # coding, comment info is not neccesory.
1193 # otherwize, writing a file in build/config.h.in, to over-write
1194 # file in this function.
1195 test -n "$IMICMNT" && strstr ! "$IMICMNT" =~ 'is not set' &&
1196 ( cd ${SRCPKG_DIR_FULL} ; echo -e "\n$IMICMNT" >> ${OUTDIR}/gencode/inc/config.h )
1198 if test "$3" = 'n'; then
1199 ( cd ${SRCPKG_DIR_FULL} ; echo "#undef $1" >> ${OUTDIR}/gencode/inc/config.h )
1200 else
1201 ( cd ${SRCPKG_DIR_FULL} ; echo "#define $1 $(echo "$3")" >> ${OUTDIR}/gencode/inc/config.h )
1203 # echo "#define $1 $(echo "$3")"
1206 ver_envar2macro ()
1208 ( cd ../ ; echo "#define $1 $(echo "$3")" >> ${OUTDIR}/gencode/inc/version.h )
1209 # echo "#define $1 $(echo "$3")"
1212 ver2h ()
1214 export PACKAGE_NAME=$SRCPKG_NAME
1216 stdh_begin ${OUTDIR}/gencode/inc/version.h
1218 on_imi_set_var=ver_envar2macro
1219 loadimi doc/VERSION
1221 stdh_end ${OUTDIR}/gencode/inc/version.h
1224 cfg2h ()
1226 test -f build/default.config && test ! -f ${OUTDIR}/config.imi &&
1227 echo "error: config file '${OUTDIR}/config.imi' is not exist, " &&
1228 echo "but this srcpkg have config file 'build/default.config'." &&
1229 exit
1231 stdh_begin ${OUTDIR}/gencode/inc/config.h
1233 on_imi_set_var=cfg_envar2macro
1234 loadimi ${OUTDIR}/config.imi
1236 # opt 2 cfg, updated in config.h
1237 local var=
1238 local optvname=$(set | grep -oE "^OPT_[[:alnum:]_]*=" | sed -E "s/=//g")
1240 for var in $optvname; do
1241 eval $(echo $var | sed -E "s/OPT_/CFG_/g;")="\"\${$var}\""
1242 var="$(echo $var | sed -E "s/OPT_/CFG_/g;")"
1243 eval sed -i -E "\"s/^.*${var}.*$/#define ${var} \${$var}/g\"" ${OUTDIR}/gencode/inc/config.h
1244 test $? != 0 && echo "#define ${var} \${$var}" >> ${OUTDIR}/gencode/inc/config.h
1245 done
1247 stdh_end ${OUTDIR}/gencode/inc/config.h
1250 tmpl2file ()
1252 local file=
1253 local data=
1255 data=`ls -1 build/*.h.in 2>/dev/null`
1256 for file in $data; do
1257 data="$(basename $file | sed -E "s/\.[^.\ ]*$//g")"
1259 ftpchk $file ${OUTDIR}/gencode/inc/$data
1260 if test $? = 0 ; then
1261 echo " [AUTOGEN] $file => $data"
1262 data="${OUTDIR}/gencode/inc/$data"
1263 eval echo "\"$(cat $file | sed -E "s/\\\\/\\\\\\\\/g; s/\"/\\\\\"/g;")\"" > $data
1265 done
1267 data=`ls -1 build/*.c.in 2>/dev/null`
1268 for file in $data; do
1269 data="$(basename $file | sed -E "s/\.[^.\ ]*$//g")"
1270 ftpchk $file ${OUTDIR}/gencode/src/$data
1271 if test $? = 0 ; then
1272 echo " [AUTOGEN] $file => $data"
1273 data="${OUTDIR}/gencode/src/$data"
1274 eval echo "\"$(cat $file)\"" > $data
1276 done
1279 autogen_config_h ()
1281 stdh_begin ${OUTDIR}/gencode/inc/config.h
1283 while read data; do
1284 test -z "$data" && continue
1285 "#define $(echo "$data" | sed -E "s/=/ /")"
1286 done << EOF
1287 $(cat ${OUTDIR}/config.imi | sed -E "s/[[:blank:]]*#.*\$//g; /^$//d")
1288 $(cat ${OUTDIR}/option.imi | sed -E "s/[[:blank:]]*#.*\$//g; /^$//d")
1289 $(cat build/dest/dest-general/*FLAGS-DEF.imi | sed -E "s/[[:blank:]]*#.*\$//g; /^$//d")
1292 stdh_end ${OUTDIR}/gencode/inc/config.h
1295 opt2cfg ()
1297 local var=
1298 local optvname=$(set | grep -oE "^OPT_[[:alnum:]_]*=" | sed -E "s/=//g")
1300 for var in $optvname; do
1301 eval $(echo $var | sed -E "s/OPT_/CFG_/g;")="\"\${$var}\""
1302 done
1305 ##############################
1306 # section: file tail
1307 ##############################
1309 return
1311 PROG_NAME
1312 DISTVERSION
1313 BUILDVERSION
1314 RELSTATUS
1315 DEFAULT_COMPAT_LEVEL
1316 SCCSVERSION
1320 # fsyntax: steplist_create <steplist-name>
1321 # fdesc: create variables about a steplist object.
1323 steplist_create ()
1329 # steplist can be create/release dynamically.
1330 # the default steplist is named null string.
1334 # fsyntax: steplist_release <steplist-name>
1335 # fdesc: release variables about a steplist object.
1337 steplist_release ()
1343 # fsyntax: src_list_init
1344 # fdesc: load src-list file.
1346 src_list_init ()
1348 local vname=
1349 local lang=$1
1350 local destdir=$2
1351 local extname=\"\${EXT_NAME_${lang,,}}\"
1352 local SRC_LIST_FILE="build/dest/dest-$DEST_NAME/${lang,,}-src-file.list"
1353 # local $(struupper lang)_SRC_FILE_LIST_Y=
1355 # infoo "src_list_init($extname, $@)\n"
1357 vname=$(struupper lang)_SRC_FILE_LIST_Y
1358 eval "${vname}=\"\""
1359 if test -e "${SRC_LIST_FILE}" ; then
1360 loadlist $SRC_LIST_FILE 2>/dev/null
1361 eval "${vname}=\"\${!vname//${extname,,}/\$'${extname,,}\n'}\""
1362 echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1363 echo ${vname}="${!vname}"
1365 eval echo "$vname=\${${vname}}"
1367 # test -e $SRC_LIST_FILE && eval "$(struupper lang)_SRC_FILE_LIST_Y=( $(cat $SRC_LIST_FILE | grep -v \"[[:space:]]*#\" | sed -e \"s/^[[:space:]]*#.*$//g\") )"
1369 test -z ${!vname} && taskinfo_dbgout no src file in src list. && return 0
1371 # taskinfo_dbgout $(struupper lang)_SRC_FILE_LIST_Y=${$(struupper lang)_SRC_FILE_LIST_Y[$i]}
1372 return 0
1376 # fsyntax: step_lang_src_tpchk <langlist-var> [<parameter-list> ... ]
1377 # fdesc: chk tp between srcfile and dstfile(obj).
1379 step_lang_exe_tpchk ()
1385 c_src2exe ()
1387 local lang=
1389 for lang in $1; do
1390 TASK_RUNNING STEP_$(struupper lang)_LANG_CMPL
1391 done