first version
[build-config.git] / build / constructor
blob3452db9941c15c107a5c042e1a4e8a990f359236
1 #!/bin/bash
2 ############################################################
3 # source: build
4 # author: devenkong(18151155@qq.com)
5 # date: 2022-04-21
6 ############################################################
7 # note:
8 # src-pkg compile utility. it orgnize compile file list
9 # and paramters like Makefile, but it is implemented by shell
10 # script.
11 ############################################################
14 # todo:
15 # @
16 # @
19 . shlibinc
21 include gplib.shlib
23 include stdio.shlib
24 #include term.shlib
25 include args.shlib
27 include shlib/toolchain.shlib
29 ##############################
30 # section: public comment info
31 ##############################
35 ##############################
36 # section: variable define
37 ##############################
39 SRCPKG_TOPDIR="."
40 SRCPKG_TOPDIR_ABP=""
41 OUTPUT_DIR_EVAL='$SRCPKG_TOPDIR/build/output'
42 OUTPUT_DIR_ABP_EVAL='$SRCPKG_TOPDIR_ABP/build/output'
44 SRCPKG_NAME=
48 ##############################
49 # section: private function
50 ##############################
53 # fsyntax: param_dbgout <output-string>
54 # fdesc: output string by dbgout switch.
56 param_dbgout ()
58 return
59 dbgoutd "$@"
63 # fsyntax: construct_dbgout <output-string>
64 # fdesc: output string by dbgout switch.
66 construct_dbgout ()
68 dbgoutd "$@"
72 # fsyntax: load_list_file <list-file-name>
73 # fdesc: load .list file. if not exist, load .lst file.
75 load_list_file ()
77 local data=
78 local bak=
79 local i=0
81 [[ ${1##*\.} != "lst" && ${1##*\.} != "list" ]] && err "specified file $1 is not .list or .lst file.\n" && return 1
83 if [[ -e "$1" ]]; then
84 param_dbgout "load_list_file($1)\n" >&2
86 while read data; do
87 : $(( i++ ))
88 # filter comment, and skip blank line.
89 [[ -z ${data//[[:space:]|]/} ]] && continue
90 if [[ ${data} =~ '#' ]]; then
91 [[ ${data} =~ ^[[:space:]]*[#] ]] && continue
92 data="${data//[[:space:]]*[#]*/}"
95 # append newline after every one.
96 # echo eval "${data}$'\n'" >&2
97 eval "${data}"$'"\n"'
98 [[ $? != 0 ]] && err "[line$i]: \"$data\" failed.\n"
99 # echo data=$data
100 bak="$data"
101 done < $1
102 # get var name, and delete redundent "\n".
103 # echo var=${bak}
104 bak="${bak%=*}"
105 # echo var=${bak}
106 # echo char=${bak: -1:1}
107 [[ ${bak: -1:1} == '+' ]] && bak="${bak:0:-1}"
108 # echo "char=\"${!bak: -3}\""
109 # echo "$bak=\"${!bak}\""
110 while [[ "${!bak: -1:1}" == $'\n' ]]; do
111 eval "$bak=\"\${!bak:0:-1}\""
112 # echo "xxxxx=================$bak=\"${!bak}\""
113 done
114 else
116 # err "list file is not exist.\n"
123 __setvar ()
125 eval "$@"
129 # fsyntax: load_imi_file <imi-file-name>
131 load_imi_file ()
133 local data=
134 local bak=
135 local vlist=
137 [[ ${1##*\.} != "imi" ]] && err "specified file $1 is not .imi file.\n" && return 1
139 if [[ -e "$1" ]]; then
140 param_dbgout "load_imi_file($1)\n"
142 while read data; do
143 # filter comment, and skip blank line.
144 [[ -z ${data//[[:space:]]/} ]] && continue
145 if [[ ${data} =~ '#' ]]; then
146 [[ ${data} =~ ^[[:space:]]*[#] ]] && continue
147 data="${data//[[:space:]]*[#]*/}"
150 # ignore [xxx] section setting, use it as an ini file.
151 [[ ${data} =~ ^[[:space:]]*\[ ]] && continue
153 if [[ ${data} =~ _EVL ]]; then
154 data="${data/_EVL/}"
156 # it can works with "" or '' in config file.
157 # multi-line paramter putted in a single line,
158 # and assign to the specified variable.
160 data="${data//\"/\\\"}"
161 data="${data//\'/\\\'}"
162 eval "$(eval echo ${data})" # \$\'\\\"\"\\\n\\\"\"\'
163 else
164 # append newline after every one.
165 eval ${data}$'"\n"'
168 # backup var name.
169 data="${data%=*}"
170 [[ ${data: -1,1} == '+' ]] && data="${data:0:-1}"
171 vlist+="${data}"$'\n'
172 done < "$1"
173 # echo "vlist=$vlist"
174 # get var name, and delete redundent "\n".
175 while read data; do
176 [[ -z $data ]] && continue
177 # echo var=$data=${!data}
178 while [[ "${!data: -1:1}" == $'\n' ]]; do
179 eval "$data=\"\${!data:0:-1}\""
180 # echo "=================$data=\"${!data}\""
181 done
182 done <<< "$vlist"
183 # eval "$bak=\"\${!bak:0:-1}\""
184 else
186 # err "list file is not exist.\n"
191 # dest
194 DEST_GENERAL_CFG_DIR_EVL='${SRCPKG_TOPDIR}/build/dest/dest-general'
195 DEST_CFG_DIR_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME'
197 DEST_NAME=
198 DEST_CFG_DIR_NAME=
199 DEST_CFG_DIR=
200 # for one dest, there are those config files in dest setting dir.
201 CFLAGS_DEF_LIST_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/CFLAGS-DEF.list'
202 CFLAGS_INCPATH_LIST_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/CFLAGS-INCPATH.list'
203 CFLAGS_MISC_IMI_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/CFLAGS-MISC.imi'
204 DEP_PKG_LIST_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/dep-pkg.list'
205 LDFLAGS_LIB_LIST_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/LDFLAGS-LIB.list'
206 LDFLAGS_LIBPATH_LIST_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/LDFLAGS-LIBPATH.list'
207 LDFLAGS_MISC_IMI_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/LDFLAGS-MISC.imi'
208 PARAMTERS_IMI_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/paramters.imi'
211 # fsyntax: one_dest_init <dest-name>
212 # fdesc: specified dest paramter load
214 one_dest_init ()
216 local DEST_CFG_DIR_NAME=$1
218 param_dbgout "one_dest_init($1)\n"
220 eval "DEST_CFG_DIR=\"${DEST_CFG_DIR_EVL}\""
222 # load CFLAGS-DEF.list
223 eval "CFLAGS_DEF_LIST=\"${CFLAGS_DEF_LIST_EVL}\""
224 # param_dbgout "CFLAGS_DEF_LIST=$CFLAGS_DEF_LIST\n"
225 load_list_file $CFLAGS_DEF_LIST
227 # load CFLAGS-INCPATH.list
228 eval "CFLAGS_INCPATH_LIST=\"${CFLAGS_INCPATH_LIST_EVL}\""
229 # param_dbgout "CFLAGS_INCPATH_LIST=$CFLAGS_INCPATH_LIST\n"
230 load_list_file $CFLAGS_INCPATH_LIST
232 # load CFLAGS-MISC.imi
233 eval "CFLAGS_MISC_IMI=\"${CFLAGS_MISC_IMI_EVL}\""
234 # param_dbgout "CFLAGS_MISC_IMI=$CFLAGS_MISC_IMI\n"
235 load_imi_file $CFLAGS_MISC_IMI
237 # load dep-pkg.list
238 eval "DEP_PKG_LIST=\"${DEP_PKG_LIST_EVL}\""
239 # param_dbgout "DEP_PKG_LIST=$DEP_PKG_LIST\n"
240 load_list_file $DEP_PKG_LIST
242 # load LDFLAGS_LIB.list
243 eval "LDFLAGS_LIB_LIST=\"${LDFLAGS_LIB_LIST_EVL}\""
244 # param_dbgout "LDFLAGS_LIB_LIST=$LDFLAGS_LIB_LIST\n"
245 load_list_file $LDFLAGS_LIB_LIST
247 # load LDFLAGS_LIBPATH.list
248 eval "LDFLAGS_LIBPATH_LIST=\"${LDFLAGS_LIBPATH_LIST_EVL}\""
249 # param_dbgout "LDFLAGS_LIBPATH_LIST=$LDFLAGS_LIBPATH_LIST\n"
250 load_list_file $LDFLAGS_LIBPATH_LIST
252 # load CFLAGS-MISC.imi
253 eval "LDFLAGS_MISC_IMI=\"${LDFLAGS_MISC_IMI_EVL}\""
254 # param_dbgout "LDFLAGS_MISC_IMI=$LDFLAGS_MISC_IMI\n"
255 load_imi_file $LDFLAGS_MISC_IMI
257 # load src list files
258 # -src-file and -src-dir can be included in this loading.
259 while read file; do
260 [[ ! ${file} =~ .+-src-.+ ]] && continue
261 load_list_file $file
262 done < <(ls -d -1 -f $DEST_CFG_DIR/{*.lst,*.list} 2>/dev/null)
264 # load CFLAGS & LDFLAGS imi file
266 # load paramters.imi
267 eval "PARAMTERS_IMI=\"${PARAMTERS_IMI_EVL}\""
268 # param_dbgout "PARAMTERS_IMI=$PARAMTERS_IMI\n"
269 load_imi_file $PARAMTERS_IMI
273 # fsyntax: dbgout_construct_param
274 # fdesc:
276 dbgout_construct_param ()
278 [[ -n $CFLAGS_DEF ]] && param_dbgout "CFLAGS_DEF=\"$CFLAGS_DEF\"\n"
279 [[ -n $CFLAGS_INCPATH ]] && param_dbgout "CFLAGS_INCPATH=\"$CFLAGS_INCPATH\"\n"
280 [[ -n $INC_PKG ]] && param_dbgout "INC_PKG=\"$INC_PKG\"\n"
281 [[ -n $LDFLAGS_LIBS ]] && param_dbgout "LDFLAGS_LIBS=\"$LDFLAGS_LIBS\"\n"
282 [[ -n $LDFLAGS_LIBPATH ]] && param_dbgout "LDFLAGS_LIBPATH=\"$LDFLAGS_LIBPATH\"\n\n"
284 [[ -n $CFLAGS_DBG ]] && param_dbgout "CFLAGS_DBG=\"$CFLAGS_DBG\"\n"
285 [[ -n $CFLAGS_SHARE ]] && param_dbgout "CFLAGS_SHARE=\"$CFLAGS_SHARE\"\n"
286 [[ -n $LDFLAGS_MISC ]] && param_dbgout "LDFLAGS_MISC=\"$LDFLAGS_MISC\"\n"
287 [[ -n $LDFLAGS_DBG ]] && param_dbgout "LDFLAGS_DBG=\"$LDFLAGS_DBG\"\n"
288 [[ -n $LDFLAGS_SHARE ]] && param_dbgout "LDFLAGS_SHARE=\"$LDFLAGS_SHARE\"\n\n"
290 [[ -n $CFLAGS ]] && param_dbgout "CFLAGS=\"$CFLAGS\"\n"
291 [[ -n $LDFLAGS ]] && param_dbgout "LDFLAGS=\"$LDFLAGS\"\n"
295 # fsyntax: dbgout_construct_param
296 # fdesc:
298 dest_param_reset ()
300 CFLAGS_DEF=""
301 CFLAGS_INCPATH=""
302 INC_PKG=""
303 LDFLAGS_LIBS=""
304 LDFLAGS_LIBPATH=""
306 CFLAGS_DBG=""
307 CFLAGS_SHARE=""
308 LDFLAGS_MISC=""
309 LDFLAGS_DBG=""
310 LDFLAGS_SHARE=""
312 LDFLAGS=""
313 CFLAGS=""
317 # fsyntax: construct_one_dest <dest-name>
318 # fdesc: construct one dest executables.
320 construct_one_dest ()
322 local dest=$1
323 local step=
325 param_dbgout "############################\n"
326 param_dbgout "construct_one_dest(${1#*-})\n"
328 # init one dest cfg paramter
329 eval "DEST_GENERAL_CFG_DIR=\"${DEST_GENERAL_CFG_DIR_EVL}\""
330 dest_param_reset
331 one_dest_init dest-general
332 one_dest_init $dest
334 CFLAGS="$CFLAGS"
336 dbgout_construct_param
338 # compile
339 compile_src_list
341 # link
342 link_dest
344 # for step in $STEPS; do
345 # #
346 # done
349 DEST_LIST_FILE_EVL='${SRCPKG_TOPDIR}/build/dest/dest.list'
350 VERSION_FILE_EVL='${SRCPKG_TOPDIR}/doc/VERSION'
353 # fsyntax: dest_list_init
354 # fdesc: load dest.imi cfg file, to get dest-list.
356 dest_list_init ()
358 param_dbgout "SRCPKG_TOPDIR=$SRCPKG_TOPDIR\n"
359 # BUILD_DEST is defined in this file
360 eval DEST_LIST_FILE="$DEST_LIST_FILE_EVL"
361 . $DEST_LIST_FILE
362 DEST_LIST=
363 DEST_NAME=
364 declare -g -A DEST_CFG_DIR=( )
365 # INST_PKG is defined in this file
366 INSTPKG_LIST_FILE="${SRCPKG_TOPDIR}/build/instpkg/instpkg.list"
367 declare -g -A INSTPKG_CFG_DIR=( )
371 # fsyntax: construct_all_dest <dest-name>
372 # fdesc: construct all dest executables.
374 construct_all_dest ()
376 # load dest.imi to get dest list.
377 dest_list_init
380 # load valid each dest.
382 if [[ -n $BUILD_DEST ]]; then
383 BUILD_DEST="${BUILD_DEST//dest-/$'\ndest-'}"
384 for dest in $BUILD_DEST; do
385 # declare -g -A DEST_CFG_DIR[${dest#*dest.?-}]="${SRCPKG_TOPDIR}/build/$dest"
386 DEST_CFG_DIR_NAME="$dest"
387 construct_one_dest $dest
388 done
389 DEST_LIST=( ${DEST_CFG_DIR[@]} )
390 echo DEST_CFG_DIR[@]=${DEST_CFG_DIR[@]}
391 else
392 err "no build dest defined in ${SRCPKG_TOPDIR}/build/dest/dest.list.\n"
393 return 1
398 ##############################
399 # section: public function
400 ##############################
402 eval "SRCPKG_TOPDIR=\"$SRCPKG_TOPDIR_EVAL\""
405 # fsyntax: construct_init
406 # fdesc: init construct variables.
407 # output:
408 # SRCPKG_TOPDIR, src pkg root dir.
409 # OUTPUT_DIR, it stores compile mid-file.
410 # VERSION_STRING,
411 # SRCPKG_FILENAME,
412 # SRCPKG_NAME,
414 construct_init ()
416 local dest=
418 # SRCPKG_TOPDIR
419 if [[ -d build ]]; then
420 SRCPKG_TOPDIR=""
421 # SRCPKG_TOPDIR="$PWD"
422 elif [[ $(basename $PWD) == build ]]; then
423 SRCPKG_TOPDIR="."
424 # SRCPKG_TOPDIR="$(cd ..; pwd)"
425 cd ..
427 # SRCPKG_TOPDIR="."
428 eval "SRCPKG_TOPDIR_ABP=\"$PWD\""
430 # if it has been defined, create src-pkg name sub-dir
431 if [[ -z $OUTPUT_DIR ]]; then
432 eval "OUTPUT_DIR=\"$OUTPUT_DIR_EVAL\""
433 # else
434 # OUTPUT_DIR="$OUTPUT_DIR/$SRCPKG_NAME"
436 if [[ -z $OUTPUT_DIR_ABP ]]; then
437 eval "OUTPUT_DIR_ABP=\"$OUTPUT_DIR_ABP_EVAL\""
440 date > ${OUTPUT_DIR}//build.log
441 time >> ${OUTPUT_DIR}/build/build.log
442 echo >> ${OUTPUT_DIR}/build/build.log
444 # load srcpkg name & version string.
445 eval "VERSION_FILE=\"$VERSION_FILE_EVL\""
446 . $VERSION_FILE
447 echo VERSION_STRING=$VERSION_STRING
448 echo SRCPKG_FILENAME=$SRCPKG_FILENAME
452 # fsyntax: get_CFLAGS
453 # fdesc: get CFLAGS.
455 get_CFLAGS ()
461 # fsyntax: compile_src_file
462 # fdesc: compile each src file.
464 src2dst_filename ()
466 local ext=
467 local dst=
468 ext="${SRC_FILE[0]##*.}"
470 DST_FILE[0]="${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${SRC_FILE[0]//\.$ext/\.o}"
471 DST_FILE[1]="${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${SRC_FILE[0]//\.$ext/\.dep}"
472 SRC_FILE[0]="${SRCPKG_TOPDIR}/${SRC_FILE[0]}"
475 src_obj_map[s]="o"
476 src_obj_map[S]="o"
477 src_obj_map[c]="o"
478 src_obj_map[cpp]="o"
480 src_obj_map[asm]="obj"
481 #src_obj_map[c]="obj"
482 #src_obj_map[cpp]="obj"
485 # fsyntax: compile_src_file
486 # fdesc: compile each src file.
488 compile_src_file ()
490 SRC_FILE[0]="$1"
492 src2dst_filename
493 # DST_FILE[0]="output/test.o"
494 # DST_FILE[1]="output/test.dep"
496 CMPL_FUNC
499 foo ()
501 # local C_SRC_LIST="dest/dest-libtui.so/c-src-file.list"
503 echo C_SRC_LIST=$C_SRC_LIST
504 if [[ -e $C_SRC_LIST ]]; then
505 . $C_SRC_LIST
506 C_SRC="${C_SRC//\.c/$'.c\n'}"
507 else
508 C_SRC_LIST="dest/dest-libtui.so/c-src-file.lst"
509 echo C_SRC_LIST=$C_SRC_LIST
510 [[ -e $C_SRC_LIST ]] && C_SRC=( $(cat $C_SRC_LIST | grep -v "^[[:space:]]*#" | sed -e "s/[[:space:]]*#.*$//g") )
515 # fsyntax: compile_src_list
516 # fdesc: compile each src file in src file list.
518 compile_src_list ()
520 local abc=
522 [[ -z ${C_SRC[@]} ]] && echo no src file in src list. && return 0
524 construct_dbgout "C_SRC=${C_SRC}\n"
526 for file in $C_SRC; do
527 [[ -z "$file" ]] && continue
529 construct_dbgout "file=$file\n"
530 compile_src_file $file
531 done
535 # fsyntax: link_dest
536 # fdesc: link .o files to an executable.
538 link_dest ()
540 local obj=
541 local flag=
543 SRC_FILE=( ${DST_FILE[@]} )
544 DST_FILE[0]="$1"
546 for obj in ${SRC_FILE[@]}; do
547 [[ $obj -nt ${DST_FILE[0]} ]] && flag=link && break;
548 done
550 if [[ $flag == 'link' ]]; then
551 o2exe
552 else
558 # construct_init
559 # construct_all_dest => dest_list_init()/construct_one_dest() => one_dest_init() =>
560 # compile_src_list()/link_list() => c2o()/o2exe()
563 main_constructor ()
565 echo GNU_CC=$GNU_CC
568 # program arguments resolve.
569 # it invoke opt_desc_str_dispatch and prog_opt_proc seperatly,
570 # instead of prog_opt_dispatch, for multiple desc-str.
571 # 测试起止范围id的初始化
572 # 初始化测试的tmp目录路径,设置testcase的目录
574 # prog_opt_dispatch "$@"
575 # opt_desc_str_dispatch scripttest_desc_str
576 # opt_desc_str_dispatch another_desc_str
577 # prog_opt_proc "$@"
579 # todo:
580 # ini文件加载环境变量
582 init_dbglogout 2 testing 20000
584 construct_init
585 #compile_src_list
586 construct_all_dest
588 return
592 #echo xxxxxxxxxxaaa
593 #exit
595 main_constructor "$@"
598 ##############################
599 # section: file tail
600 ##############################
604 # fsyntax: compile_src_list
605 # fdesc: compile each src file in src file list.
607 compile_src_list_bak ()
609 local abc=
610 local C_SRC_LIST="dest/dest-libtui.so/c-src-file.list"
612 echo C_SRC_LIST=$C_SRC_LIST
613 if [[ -e $C_SRC_LIST ]]; then
614 . $C_SRC_LIST
615 C_SRC="${C_SRC//\.c/$'.c\n'}"
616 else
617 C_SRC_LIST="dest/dest-libtui.so/c-src-file.lst"
618 echo C_SRC_LIST=$C_SRC_LIST
619 [[ -e $C_SRC_LIST ]] && C_SRC=( $(cat $C_SRC_LIST | grep -v "^[[:space:]]*#" | sed -e "s/[[:space:]]*#.*$//g") )
622 [[ -z ${C_SRC[@]} ]] && echo no src file in src list. && return 0
624 echo C_SRC=${C_SRC[$i]}
626 while read file; do
627 [[ -z "$file" ]] && continue
629 echo file=$file
630 compile_src_file $file
631 done < $C_SRC_LIST