use tokenlist for lexer parser.
[build-config.git] / build / constructor
bloba70c6fc8404e423a96edf5a4caeffb3dd6914dbf
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 # === ATTENSION ===
15 # @ use "while read file; do ; done <<< ${VAR}" to repalce
16 # "for file in $VAR; do ; done", if there are many files to
17 # be compiled, it while loop is suitable.
22 # todo:
23 # @ auto-generated file use ext-name ".auto", it could hint user that
24 # this file should not be modified menually, or follow the syntax
25 # of this file.
26 # @ compare compile err info, get err type, and show info for
27 # processing.
28 # eg: (.text+0x18): undefined reference to `main'
29 # by matching "undefined reference to", we can get the err type.
30 # get string of 'main', searching in src code to show infos.
31 # @ when searching src file, show the same name .c and .cpp file.
32 # @ reference code in linux, it put .c file and dir to be compiled
33 # in Makefile. for few file srcpkg, it uses c-src-file.list to include
34 # files to be compiled. for large number of src files in srcpkg, it
35 # uses .list file under src dir. which can include sub-dir nestly,
36 # and output a built-in.o or built-in.a file to combine the .o file
37 # in one dir.
38 # @
41 . shlibinc
43 include gplib.shlib
44 include stdio.shlib
45 #include term.shlib
46 include args.shlib
48 include shlib/toolchain.shlib
49 include shlib/constructor.shlib
50 include shlib/docgen.shlib
51 include shlib/tasks.shlib
52 #include shlib/constructor.shlib
54 ##############################
55 # section: public comment info
56 ##############################
60 ##############################
61 # section: variable define
62 ##############################
64 SRCPKG_TOPDIR=".."
65 SRCPKG_TOPDIR_ABP=""
66 OUTPUT_DIR_EVAL='$SRCPKG_TOPDIR/build/output'
67 OUTPUT_DIR_ABP_EVAL='$SRCPKG_TOPDIR_ABP/build/output'
69 SRCPKG_NAME=
71 DEST_LIST_FILE_EVL='${SRCPKG_TOPDIR}/build/dest/dest.list'
72 BUILD_STEP_IMI_EVL='${SRCPKG_TOPDIR}/build/dest/build-step.imi'
73 VERSION_FILE_EVL='${SRCPKG_TOPDIR}/doc/VERSION'
77 # XXX:
80 DEST_GENERAL_CFG_DIR_EVL='${SRCPKG_TOPDIR}/build/dest/dest-general'
81 DEST_CFG_DIR_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME'
83 DEST_NAME=
84 DEST_CFG_DIR_NAME=
85 DEST_CFG_DIR=
86 # for one dest, there are those config files in dest setting dir.
87 DEST_IMI_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/dest.imi'
88 ARFLAGS_MISC_IMI_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/ARFLAGS-MISC.imi'
89 CFLAGS_DEF_LIST_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/CFLAGS-DEF.list'
90 CFLAGS_INCPATH_LIST_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/CFLAGS-INCPATH.list'
91 CFLAGS_MISC_IMI_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/CFLAGS-MISC.imi'
92 DEP_PKG_LIST_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/dep-pkg.list'
93 LDFLAGS_LIB_LIST_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/LDFLAGS-LIB.list'
94 LDFLAGS_SHAREDLIB_IMI_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/LDFLAGS-SHAREDLIB.imi'
95 LDFLAGS_LIBPATH_LIST_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/LDFLAGS-LIBPATH.list'
96 LDFLAGS_MISC_IMI_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/LDFLAGS-MISC.imi'
97 STATIC_LIB_FILE_LIST_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/static-lib-file.list'
98 PARAMTERS_IMI_EVL='${SRCPKG_TOPDIR}/build/dest/$DEST_CFG_DIR_NAME/paramters.imi'
101 OBJ_LIST=
104 ##############################
105 # section: private function
106 ##############################
109 # fsyntax: buildparam_dbgout <output-string>
110 # fdesc: output string by dbgout switch.
112 #buildparam_dbgout ()
114 # return
115 # dbgoutd "$@"
119 # fsyntax: construct_dbgout <output-string>
120 # fdesc: output string by dbgout switch.
122 construct_dbgout ()
124 dbgoutd "$@"
128 # fsyntax: load_list_file <list-file-name>
129 # fdesc: load .list file. if not exist, load .lst file.
131 load_list_file ()
133 local data=
134 local bak=
135 local i=0
137 buildparam_dbgout "load_list_file($1)\n"
139 [[ ${1##*\.} != "lst" && ${1##*\.} != "list" ]] && err "specified file $1 is not .list or .lst file.\n" && return 1
141 if [[ -e "$1" ]]; then
142 while read data; do
143 : $(( i++ ))
144 # filter comment, and skip blank line.
145 [[ -z ${data//[[:space:]|]/} ]] && continue
146 if [[ ${data} =~ '#' ]]; then
147 [[ ${data} =~ ^[[:space:]]*[#] ]] && continue
148 data="${data//[[:space:]]*[#]*/}"
149 [[ -z "${data}" ]] && continue
152 # append newline after every one.
153 eval "${data}"$'"\n"'
154 [[ $? != 0 ]] && err "[line$i]: \"$data\" failed.\n"
155 bak="$data"
156 done < $1
157 # get var name, and delete redundent "\n".
158 bak="${bak%=*}"
159 [[ ${bak: -1:1} == '+' ]] && bak="${bak:0:-1}"
160 while [[ "${!bak: -1:1}" == $'\n' ]]; do
161 eval "$bak=\"\${!bak:0:-1}\""
162 done
163 else
165 # err "list file is not exist.\n"
170 # fsyntax: load_imi_file <imi-file-name>
172 load_imi_file ()
174 local data=
175 local bak=
176 local vlist=
177 local flag=""
178 local tmp=
180 buildparam_dbgout "load_imi_file ($@)\n"
182 # it's normal if file is not exist.
183 [[ ! -e ${1} ]] && buildparam_dbgout "parameter file($1) is not exist.\n" && return 0
185 [[ ${1##*\.} != "imi" ]] && err "specified file $1 is not .imi file.\n" && return 1
187 if [[ -e "$1" ]]; then
188 while read data; do
189 [[ "${data}" =~ $'\r' ]] && data=$(echo ${data:0:-1})
190 # filter comment, and skip blank line.
191 [[ -z ${data//[[:space:]]/} ]] && continue
192 if [[ ${data} =~ '#' ]]; then
193 [[ ${data} =~ ^[[:space:]]*[#] ]] && continue
194 data="${data//[[:space:]]*[#].*/}"
197 if [[ "${data}" =~ '=(' ]]; then
198 flag="array"
199 tmp="${data}"$'\n'
200 continue
203 if [[ "${flag}" == 'array' ]]; then
204 if [[ "${data}" =~ ')' ]]; then
205 tmp+="${data%%\)*})"$'\n'
206 data="$tmp"
207 flag=""
208 else
209 tmp+="${data}"$'\n'
210 continue
214 # ignore [xxx] section setting, use it as an ini file.
215 [[ ${data} =~ ^[[:space:]]*\[ ]] && continue
217 if [[ ${data} =~ _EVL ]]; then
218 data="${data/_EVL/}"
220 # it can works with "" or '' in config file.
221 # multi-line paramter putted in a single line,
222 # and assign to the specified variable.
224 data="${data//\"/\\\"}"
225 data="${data//\'/\\\'}"
226 # buildparam_dbgout "=== ${data}\n"
227 eval "$(eval echo ${data})" # \$\'\\\"\"\\\n\\\"\"\'
228 else
229 # append newline after every one.
230 # buildparam_dbgout "=== ${data}\n"
231 eval ${data}
232 #$'"\n"'
235 # backup var name.
236 data="${data%=*}"
237 [[ ${data: -1,1} == '+' ]] && data="${data:0:-1}"
238 vlist+="${data}"$'\n'
239 done < "$1"
241 # get var name, and delete redundent "\n".
242 while read data; do
243 [[ -z $data ]] && continue
245 while [[ "${!data: -1:1}" == $'\n' ]]; do
246 eval "$data=\"\${!data:0:-1}\""
247 done
248 done <<< "$vlist"
249 else
251 # err "list file is not exist.\n"
257 ##############################
258 # section: public function
259 ##############################
262 # fsyntax: dbgout_construct_param
263 # fdesc:
265 dbgout_construct_param ()
267 [[ -n $CFLAGS_DEF ]] && buildparam_dbgout "CFLAGS_DEF=\"$CFLAGS_DEF\"\n"
268 [[ -n $CFLAGS_INCPATH ]] && buildparam_dbgout "CFLAGS_INCPATH=\"$CFLAGS_INCPATH\"\n"
269 [[ -n $INC_PKG ]] && buildparam_dbgout "INC_PKG=\"$INC_PKG\"\n"
270 [[ -n $LDFLAGS_LIBS ]] && buildparam_dbgout "LDFLAGS_LIBS=\"$LDFLAGS_LIBS\"\n"
271 [[ -n $LDFLAGS_LIBPATH ]] && buildparam_dbgout "LDFLAGS_LIBPATH=\"$LDFLAGS_LIBPATH\"\n\n"
273 [[ -n $CFLAGS_DBG ]] && buildparam_dbgout "CFLAGS_DBG=\"$CFLAGS_DBG\"\n"
274 [[ -n $CFLAGS_SHARE ]] && buildparam_dbgout "CFLAGS_SHARE=\"$CFLAGS_SHARE\"\n"
275 [[ -n $LDFLAGS_MISC ]] && buildparam_dbgout "LDFLAGS_MISC=\"$LDFLAGS_MISC\"\n"
276 [[ -n $LDFLAGS_DBG ]] && buildparam_dbgout "LDFLAGS_DBG=\"$LDFLAGS_DBG\"\n"
277 [[ -n $LDFLAGS_SHARE ]] && buildparam_dbgout "LDFLAGS_SHARE=\"$LDFLAGS_SHARE\"\n\n"
279 [[ -n $CFLAGS ]] && buildparam_dbgout "CFLAGS=\"$CFLAGS\"\n"
280 [[ -n $LDFLAGS ]] && buildparam_dbgout "LDFLAGS=\"$LDFLAGS\"\n"
284 # fsyntax: dbgout_construct_param
285 # fdesc:
287 dest_param_reset ()
289 C_SRC_LIST=""
290 CXX_SRC_LIST=""
291 CPP_SRC_LIST=""
292 ASM_SRC_LIST=""
293 SH_SRC_LIST=""
294 STATIC_LIB_LIST=""
296 CFLAGS_DEF=""
297 CFLAGS_INCPATH=""
298 INC_PKG=""
299 LDFLAGS_LIBS=""
300 LDFLAGS_LIBPATH=""
302 CFLAGS_DBG=""
303 CFLAGS_SHARE=""
304 LDFLAGS_MISC=""
305 LDFLAGS_DBG=""
306 LDFLAGS_SHARE=""
308 LDFLAGS=""
309 CFLAGS=""
313 # dest
319 dest_info_init ()
321 # load dest.imi
322 eval "DEST_IMI=\"${DEST_IMI_EVL}\""
323 load_imi_file $DEST_IMI
327 # fsyntax: one_dest_init <dest-name>
328 # fdesc: specified dest paramter load
330 one_dest_init ()
332 DEST_CFG_DIR_NAME=$1
334 buildparam_dbgout "one_dest_init($1)\n"
336 eval "DEST_CFG_DIR=\"${DEST_CFG_DIR_EVL}\""
338 # load ARFLAGS_MISC.list
339 eval "ARFLAGS_MISC_IMI=\"${ARFLAGS_MISC_IMI_EVL}\""
340 # buildparam_dbgout "ARFLAGS_MISC_IMI=$ARFLAGS_MISC_IMI\n"
341 load_imi_file $ARFLAGS_MISC_IMI
343 # load CFLAGS-DEF.list
344 eval "CFLAGS_DEF_LIST=\"${CFLAGS_DEF_LIST_EVL}\""
345 # buildparam_dbgout "CFLAGS_DEF_LIST=$CFLAGS_DEF_LIST\n"
346 load_list_file $CFLAGS_DEF_LIST
348 # load CFLAGS-INCPATH.list
349 eval "CFLAGS_INCPATH_LIST=\"${CFLAGS_INCPATH_LIST_EVL}\""
350 # buildparam_dbgout "CFLAGS_INCPATH_LIST=$CFLAGS_INCPATH_LIST\n"
351 load_list_file $CFLAGS_INCPATH_LIST
353 # load CFLAGS-MISC.imi
354 eval "CFLAGS_MISC_IMI=\"${CFLAGS_MISC_IMI_EVL}\""
355 # buildparam_dbgout "CFLAGS_MISC_IMI=$CFLAGS_MISC_IMI\n"
356 load_imi_file $CFLAGS_MISC_IMI
358 # load dep-pkg.list
359 eval "DEP_PKG_LIST=\"${DEP_PKG_LIST_EVL}\""
360 # buildparam_dbgout "DEP_PKG_LIST=$DEP_PKG_LIST\n"
361 load_list_file $DEP_PKG_LIST
363 # load LDFLAGS_LIB.list
364 eval "LDFLAGS_LIB_LIST=\"${LDFLAGS_LIB_LIST_EVL}\""
365 # buildparam_dbgout "LDFLAGS_LIB_LIST=$LDFLAGS_LIB_LIST\n"
366 load_list_file $LDFLAGS_LIB_LIST
368 # load LDFLAGS_LIB.list
369 eval "LDFLAGS_SHAREDLIB_IMI=\"${LDFLAGS_SHAREDLIB_IMI_EVL}\""
370 # echo "LDFLAGS_SHAREDLIB_IMI=$LDFLAGS_SHAREDLIB_IMI\n"
371 load_imi_file $LDFLAGS_SHAREDLIB_IMI
372 # echo "LDFLAGS_SHARE=$LDFLAGS_SHARE\n"
374 # load LDFLAGS_LIBPATH.list
375 eval "LDFLAGS_LIBPATH_LIST=\"${LDFLAGS_LIBPATH_LIST_EVL}\""
376 # buildparam_dbgout "LDFLAGS_LIBPATH_LIST=$LDFLAGS_LIBPATH_LIST\n"
377 load_list_file $LDFLAGS_LIBPATH_LIST
379 # load CFLAGS-MISC.imi
380 eval "LDFLAGS_MISC_IMI=\"${LDFLAGS_MISC_IMI_EVL}\""
381 # buildparam_dbgout "LDFLAGS_MISC_IMI=$LDFLAGS_MISC_IMI\n"
382 load_imi_file $LDFLAGS_MISC_IMI
384 # TBD: disable src-list load in init. load it before corresponding
385 # program language src file list compile.
386 if false; then
387 # load src list files
388 # -src-file and -src-dir can be included in this loading.
389 while read file; do
390 [[ ! ${file} =~ .+-src-.+ ]] && continue
391 load_list_file $file
392 done < <(ls -d -1 -f $DEST_CFG_DIR/{*.lst,*.list} 2>/dev/null)
395 # load LDFLAGS_LIBPATH.list
396 eval "STATIC_LIB_FILE_LIST=\"${STATIC_LIB_FILE_LIST_EVL}\""
397 # buildparam_dbgout "STATIC_LIB_FILE_LIST=$STATIC_LIB_FILE_LIST\n"
398 load_list_file $STATIC_LIB_FILE_LIST
400 # load CFLAGS & LDFLAGS imi file
402 # load paramters.imi
403 eval "PARAMTERS_IMI=\"${PARAMTERS_IMI_EVL}\""
404 # buildparam_dbgout "PARAMTERS_IMI=$PARAMTERS_IMI\n"
405 load_imi_file $PARAMTERS_IMI
407 buildparam_dbgout "CFLAGS=$CFLAGS\n"
408 buildparam_dbgout "LDFLAGS=$LDFLAGS\n"
412 # fsyntax: dest_init
413 # fdesc: init one dest build. it loads the relative paramter files.
415 dest_init ()
417 local dest=${dest#*-}
418 local step=
419 local ret=
421 declare -g $1="${2#*-}"
423 # init one dest cfg paramter
424 eval "DEST_GENERAL_CFG_DIR=\"${DEST_GENERAL_CFG_DIR_EVL}\""
425 dest_param_reset
426 one_dest_init dest-general
427 one_dest_init $2
429 CFLAGS="$CFLAGS"
431 mkdir -p ${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/
433 unset OBJ_LIST
434 declare -g OBJ_LIST=""
436 dest_info_init
438 dbgout_construct_param
439 buildstep_dbgout "############################\n"
440 buildstep_dbgout "construct_one_dest($1, ${!1}, ${2#*-})\n"
441 buildstep_dbgout "############################\n"
443 info "[BUILD-DEST] ${2#*-}"
445 return 0
449 # fsyntax: build_step_init
450 # fdesc: load build-step.imi cfg file.
452 build_step_init ()
454 # load CFLAGS-MISC.imi
455 eval "BUILD_STEP_IMI=\"${BUILD_STEP_IMI_EVL}\""
456 buildparam_dbgout "BUILD_STEP_IMI=$BUILD_STEP_IMI\n"
457 # buildparam_dbgout "BUILD_STEP_IMI=$BUILD_STEP_IMI\n"
458 # load_imi_file $BUILD_STEP_IMI
459 # use source instead of load_imi_file
460 . $BUILD_STEP_IMI
464 # fsyntax: dest_list_init
465 # fdesc: load dest.imi cfg file, to get dest-list.
467 dest_list_init ()
469 DEST_LIST=
470 DEST_NAME=
472 buildparam_dbgout "SRCPKG_TOPDIR=$SRCPKG_TOPDIR\n"
474 # BUILD_DEST is defined in this file
475 eval DEST_LIST_FILE="$DEST_LIST_FILE_EVL"
476 . $DEST_LIST_FILE
477 DEST_LIST="${BUILD_DEST//dest-/$'\ndest-'}"
479 buildparam_dbgout "###############################\n"
480 buildparam_dbgout "dest_list_init($DEST_LIST_FILE)\n"
481 buildparam_dbgout "DEST_LIST=\"$DEST_LIST\"\n"
483 declare -g -A DEST_CFG_DIR=( )
484 # INST_PKG is defined in this file
485 INSTPKG_LIST_FILE="${SRCPKG_TOPDIR}/build/instpkg/instpkg.list"
486 declare -g -A INSTPKG_CFG_DIR=( )
490 # fsyntax: construct_init
491 # fdesc: init construct variables.
492 # output:
493 # SRCPKG_TOPDIR, src pkg root dir.
494 # OUTPUT_DIR, it stores compile mid-file.
495 # VERSION_STRING,
496 # SRCPKG_FILENAME,
497 # SRCPKG_NAME,
499 construct_init ()
501 local dest=
503 # SRCPKG_TOPDIR
504 if [[ -d build ]]; then
505 SRCPKG_TOPDIR=""
506 # SRCPKG_TOPDIR="$PWD"
507 eval "SRCPKG_TOPDIR_ABP=\"$PWD\""
508 elif [[ $(basename $PWD) == build ]]; then
509 SRCPKG_TOPDIR="."
510 # SRCPKG_TOPDIR="$(cd ..; pwd)"
511 cd ..
512 eval "SRCPKG_TOPDIR_ABP=\"$PWD\""
514 # SRCPKG_TOPDIR="."
516 # if it has been defined, create src-pkg name sub-dir
517 if [[ -z $OUTPUT_DIR ]]; then
518 eval "OUTPUT_DIR=\"$OUTPUT_DIR_EVAL\""
519 # else
520 # OUTPUT_DIR="$OUTPUT_DIR/$SRCPKG_NAME"
522 if [[ -z $OUTPUT_DIR_ABP ]]; then
523 eval "OUTPUT_DIR_ABP=\"$OUTPUT_DIR_ABP_EVAL\""
526 # echo OUTPUT_DIR=$OUTPUT_DIR
527 info_dbgout_init
529 date > ${OUTPUT_DIR}/build.log
530 echo >> ${OUTPUT_DIR}/build.log
532 # load srcpkg name & version string.
533 eval "VERSION_FILE=\"$VERSION_FILE_EVL\""
535 source $VERSION_FILE
536 buildparam_dbgout VERSION_STRING=$VERSION_STRING
537 buildparam_dbgout SRCPKG_FILENAME=$SRCPKG_FILENAME
538 buildparam_dbgout SRCPKG_NAME=$SRCPKG_NAME
540 # set env $PATH
541 PATH="$SRCPKG_TOPDIR/support/:$PATH"
543 mkdir -p ${OUTPUT_DIR}
545 # load dest.list & build-step.imi to get dest list.
546 dest_list_init
547 build_step_init
549 # load srcpkg shlib file
550 [[ -z $SRCPKG_NAME ]] && err "SRCPKG_NAME defined in file of doc/VERSION is not valid.\n"
551 include build/${SRCPKG_NAME}.shlib
553 buildstep_dbgout "############################\n"
554 buildstep_dbgout "construct_init()\n"
555 buildstep_dbgout "############################\n"
559 # construct_init
560 # construct_all_dest => dest_list_init()/construct_one_dest() => one_dest_init() =>
561 # compile_src_list()/link_list() => c2o()/o2exe()
563 construct ()
565 construct_init
567 TASK_RUNNING "STEP_BUILD_DEST"
570 main_constructor ()
573 # program arguments resolve.
574 # it invoke opt_desc_str_dispatch and prog_opt_proc seperatly,
575 # instead of prog_opt_dispatch, for multiple desc-str.
576 # 测试起止范围id的初始化
577 # 初始化测试的tmp目录路径,设置testcase的目录
579 # prog_opt_dispatch "$@"
581 # opt_desc_str_dispatch scripttest_desc_str
582 # opt_desc_str_dispatch another_desc_str
583 # prog_opt_proc "$@"
585 # todo:
586 # ini文件加载环境变量
588 init_dbglogout 2 testing 20000
590 construct
592 return
595 ##########################################################################
597 ##########################################################################
599 main_constructor "$@"
602 ##############################
603 # section: file tail
604 ##############################